open System open System.Drawing open System.Windows.Forms module Layout = // [snippet:Layout combinators] /// Add single control to the layout let (!!) (ctrl:#Control) (x, y) = ctrl.Left <- x ctrl.Top <- y x + ctrl.Width, y + ctrl.Height, [ctrl :> Control] /// Add border around the specified layout let margin (sizew, sizeh) f (x, y) = let w, h, ctrls = f (x + sizew, y + sizeh) w + sizew, h + sizeh, ctrls /// Add controls in the layout to a control or form let createLayout layout = layout (0, 0) |> ignore /// Place two layouts beside each other horizontally let ( <||> ) f1 f2 (x, y) = let w1, h1, ctrls1 = f1 (x, y) let w2, h2, ctrls2 = f2 (w1, y) max w1 w2, max h1 h2, ctrls1 @ ctrls2 (*[omit:(Other composition combinators omitted)]*) /// Place two layouts beside each other vertically let ( <=> ) f1 f2 (x, y) = let w1, h1, ctrls1 = f1 (x, y) let w2, h2, ctrls2 = f2 (x, h1) max w1 w2, max h1 h2, ctrls1 @ ctrls2 /// Place two layouts over each other let ( ) f1 f2 (x, y) = let w, h, ctrls1 = f1 (x, y) let _, _, ctrls2 = f2 (0, 0) match ctrls1 with | [single:Control] -> single.Controls.AddRange(Array.ofSeq ctrls2) | _ -> failwith "Children can be added on a single control layout only" w, h, ctrls1(*[/omit]*) /// Creates a rectangle control filled with the specified color let rectangle (w, h) clr = !! (new Control(BackColor = clr, Width = w, Height = h)) /// Create label using the specified font let label (w, h) fnt s = !!(new Label(Text = s, Font = fnt, Width = w, Height = h, TextAlign = ContentAlignment.MiddleLeft)) /// Normal system font let normal = SystemFonts.DefaultFont /// Bold version of normal font let title = new Font(SystemFonts.DialogFont, FontStyle.Bold) /// Larger and bold version of normal font let head = new Font(SystemFonts.DialogFont.FontFamily, 10.0f, FontStyle.Bold) // [/snippet] open Layout do // [snippet:Sample dialog window] let form = new Form(TopMost = true, Visible = true, Width = 500) let name = new TextBox() let msg = new TextBox() !! form ( ( rectangle (500, 40) Color.White margin (10, 10) ( label (500, 20) head "Hello world!") ) <=> margin (10, 15) ( label (450, 36) normal ("This sample demonstrates how to create a simple layout using combinators" + "in F#. Please enter some information to these two boxes:") <=> margin (10, 5) ( ( label (100, 22) title "Name: " <||> !!name) <=> ( label (100, 22) title "Message: " <||> !!msg) ) ) ) |> createLayout // [/snippet]