Migrated window.go and sysdata.go to the new API. Controls will need to be migrated as well.
This commit is contained in:
parent
ea6200a432
commit
d13e398e90
25
sysdata.go
25
sysdata.go
|
@ -2,21 +2,15 @@
|
||||||
|
|
||||||
package ui
|
package ui
|
||||||
|
|
||||||
const eventbufsiz = 100 // suggested by skelterjohn
|
|
||||||
|
|
||||||
// newEvent returns a new channel suitable for listening for events.
|
|
||||||
func newEvent() chan struct{} {
|
|
||||||
return make(chan struct{}, eventbufsiz)
|
|
||||||
}
|
|
||||||
|
|
||||||
// The sysData type contains all system data. It provides the system-specific underlying implementation. It is guaranteed to have the following by embedding:
|
// The sysData type contains all system data. It provides the system-specific underlying implementation. It is guaranteed to have the following by embedding:
|
||||||
type cSysData struct {
|
type cSysData struct {
|
||||||
ctype int
|
ctype int
|
||||||
event chan struct{}
|
|
||||||
allocate func(x int, y int, width int, height int, d *sysSizeData) []*allocation
|
allocate func(x int, y int, width int, height int, d *sysSizeData) []*allocation
|
||||||
spaced bool
|
spaced bool
|
||||||
alternate bool // editable for Combobox, multi-select for listbox, password for lineedit
|
alternate bool // editable for Combobox, multi-select for listbox, password for lineedit
|
||||||
handler AreaHandler // for Areas
|
handler AreaHandler // for Areas; TODO rename to areahandler
|
||||||
|
winhandler WindowHandler // for Windows
|
||||||
|
event func() // provided by each widget
|
||||||
}
|
}
|
||||||
|
|
||||||
// this interface is used to make sure all sysDatas are synced
|
// this interface is used to make sure all sysDatas are synced
|
||||||
|
@ -44,19 +38,6 @@ var _xSysData interface {
|
||||||
setChecked(bool)
|
setChecked(bool)
|
||||||
} = &sysData{} // this line will error if there's an inconsistency
|
} = &sysData{} // this line will error if there's an inconsistency
|
||||||
|
|
||||||
// signal sends the event signal. This raise is done asynchronously to avoid deadlocking the UI task.
|
|
||||||
// Thanks skelterjohn for this techinque: if we can't queue any more events, drop them
|
|
||||||
func (s *cSysData) signal() {
|
|
||||||
if s.event != nil {
|
|
||||||
go func() {
|
|
||||||
select {
|
|
||||||
case s.event <- struct{}{}:
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
c_window = iota
|
c_window = iota
|
||||||
c_button
|
c_button
|
||||||
|
|
56
window.go
56
window.go
|
@ -4,17 +4,10 @@ package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Window represents an on-screen window.
|
// Window represents an on-screen window.
|
||||||
type Window struct {
|
type Window struct {
|
||||||
// Closing gets a message when the user clicks the window's close button.
|
|
||||||
// You cannot change it once the Window has been created.
|
|
||||||
// If you do not respond to this signal, nothing will happen; regardless of whether you handle the signal or not, the window will not be closed.
|
|
||||||
Closing chan struct{}
|
|
||||||
|
|
||||||
lock sync.Mutex
|
|
||||||
created bool
|
created bool
|
||||||
sysData *sysData
|
sysData *sysData
|
||||||
initTitle string
|
initTitle string
|
||||||
|
@ -22,24 +15,44 @@ type Window struct {
|
||||||
initHeight int
|
initHeight int
|
||||||
shownOnce bool
|
shownOnce bool
|
||||||
spaced bool
|
spaced bool
|
||||||
|
handler WindowHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WindowHandler represents an event handler for a Window and all its child Controls.
|
||||||
|
//
|
||||||
|
// When an event on a Window or one of its child Controls comes in, the respect Window's handler's Event() method is called. The method call occurs on the main thread, and thus any call to any package ui method can be performed.
|
||||||
|
//
|
||||||
|
// Each Event() call takes two parameters: the event ID and a data argument. For most events, the data argument is a pointer to the Control that triggered the event.
|
||||||
|
//
|
||||||
|
// For Closing, the data argument is [TODO].
|
||||||
|
//
|
||||||
|
// For any event >= CustomEvent, the data argument is the argument passed to the Window's SendEvent() method.
|
||||||
|
type WindowHandler interface {
|
||||||
|
Event(e Event, data interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Event represents an event; see WindowHandler for details.
|
||||||
|
// All event values >= CustomEvent are available for program use.
|
||||||
|
type Event int
|
||||||
|
const (
|
||||||
|
Closing Event = iota // Window close
|
||||||
|
Clicked // Button click
|
||||||
|
CustomEvent = 5000 // very high number; higher than the package would ever need, anyway
|
||||||
|
)
|
||||||
|
|
||||||
// NewWindow allocates a new Window with the given title and size. The window is not created until a call to Create() or Open().
|
// NewWindow allocates a new Window with the given title and size. The window is not created until a call to Create() or Open().
|
||||||
func NewWindow(title string, width int, height int) *Window {
|
func NewWindow(title string, width int, height int, handler WindowHandler) *Window {
|
||||||
return &Window{
|
return &Window{
|
||||||
sysData: mksysdata(c_window),
|
sysData: mksysdata(c_window),
|
||||||
initTitle: title,
|
initTitle: title,
|
||||||
initWidth: width,
|
initWidth: width,
|
||||||
initHeight: height,
|
initHeight: height,
|
||||||
Closing: newEvent(),
|
handler: handler,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetTitle sets the window's title.
|
// SetTitle sets the window's title.
|
||||||
func (w *Window) SetTitle(title string) {
|
func (w *Window) SetTitle(title string) {
|
||||||
w.lock.Lock()
|
|
||||||
defer w.lock.Unlock()
|
|
||||||
|
|
||||||
if w.created {
|
if w.created {
|
||||||
w.sysData.setText(title)
|
w.sysData.setText(title)
|
||||||
return
|
return
|
||||||
|
@ -49,9 +62,6 @@ func (w *Window) SetTitle(title string) {
|
||||||
|
|
||||||
// SetSize sets the window's size.
|
// SetSize sets the window's size.
|
||||||
func (w *Window) SetSize(width int, height int) (err error) {
|
func (w *Window) SetSize(width int, height int) (err error) {
|
||||||
w.lock.Lock()
|
|
||||||
defer w.lock.Unlock()
|
|
||||||
|
|
||||||
if w.created {
|
if w.created {
|
||||||
err := w.sysData.setWindowSize(width, height)
|
err := w.sysData.setWindowSize(width, height)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -70,9 +80,6 @@ func (w *Window) SetSize(width int, height int) (err error) {
|
||||||
// This property is visible recursively throughout the widget hierarchy of the Window.
|
// This property is visible recursively throughout the widget hierarchy of the Window.
|
||||||
// This property cannot be set after the Window has been created.
|
// This property cannot be set after the Window has been created.
|
||||||
func (w *Window) SetSpaced(spaced bool) {
|
func (w *Window) SetSpaced(spaced bool) {
|
||||||
w.lock.Lock()
|
|
||||||
defer w.lock.Unlock()
|
|
||||||
|
|
||||||
if w.created {
|
if w.created {
|
||||||
panic(fmt.Errorf("Window.SetSpaced() called after window created"))
|
panic(fmt.Errorf("Window.SetSpaced() called after window created"))
|
||||||
}
|
}
|
||||||
|
@ -87,14 +94,10 @@ func (w *Window) Open(control Control) {
|
||||||
|
|
||||||
// Create creates the Window, setting its control to the given control. It does not show the window. This can only be called once per window, and finalizes all initialization of the control.
|
// Create creates the Window, setting its control to the given control. It does not show the window. This can only be called once per window, and finalizes all initialization of the control.
|
||||||
func (w *Window) Create(control Control) {
|
func (w *Window) Create(control Control) {
|
||||||
w.lock.Lock()
|
|
||||||
defer w.lock.Unlock()
|
|
||||||
|
|
||||||
if w.created {
|
if w.created {
|
||||||
panic("window already open")
|
panic("window already open")
|
||||||
}
|
}
|
||||||
w.sysData.spaced = w.spaced
|
w.sysData.spaced = w.spaced
|
||||||
w.sysData.event = w.Closing
|
|
||||||
err := w.sysData.make(nil)
|
err := w.sysData.make(nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Errorf("error opening window: %v", err))
|
panic(fmt.Errorf("error opening window: %v", err))
|
||||||
|
@ -116,9 +119,6 @@ func (w *Window) Create(control Control) {
|
||||||
|
|
||||||
// Show shows the window.
|
// Show shows the window.
|
||||||
func (w *Window) Show() {
|
func (w *Window) Show() {
|
||||||
w.lock.Lock()
|
|
||||||
defer w.lock.Unlock()
|
|
||||||
|
|
||||||
if !w.shownOnce {
|
if !w.shownOnce {
|
||||||
w.shownOnce = true
|
w.shownOnce = true
|
||||||
err := w.sysData.firstShow()
|
err := w.sysData.firstShow()
|
||||||
|
@ -132,9 +132,6 @@ func (w *Window) Show() {
|
||||||
|
|
||||||
// Hide hides the window.
|
// Hide hides the window.
|
||||||
func (w *Window) Hide() {
|
func (w *Window) Hide() {
|
||||||
w.lock.Lock()
|
|
||||||
defer w.lock.Unlock()
|
|
||||||
|
|
||||||
w.sysData.hide()
|
w.sysData.hide()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,9 +139,6 @@ func (w *Window) Hide() {
|
||||||
// The concept of "screen" in the case of a multi-monitor setup is implementation-defined.
|
// The concept of "screen" in the case of a multi-monitor setup is implementation-defined.
|
||||||
// It presently panics if the Window has not been created.
|
// It presently panics if the Window has not been created.
|
||||||
func (w *Window) Center() {
|
func (w *Window) Center() {
|
||||||
w.lock.Lock()
|
|
||||||
defer w.lock.Unlock()
|
|
||||||
|
|
||||||
if !w.created {
|
if !w.created {
|
||||||
panic("attempt to center Window before it has been created")
|
panic("attempt to center Window before it has been created")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue