Began the work for moving everything to the new control sizing system.

This commit is contained in:
Pietro Gagliardi 2014-06-25 22:07:37 -04:00
parent cf1da0218c
commit e4992dbcb2
5 changed files with 78 additions and 70 deletions

View File

@ -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
}

54
controlsize.go Normal file
View File

@ -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

View File

@ -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 {

View File

@ -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())
}
}
}
}

View File

@ -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 {