Skip to content

Instantly share code, notes, and snippets.

@moloneymb
Created December 18, 2018 07:24
Show Gist options
  • Save moloneymb/107c24ca3705e72b672ff19290c9b3a7 to your computer and use it in GitHub Desktop.
Save moloneymb/107c24ca3705e72b672ff19290c9b3a7 to your computer and use it in GitHub Desktop.
namespace Tsunami.IDE.UI.SplitView2
open System
open System.Windows
open System.Windows.Input
open System.Windows.Controls
open System.Collections.ObjectModel
open System.Windows.Media.Imaging
open Tsunami.Utilities
open Microsoft.Win32
open Tsunami
open Tsunami.IDE.UI
open Tsunami.Utilities
open System
open System.Xml
open System.Xml.Linq
open System.IO
open System.Windows
open System.Windows.Input
open System.Windows.Controls
open System.Collections.ObjectModel
open System.Windows.Controls
open System.ComponentModel
open System.ComponentModel.DataAnnotations
open System.Windows.Data
open System.Windows.Media
open System.Windows.Markup
open System.Xaml
open Tsunami.IDE.UI
open System.Windows.Data
open System.Windows.Documents
open System.Windows.Input
open System.Windows.Media
open System.Windows.Media.Imaging
open System.Windows.Navigation
open System.Windows.Shapes
open System.Windows.Controls
open ActiproSoftware.Windows.Controls.SyntaxEditor
open System.Windows
open System.Windows.Controls
open Tsunami.Utilities
[<System.Flags>]
type SplitViewState =
| VerticalLeft = 1
| VerticalCenter = 2
| VerticalRight = 3
| HorizontalTop = 4
| HorizontalCenter = 5
| HorizontalBottom = 6
[<TemplatePart(Name = "PART_Main_Grid", Type = typeof<Grid>)>]
[<TemplatePart(Name = "PART_A_Host", Type = typeof<ContentPresenter>)>]
[<TemplatePart(Name = "PART_B_Host", Type = typeof<ContentPresenter>)>]
[<TemplatePart(Name = "PART_A_Vertical_Header", Type = typeof<ContentPresenter>)>]
[<TemplatePart(Name = "PART_B_Vertical_Header", Type = typeof<ContentPresenter>)>]
[<TemplatePart(Name = "PART_A_Horizontal_Header", Type = typeof<ContentPresenter>)>]
[<TemplatePart(Name = "PART_B_Horizontal_Header", Type = typeof<ContentPresenter>)>]
[<TemplatePart(Name = "PART_Splitter", Type = typeof<GridSplitter>)>]
[<TemplatePart(Name = "PART_Splitter_Controls", Type = typeof<Panel>)>]
[<TemplatePart(Name = "PART_Extra_Buttons_Host", Type = typeof<Panel>)>]
[<TemplatePart(Name = "PART_Swap_Button_Vertical", Type = typeof<Button>)>]
[<TemplatePart(Name = "PART_Swap_Button_Horizontal", Type = typeof<Button>)>]
[<TemplatePart(Name = "PART_Vertical_ToggleButton", Type = typeof<System.Windows.Controls.Primitives.ToggleButton>)>]
[<TemplatePart(Name = "PART_Horizontal_ToggleButton", Type = typeof<System.Windows.Controls.Primitives.ToggleButton>)>]
[<TemplatePart(Name = "PART_Move_Up_Button", Type = typeof<Button>)>]
[<TemplatePart(Name = "PART_Move_Down_Button", Type = typeof<Button>)>]
[<TemplatePart(Name = "PART_Move_Left_Button", Type = typeof<Button>)>]
[<TemplatePart(Name = "PART_Move_Right_Button", Type = typeof<Button>)>]
type SplitViewControl() =
inherit Control()
let mutable lastRightWidth = GridLength(1.,GridUnitType.Star)
let mutable lastLeftWidth = GridLength(1.,GridUnitType.Star)
let mutable lastTopHeight = GridLength(1.,GridUnitType.Star)
let mutable lastBottomHeight = GridLength(1.,GridUnitType.Star)
static let controlAProperty = DependencyProperty.RegisterAttached("ControlA", typeof<Control>, typeof<SplitViewControl>)
static let controlBProperty = DependencyProperty.RegisterAttached("ControlB", typeof<Control>, typeof<SplitViewControl>)
static let splitterControlProperty = DependencyProperty.RegisterAttached("SplitterControl", typeof<UIElement>, typeof<SplitViewControl>)
static let verticalHeaderAProperty = DependencyProperty.RegisterAttached("VerticalHeaderA", typeof<UIElement>, typeof<SplitViewControl>)
static let verticalHeaderBProperty = DependencyProperty.RegisterAttached("VerticalHeaderB", typeof<UIElement>, typeof<SplitViewControl>)
static let horizontalHeaderAProperty = DependencyProperty.RegisterAttached("HorizontalHeaderA", typeof<UIElement>, typeof<SplitViewControl>)
static let horizontalHeaderBProperty = DependencyProperty.RegisterAttached("HorizontalHeaderB", typeof<UIElement>, typeof<SplitViewControl>)
static let swappedProperty = DependencyProperty.RegisterAttached("Swapped", typeof<bool>, typeof<SplitViewControl>, PropertyMetadata(false))
static let rightWidthProperty = DependencyProperty.RegisterAttached("RightWidth", typeof<GridLength>, typeof<SplitViewControl>, PropertyMetadata(GridLength(1.,GridUnitType.Star)))
static let leftWidthProperty = DependencyProperty.RegisterAttached("LeftWidth", typeof<GridLength>, typeof<SplitViewControl>, PropertyMetadata(GridLength(1.,GridUnitType.Star)))
static let topHeightProperty = DependencyProperty.RegisterAttached("TopHeight", typeof<GridLength>, typeof<SplitViewControl>, PropertyMetadata(GridLength(1.,GridUnitType.Star)))
static let bottomHeightProperty = DependencyProperty.RegisterAttached("BottomHeight", typeof<GridLength>, typeof<SplitViewControl>, PropertyMetadata(GridLength(1.,GridUnitType.Star)))
static let orientationProperty = DependencyProperty.RegisterAttached("Orientation", typeof<Orientation>, typeof<SplitViewControl>, PropertyMetadata(Orientation.Vertical))
static let callback = PropertyChangedCallback(fun d e ->
match d with
| :? SplitViewControl as svc ->
match e.NewValue with
| :? SplitViewState as x ->
match x with
| SplitViewState.VerticalLeft ->
d.SetValue(leftWidthProperty, GridLength(0., GridUnitType.Star))
d.SetValue(orientationProperty, Orientation.Vertical)
| SplitViewState.VerticalCenter ->
d.SetValue(leftWidthProperty, svc.LastLeftWidth)
d.SetValue(rightWidthProperty, svc.LastRightWidth)
d.SetValue(orientationProperty, Orientation.Vertical)
| SplitViewState.VerticalRight ->
d.SetValue(rightWidthProperty, GridLength(0., GridUnitType.Star))
d.SetValue(orientationProperty, Orientation.Vertical)
| SplitViewState.HorizontalTop ->
d.SetValue(topHeightProperty, GridLength(0., GridUnitType.Star))
d.SetValue(orientationProperty, Orientation.Horizontal)
| SplitViewState.HorizontalCenter ->
d.SetValue(topHeightProperty, svc.LastTopHeight)
d.SetValue(bottomHeightProperty, svc.LastBottomHeight)
d.SetValue(orientationProperty, Orientation.Horizontal)
| SplitViewState.HorizontalBottom ->
d.SetValue(bottomHeightProperty, GridLength(0., GridUnitType.Star))
d.SetValue(orientationProperty, Orientation.Horizontal)
| _ -> ()
| _ -> ()
| _ -> ()
)
static let viewStateProperty = DependencyProperty.RegisterAttached("ViewState", typeof<SplitViewState>, typeof<SplitViewControl>, PropertyMetadata(SplitViewState.VerticalCenter, callback))
static member public SetControlA(d:DependencyObject, source) = d.SetValue(controlAProperty, source)
static member public GetControlA(d:DependencyObject) = d.GetValue(controlAProperty) :?> Control
static member public SetControlB(d:DependencyObject, source) = d.SetValue(controlBProperty, source)
static member public GetControlB(d:DependencyObject) = d.GetValue(controlBProperty) :?> Control
static member public SetSplitterControl(d:DependencyObject, source) = d.SetValue(controlBProperty, source)
static member public GetSplitterControl(d:DependencyObject) = d.GetValue(splitterControlProperty) :?> UIElement
static member public SetVerticalHeaderA(d:DependencyObject, source) = d.SetValue(verticalHeaderAProperty, source)
static member public GetVerticalHeaderA(d:DependencyObject) = d.GetValue(verticalHeaderAProperty) :?> UIElement
static member public SetVerticalHeaderB(d:DependencyObject, source) = d.SetValue(verticalHeaderBProperty, source)
static member public GetVerticalHeaderB(d:DependencyObject) = d.GetValue(verticalHeaderBProperty) :?> UIElement
static member public SetHorizontalHeaderA(d:DependencyObject, source) = d.SetValue(horizontalHeaderAProperty, source)
static member public GetHorizontalHeaderA(d:DependencyObject) = d.GetValue(horizontalHeaderAProperty) :?> UIElement
static member public SetHorizontalHeaderB(d:DependencyObject, source) = d.SetValue(horizontalHeaderBProperty, source)
static member public GetHorizontalHeaderB(d:DependencyObject) = d.GetValue(horizontalHeaderBProperty) :?> UIElement
static member public SetRightWidth(d:DependencyObject, source) = d.SetValue(rightWidthProperty, source)
static member public GetRightWidth(d:DependencyObject) = d.GetValue(rightWidthProperty) :?> GridLength
static member public SetLeftWidth(d:DependencyObject, source) = d.SetValue(leftWidthProperty, source)
static member public GetLeftWidth(d:DependencyObject) = d.GetValue(leftWidthProperty) :?> GridLength
static member public SetTopHeight(d:DependencyObject, source) = d.SetValue(topHeightProperty, source)
static member public GetTopHeight(d:DependencyObject) = d.GetValue(topHeightProperty) :?> GridLength
static member public SetBottomHeight(d:DependencyObject, source) = d.SetValue(bottomHeightProperty, source)
static member public GetBottomHeight(d:DependencyObject) = d.GetValue(bottomHeightProperty) :?> GridLength
static member public SetSwapped(d:DependencyObject, source) = d.SetValue(swappedProperty, source)
static member public GetSwapped(d:DependencyObject) = d.GetValue(swappedProperty) :?> bool
static member public GetOrientation(d:DependencyObject) = d.GetValue(orientationProperty) :?> Orientation
static member public SetViewState(d:DependencyObject, source) = d.SetValue(viewStateProperty, source)
static member public GetViewState(d:DependencyObject) = d.GetValue(viewStateProperty) :?> SplitViewState
static member ControlAProperty = controlAProperty
static member ControlBProperty = controlBProperty
static member SplitterControlProperty = splitterControlProperty
static member VerticalHeaderAProperty = verticalHeaderAProperty
static member VerticalHeaderBProperty = verticalHeaderBProperty
static member HorizontalHeaderAProperty = horizontalHeaderAProperty
static member HorizontalHeaderBProperty = horizontalHeaderBProperty
static member SwappedProperty = swappedProperty
static member RightWidthProperty = rightWidthProperty
static member LeftWidthProperty = leftWidthProperty
static member TopHeightProperty = topHeightProperty
static member BottomHeightProperty = bottomHeightProperty
static member OrientationProperty = orientationProperty
static member ViewStateProperty = viewStateProperty
member this.LastRightWidth with get() = lastRightWidth and set(x) = lastRightWidth <- x
member this.LastLeftWidth with get() = lastLeftWidth and set(x) = lastLeftWidth <- x
member this.LastTopHeight with get() = lastTopHeight and set(x) = lastTopHeight <- x
member this.LastBottomHeight with get() = lastBottomHeight and set(x) = lastBottomHeight <- x
member this.ViewState with get() = this.GetValue(viewStateProperty) :?> SplitViewState and set (x:SplitViewState) = this.SetValue(viewStateProperty,x)
member this.ControlA with get() = this.GetValue(controlAProperty) :?> Control and set(x:Control) = this.SetValue(controlAProperty,x)
member this.ControlB with get() = this.GetValue(controlBProperty) :?> Control and set(x:Control) = this.SetValue(controlBProperty,x)
member this.SplitterControl with get() = this.GetValue(splitterControlProperty) :?> UIElement and set(x:UIElement) = this.SetValue(splitterControlProperty,x)
member this.VerticalHeaderA with get() = this.GetValue(verticalHeaderAProperty) :?> UIElement and set(x:UIElement) = this.SetValue(verticalHeaderAProperty,x)
member this.VerticalHeaderB with get() = this.GetValue(verticalHeaderBProperty) :?> UIElement and set(x:UIElement) = this.SetValue(verticalHeaderBProperty,x)
member this.HorizontalHeaderA with get() = this.GetValue(horizontalHeaderAProperty) :?> UIElement and set(x:UIElement) = this.SetValue(horizontalHeaderAProperty,x)
member this.HorizontalHeaderB with get() = this.GetValue(horizontalHeaderBProperty) :?> UIElement and set(x:UIElement) = this.SetValue(horizontalHeaderBProperty,x)
member this.LeftWidth with get() = this.GetValue(leftWidthProperty) :?> GridLength and set (x:GridLength) = this.SetValue(leftWidthProperty,x)
member this.RightWidth with get() = this.GetValue(rightWidthProperty) :?> GridLength and set (x:GridLength) = this.SetValue(rightWidthProperty,x)
member this.TopHeight with get() = this.GetValue(topHeightProperty) :?> GridLength and set (x:GridLength) = this.SetValue(topHeightProperty,x)
member this.BottomHeight with get() = this.GetValue(bottomHeightProperty) :?> GridLength and set (x:GridLength) = this.SetValue(bottomHeightProperty,x)
member this.Swapped with get() = this.GetValue(swappedProperty) :?> bool and set(x:bool) = this.SetValue(swappedProperty,x)
member this.Orientation with get() = this.GetValue(orientationProperty) :?> Orientation
member this.PublicGetTemplateChild(name:string) = this.GetTemplateChild(name)
override this.OnApplyTemplate() =
maybe {
let! main_grid = this.PublicGetTemplateChild("PART_Main_Grid") |> ofType<Grid>
let! a_host = this.PublicGetTemplateChild("PART_A_Host") |> ofType<ContentPresenter>
let! b_host = this.PublicGetTemplateChild("PART_B_Host") |> ofType<ContentPresenter>
let! a_vertical_header = this.PublicGetTemplateChild("PART_A_Vertical_Header") |> ofType<ContentPresenter>
let! b_vertical_header = this.PublicGetTemplateChild("PART_B_Vertical_Header") |> ofType<ContentPresenter>
let! a_horizontal_header = this.PublicGetTemplateChild("PART_A_Horizontal_Header") |> ofType<ContentPresenter>
let! b_horizontal_header = this.PublicGetTemplateChild("PART_B_Horizontal_Header") |> ofType<ContentPresenter>
let! splitter = this.PublicGetTemplateChild("PART_Splitter") |> ofType<GridSplitter>
let! splitter_controls = this.PublicGetTemplateChild("PART_Splitter_Controls") |> ofType<Panel>
let! extra_buttons_host = this.PublicGetTemplateChild("PART_Extra_Buttons_Host") |> ofType<ContentPresenter>
let! swap_button_vertical = this.PublicGetTemplateChild("PART_Swap_Button_Vertical") |> ofType<Button>
let! swap_button_horizontal = this.PublicGetTemplateChild("PART_Swap_Button_Horizontal") |> ofType<Button>
let! vertical_toggleButton = this.PublicGetTemplateChild("PART_Vertical_ToggleButton") |> ofType<System.Windows.Controls.Primitives.ToggleButton>
let! horizontal_toggleButton = this.PublicGetTemplateChild("PART_Horizontal_ToggleButton") |> ofType<System.Windows.Controls.Primitives.ToggleButton>
let! move_up_button = this.PublicGetTemplateChild("PART_Move_Up_Button") |> ofType<Button>
let! move_down_button = this.PublicGetTemplateChild("PART_Move_Down_Button") |> ofType<Button>
let! move_left_button = this.PublicGetTemplateChild("PART_Move_Left_Button") |> ofType<Button>
let! move_right_button = this.PublicGetTemplateChild("PART_Move_Right_Button") |> ofType<Button>
let updateState(viewState:SplitViewState) =
this.ViewState <- viewState
// Wire up buttons
swap_button_vertical.Click.Add(fun _ -> this.Swapped <- not this.Swapped)
swap_button_horizontal.Click.Add(fun _ -> this.Swapped <- not this.Swapped)
vertical_toggleButton.Click.Add(fun e ->
e.Handled <- true
updateState SplitViewState.VerticalCenter)
horizontal_toggleButton.Click.Add(fun e ->
e.Handled <- true
updateState SplitViewState.HorizontalCenter
)
let a_header_click() =
match this.ViewState with
| SplitViewState.VerticalCenter
| SplitViewState.HorizontalCenter -> () // ignore
| SplitViewState.VerticalRight
|SplitViewState.HorizontalBottom -> if this.Swapped then this.Swapped <- false
| SplitViewState.VerticalLeft
| SplitViewState.HorizontalTop -> if not this.Swapped then this.Swapped <- true
| _ -> ()
let b_header_click() =
match this.ViewState with
| SplitViewState.VerticalCenter
| SplitViewState.HorizontalCenter -> () // ignore
| SplitViewState.VerticalRight
| SplitViewState.HorizontalBottom -> if not this.Swapped then this.Swapped <- true
| SplitViewState.VerticalLeft
| SplitViewState.HorizontalTop -> if this.Swapped then this.Swapped <- false
| _ -> ()
splitter.DragCompleted.Add(fun _ ->
let pos = Input.Mouse.GetPosition(main_grid)
if pos.Y < 0. then this.ViewState <- SplitViewState.HorizontalTop
elif pos.X < 0. then this.ViewState <- SplitViewState.VerticalLeft
elif pos.Y > main_grid.ActualHeight then this.ViewState <- SplitViewState.HorizontalBottom
elif pos.X > main_grid.ActualWidth then this.ViewState <- SplitViewState.VerticalRight
else
let topHeight = main_grid.RowDefinitions.[0].ActualHeight
let bottomHeight = main_grid.RowDefinitions.[2].ActualHeight
let leftWidth = main_grid.ColumnDefinitions.[0].ActualWidth
let rightWidth = main_grid.ColumnDefinitions.[2].ActualWidth
match this.ViewState with
| SplitViewState.VerticalLeft
| SplitViewState.VerticalCenter
| SplitViewState.VerticalRight ->
if rightWidth < 10. then this.ViewState <- SplitViewState.VerticalRight
elif leftWidth < 10. then this.ViewState <- SplitViewState.VerticalLeft
else
lastRightWidth <- this.RightWidth
lastLeftWidth <- this.LeftWidth
this.ViewState <- SplitViewState.VerticalCenter
| SplitViewState.HorizontalCenter
| SplitViewState.HorizontalBottom
| SplitViewState.HorizontalTop ->
if topHeight < 10. then this.ViewState <- SplitViewState.HorizontalTop
elif bottomHeight < 10. then this.ViewState <- SplitViewState.HorizontalBottom
else
lastTopHeight <- this.TopHeight
lastBottomHeight <- this.BottomHeight
this.ViewState <- SplitViewState.HorizontalCenter
| _ -> ()
)
a_vertical_header.MouseDown.Add(fun _ -> a_header_click())
a_horizontal_header.MouseDown.Add(fun _ -> a_header_click())
b_vertical_header.MouseDown.Add(fun _ -> b_header_click())
b_horizontal_header.MouseDown.Add(fun _ -> b_header_click())
move_up_button.Click.Add(fun _ ->
match this.ViewState with
| SplitViewState.HorizontalBottom -> updateState SplitViewState.HorizontalCenter
| SplitViewState.HorizontalCenter -> updateState SplitViewState.HorizontalTop
| _ -> () // ignore
)
move_down_button.Click.Add(fun _ ->
match this.ViewState with
| SplitViewState.HorizontalTop -> updateState SplitViewState.HorizontalCenter
| SplitViewState.HorizontalCenter -> updateState SplitViewState.HorizontalBottom
| _ -> () // ignore
)
move_left_button.Click.Add(fun _ ->
match this.ViewState with
| SplitViewState.VerticalRight -> updateState SplitViewState.VerticalCenter
| SplitViewState.VerticalCenter -> updateState SplitViewState.VerticalLeft
| _ -> () // ignore
)
move_right_button.Click.Add(fun _ ->
match this.ViewState with
| SplitViewState.VerticalLeft -> updateState SplitViewState.VerticalCenter
| SplitViewState.VerticalCenter -> updateState SplitViewState.VerticalRight
| _ -> () // ignore
)
return! Some(1)
} |> function | None -> failwith "unable to find a part" | _ -> ()
let x = this.GetTemplateChild("")
()
open System.Windows.Media
// SolidColorBrushes
module DT = DataTemplate
[<AutoOpen>]
module Util =
let shape (xs:(float*float)[]) =
let head = xs.[0]
let tail = xs.[1..]
PathFigure(IsClosed=true, StartPoint = Point(fst head, snd head), Segments = PathSegmentCollection(tail |> Seq.map (fun (x,y) -> LineSegment(Point = Point(x,y)) :> PathSegment)))
let geometry (xss:(float*float)[][]) = PathGeometry(xss |> Array.map shape)
let square (x:float,y:float,width:float,height:float) : (float*float) []= [|x,y;x+width,y;x+width,y-height;x,y-height|]
let path1 =
[|14.;10.;6.;2.|]
|> Array.map (fun y -> square(0.,y,2.,2.))
|> geometry
let path2 =
[|14.;10.;6.;2.|]
|> Array.map (fun x -> square(x,0.,2.,2.))
|> geometry
let handle path =
[
Thickness(0.,0.,1.,1.), Brushes.Black
Thickness(1.,1.,0.,0.), Brushes.White
] |> List.map (fun (t,b) ->
DT.toFactory<Path>
|> DT.setValues [
Path.MarginProperty, box <| t
Path.FillProperty, box b
Path.DataProperty, box <| path
])
|> DT.appendChildren
(DT.toFactory<Grid>
|> DT.setValues [
Grid.ColumnProperty, box 1;
Grid.RowProperty, box 1;
Grid.HorizontalAlignmentProperty, box HorizontalAlignment.Center;
Grid.VerticalAlignmentProperty, box VerticalAlignment.Center;
Grid.IsHitTestVisibleProperty, box false
])
let multiTrigger conditions setters =
conditions |> Seq.fold (fun (mt:MultiTrigger) (c:Condition) -> mt.Conditions.Add(c); mt) (
setters |> Seq.fold (fun (mt:MultiTrigger) (s:Setter) -> mt.Setters.Add(s); mt) (MultiTrigger()))
let headers (cntrl:string) =
[
[ "VerticalHeader" + cntrl,"PART_" + cntrl + "_Vertical_Header";"HorizontalHeader" + cntrl, "PART_" + cntrl + "_Horizontal_Header"]
|> List.map (fun (b,n) ->
DT.toFactory<ContentPresenter>
|> DT.setBindings [ContentPresenter.ContentProperty, Binding(b, RelativeSource = RelativeSource.TemplatedParent)]
|> DT.setName n)
|> DT.appendChildren (
DT.toFactory<StackPanel>
|> DT.setValues [
StackPanel.VerticalAlignmentProperty, box VerticalAlignment.Center
StackPanel.HorizontalAlignmentProperty, box HorizontalAlignment.Center
]
|> DT.setName (cntrl + "_StackPanel")
)
]
|> DT.appendChildren(
DT.toFactory<Border>
|> DT.setValues [Border.BorderBrushProperty, SolidColorBrush(Color.FromHex("#FF9098A3"))]
|> DT.setName (cntrl + "_Border"))
let backgroundBrush() = box <| Binding("Background", RelativeSource = RelativeSource.TemplatedParent)
type TsunamiResources() =
//static let xamlNamespaces = """xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:ui="clr-namespace:Tsunami;assembly=Tsunami.IDEDesktop" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sv="clr-namespace:Tsunami.IDE.UI.SplitView;assembly=Tsunami.IDEDesktop" """
//static let splitViewNamespace = System.Xml.Linq.XNamespace.Get "clr-namespace:Tsunami.IDE.UI.SplitView;assembly=Tsunami.IDEDesktop"
static let blueHighlight = lazy (SolidColorBrush(Color.FromArgb(255uy,0uy,122uy,204uy)))
static let buttonBrush = lazy (LinearGradientBrush.ofData((0.,0.),(0.,1.),[|(255,243,243,243,0.);(255,235,235,235,0.5);(255,221,221,221,0.5);(255,205,205,205,0.1)|]))
static let splitterBrushHorizontal = lazy (LinearGradientBrush.ofData((0.,1.),(0.,0.),[|(255,250,250,250,0.996);(255,227,227,227,0.4);(255,212,212,212,0.0)|]))
static let splitterBrushVertical = lazy (LinearGradientBrush.ofData((1.,0.),(0.,0.),[|(255,250,250,250,0.996);(255,227,227,227,0.4);(255,212,212,212,0.0)|]))
static let splitterButtonTemplate =
lazy (
let controlTemplate =
let border =
DataTemplate.toFactory<Border>
|> DataTemplate.setValues [Border.CornerRadiusProperty, box 0.; Border.BorderThicknessProperty, box <| Thickness(1.) ]
border.Name <- "Border"
let contentPresenter =
DataTemplate.toFactory<ContentPresenter>
|> DataTemplate.setValues [ ContentPresenter.HorizontalAlignmentProperty, box HorizontalAlignment.Center; ContentPresenter.VerticalAlignmentProperty, box VerticalAlignment.Center]
DataTemplate.appendChildren contentPresenter [border] |> ignore
contentPresenter |> DataTemplate.toControlTemplate
[
[
Setter(TargetName = "Border", Property = Border.BackgroundProperty, Value = SystemColors.ControlLightLightBrush)
Setter(TargetName = "Border", Property = Border.BorderBrushProperty, Value = TsunamiResources.BlueHighlight)
] |> Seq.fold (fun (t:Trigger) s -> t.Setters.Add(s); t) (Trigger(Property = Border.IsMouseOverProperty, Value = true))
[
Setter(Property = Control.ForegroundProperty, Value = SolidColorBrush(Color.FromArgb(255uy,173uy,173uy,173uy)))
Setter(Property = Control.OpacityProperty, Value = 0.5)
] |> Seq.fold (fun (t:Trigger) s -> t.Setters.Add(s); t) (Trigger(Property = Border.IsEnabledProperty, Value = false))
] |> Seq.iter (fun trigger -> controlTemplate.Triggers.Add(trigger))
controlTemplate.TargetType <- typeof<Primitives.ButtonBase>
controlTemplate
)
static let splitterToggleButtonTemplate =
lazy (
let controlTemplate =
let border =
DataTemplate.toFactory<Border>
|> DataTemplate.setValues [Border.CornerRadiusProperty, box 0.; Border.BorderThicknessProperty, box <| Thickness(1.) ]
border.Name <- "Border"
let contentPresenter =
DataTemplate.toFactory<ContentPresenter>
|> DataTemplate.setValues [ ContentPresenter.HorizontalAlignmentProperty, box HorizontalAlignment.Center; ContentPresenter.VerticalAlignmentProperty, box VerticalAlignment.Center]
DataTemplate.appendChildren contentPresenter [border] |> ignore
contentPresenter |> DataTemplate.toControlTemplate
[
[
Setter(TargetName = "Border", Property = Border.BackgroundProperty, Value = SystemColors.ControlLightLightBrush)
Setter(TargetName = "Border", Property = Border.BorderBrushProperty, Value = TsunamiResources.BlueHighlight)
] |> Seq.fold (fun (t:Trigger) s -> t.Setters.Add(s); t) (Trigger(Property = Border.IsMouseOverProperty, Value = true))
[
Setter(TargetName = "Border", Property = Control.ForegroundProperty, Value = TsunamiResources.BlueHighlight)
] |> Seq.fold (fun (t:Trigger) s -> t.Setters.Add(s); t) (Trigger(Property = Primitives.ToggleButton.IsCheckedProperty, Value = true))
[
Setter(Property = Control.ForegroundProperty, Value = SolidColorBrush(Color.FromArgb(255uy,173uy,173uy,173uy)))
] |> Seq.fold (fun (t:Trigger) s -> t.Setters.Add(s); t) (Trigger(Property = Border.IsEnabledProperty, Value = false))
] |> Seq.iter (fun trigger -> controlTemplate.Triggers.Add(trigger))
controlTemplate.TargetType <- typeof<Primitives.ToggleButton>
controlTemplate
)
static let splitViewTemplate =
lazy (
let splitterButton (img:BitmapImage) =
DT.toFactory<Button>
|> DT.setValues [
Button.HeightProperty, box 15.
Button.WidthProperty, box 15.
Button.TemplateProperty, box TsunamiResources.SplitterButtonTemplate
Button.ContentProperty,
Image(Height = 11., Width = 11., Source = img)
|> fun img -> RenderOptions.SetBitmapScalingMode(img,BitmapScalingMode.HighQuality); box img
]
let toggleButton (img:BitmapImage) =
DT.toFactory<Primitives.ToggleButton>
|> DT.setValues [
Button.HeightProperty, box 15.
Button.WidthProperty, box 15.
Button.TemplateProperty, box TsunamiResources.SplitterToggleButtonTemplate
Button.ContentProperty,
Image(Height = 11., Width = 11., Source = img)
|> fun img -> RenderOptions.SetBitmapScalingMode(img,BitmapScalingMode.HighQuality); box img
]
let controlTemplate =
[
DT.toFactory<RowDefinition> |> DT.setBindings [RowDefinition.HeightProperty, Binding(Source = RelativeSource.TemplatedParent, Path=PropertyPath("TopHeight"), Mode = BindingMode.TwoWay)]
DT.toFactory<RowDefinition> |> DataTemplate.setValues [(RowDefinition.HeightProperty, GridLength(1.,GridUnitType.Auto))]
DT.toFactory<RowDefinition> |> DT.setBindings [RowDefinition.HeightProperty, Binding(Source = RelativeSource.TemplatedParent, Path=PropertyPath("BottomHeight"), Mode = BindingMode.TwoWay)]
DT.toFactory<ColumnDefinition> |> DT.setBindings [ColumnDefinition.WidthProperty, Binding(Source = RelativeSource.TemplatedParent, Path=PropertyPath("LeftWidth"), Mode = BindingMode.TwoWay)]
DT.toFactory<ColumnDefinition> |> DataTemplate.setValues [(ColumnDefinition.WidthProperty, GridLength(1.,GridUnitType.Auto))]
DT.toFactory<ColumnDefinition> |> DT.setBindings [ColumnDefinition.WidthProperty, Binding(Source = RelativeSource.TemplatedParent, Path=PropertyPath("RightWidth"), Mode = BindingMode.TwoWay)]
DT.toFactory<ContentPresenter>
|> DT.setBindings [ContentPresenter.ContentProperty, Binding(Source = RelativeSource.TemplatedParent, Path=PropertyPath("ControlA"))]
|> DT.setName "PART_A_Host"
DT.toFactory<ContentPresenter>
|> DT.setBindings [ContentPresenter.ContentProperty, Binding(Source = RelativeSource.TemplatedParent, Path=PropertyPath("ControlB"))]
|> DT.setName "PART_B_Host"
DT.toFactory<GridSplitter>
|> DT.setValues [GridSplitter.BorderBrushProperty, Media.SolidColorBrush(Color.FromHex("#FF9098A3")) ]
|> DT.setName "PART_Splitter"
handle path1
|> DT.setName "vertical_handle"
handle path2
|> DT.setName "horizontal_handle"
[
[
DT.toFactory<RowDefinition> |> DataTemplate.setValues [(RowDefinition.HeightProperty, GridLength(1.,GridUnitType.Auto))]
DT.toFactory<RowDefinition> |> DataTemplate.setValues [(RowDefinition.HeightProperty, GridLength(1.,GridUnitType.Star))]
DT.toFactory<RowDefinition> |> DataTemplate.setValues [(RowDefinition.HeightProperty, GridLength(1.,GridUnitType.Auto))]
DT.toFactory<ColumnDefinition> |> DataTemplate.setValues [(ColumnDefinition.WidthProperty, GridLength(1.,GridUnitType.Auto))]
DT.toFactory<ColumnDefinition> |> DataTemplate.setValues [(ColumnDefinition.WidthProperty, GridLength(1.,GridUnitType.Star))]
DT.toFactory<ColumnDefinition> |> DataTemplate.setValues [(ColumnDefinition.WidthProperty, GridLength(1.,GridUnitType.Auto))]
[
headers "A"
splitterButton Images.Swap_vertical_11_gif
|> DT.setName "PART_Swap_Button_Vertical"
splitterButton Images.Swap_horizontal_11_gif
|> DT.setName "PART_Swap_Button_Horizontal"
headers "B"
DT.toFactory<ContentPresenter>
|> DT.setBindings [ContentPresenter.ContentProperty, Binding("SplitterControl", RelativeSource = RelativeSource.TemplatedParent)]
|> DT.setName "PART_Extra_Buttons_Host"
] |> DT.appendChildren (DT.toFactory<StackPanel> |> DT.setName "Splitter_TopLeftPanel")
[
toggleButton Images.Vertical_bar_border_11_gif
|> DT.setName "PART_Vertical_ToggleButton"
toggleButton Images.Horizontal_bar_border_11_gif
|> DT.setName "PART_Horizontal_ToggleButton"
splitterButton Images.Collapse_bottom_border_11_gif
|> DT.setName "PART_Move_Down_Button"
splitterButton Images.Collapse_top_border_11_gif
|> DT.setName "PART_Move_Up_Button"
splitterButton Images.Collapse_left_border_11_gif
|> DT.setName "PART_Move_Left_Button"
splitterButton Images.Collapse_right_border_11_gif
|> DT.setName "PART_Move_Right_Button"
] |> DT.appendChildren (DT.toFactory<StackPanel> |> DT.setName "Splitter_BottomRightPanel")
]
|> DT.appendChildren (DT.toFactory<Grid> |> DT.setName "PART_Splitter_Controls")
]
|> DT.appendChildren (DT.toFactory<Border> |> DT.setName "Splitter_Controls_Border")
]
|> DT.appendChildren (DT.toFactory<Grid>)
|> DT.setName "PART_Main_Grid"
|> DT.toControlTemplate
[
[
yield!
[Grid.RowSpanProperty, 3; Grid.ColumnProperty, 0]
|> Seq.map (fun (p,v) -> Setter(TargetName = "PART_A_Host", Property = p, Value = v))
yield!
[Grid.RowSpanProperty, 3; Grid.ColumnProperty, 2]
|> Seq.map (fun (p,v) -> Setter(TargetName = "PART_B_Host", Property = p, Value = v))
yield!
[
Grid.ColumnProperty, box 1
Grid.RowSpanProperty, box 3
GridSplitter.WidthProperty, box 19.
GridSplitter.HorizontalAlignmentProperty, box HorizontalAlignment.Center
GridSplitter.VerticalAlignmentProperty, box VerticalAlignment.Stretch
GridSplitter.BackgroundProperty, box TsunamiResources.SplitterBrushVertical
GridSplitter.BorderThicknessProperty, box <| Thickness(1.,0.,1.,0.)
] |> Seq.map (fun (p,v) -> Setter(TargetName = "PART_Splitter", Property = p, Value = v))
yield!
[
Grid.ColumnProperty, box 1
Grid.RowSpanProperty, box 3
Border.WidthProperty, box 19.
Border.HorizontalAlignmentProperty, box HorizontalAlignment.Center
Border.VerticalAlignmentProperty, box VerticalAlignment.Stretch
] |> Seq.map (fun (p,v) -> Setter(TargetName = "Splitter_Controls_Border", Property = p, Value = v))
yield!
[
"PART_A_Horizontal_Header"
"PART_B_Horizontal_Header"
"PART_Move_Down_Button"
"PART_Move_Up_Button"
"PART_Swap_Button_Vertical"
"horizontal_handle"
] |> Seq.map (fun tn -> Setter(TargetName = tn, Property = Control.VisibilityProperty, Value = Visibility.Collapsed))
yield Setter(TargetName = "Splitter_TopLeftPanel", Property = Grid.ColumnProperty, Value = box 1)
yield! [
StackPanel.VerticalAlignmentProperty, box VerticalAlignment.Bottom
StackPanel.OrientationProperty, box Orientation.Vertical
Grid.RowProperty, box 2
Grid.ColumnProperty, box 1
] |> Seq.map (fun (p,v) -> Setter(TargetName = "Splitter_BottomRightPanel", Property = p, Value = v))
yield! [
Grid.RowProperty, box 0
Grid.RowSpanProperty, box 3
] |> Seq.map (fun (p,v) -> Setter(TargetName = "vertical_handle", Property = p, Value = v))
]
|> Seq.fold (fun (t:Trigger) (s:Setter) -> t.Setters.Add(s);t) (Trigger(Property = SplitViewControl.OrientationProperty, Value = Orientation.Vertical))
:> TriggerBase
[
yield!
[Grid.ColumnSpanProperty, 3; Grid.RowProperty, 0]
|> Seq.map (fun (p,v) -> Setter(TargetName = "PART_A_Host", Property = p, Value = v))
yield!
[Grid.ColumnSpanProperty, 3; Grid.RowProperty, 2]
|> Seq.map (fun (p,v) -> Setter(TargetName = "PART_B_Host", Property = p, Value = v))
yield!
[
Grid.RowProperty, box 1
Grid.ColumnSpanProperty, box 3
GridSplitter.HeightProperty, box 19.
GridSplitter.HorizontalAlignmentProperty, box HorizontalAlignment.Stretch
GridSplitter.VerticalAlignmentProperty, box VerticalAlignment.Center
GridSplitter.BackgroundProperty, box TsunamiResources.SplitterBrushHorizontal
GridSplitter.BorderThicknessProperty, box <| Thickness(0.,1.,0.,1.)
] |> Seq.map (fun (p,v) -> Setter(TargetName = "PART_Splitter", Property = p, Value = v))
yield!
[
Grid.RowProperty, box 1
Grid.ColumnSpanProperty, box 3
Border.HeightProperty, box 19.
Border.HorizontalAlignmentProperty, box HorizontalAlignment.Stretch
Border.VerticalAlignmentProperty, box VerticalAlignment.Center
] |> Seq.map (fun (p,v) -> Setter(TargetName = "Splitter_Controls_Border", Property = p, Value = v))
yield!
[
"PART_A_Vertical_Header"
"PART_B_Vertical_Header"
"PART_Move_Left_Button"
"PART_Move_Right_Button"
"PART_Swap_Button_Horizontal"
"vertical_handle"
] |> Seq.map (fun tn -> Setter(TargetName = tn, Property = Control.VisibilityProperty, Value = Visibility.Collapsed))
yield Setter(TargetName = "Splitter_TopLeftPanel", Property = Grid.RowProperty, Value = box 1)
yield! [
StackPanel.HorizontalAlignmentProperty, box HorizontalAlignment.Left
StackPanel.OrientationProperty, box Orientation.Horizontal
Grid.RowProperty, box 1
Grid.ColumnProperty, box 2
] |> Seq.map (fun (p,v) -> Setter(TargetName = "Splitter_BottomRightPanel", Property = p, Value = v))
yield! [
Grid.ColumnProperty, box 0
Grid.ColumnSpanProperty, box 3
] |> Seq.map (fun (p,v) -> Setter(TargetName = "horizontal_handle", Property = p, Value = v))
]
|> Seq.fold (fun (t:Trigger) (s:Setter) -> t.Setters.Add(s);t) (Trigger(Property = SplitViewControl.OrientationProperty, Value = Orientation.Horizontal))
:> TriggerBase
[
Setter(TargetName = "PART_A_Host", Property = Grid.ColumnProperty, Value = 2)
Setter(TargetName = "PART_A_Host", Property = Grid.RowSpanProperty, Value = 3)
Setter(TargetName = "PART_B_Host", Property = Grid.RowSpanProperty, Value = 3)
Setter(TargetName = "PART_B_Host", Property = Grid.ColumnProperty, Value = 0)
]
|> multiTrigger [
Condition(Property = SplitViewControl.OrientationProperty, Value = Orientation.Vertical)
Condition(Property = SplitViewControl.SwappedProperty, Value = true)
] :> TriggerBase
[
Setter(TargetName = "PART_A_Host", Property = Grid.RowProperty, Value = 2)
Setter(TargetName = "PART_A_Host", Property = Grid.ColumnSpanProperty, Value = 3)
Setter(TargetName = "PART_B_Host", Property = Grid.ColumnSpanProperty, Value = 3)
Setter(TargetName = "PART_B_Host", Property = Grid.RowProperty, Value = 0)
]
|> multiTrigger [
Condition(Property = SplitViewControl.OrientationProperty, Value = Orientation.Vertical)
Condition(Property = SplitViewControl.SwappedProperty, Value = true)
] :> TriggerBase
[
yield Setter(TargetName = "PART_Swap_Button_Horizontal", Property = Control.VisibilityProperty, Value = Visibility.Collapsed)
yield! [
Border.HeightProperty, box 15.
Border.WidthProperty, box 15.
Border.BorderThicknessProperty, box <| Thickness(1.)
Border.BackgroundProperty, box TsunamiResources.ButtonBrush
Border.MarginProperty, box <| Thickness(0.,6.,-3.,0.)
] |> Seq.map (fun (p,v) -> Setter(TargetName = "A_Border", Property = p, Value = v))
yield! [
Border.HeightProperty, box 17.
Border.WidthProperty, box 17.
Border.MarginProperty, box <| Thickness(0.,-1.,-3.,0.)
Border.BorderThicknessProperty, box <| Thickness(1.,1.,0.,1.)
Border.BackgroundProperty, backgroundBrush()
] |> Seq.map (fun (p,v) -> Setter(TargetName = "B_Border", Property = p, Value = v))
yield Setter(TargetName = "PART_Move_Left_Button", Property = Button.IsEnabledProperty, Value = false)
]
|> Seq.fold (fun (t:Trigger) (s:Setter) -> t.Setters.Add(s);t) (Trigger(Property = SplitViewControl.ViewStateProperty, Value = SplitViewState.VerticalLeft))
:> TriggerBase
[
yield! [
Border.HeightProperty, box 17.
Border.WidthProperty, box 17.
Border.MarginProperty, box <| Thickness(0.,6.,-3.,0.)
Border.BorderThicknessProperty, box <| Thickness(1.,1.,0.,1.)
Border.BackgroundProperty, backgroundBrush()
] |> Seq.map (fun (p,v) -> Setter(TargetName = "A_Border", Property = p, Value = v))
yield! [
Border.HeightProperty, box 15.
Border.WidthProperty, box 15.
Border.MarginProperty, box <| Thickness(0.,-1.,-3.,0.)
Border.BorderThicknessProperty, box <| Thickness(1.)
Border.BackgroundProperty, box TsunamiResources.ButtonBrush
] |> Seq.map (fun (p,v) -> Setter(TargetName = "B_Border", Property = p, Value = v))
]
|> multiTrigger [
Condition(Property = SplitViewControl.ViewStateProperty, Value = SplitViewState.VerticalLeft)
Condition(Property = SplitViewControl.SwappedProperty, Value = true)
] :> TriggerBase
[
yield Setter(TargetName = "PART_Swap_Button_Horizontal", Property = Button.MarginProperty, Value = Thickness(0.,3.,0.,3.))
yield Setter(TargetName = "PART_Vertical_ToggleButton", Property = Primitives.ToggleButton.IsCheckedProperty, Value = true)
yield Setter(TargetName = "PART_Vertical_ToggleButton", Property = Primitives.ToggleButton.IsHitTestVisibleProperty, Value = false)
yield! [
Border.HeightProperty, box 17.
Border.WidthProperty, box 17.
Border.BorderThicknessProperty, box <| Thickness(0.,1.,1.,1.)
Border.MarginProperty, box <| Thickness(-3.,6.,0.,0.)
Border.BackgroundProperty, backgroundBrush()
] |> Seq.map (fun (p,v) -> Setter(TargetName = "A_Border", Property = p, Value = v))
yield! [
Border.HeightProperty, box 17.
Border.WidthProperty, box 17.
Border.BorderThicknessProperty, box <| Thickness(1.,1.,0.,1.)
Border.MarginProperty, box <| Thickness(0.,-1.,-3.,0.)
Border.BackgroundProperty, box TsunamiResources.ButtonBrush
] |> Seq.map (fun (p,v) -> Setter(TargetName = "B_Border", Property = p, Value = v))
]
|> Seq.fold (fun (t:Trigger) (s:Setter) -> t.Setters.Add(s);t) (Trigger(Property = SplitViewControl.ViewStateProperty, Value = SplitViewState.VerticalCenter))
:> TriggerBase
[
Setter(TargetName = "A_Border", Property = Border.MarginProperty, Value = Thickness(0.,6.,-3.,0.))
Setter(TargetName = "A_Border", Property = Border.BorderThicknessProperty, Value = Thickness(1.,1.,0.,1.))
Setter(TargetName = "B_Border", Property = Border.MarginProperty, Value = Thickness(-3.,-1.,0.,0.))
Setter(TargetName = "B_Border", Property = Border.BorderThicknessProperty, Value = Thickness(0.,1.,1.,1.))
]
|> multiTrigger [
Condition(Property = SplitViewControl.ViewStateProperty, Value = SplitViewState.VerticalCenter)
Condition(Property = SplitViewControl.SwappedProperty, Value = true)
] :> TriggerBase
[
yield Setter(TargetName = "PART_Swap_Button_Horizontal", Property = Control.VisibilityProperty, Value = Visibility.Collapsed)
yield Setter(TargetName = "PART_Move_Right_Button", Property = Button.IsEnabledProperty, Value = false)
yield! [
Border.HeightProperty, box 17.
Border.WidthProperty, box 17.
Border.BorderThicknessProperty, box <| Thickness(0.,1.,1.,1.)
Border.MarginProperty, box <| Thickness(-3.,6.,0.,0.)
Border.BackgroundProperty, backgroundBrush()
] |> Seq.map (fun (p,v) -> Setter(TargetName = "A_Border", Property = p, Value = v))
yield! [
Border.HeightProperty, box 15.
Border.WidthProperty, box 15.
Border.BorderThicknessProperty, box <| Thickness(1.)
Border.MarginProperty, box <| Thickness(-3.,-1.,0.,0.)
Border.BackgroundProperty, box TsunamiResources.ButtonBrush
] |> Seq.map (fun (p,v) -> Setter(TargetName = "B_Border", Property = p, Value = v))
]
|> Seq.fold (fun (t:Trigger) (s:Setter) -> t.Setters.Add(s);t) (Trigger(Property = SplitViewControl.ViewStateProperty, Value = SplitViewState.VerticalRight))
:> TriggerBase
[
yield! [
Border.HeightProperty, box 15.
Border.WidthProperty, box 15.
Border.BorderThicknessProperty, box <| Thickness(1.)
Border.MarginProperty, box <| Thickness(-3.,6.,0.,0.)
Border.BackgroundProperty, box TsunamiResources.ButtonBrush
] |> Seq.map (fun (p,v) -> Setter(TargetName = "A_Border", Property = p, Value = v))
yield! [
Border.HeightProperty, box 17.
Border.WidthProperty, box 17.
Border.BorderThicknessProperty, box <| Thickness(0.,1.,1.,1.)
Border.MarginProperty, box <| Thickness(-3.,-1.,0.,0.)
Border.BackgroundProperty, backgroundBrush()
] |> Seq.map (fun (p,v) -> Setter(TargetName = "B_Border", Property = p, Value = v))
]
|> multiTrigger [
Condition(Property = SplitViewControl.ViewStateProperty, Value = SplitViewState.VerticalRight)
Condition(Property = SplitViewControl.SwappedProperty, Value = true)
] :> TriggerBase
[
yield Setter(TargetName = "PART_Swap_Button_Vertical", Property = Control.VisibilityProperty, Value = Visibility.Collapsed)
yield Setter(TargetName = "PART_Move_Up_Button", Property = Button.IsEnabledProperty, Value = false)
yield! [
Border.PaddingProperty, box <| Thickness(3.,0.,3.,0.)
Border.WidthProperty, box 15.
Border.BorderThicknessProperty, box <| Thickness(1.)
Border.MarginProperty, box <| Thickness(6.,0.,0.,-3.)
Border.BackgroundProperty, box TsunamiResources.ButtonBrush
] |> Seq.map (fun (p,v) -> Setter(TargetName = "A_Border", Property = p, Value = v))
yield! [
Border.PaddingProperty, box <| Thickness(3.,0.,3.,0.)
Border.HeightProperty, box 17.
Border.BorderThicknessProperty, box <| Thickness(1.,1.,1.,0.)
Border.MarginProperty, box <| Thickness(0.,0.,0.,-3.)
Border.BackgroundProperty, backgroundBrush()
] |> Seq.map (fun (p,v) -> Setter(TargetName = "B_Border", Property = p, Value = v))
]
|> Seq.fold (fun (t:Trigger) (s:Setter) -> t.Setters.Add(s);t) (Trigger(Property = SplitViewControl.ViewStateProperty, Value = SplitViewState.HorizontalTop))
:> TriggerBase
[
yield!
[
Border.HeightProperty, box 17.
Border.BorderThicknessProperty, box <| Thickness(1.,1.,1.,0.)
Border.BackgroundProperty, backgroundBrush()
] |> Seq.map (fun (p,v) -> Setter(TargetName = "A_Border", Property = p, Value = v))
yield!
[
Border.HeightProperty, box 15.
Border.BorderThicknessProperty, box <| Thickness(1.)
Border.BackgroundProperty, box <| TsunamiResources.ButtonBrush
] |> Seq.map (fun (p,v) -> Setter(TargetName = "B_Border", Property = p, Value = v))
]
|> multiTrigger [
Condition(Property = SplitViewControl.ViewStateProperty, Value = SplitViewState.HorizontalTop)
Condition(Property = SplitViewControl.SwappedProperty, Value = true)
] :> TriggerBase
[
yield Setter(TargetName = "PART_Swap_Button_Vertical", Property = Button.MarginProperty, Value = Thickness(3.,0.,3.,0.))
yield Setter(TargetName = "PART_Horizontal_ToggleButton", Property = Primitives.ToggleButton.IsCheckedProperty, Value = true)
yield Setter(TargetName = "PART_Horizontal_ToggleButton", Property = Primitives.ToggleButton.IsHitTestVisibleProperty, Value = false)
yield! [
Border.PaddingProperty, box <| Thickness(3.,0.,3.,0.)
Border.HeightProperty, box 17.
Border.BorderThicknessProperty, box <| Thickness(1.,0.,1.,1.)
Border.MarginProperty, box <| Thickness(6.,-3.,0.,0.)
Border.BackgroundProperty, backgroundBrush()
] |> Seq.map (fun (p,v) -> Setter(TargetName = "A_Border", Property = p, Value = v))
yield! [
Border.PaddingProperty, box <| Thickness(3.,0.,3.,0.)
Border.HeightProperty, box 17.
Border.BorderThicknessProperty, box <| Thickness(1.,1.,1.,0.)
Border.MarginProperty, box <| Thickness(0.,0.,0.,-3.)
Border.BackgroundProperty, backgroundBrush()
] |> Seq.map (fun (p,v) -> Setter(TargetName = "B_Border", Property = p, Value = v))
]
|> Seq.fold (fun (t:Trigger) (s:Setter) -> t.Setters.Add(s);t) (Trigger(Property = SplitViewControl.ViewStateProperty, Value = SplitViewState.HorizontalCenter))
:> TriggerBase
[
Setter(TargetName = "A_Border", Property = Border.BorderThicknessProperty, Value = Thickness(1.,1.,1.,0.))
Setter(TargetName = "A_Border", Property = Border.MarginProperty, Value = Thickness(6.,0.,0.,-3.))
Setter(TargetName = "B_Border", Property = Border.BorderThicknessProperty, Value = Thickness(1.,0.,1.,1.))
Setter(TargetName = "B_Border", Property = Border.MarginProperty, Value = Thickness(0.,-3.,0.,0.))
]
|> multiTrigger [
Condition(Property = SplitViewControl.ViewStateProperty, Value = SplitViewState.HorizontalCenter)
Condition(Property = SplitViewControl.SwappedProperty, Value = true)
] :> TriggerBase
[
yield Setter(TargetName = "PART_Swap_Button_Vertical", Property = Button.VisibilityProperty, Value = Visibility.Collapsed)
yield Setter(TargetName = "PART_Move_Down_Button", Property = Control.IsEnabledProperty, Value = false)
yield! [
Border.PaddingProperty, box <| Thickness(3.,0.,3.,0.)
Border.HeightProperty, box 17.
Border.BorderThicknessProperty, box <| Thickness(1.,0.,1.,1.)
Border.MarginProperty, box <| Thickness(6.,-3.,0.,0.)
Border.BackgroundProperty, backgroundBrush()
] |> Seq.map (fun (p,v) -> Setter(TargetName = "A_Border", Property = p, Value = v))
yield! [
Border.PaddingProperty, box <| Thickness(3.,0.,3.,0.)
Border.HeightProperty, box 15.
Border.BorderThicknessProperty, box <| Thickness(1.)
Border.MarginProperty, box <| Thickness(-1.,-3.,0.,0.)
Border.BackgroundProperty, box <| TsunamiResources.ButtonBrush
] |> Seq.map (fun (p,v) -> Setter(TargetName = "B_Border", Property = p, Value = v))
]
|> Seq.fold (fun (t:Trigger) (s:Setter) -> t.Setters.Add(s);t) (Trigger(Property = SplitViewControl.ViewStateProperty, Value = SplitViewState.HorizontalBottom))
:> TriggerBase
[
yield! [
Border.HeightProperty, box 15.
Border.BorderThicknessProperty, box <| Thickness(1.)
Border.BackgroundProperty, box TsunamiResources.ButtonBrush
] |> Seq.map (fun (p,v) -> Setter(TargetName = "A_Border", Property = p, Value = v))
yield! [
Border.HeightProperty, box 17.
Border.BorderThicknessProperty, box <| Thickness(1.,0.,1.,1.)
Border.BackgroundProperty, backgroundBrush()
] |> Seq.map (fun (p,v) -> Setter(TargetName = "B_Border", Property = p, Value = v))
]
|> multiTrigger [
Condition(Property = SplitViewControl.ViewStateProperty, Value = SplitViewState.HorizontalBottom)
Condition(Property = SplitViewControl.SwappedProperty, Value = true)
] :> TriggerBase
] |> Seq.iter (fun t -> controlTemplate.Triggers.Add(t))
controlTemplate
)
static let simpleSplitterViewTemplate =
lazy (
let controlTemplate =
[
DT.toFactory<RowDefinition> |> DT.setBindings [RowDefinition.HeightProperty, Binding(Source = RelativeSource.TemplatedParent, Path=PropertyPath("TopHeight"), Mode = BindingMode.TwoWay)]
DT.toFactory<RowDefinition> |> DataTemplate.setValues [(RowDefinition.HeightProperty, GridLength(1.,GridUnitType.Auto))]
DT.toFactory<RowDefinition> |> DT.setBindings [RowDefinition.HeightProperty, Binding(Source = RelativeSource.TemplatedParent, Path=PropertyPath("BottomHeight"), Mode = BindingMode.TwoWay)]
DT.toFactory<ColumnDefinition> |> DT.setBindings [ColumnDefinition.WidthProperty, Binding(Source = RelativeSource.TemplatedParent, Path=PropertyPath("LeftWidth"), Mode = BindingMode.TwoWay)]
DT.toFactory<ColumnDefinition> |> DataTemplate.setValues [(ColumnDefinition.WidthProperty, GridLength(1.,GridUnitType.Auto))]
DT.toFactory<ColumnDefinition> |> DT.setBindings [ColumnDefinition.WidthProperty, Binding(Source = RelativeSource.TemplatedParent, Path=PropertyPath("RightWidth"), Mode = BindingMode.TwoWay)]
DT.toFactory<ContentPresenter>
|> DT.setBindings [ContentPresenter.ContentProperty, Binding(Source = RelativeSource.TemplatedParent, Path=PropertyPath("ControlA"))]
|> DT.setName "PART_A_Host"
DT.toFactory<ContentPresenter>
|> DT.setBindings [ContentPresenter.ContentProperty, Binding(Source = RelativeSource.TemplatedParent, Path=PropertyPath("ControlB"))]
|> DT.setName "PART_B_Host"
DT.toFactory<GridSplitter>
|> DT.setValues [GridSplitter.BorderBrushProperty, Media.SolidColorBrush(Color.FromHex("#FF9098A3")) ]
|> DT.setName "PART_Splitter"
handle path1
|> DT.setName "vertical_handle"
handle path2
|> DT.setName "horizontal_handle"
[
[
yield! ["PART_A_Vertical_Header"; "PART_A_Horizontal_Header"; "PART_B_Vertical_Header"; "PART_B_Horizontal_Header"; "PART_Extra_Buttons_Host"]
|> Seq.map (fun name -> DT.toFactory<ContentPresenter> |> DT.setName name)
yield! ["PART_Swap_Button_Vertical"; "PART_Swap_Button_Horizontal"; "PART_Move_Down_Button"; "PART_Move_Up_Button"; "PART_Move_Left_Button"; "PART_Move_Right_Button" ]
|> Seq.map (fun name -> DT.toFactory<Button> |> DT.setName name)
yield! ["PART_Horizontal_ToggleButton"; "PART_Vertical_ToggleButton"]
|> Seq.map (fun name -> DT.toFactory<Primitives.ToggleButton> |> DT.setName name)
] |> DT.appendChildren (DT.toFactory<Grid> |> DT.setName "PART_Splitter_Controls")
] |> DT.appendChildren (DT.toFactory<Border> |> DT.setName "Splitter_Controls_Border" |> DT.setValues [UIElement.VisibilityProperty, Visibility.Collapsed])
]
|> DT.appendChildren (DT.toFactory<Grid>)
|> DT.setName "PART_Main_Grid"
|> DT.toControlTemplate
[
[
yield! [Grid.RowSpanProperty, box 3; Grid.ColumnProperty, box 0] |> Seq.map (fun (p,v) -> Setter(TargetName = "PART_A_Host", Property = p, Value = v))
yield! [Grid.RowSpanProperty, box 3; Grid.ColumnProperty, box 2] |> Seq.map (fun (p,v) -> Setter(TargetName = "PART_B_Host", Property = p, Value = v))
yield! [
Grid.RowSpanProperty, box 3
Grid.ColumnProperty, box 1
GridSplitter.WidthProperty, box 5.
GridSplitter.HorizontalAlignmentProperty, box HorizontalAlignment.Center
GridSplitter.VerticalAlignmentProperty, box VerticalAlignment.Center
GridSplitter.BackgroundProperty, box TsunamiResources.SplitterBrushVertical
GridSplitter.BorderThicknessProperty, box <| Thickness(1.,0.,1.,0.)
] |> Seq.map (fun (p,v) -> Setter(TargetName = "PART_Splitter", Property = p, Value = v))
yield Setter(TargetName = "horizontal_handle", Property = UIElement.VisibilityProperty, Value = Visibility.Collapsed)
yield! [Grid.RowSpanProperty, box 3; Grid.RowProperty, box 0] |> Seq.map (fun (p,v) -> Setter(TargetName = "vertical_handle", Property = p, Value = v))
]
|> Seq.fold (fun (t:Trigger) (s:Setter) -> t.Setters.Add(s);t) (Trigger(Property = SplitViewControl.OrientationProperty, Value = Orientation.Vertical))
:> TriggerBase
[
yield! [Grid.ColumnSpanProperty, box 3; Grid.RowProperty, box 0] |> Seq.map (fun (p,v) -> Setter(TargetName = "PART_A_Host", Property = p, Value = v))
yield! [Grid.ColumnSpanProperty, box 3; Grid.RowProperty, box 2] |> Seq.map (fun (p,v) -> Setter(TargetName = "PART_B_Host", Property = p, Value = v))
yield! [
Grid.ColumnSpanProperty, box 3
Grid.RowProperty, box 1
GridSplitter.HeightProperty, box 5.
GridSplitter.HorizontalAlignmentProperty, box HorizontalAlignment.Center
GridSplitter.VerticalAlignmentProperty, box VerticalAlignment.Center
GridSplitter.BackgroundProperty, box TsunamiResources.SplitterBrushHorizontal
GridSplitter.BorderThicknessProperty, box <| Thickness(0.,1.,0.,1.)
] |> Seq.map (fun (p,v) -> Setter(TargetName = "PART_Splitter", Property = p, Value = v))
yield Setter(TargetName = "vertical_handle", Property = UIElement.VisibilityProperty, Value = Visibility.Collapsed)
yield! [Grid.ColumnSpanProperty, box 3; Grid.ColumnProperty, box 0] |> Seq.map (fun (p,v) -> Setter(TargetName = "horizontal_handle", Property = p, Value = v))
]
|> Seq.fold (fun (t:Trigger) (s:Setter) -> t.Setters.Add(s);t) (Trigger(Property = SplitViewControl.OrientationProperty, Value = Orientation.Horizontal))
:> TriggerBase
[
Setter(TargetName = "PART_A_Host", Property = Grid.ColumnProperty, Value = 2)
Setter(TargetName = "PART_A_Host", Property = Grid.RowSpanProperty, Value = 3)
Setter(TargetName = "PART_B_Host", Property = Grid.ColumnProperty, Value = 0)
Setter(TargetName = "PART_B_Host", Property = Grid.RowSpanProperty, Value = 3)
] |> multiTrigger [
Condition(Property = SplitViewControl.OrientationProperty, Value = Orientation.Vertical)
Condition(Property = SplitViewControl.SwappedProperty, Value = true)
] :> TriggerBase
[
Setter(TargetName = "PART_A_Host", Property = Grid.RowProperty, Value = 2)
Setter(TargetName = "PART_A_Host", Property = Grid.ColumnSpanProperty, Value = 3)
Setter(TargetName = "PART_B_Host", Property = Grid.RowProperty, Value = 0)
Setter(TargetName = "PART_B_Host", Property = Grid.ColumnSpanProperty, Value = 3)
] |> multiTrigger [
Condition(Property = SplitViewControl.OrientationProperty, Value = Orientation.Horizontal)
Condition(Property = SplitViewControl.SwappedProperty, Value = true)
] :> TriggerBase
] |> Seq.iter (fun t -> controlTemplate.Triggers.Add(t))
controlTemplate
)
static member BlueHighlight = blueHighlight.Force()
static member ButtonBrush = buttonBrush.Force()
static member SplitterBrushHorizontal = splitterBrushHorizontal.Force()
static member SplitterBrushVertical = splitterBrushVertical.Force()
static member SimpleSplitterViewTemplate = simpleSplitterViewTemplate.Force()
static member SplitViewTemplate = splitViewTemplate.Force()
static member SplitterToggleButtonTemplate = splitterToggleButtonTemplate.Force()
static member SplitterButtonTemplate = splitterButtonTemplate.Force()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment