Began the work for moving everything to the new control sizing system.
This commit is contained in:
parent
cf1da0218c
commit
e4992dbcb2
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -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 {
|
26
sysdata.go
26
sysdata.go
|
@ -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())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
17
window.go
17
window.go
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue