From 3983f630480c2e5fb4dd9941b1df3e7750b6e504 Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Mon, 20 Aug 2018 22:55:40 -0400 Subject: [PATCH] Added Grid and finally rounded out the control gallery example. --- grid.go | 96 ++++++++++++++++++++++++++++++++++++++++++++++ zz_controls.go | 102 +++++++++++++++++++++++++++++-------------------- 2 files changed, 156 insertions(+), 42 deletions(-) create mode 100644 grid.go diff --git a/grid.go b/grid.go new file mode 100644 index 0000000..a1985fc --- /dev/null +++ b/grid.go @@ -0,0 +1,96 @@ +// 12 december 2015 + +package ui + +import ( + "unsafe" +) + +// #include "ui.h" +import "C" + +// Grid is a Control that arranges other Controls in a grid. +// Grid is a very powerful container: it can position and size each +// Control in several ways and can (and must) have Controls added +// to it in any direction. It can also have Controls spanning multiple +// rows and columns. +// +// Each Control in a Grid has associated "expansion" and +// "alignment" values in both the X and Y direction. +// Expansion determines whether all cells in the same row/column +// are given whatever space is left over after figuring out how big +// the rest of the Grid should be. Alignment determines the position +// of a Control relative to its cell after computing the above. The +// special alignment Fill can be used to grow a Control to fit its cell. +// Note that expansion and alignment are independent variables. +// For more information on expansion and alignment, read +// https://developer.gnome.org/gtk3/unstable/ch28s02.html. +type Grid struct { + ControlBase + g *C.uiGrid + children []Control +} + +// Align represents the alignment of a Control in its cell of a Grid. +type Align int +const ( + AlignFill Align = iota + AlignStart + AlignCenter + AlignEnd +) + +// At represents a side of a Control to add other Controls to a Grid to. +type At int +const ( + Leading At = iota + Top + Trailing + Bottom +) + +// NewGrid creates a new Grid. +func NewGrid() *Grid { + g := new(Grid) + + g.g = C.uiNewGrid() + + g.ControlBase = NewControlBase(g, uintptr(unsafe.Pointer(g.g))) + return g +} + +// TODO Destroy + +// Append adds the given control to the Grid, at the given coordinate. +func (g *Grid) Append(child Control, left, top int, xspan, yspan int, hexpand bool, halign Align, vexpand bool, valign Align) { + C.uiGridAppend(g.g, touiControl(child.LibuiControl()), + C.int(left), C.int(top), + C.int(xspan), C.int(yspan), + frombool(hexpand), C.uiAlign(halign), + frombool(vexpand), C.uiAlign(valign)) + g.children = append(g.children, child) +} + +// InsertAt adds the given control to the Grid relative to an existing +// control. +func (g *Grid) InsertAt(child Control, existing Control, at At, xspan, yspan int, hexpand bool, halign Align, vexpand bool, valign Align) { + C.uiGridInsertAt(g.g, touiControl(child.LibuiControl()), + touiControl(existing.LibuiControl()), C.uiAt(at), + C.int(xspan), C.int(yspan), + frombool(hexpand), C.uiAlign(halign), + frombool(vexpand), C.uiAlign(valign)) + g.children = append(g.children, child) +} + +// Padded returns whether there is space between each control +// of the Grid. +func (g *Grid) Padded() bool { + return tobool(C.uiGridPadded(g.g)) +} + +// SetPadded controls whether there is space between each control +// of the Grid. The size of the padding is determined by the OS and +// its best practices. +func (g *Grid) SetPadded(padded bool) { + C.uiGridSetPadded(g.g, frombool(padded)) +} diff --git a/zz_controls.go b/zz_controls.go index b879b39..d77bebe 100644 --- a/zz_controls.go +++ b/zz_controls.go @@ -8,6 +8,8 @@ import ( "github.com/andlabs/ui" ) +var mainwin *ui.Window + func makeBasicControlsPage() ui.Control { vbox := ui.NewVerticalBox() vbox.SetPadded(true) @@ -116,64 +118,80 @@ func makeDataChoosersPage() ui.Control { vbox.Append(ui.NewFontButton(), false) vbox.Append(ui.NewColorButton(), false) -/* - uiBoxAppend(hbox, - uiControl(uiNewVerticalSeparator()), - 0); + hbox.Append(ui.NewVerticalSeparator(), false) - vbox = uiNewVerticalBox(); - uiBoxSetPadded(vbox, 1); - uiBoxAppend(hbox, uiControl(vbox), 1); + vbox = ui.NewVerticalBox() + vbox.SetPadded(true) + hbox.Append(vbox, true) - grid = uiNewGrid(); - uiGridSetPadded(grid, 1); - uiBoxAppend(vbox, uiControl(grid), 0); + grid := ui.NewGrid() + grid.SetPadded(true) + vbox.Append(grid, false) - button = uiNewButton("Open File"); - entry = uiNewEntry(); - uiEntrySetReadOnly(entry, 1); - uiButtonOnClicked(button, onOpenFileClicked, entry); - uiGridAppend(grid, uiControl(button), + button := ui.NewButton("Open File") + entry := ui.NewEntry() + entry.SetReadOnly(true) + button.OnClicked(func(*ui.Button) { + filename := ui.OpenFile(mainwin) + if filename == "" { + filename = "(cancelled)" + } + entry.SetText(filename) + }) + grid.Append(button, 0, 0, 1, 1, - 0, uiAlignFill, 0, uiAlignFill); - uiGridAppend(grid, uiControl(entry), + false, ui.AlignFill, false, ui.AlignFill) + grid.Append(entry, 1, 0, 1, 1, - 1, uiAlignFill, 0, uiAlignFill); + true, ui.AlignFill, false, ui.AlignFill) - button = uiNewButton("Save File"); - entry = uiNewEntry(); - uiEntrySetReadOnly(entry, 1); - uiButtonOnClicked(button, onSaveFileClicked, entry); - uiGridAppend(grid, uiControl(button), + button = ui.NewButton("Save File") + entry2 := ui.NewEntry() + entry2.SetReadOnly(true) + button.OnClicked(func(*ui.Button) { + filename := ui.SaveFile(mainwin) + if filename == "" { + filename = "(cancelled)" + } + entry2.SetText(filename) + }) + grid.Append(button, 0, 1, 1, 1, - 0, uiAlignFill, 0, uiAlignFill); - uiGridAppend(grid, uiControl(entry), + false, ui.AlignFill, false, ui.AlignFill) + grid.Append(entry2, 1, 1, 1, 1, - 1, uiAlignFill, 0, uiAlignFill); + true, ui.AlignFill, false, ui.AlignFill) - msggrid = uiNewGrid(); - uiGridSetPadded(msggrid, 1); - uiGridAppend(grid, uiControl(msggrid), + msggrid := ui.NewGrid() + msggrid.SetPadded(true) + grid.Append(msggrid, 0, 2, 2, 1, - 0, uiAlignCenter, 0, uiAlignStart); + false, ui.AlignCenter, false, ui.AlignStart) - button = uiNewButton("Message Box"); - uiButtonOnClicked(button, onMsgBoxClicked, NULL); - uiGridAppend(msggrid, uiControl(button), + button = ui.NewButton("Message Box") + button.OnClicked(func(*ui.Button) { + ui.MsgBox(mainwin, + "This is a normal message box.", + "More detailed information can be shown here.") + }) + msggrid.Append(button, 0, 0, 1, 1, - 0, uiAlignFill, 0, uiAlignFill); - button = uiNewButton("Error Box"); - uiButtonOnClicked(button, onMsgBoxErrorClicked, NULL); - uiGridAppend(msggrid, uiControl(button), + false, ui.AlignFill, false, ui.AlignFill) + button = ui.NewButton("Error Box") + button.OnClicked(func(*ui.Button) { + ui.MsgBoxError(mainwin, + "This message box describes an error.", + "More detailed information can be shown here.") + }) + msggrid.Append(button, 1, 0, 1, 1, - 0, uiAlignFill, 0, uiAlignFill); -*/ + false, ui.AlignFill, false, ui.AlignFill) return hbox } func setupUI() { - mainwin := ui.NewWindow("libui Control Gallery", 640, 480, true) + mainwin = ui.NewWindow("libui Control Gallery", 640, 480, true) mainwin.OnClosing(func(*ui.Window) bool { ui.Quit() return true @@ -190,10 +208,10 @@ func setupUI() { tab.Append("Basic Controls", makeBasicControlsPage()) tab.SetMargined(0, true) - tab.Append("Numbers and Lists", makeNumbersPage()); + tab.Append("Numbers and Lists", makeNumbersPage()) tab.SetMargined(1, true) - tab.Append("Data Choosers", makeDataChoosersPage()); + tab.Append("Data Choosers", makeDataChoosersPage()) tab.SetMargined(2, true) mainwin.Show()