Rename Anchor to Side in Frame.Pack() config

menus
Noah 2019-12-28 21:47:46 -08:00
parent 3e73a6effb
commit 9d6b172878
8 changed files with 81 additions and 87 deletions

View File

@ -56,7 +56,7 @@ func main() {
}, },
}) })
mw.Pack(label, ui.Pack{ mw.Pack(label, ui.Pack{
Anchor: ui.N, Side: ui.N,
PadY: 12, PadY: 12,
}) })
@ -74,7 +74,7 @@ func main() {
fmt.Println("I've been clicked!") fmt.Println("I've been clicked!")
}) })
mw.Pack(button, ui.Pack{ mw.Pack(button, ui.Pack{
Anchor: ui.N, Side: ui.N,
}) })
// Add the button to the MainWindow's Supervisor so it can be // Add the button to the MainWindow's Supervisor so it can be
@ -232,12 +232,6 @@ need of a re-write. Some examples of issues with it:
Frame is _added_ to the position of the Button which throws it off even Frame is _added_ to the position of the Button which throws it off even
further. further.
It's on my to-do list to rewrite the algorithm from scratch and make it
more resilient. One thing I also want to do is rename the `Anchor` field
and call it `Side` to be more in line with the Tk GUI toolkit's naming
convention. ("Side: N" or "Side: SE", and let the "Anchor" name be used for
how to center the widget inside of its space ("Top", "Center", "Left", etc.)
# License # License
MIT. MIT.

View File

@ -44,10 +44,10 @@ func makeCheckbox(name string, boolVar *bool, stringVar *string, value string, c
} }
w.Pack(w.button, Pack{ w.Pack(w.button, Pack{
Anchor: W, Side: W,
}) })
w.Pack(w.child, Pack{ w.Pack(w.child, Pack{
Anchor: W, Side: W,
}) })
return w return w

View File

@ -26,8 +26,8 @@ func main() {
}, },
}) })
mw.Pack(label, ui.Pack{ mw.Pack(label, ui.Pack{
Anchor: ui.N, Side: ui.N,
PadY: 12, PadY: 12,
}) })
// Draw a button. // Draw a button.
@ -44,7 +44,7 @@ func main() {
fmt.Println("I've been clicked!") fmt.Println("I've been clicked!")
}) })
mw.Pack(button, ui.Pack{ mw.Pack(button, ui.Pack{
Anchor: ui.N, Side: ui.N,
}) })
// Add the button to the MainWindow's Supervisor so it can be // Add the button to the MainWindow's Supervisor so it can be

View File

@ -21,8 +21,8 @@ func main() {
Background: render.Grey, Background: render.Grey,
}) })
mw.Pack(leftFrame, ui.Pack{ mw.Pack(leftFrame, ui.Pack{
Anchor: ui.W, Side: ui.W,
FillY: true, FillY: true,
}) })
mainFrame := ui.NewFrame("Main Frame") mainFrame := ui.NewFrame("Main Frame")
@ -30,7 +30,7 @@ func main() {
Background: render.RGBA(255, 255, 255, 180), Background: render.RGBA(255, 255, 255, 180),
}) })
mw.Pack(mainFrame, ui.Pack{ mw.Pack(mainFrame, ui.Pack{
Anchor: ui.W, Side: ui.W,
Expand: true, Expand: true,
PadX: 10, PadX: 10,
}) })
@ -39,8 +39,8 @@ func main() {
Text: "Hello world", Text: "Hello world",
}) })
leftFrame.Pack(label, ui.Pack{ leftFrame.Pack(label, ui.Pack{
Anchor: ui.N, Side: ui.N,
PadY: 12, PadY: 12,
}) })
// Draw some buttons in the left frame. // Draw some buttons in the left frame.
@ -59,17 +59,17 @@ func main() {
mw.Add(btn) mw.Add(btn)
leftFrame.Pack(btn, ui.Pack{ leftFrame.Pack(btn, ui.Pack{
Anchor: ui.N, Side: ui.N,
FillX: true, FillX: true,
PadY: 2, PadY: 2,
}) })
} }
// Frame to show off check buttons. // Frame to show off check buttons.
mainFrame.Pack(radioButtonFrame(mw), ui.Pack{ mainFrame.Pack(radioButtonFrame(mw), ui.Pack{
Anchor: ui.N, Side: ui.N,
FillX: true, FillX: true,
PadY: 8, PadY: 8,
}) })
err = mw.MainLoop() err = mw.MainLoop()
@ -95,8 +95,8 @@ func radioButtonFrame(mw *ui.MainWindow) *ui.Frame {
// Top row to show the label and current radiobutton bound value. // Top row to show the label and current radiobutton bound value.
topFrame := ui.NewFrame("radio button label frame") topFrame := ui.NewFrame("radio button label frame")
frame.Pack(topFrame, ui.Pack{ frame.Pack(topFrame, ui.Pack{
Anchor: ui.N, Side: ui.N,
FillX: true, FillX: true,
}) })
// Draw the labels. // Draw the labels.
@ -105,23 +105,23 @@ func radioButtonFrame(mw *ui.MainWindow) *ui.Frame {
Text: "Radio buttons. Value:", Text: "Radio buttons. Value:",
}) })
topFrame.Pack(label, ui.Pack{ topFrame.Pack(label, ui.Pack{
Anchor: ui.W, Side: ui.W,
}) })
valueLabel := ui.NewLabel(ui.Label{ valueLabel := ui.NewLabel(ui.Label{
TextVariable: &radioValue, TextVariable: &radioValue,
}) })
topFrame.Pack(valueLabel, ui.Pack{ topFrame.Pack(valueLabel, ui.Pack{
Anchor: ui.W, Side: ui.W,
PadX: 4, PadX: 4,
}) })
} }
// The radio buttons themselves. // The radio buttons themselves.
btnFrame := ui.NewFrame("radio button frame") btnFrame := ui.NewFrame("radio button frame")
frame.Pack(btnFrame, ui.Pack{ frame.Pack(btnFrame, ui.Pack{
Anchor: ui.N, Side: ui.N,
FillX: true, FillX: true,
}) })
{ {
colors := []string{"Red", "Green", "Blue", "Yellow"} colors := []string{"Red", "Green", "Blue", "Yellow"}
@ -133,8 +133,8 @@ func radioButtonFrame(mw *ui.MainWindow) *ui.Frame {
})) }))
mw.Add(btn) mw.Add(btn)
btnFrame.Pack(btn, ui.Pack{ btnFrame.Pack(btn, ui.Pack{
Anchor: ui.W, Side: ui.W,
PadX: 2, PadX: 2,
}) })
} }
} }

View File

@ -10,7 +10,7 @@ import (
type Frame struct { type Frame struct {
Name string Name string
BaseWidget BaseWidget
packs map[Anchor][]packedWidget packs map[Side][]packedWidget
widgets []Widget widgets []Widget
} }
@ -18,7 +18,7 @@ type Frame struct {
func NewFrame(name string) *Frame { func NewFrame(name string) *Frame {
w := &Frame{ w := &Frame{
Name: name, Name: name,
packs: map[Anchor][]packedWidget{}, packs: map[Side][]packedWidget{},
widgets: []Widget{}, widgets: []Widget{},
} }
w.SetBackground(render.RGBA(1, 0, 0, 0)) // invisible default BG w.SetBackground(render.RGBA(1, 0, 0, 0)) // invisible default BG
@ -33,7 +33,7 @@ func NewFrame(name string) *Frame {
// Setup ensures all the Frame's data is initialized and not null. // Setup ensures all the Frame's data is initialized and not null.
func (w *Frame) Setup() { func (w *Frame) Setup() {
if w.packs == nil { if w.packs == nil {
w.packs = map[Anchor][]packedWidget{} w.packs = map[Side][]packedWidget{}
} }
if w.widgets == nil { if w.widgets == nil {
w.widgets = []Widget{} w.widgets = []Widget{}

View File

@ -8,7 +8,7 @@ import (
type Pack struct { type Pack struct {
// Side of the parent to anchor the position to, like N, SE, W. Default // Side of the parent to anchor the position to, like N, SE, W. Default
// is Center. // is Center.
Anchor Anchor Side Side
// If the widget is smaller than its allocated space, grow the widget // If the widget is smaller than its allocated space, grow the widget
// to fill its space in the Frame. // to fill its space in the Frame.
@ -29,9 +29,9 @@ func (w *Frame) Pack(child Widget, config ...Pack) {
C = config[0] C = config[0]
} }
// Initialize the pack list for this anchor? // Initialize the pack list for this side?
if _, ok := w.packs[C.Anchor]; !ok { if _, ok := w.packs[C.Side]; !ok {
w.packs[C.Anchor] = []packedWidget{} w.packs[C.Side] = []packedWidget{}
} }
// Padding: if the user only provided Padding add it to both // Padding: if the user only provided Padding add it to both
@ -49,7 +49,7 @@ func (w *Frame) Pack(child Widget, config ...Pack) {
// Adopt the child widget so it can access the Frame. // Adopt the child widget so it can access the Frame.
child.Adopt(w) child.Adopt(w)
w.packs[C.Anchor] = append(w.packs[C.Anchor], packedWidget{ w.packs[C.Side] = append(w.packs[C.Side], packedWidget{
widget: child, widget: child,
pack: C, pack: C,
}) })
@ -72,10 +72,10 @@ func (w *Frame) computePacked(e render.Engine) {
expanded = []packedWidget{} expanded = []packedWidget{}
) )
// Iterate through all anchored directions and compute how much space to // Iterate through all directions and compute how much space to
// reserve to contain all of their widgets. // reserve to contain all of their widgets.
for anchor := AnchorMin; anchor <= AnchorMax; anchor++ { for side := SideMin; side <= SideMax; side++ {
if _, ok := w.packs[anchor]; !ok { if _, ok := w.packs[side]; !ok {
continue continue
} }
@ -86,15 +86,15 @@ func (w *Frame) computePacked(e render.Engine) {
xDirection int = 1 xDirection int = 1
) )
if anchor.IsSouth() { if side.IsSouth() {
y = frameSize.H - w.BoxThickness(4) y = frameSize.H - w.BoxThickness(4)
yDirection = -1 yDirection = -1
} else if anchor.IsEast() { } else if side.IsEast() {
x = frameSize.W - w.BoxThickness(4) x = frameSize.W - w.BoxThickness(4)
xDirection = -1 xDirection = -1
} }
for _, packedWidget := range w.packs[anchor] { for _, packedWidget := range w.packs[side] {
child := packedWidget.widget child := packedWidget.widget
pack := packedWidget.pack pack := packedWidget.pack
@ -121,19 +121,19 @@ func (w *Frame) computePacked(e render.Engine) {
maxHeight = yStep + size.H + (pack.PadY * 2) maxHeight = yStep + size.H + (pack.PadY * 2)
} }
if anchor.IsSouth() { if side.IsSouth() {
y -= size.H - pack.PadY y -= size.H - pack.PadY
} }
if anchor.IsEast() { if side.IsEast() {
x -= size.W - pack.PadX x -= size.W - pack.PadX
} }
child.MoveTo(render.NewPoint(x, y)) child.MoveTo(render.NewPoint(x, y))
if anchor.IsNorth() { if side.IsNorth() {
y += size.H + pack.PadY y += size.H + pack.PadY
} }
if anchor == W { if side == W {
x += size.W + pack.PadX x += size.W + pack.PadX
} }
@ -172,7 +172,7 @@ func (w *Frame) computePacked(e render.Engine) {
} }
} }
// Rescan all the widgets in this anchor to re-center them // Rescan all the widgets in this side to re-center them
// in their space. // in their space.
innerFrameSize := render.NewRect( innerFrameSize := render.NewRect(
frameSize.W-w.BoxThickness(2), frameSize.W-w.BoxThickness(2),
@ -189,23 +189,23 @@ func (w *Frame) computePacked(e render.Engine) {
moved bool moved bool
) )
if pack.Anchor.IsNorth() || pack.Anchor.IsSouth() { if pack.Side.IsNorth() || pack.Side.IsSouth() {
if pack.FillX && resize.W < innerFrameSize.W { if pack.FillX && resize.W < innerFrameSize.W {
resize.W = innerFrameSize.W - w.BoxThickness(2) resize.W = innerFrameSize.W - w.BoxThickness(2)
resized = true resized = true
} }
if resize.W < innerFrameSize.W-w.BoxThickness(4) { if resize.W < innerFrameSize.W-w.BoxThickness(4) {
if pack.Anchor.IsCenter() { if pack.Side.IsCenter() {
point.X = (innerFrameSize.W / 2) - (resize.W / 2) point.X = (innerFrameSize.W / 2) - (resize.W / 2)
} else if pack.Anchor.IsWest() { } else if pack.Side.IsWest() {
point.X = pack.PadX point.X = pack.PadX
} else if pack.Anchor.IsEast() { } else if pack.Side.IsEast() {
point.X = innerFrameSize.W - resize.W - pack.PadX point.X = innerFrameSize.W - resize.W - pack.PadX
} }
moved = true moved = true
} }
} else if pack.Anchor.IsWest() || pack.Anchor.IsEast() { } else if pack.Side.IsWest() || pack.Side.IsEast() {
if pack.FillY && resize.H < innerFrameSize.H { if pack.FillY && resize.H < innerFrameSize.H {
resize.H = innerFrameSize.H - w.BoxThickness(2) // BoxThickness(2) for parent + child resize.H = innerFrameSize.H - w.BoxThickness(2) // BoxThickness(2) for parent + child
// point.Y -= (w.BoxThickness(4) + child.BoxThickness(2)) // point.Y -= (w.BoxThickness(4) + child.BoxThickness(2))
@ -215,17 +215,17 @@ func (w *Frame) computePacked(e render.Engine) {
// Vertically align the widgets. // Vertically align the widgets.
if resize.H < innerFrameSize.H { if resize.H < innerFrameSize.H {
if pack.Anchor.IsMiddle() { if pack.Side.IsMiddle() {
point.Y = (innerFrameSize.H / 2) - (resize.H / 2) - w.BoxThickness(1) point.Y = (innerFrameSize.H / 2) - (resize.H / 2) - w.BoxThickness(1)
} else if pack.Anchor.IsNorth() { } else if pack.Side.IsNorth() {
point.Y = pack.PadY - w.BoxThickness(4) point.Y = pack.PadY - w.BoxThickness(4)
} else if pack.Anchor.IsSouth() { } else if pack.Side.IsSouth() {
point.Y = innerFrameSize.H - resize.H - pack.PadY point.Y = innerFrameSize.H - resize.H - pack.PadY
} }
moved = true moved = true
} }
} else { } else {
panic("unsupported pack.Anchor") panic("unsupported pack.Side")
} }
if resized && size != resize { if resized && size != resize {
@ -245,12 +245,12 @@ func (w *Frame) computePacked(e render.Engine) {
// } // }
} }
// Anchor is a cardinal direction. // Side is a cardinal direction.
type Anchor uint8 type Side uint8
// Anchor values. // Side values.
const ( const (
Center Anchor = iota Center Side = iota
N N
NE NE
E E
@ -261,41 +261,41 @@ const (
NW NW
) )
// Range of Anchor values. // Range of Side values.
const ( const (
AnchorMin = Center SideMin = Center
AnchorMax = NW SideMax = NW
) )
// IsNorth returns if the anchor is N, NE or NW. // IsNorth returns if the side is N, NE or NW.
func (a Anchor) IsNorth() bool { func (a Side) IsNorth() bool {
return a == N || a == NE || a == NW return a == N || a == NE || a == NW
} }
// IsSouth returns if the anchor is S, SE or SW. // IsSouth returns if the side is S, SE or SW.
func (a Anchor) IsSouth() bool { func (a Side) IsSouth() bool {
return a == S || a == SE || a == SW return a == S || a == SE || a == SW
} }
// IsEast returns if the anchor is E, NE or SE. // IsEast returns if the side is E, NE or SE.
func (a Anchor) IsEast() bool { func (a Side) IsEast() bool {
return a == E || a == NE || a == SE return a == E || a == NE || a == SE
} }
// IsWest returns if the anchor is W, NW or SW. // IsWest returns if the side is W, NW or SW.
func (a Anchor) IsWest() bool { func (a Side) IsWest() bool {
return a == W || a == NW || a == SW return a == W || a == NW || a == SW
} }
// IsCenter returns if the anchor is Center, N or S, to determine // IsCenter returns if the side is Center, N or S, to determine
// whether to align text as centered for North/South anchors. // whether to align text as centered for North/South sides.
func (a Anchor) IsCenter() bool { func (a Side) IsCenter() bool {
return a == Center || a == N || a == S return a == Center || a == N || a == S
} }
// IsMiddle returns if the anchor is Center, E or W, to determine // IsMiddle returns if the side is Center, E or W, to determine
// whether to align text as middled for East/West anchors. // whether to align text as middled for East/West sides.
func (a Anchor) IsMiddle() bool { func (a Side) IsMiddle() bool {
return a == Center || a == W || a == E return a == Center || a == W || a == E
} }

View File

@ -53,7 +53,7 @@ func (w *Menu) AddItem(label string, command func()) *MenuItem {
// Pack a menu item onto the menu. // Pack a menu item onto the menu.
func (w *Menu) Pack(item *MenuItem) { func (w *Menu) Pack(item *MenuItem) {
w.body.Pack(item, Pack{ w.body.Pack(item, Pack{
Anchor: NE, Side: NE,
// Expand: true, // Expand: true,
// Padding: 8, // Padding: 8,
FillX: true, FillX: true,

View File

@ -50,8 +50,8 @@ func NewWindow(title string) *Window {
Background: render.Blue, Background: render.Blue,
}) })
w.body.Pack(titleBar, Pack{ w.body.Pack(titleBar, Pack{
Anchor: N, Side: N,
Fill: true, Fill: true,
}) })
w.titleBar = titleBar w.titleBar = titleBar
@ -61,8 +61,8 @@ func NewWindow(title string) *Window {
Background: render.Grey, Background: render.Grey,
}) })
w.body.Pack(content, Pack{ w.body.Pack(content, Pack{
Anchor: N, Side: N,
Fill: true, Fill: true,
}) })
w.content = content w.content = content