diff options
| -rw-r--r-- | control.go | 3 | ||||
| -rw-r--r-- | controlsize.go | 54 | ||||
| -rw-r--r-- | controlsize_sys.go (renamed from newsizing) | 48 | ||||
| -rw-r--r-- | sysdata.go | 26 | ||||
| -rw-r--r-- | window.go | 17 |
5 files changed, 78 insertions, 70 deletions
@@ -5,6 +5,5 @@ package ui // A Control represents an UI control. Note that Control contains unexported members; this has the consequence that you can't build custom controls that interface directly with the system-specific code (fo rinstance, to import an unsupported control), or at least not without some hackery. If you want to make your own controls, create an Area and provide an AreaHandler that does what you need. type Control interface { make(window *sysData) error - setRect(x int, y int, width int, height int, rr *[]resizerequest) - preferredSize() (width int, height int, yoff int) + controlSizing } diff --git a/controlsize.go b/controlsize.go new file mode 100644 index 0000000..d4d9d31 --- /dev/null +++ b/controlsize.go @@ -0,0 +1,54 @@ +// 25 june 2014 + +package ui + +type allocation struct { + x int + y int + width int + height int + this Control + neighbor Control +} + +// for verification; see sysdata.go +type sysDataSizeFuncs interface { + beginResize() *sysSizeData + endResize(*sysSizeData) + translateAllocationCoords([]*allocation, int, int) + preferredSize(*sysSizeData) (int, int) + commitResize(*allocation, *sysSizeData) + getAuxResizeInfo(*sysSizeData) +} + +func (s *sysData) resizeWindow(width, height int) { + d := s.beginResize() + allocations := s.allocate(0, 0, width, height, d) + s.translateAllocationCoords(allocations, width, height) + for _, c := range s.allocations { + c.this.commitResize(c, d) + } + s.endResize(d) +} + +// non-layout controls: allocate() should just return a one-element slice; preferredSize(), commitResize(), and getAuxResizeInfo() should defer to their sysData equivalents +type controlSizing interface { + allocate(x int, y int, width int, height int, d *sysSizeData) []*allocation + preferredSize(d *sysSizeData) (width, height int) + commitResize(c *allocation, d *sysSizeData) + getAuxResizeInfo(d *sysSizeData) +} + +// vertical stack: no concept of neighbor, but not too hard to add a vertical neighbor +// horizontal stack: + var current *allocation + // ... + as := s.controls[i].allocate(...) + if current != nil { + current.neighbor = as[0].self + } + current = as[0] + // append all of as +// grid: + // same as above, except current is set to nil on each new row + // adding a vertical neighbor would require storing an extra list diff --git a/newsizing b/controlsize_sys.go index add1186..c520a30 100644 --- a/newsizing +++ b/controlsize_sys.go @@ -1,3 +1,7 @@ +// <codedate + +package ui + type sysSizeData struct { // for size calculations // all platforms @@ -26,15 +30,6 @@ func (s *sysData) endResize(d *sysSizeData) { // redraw } -type allocation struct { - x int - y int - width int - height int - this Control - neighbor Control -} - func (s *sysData) translateAllocationCoords(allocations []*allocation, winwidth, winheight int) { // windows, gtk: nothing // mac @@ -45,41 +40,6 @@ func (s *sysData) translateAllocationCoords(allocations []*allocation, winwidth, } } -func (s *sysData) resizeWindow(width, height int) { - d := s.beginResize() - allocations := s.allocate(0, 0, width, height, d) - s.translateAllocationCoords(allocations, width, height) - for _, c := range s.allocations { - c.this.doResize(c, d) - } - s.endResize(d) -} - -// setSize() becomes allocate() -// each allocate on a non-layout control should just return a one-element slice -// each doResize and getAuxResizeInfo on a control should just defer to sysData -type Control interface { - // ... - allocate(x int, y int, width int, height int, d *sysSizeData) []*allocation - preferredSize(d *sysSizeData) (width, height int) - doResize(c *allocation, d *sysSizeData) - getAuxResizeInfo(d *sysSizeData) -} - -// vertical stack: no concept of neighbor, but not too hard to add a vertical neighbor -// horizontal stack: - var current *allocation - // ... - as := s.controls[i].allocate(...) - if current != nil { - current.neighbor = as[0].self - } - current = as[0] - // append all of as -// grid: - // same as above, except current is set to nil on each new row - // adding a vertical neighbor would require storing an extra list - // windows func (s *sysData) doResize(c *allocation, d *sysSizeData) { if s.ctype == c_label { @@ -14,13 +14,14 @@ type cSysData struct { ctype int event chan struct{} resize func(x int, y int, width int, height int, rr *[]resizerequest) - resizes []resizerequest + spaced bool alternate bool // editable for Combobox, multi-select for listbox, password for lineedit handler AreaHandler // for Areas } // this interface is used to make sure all sysDatas are synced var _xSysData interface { + sysDataSizingFunctions make(window *sysData) error firstShow() error show() @@ -35,8 +36,6 @@ var _xSysData interface { selectedIndices() []int selectedTexts() []string setWindowSize(int, int) error - delete(int) - preferredSize() (int, int, int) setProgress(int) len() int setAreaSize(int, int) @@ -81,24 +80,3 @@ func mksysdata(ctype int) *sysData { } return s } - -type resizerequest struct { - sysData *sysData - x int - y int - width int - height int -} - -func (s *sysData) doResize(x int, y int, width int, height int, winheight int) { - if s.resize != nil { - s.resizes = s.resizes[0:0] // set len to 0 without changing cap - s.resize(x, y, width, height, &s.resizes) - for _, s := range s.resizes { - err := s.sysData.setRect(s.x, s.y, s.width, s.height, winheight) - if err != nil { - panic("child resize failed: " + err.Error()) - } - } - } -} @@ -21,6 +21,7 @@ type Window struct { initWidth int initHeight int shownOnce bool + spaced bool } // NewWindow allocates a new Window with the given title and size. The window is not created until a call to Create() or Open(). @@ -63,6 +64,21 @@ func (w *Window) SetSize(width int, height int) (err error) { return nil } +// SetSpaced sets whether the Window's child control takes padding and spacing into account. +// That is, with w.SetSpaced(true), w's child will have a margin around the window frame and will have sub-controls separated by an implementation-defined amount. +// Currently, only Stack and Grid explicitly understand this property. +// This property is visible recursively throughout the widget hierarchy of the Window. +// This property cannot be set after the Window has been created. +func (w *Window) SetSpaced(spaced bool) { + w.lock.Lock() + defer w.lock.Unlock() + + if w.created { + panic(fmt.Errorf("Window.SetSpaced() called after window created")) + } + w.spaced = spaced +} + // Open creates the Window with Create and then shows the Window with Show. As with Create, you cannot call Open more than once per window. func (w *Window) Open(control Control) { w.Create(control) @@ -77,6 +93,7 @@ func (w *Window) Create(control Control) { if w.created { panic("window already open") } + w.sysData.spaced = w.spaced w.sysData.event = w.Closing err := w.sysData.make(nil) if err != nil { |
