Re-organized module structure
This commit is contained in:
parent
719b7b99ac
commit
53bfc8df68
@ -3,7 +3,6 @@ package tomo
|
||||
import "errors"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/theme"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/config"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements"
|
||||
|
||||
// Backend represents a connection to a display server, or something similar.
|
||||
// It is capable of managing an event loop, and creating windows.
|
||||
@ -22,7 +21,7 @@ type Backend interface {
|
||||
// NewWindow creates a new window with the specified width and height,
|
||||
// and returns a struct representing it that fulfills the MainWindow
|
||||
// interface.
|
||||
NewWindow (width, height int) (window elements.MainWindow, err error)
|
||||
NewWindow (width, height int) (window MainWindow, err error)
|
||||
|
||||
// SetTheme sets the theme of all open windows.
|
||||
SetTheme (theme.Theme)
|
||||
|
@ -1,8 +1,8 @@
|
||||
package x
|
||||
|
||||
import "image"
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/input"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements"
|
||||
|
||||
import "github.com/jezek/xgbutil"
|
||||
import "github.com/jezek/xgb/xproto"
|
||||
@ -127,7 +127,7 @@ func (window *window) handleKeyPress (
|
||||
modifiers.NumberPad = numberPad
|
||||
|
||||
if key == input.KeyTab && modifiers.Alt {
|
||||
if child, ok := window.child.(elements.Focusable); ok {
|
||||
if child, ok := window.child.(tomo.Focusable); ok {
|
||||
direction := input.KeynavDirectionForward
|
||||
if modifiers.Shift {
|
||||
direction = input.KeynavDirectionBackward
|
||||
@ -137,7 +137,7 @@ func (window *window) handleKeyPress (
|
||||
child.HandleUnfocus()
|
||||
}
|
||||
}
|
||||
} else if child, ok := window.child.(elements.KeyboardTarget); ok {
|
||||
} else if child, ok := window.child.(tomo.KeyboardTarget); ok {
|
||||
child.HandleKeyDown(key, modifiers)
|
||||
}
|
||||
}
|
||||
@ -171,7 +171,7 @@ func (window *window) handleKeyRelease (
|
||||
modifiers := window.modifiersFromState(keyEvent.State)
|
||||
modifiers.NumberPad = numberPad
|
||||
|
||||
if child, ok := window.child.(elements.KeyboardTarget); ok {
|
||||
if child, ok := window.child.(tomo.KeyboardTarget); ok {
|
||||
child.HandleKeyUp(key, modifiers)
|
||||
}
|
||||
}
|
||||
@ -185,7 +185,7 @@ func (window *window) handleButtonPress (
|
||||
|
||||
buttonEvent := *event.ButtonPressEvent
|
||||
if buttonEvent.Detail >= 4 && buttonEvent.Detail <= 7 {
|
||||
if child, ok := window.child.(elements.ScrollTarget); ok {
|
||||
if child, ok := window.child.(tomo.ScrollTarget); ok {
|
||||
sum := scrollSum { }
|
||||
sum.add(buttonEvent.Detail, window, buttonEvent.State)
|
||||
window.compressScrollSum(buttonEvent, &sum)
|
||||
@ -195,7 +195,7 @@ func (window *window) handleButtonPress (
|
||||
float64(sum.x), float64(sum.y))
|
||||
}
|
||||
} else {
|
||||
if child, ok := window.child.(elements.MouseTarget); ok {
|
||||
if child, ok := window.child.(tomo.MouseTarget); ok {
|
||||
child.HandleMouseDown (
|
||||
int(buttonEvent.EventX),
|
||||
int(buttonEvent.EventY),
|
||||
@ -211,7 +211,7 @@ func (window *window) handleButtonRelease (
|
||||
) {
|
||||
if window.child == nil { return }
|
||||
|
||||
if child, ok := window.child.(elements.MouseTarget); ok {
|
||||
if child, ok := window.child.(tomo.MouseTarget); ok {
|
||||
buttonEvent := *event.ButtonReleaseEvent
|
||||
if buttonEvent.Detail >= 4 && buttonEvent.Detail <= 7 { return }
|
||||
child.HandleMouseUp (
|
||||
@ -227,7 +227,7 @@ func (window *window) handleMotionNotify (
|
||||
) {
|
||||
if window.child == nil { return }
|
||||
|
||||
if child, ok := window.child.(elements.MotionTarget); ok {
|
||||
if child, ok := window.child.(tomo.MotionTarget); ok {
|
||||
motionEvent := window.compressMotionNotify(*event.MotionNotifyEvent)
|
||||
child.HandleMotion (
|
||||
int(motionEvent.EventX),
|
||||
|
@ -9,12 +9,12 @@ import "github.com/jezek/xgbutil/xprop"
|
||||
import "github.com/jezek/xgbutil/xevent"
|
||||
import "github.com/jezek/xgbutil/xwindow"
|
||||
import "github.com/jezek/xgbutil/xgraphics"
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/data"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/input"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/theme"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/config"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/canvas"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements"
|
||||
// import "runtime/debug"
|
||||
|
||||
type mainWindow struct { *window }
|
||||
@ -23,7 +23,7 @@ type window struct {
|
||||
xWindow *xwindow.Window
|
||||
xCanvas *xgraphics.Image
|
||||
canvas canvas.BasicCanvas
|
||||
child elements.Element
|
||||
child tomo.Element
|
||||
onClose func ()
|
||||
skipChildDrawCallback bool
|
||||
|
||||
@ -45,7 +45,7 @@ type window struct {
|
||||
func (backend *Backend) NewWindow (
|
||||
width, height int,
|
||||
) (
|
||||
output elements.MainWindow,
|
||||
output tomo.MainWindow,
|
||||
err error,
|
||||
) {
|
||||
if backend == nil { panic("nil backend") }
|
||||
@ -120,35 +120,35 @@ func (backend *Backend) newWindow (
|
||||
return
|
||||
}
|
||||
|
||||
func (window *window) NotifyMinimumSizeChange (child elements.Element) {
|
||||
func (window *window) NotifyMinimumSizeChange (child tomo.Element) {
|
||||
window.childMinimumSizeChangeCallback(child.MinimumSize())
|
||||
}
|
||||
|
||||
func (window *window) RequestFocus (
|
||||
child elements.Focusable,
|
||||
child tomo.Focusable,
|
||||
) (
|
||||
granted bool,
|
||||
) {
|
||||
return true
|
||||
}
|
||||
|
||||
func (window *window) RequestFocusNext (child elements.Focusable) {
|
||||
if child, ok := window.child.(elements.Focusable); ok {
|
||||
func (window *window) RequestFocusNext (child tomo.Focusable) {
|
||||
if child, ok := window.child.(tomo.Focusable); ok {
|
||||
if !child.HandleFocus(input.KeynavDirectionForward) {
|
||||
child.HandleUnfocus()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (window *window) RequestFocusPrevious (child elements.Focusable) {
|
||||
if child, ok := window.child.(elements.Focusable); ok {
|
||||
func (window *window) RequestFocusPrevious (child tomo.Focusable) {
|
||||
if child, ok := window.child.(tomo.Focusable); ok {
|
||||
if !child.HandleFocus(input.KeynavDirectionBackward) {
|
||||
child.HandleUnfocus()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (window *window) Adopt (child elements.Element) {
|
||||
func (window *window) Adopt (child tomo.Element) {
|
||||
// disown previous child
|
||||
if window.child != nil {
|
||||
window.child.SetParent(nil)
|
||||
@ -159,10 +159,10 @@ func (window *window) Adopt (child elements.Element) {
|
||||
// adopt new child
|
||||
window.child = child
|
||||
child.SetParent(window)
|
||||
if newChild, ok := child.(elements.Themeable); ok {
|
||||
if newChild, ok := child.(tomo.Themeable); ok {
|
||||
newChild.SetTheme(window.theme)
|
||||
}
|
||||
if newChild, ok := child.(elements.Configurable); ok {
|
||||
if newChild, ok := child.(tomo.Configurable); ok {
|
||||
newChild.SetConfig(window.config)
|
||||
}
|
||||
if child != nil {
|
||||
@ -174,7 +174,7 @@ func (window *window) Adopt (child elements.Element) {
|
||||
}
|
||||
}
|
||||
|
||||
func (window *window) Child () (child elements.Element) {
|
||||
func (window *window) Child () (child tomo.Element) {
|
||||
child = window.child
|
||||
return
|
||||
}
|
||||
@ -225,7 +225,7 @@ func (window *window) SetIcon (sizes []image.Image) {
|
||||
wmIcons)
|
||||
}
|
||||
|
||||
func (window *window) NewModal (width, height int) (elements.Window, error) {
|
||||
func (window *window) NewModal (width, height int) (tomo.Window, error) {
|
||||
modal, err := window.backend.newWindow(width, height)
|
||||
icccm.WmTransientForSet (
|
||||
window.backend.connection,
|
||||
@ -240,7 +240,7 @@ func (window *window) NewModal (width, height int) (elements.Window, error) {
|
||||
return modal, err
|
||||
}
|
||||
|
||||
func (window mainWindow) NewPanel (width, height int) (elements.Window, error) {
|
||||
func (window mainWindow) NewPanel (width, height int) (tomo.Window, error) {
|
||||
panel, err := window.backend.newWindow(width, height)
|
||||
if err != nil { return nil, err }
|
||||
panel.setClientLeader(window.window)
|
||||
@ -336,14 +336,14 @@ func (window *window) OnClose (callback func ()) {
|
||||
|
||||
func (window *window) SetTheme (theme theme.Theme) {
|
||||
window.theme = theme
|
||||
if child, ok := window.child.(elements.Themeable); ok {
|
||||
if child, ok := window.child.(tomo.Themeable); ok {
|
||||
child.SetTheme(theme)
|
||||
}
|
||||
}
|
||||
|
||||
func (window *window) SetConfig (config config.Config) {
|
||||
window.config = config
|
||||
if child, ok := window.child.(elements.Configurable); ok {
|
||||
if child, ok := window.child.(tomo.Configurable); ok {
|
||||
child.SetConfig(config)
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package elements
|
||||
package tomo
|
||||
|
||||
import "image"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/input"
|
@ -1,3 +0,0 @@
|
||||
// Package basicElements provides standard elements that are commonly used in
|
||||
// GUI applications.
|
||||
package basicElements
|
@ -1,4 +1,4 @@
|
||||
package basicElements
|
||||
package elements
|
||||
|
||||
import "image"
|
||||
// import "runtime/debug"
|
||||
@ -34,7 +34,7 @@ type Button struct {
|
||||
// NewButton creates a new button with the specified label text.
|
||||
func NewButton (text string) (element *Button) {
|
||||
element = &Button { showText: true }
|
||||
element.theme.Case = theme.C("basic", "button")
|
||||
element.theme.Case = theme.C("tomo", "button")
|
||||
element.Core, element.core = core.NewCore(element, element.drawAll)
|
||||
element.FocusableCore,
|
||||
element.focusableControl = core.NewFocusableCore(element.core, element.drawAndPush)
|
@ -1,4 +1,4 @@
|
||||
package basicElements
|
||||
package elements
|
||||
|
||||
import "image"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/input"
|
||||
@ -28,7 +28,7 @@ type Checkbox struct {
|
||||
// NewCheckbox creates a new cbeckbox with the specified label text.
|
||||
func NewCheckbox (text string, checked bool) (element *Checkbox) {
|
||||
element = &Checkbox { checked: checked }
|
||||
element.theme.Case = theme.C("basic", "checkbox")
|
||||
element.theme.Case = theme.C("tomo", "checkbox")
|
||||
element.Core, element.core = core.NewCore(element, element.draw)
|
||||
element.FocusableCore,
|
||||
element.focusableControl = core.NewFocusableCore(element.core, element.redo)
|
@ -1,13 +1,12 @@
|
||||
package containers
|
||||
|
||||
import "image"
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/input"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/theme"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/config"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/canvas"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/artist"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/core"
|
||||
|
||||
// Container is an element capable of containg other elements, and arranging
|
||||
@ -17,8 +16,8 @@ type Container struct {
|
||||
*core.Propagator
|
||||
core core.CoreControl
|
||||
|
||||
layout layouts.Layout
|
||||
children []layouts.LayoutEntry
|
||||
layout tomo.Layout
|
||||
children []tomo.LayoutEntry
|
||||
warping bool
|
||||
|
||||
config config.Wrapped
|
||||
@ -29,9 +28,9 @@ type Container struct {
|
||||
}
|
||||
|
||||
// NewContainer creates a new container.
|
||||
func NewContainer (layout layouts.Layout) (element *Container) {
|
||||
func NewContainer (layout tomo.Layout) (element *Container) {
|
||||
element = &Container { }
|
||||
element.theme.Case = theme.C("containers", "container")
|
||||
element.theme.Case = theme.C("tomo", "container")
|
||||
element.Core, element.core = core.NewCore(element, element.redoAll)
|
||||
element.Propagator = core.NewPropagator(element, element.core)
|
||||
element.SetLayout(layout)
|
||||
@ -39,7 +38,7 @@ func NewContainer (layout layouts.Layout) (element *Container) {
|
||||
}
|
||||
|
||||
// SetLayout sets the layout of this container.
|
||||
func (element *Container) SetLayout (layout layouts.Layout) {
|
||||
func (element *Container) SetLayout (layout tomo.Layout) {
|
||||
element.layout = layout
|
||||
element.updateMinimumSize()
|
||||
if element.core.HasImage() {
|
||||
@ -51,17 +50,17 @@ func (element *Container) SetLayout (layout layouts.Layout) {
|
||||
// Adopt adds a new child element to the container. If expand is set to true,
|
||||
// the element will expand (instead of contract to its minimum size), in
|
||||
// whatever way is defined by the current layout.
|
||||
func (element *Container) Adopt (child elements.Element, expand bool) {
|
||||
if child0, ok := child.(elements.Themeable); ok {
|
||||
func (element *Container) Adopt (child tomo.Element, expand bool) {
|
||||
if child0, ok := child.(tomo.Themeable); ok {
|
||||
child0.SetTheme(element.theme.Theme)
|
||||
}
|
||||
if child0, ok := child.(elements.Configurable); ok {
|
||||
if child0, ok := child.(tomo.Configurable); ok {
|
||||
child0.SetConfig(element.config.Config)
|
||||
}
|
||||
child.SetParent(element)
|
||||
|
||||
// add child
|
||||
element.children = append (element.children, layouts.LayoutEntry {
|
||||
element.children = append (element.children, tomo.LayoutEntry {
|
||||
Element: child,
|
||||
Expand: expand,
|
||||
})
|
||||
@ -98,7 +97,7 @@ func (element *Container) Warp (callback func ()) {
|
||||
|
||||
// Disown removes the given child from the container if it is contained within
|
||||
// it.
|
||||
func (element *Container) Disown (child elements.Element) {
|
||||
func (element *Container) Disown (child tomo.Element) {
|
||||
for index, entry := range element.children {
|
||||
if entry.Element == child {
|
||||
element.clearChildEventHandlers(entry.Element)
|
||||
@ -116,11 +115,11 @@ func (element *Container) Disown (child elements.Element) {
|
||||
}
|
||||
}
|
||||
|
||||
func (element *Container) clearChildEventHandlers (child elements.Element) {
|
||||
func (element *Container) clearChildEventHandlers (child tomo.Element) {
|
||||
child.DrawTo(nil, image.Rectangle { }, nil)
|
||||
child.SetParent(nil)
|
||||
|
||||
if child, ok := child.(elements.Focusable); ok {
|
||||
if child, ok := child.(tomo.Focusable); ok {
|
||||
if child.Focused() {
|
||||
child.HandleUnfocus()
|
||||
}
|
||||
@ -142,8 +141,8 @@ func (element *Container) DisownAll () {
|
||||
}
|
||||
|
||||
// Children returns a slice containing this element's children.
|
||||
func (element *Container) Children () (children []elements.Element) {
|
||||
children = make([]elements.Element, len(element.children))
|
||||
func (element *Container) Children () (children []tomo.Element) {
|
||||
children = make([]tomo.Element, len(element.children))
|
||||
for index, entry := range element.children {
|
||||
children[index] = entry.Element
|
||||
}
|
||||
@ -157,14 +156,14 @@ func (element *Container) CountChildren () (count int) {
|
||||
|
||||
// Child returns the child at the specified index. If the index is out of
|
||||
// bounds, this method will return nil.
|
||||
func (element *Container) Child (index int) (child elements.Element) {
|
||||
func (element *Container) Child (index int) (child tomo.Element) {
|
||||
if index < 0 || index > len(element.children) { return }
|
||||
return element.children[index].Element
|
||||
}
|
||||
|
||||
// ChildAt returns the child that contains the specified x and y coordinates. If
|
||||
// there are no children at the coordinates, this method will return nil.
|
||||
func (element *Container) ChildAt (point image.Point) (child elements.Element) {
|
||||
func (element *Container) ChildAt (point image.Point) (child tomo.Element) {
|
||||
for _, entry := range element.children {
|
||||
if point.In(entry.Bounds) {
|
||||
child = entry.Element
|
||||
@ -207,7 +206,7 @@ func (element *Container) redoAll () {
|
||||
|
||||
// NotifyMinimumSizeChange notifies the container that the minimum size of a
|
||||
// child element has changed.
|
||||
func (element *Container) NotifyMinimumSizeChange (child elements.Element) {
|
||||
func (element *Container) NotifyMinimumSizeChange (child tomo.Element) {
|
||||
element.updateMinimumSize()
|
||||
element.redoAll()
|
||||
element.core.DamageAll()
|
||||
|
@ -1,12 +1,11 @@
|
||||
package containers
|
||||
|
||||
import "image"
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/theme"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/config"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/canvas"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/artist"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/core"
|
||||
|
||||
type DocumentContainer struct {
|
||||
@ -14,7 +13,7 @@ type DocumentContainer struct {
|
||||
*core.Propagator
|
||||
core core.CoreControl
|
||||
|
||||
children []layouts.LayoutEntry
|
||||
children []tomo.LayoutEntry
|
||||
scroll image.Point
|
||||
warping bool
|
||||
contentBounds image.Rectangle
|
||||
@ -28,24 +27,24 @@ type DocumentContainer struct {
|
||||
// NewDocumentContainer creates a new document container.
|
||||
func NewDocumentContainer () (element *DocumentContainer) {
|
||||
element = &DocumentContainer { }
|
||||
element.theme.Case = theme.C("containers", "documentContainer")
|
||||
element.theme.Case = theme.C("tomo", "documentContainer")
|
||||
element.Core, element.core = core.NewCore(element, element.redoAll)
|
||||
element.Propagator = core.NewPropagator(element, element.core)
|
||||
return
|
||||
}
|
||||
|
||||
// Adopt adds a new child element to the container.
|
||||
func (element *DocumentContainer) Adopt (child elements.Element) {
|
||||
func (element *DocumentContainer) Adopt (child tomo.Element) {
|
||||
// set event handlers
|
||||
if child0, ok := child.(elements.Themeable); ok {
|
||||
if child0, ok := child.(tomo.Themeable); ok {
|
||||
child0.SetTheme(element.theme.Theme)
|
||||
}
|
||||
if child0, ok := child.(elements.Configurable); ok {
|
||||
if child0, ok := child.(tomo.Configurable); ok {
|
||||
child0.SetConfig(element.config.Config)
|
||||
}
|
||||
|
||||
// add child
|
||||
element.children = append (element.children, layouts.LayoutEntry {
|
||||
element.children = append (element.children, tomo.LayoutEntry {
|
||||
Element: child,
|
||||
})
|
||||
|
||||
@ -80,7 +79,7 @@ func (element *DocumentContainer) Warp (callback func ()) {
|
||||
|
||||
// Disown removes the given child from the container if it is contained within
|
||||
// it.
|
||||
func (element *DocumentContainer) Disown (child elements.Element) {
|
||||
func (element *DocumentContainer) Disown (child tomo.Element) {
|
||||
for index, entry := range element.children {
|
||||
if entry.Element == child {
|
||||
element.clearChildEventHandlers(entry.Element)
|
||||
@ -98,11 +97,11 @@ func (element *DocumentContainer) Disown (child elements.Element) {
|
||||
}
|
||||
}
|
||||
|
||||
func (element *DocumentContainer) clearChildEventHandlers (child elements.Element) {
|
||||
func (element *DocumentContainer) clearChildEventHandlers (child tomo.Element) {
|
||||
child.DrawTo(nil, image.Rectangle { }, nil)
|
||||
child.SetParent(nil)
|
||||
|
||||
if child, ok := child.(elements.Focusable); ok {
|
||||
if child, ok := child.(tomo.Focusable); ok {
|
||||
if child.Focused() {
|
||||
child.HandleUnfocus()
|
||||
}
|
||||
@ -124,8 +123,8 @@ func (element *DocumentContainer) DisownAll () {
|
||||
}
|
||||
|
||||
// Children returns a slice containing this element's children.
|
||||
func (element *DocumentContainer) Children () (children []elements.Element) {
|
||||
children = make([]elements.Element, len(element.children))
|
||||
func (element *DocumentContainer) Children () (children []tomo.Element) {
|
||||
children = make([]tomo.Element, len(element.children))
|
||||
for index, entry := range element.children {
|
||||
children[index] = entry.Element
|
||||
}
|
||||
@ -139,14 +138,14 @@ func (element *DocumentContainer) CountChildren () (count int) {
|
||||
|
||||
// Child returns the child at the specified index. If the index is out of
|
||||
// bounds, this method will return nil.
|
||||
func (element *DocumentContainer) Child (index int) (child elements.Element) {
|
||||
func (element *DocumentContainer) Child (index int) (child tomo.Element) {
|
||||
if index < 0 || index > len(element.children) { return }
|
||||
return element.children[index].Element
|
||||
}
|
||||
|
||||
// ChildAt returns the child that contains the specified x and y coordinates. If
|
||||
// there are no children at the coordinates, this method will return nil.
|
||||
func (element *DocumentContainer) ChildAt (point image.Point) (child elements.Element) {
|
||||
func (element *DocumentContainer) ChildAt (point image.Point) (child tomo.Element) {
|
||||
for _, entry := range element.children {
|
||||
if point.In(entry.Bounds) {
|
||||
child = entry.Element
|
||||
@ -178,7 +177,7 @@ func (element *DocumentContainer) redoAll () {
|
||||
artist.DrawShatter(element.core, pattern, element.Bounds(), rocks...)
|
||||
|
||||
element.partition()
|
||||
if parent, ok := element.core.Parent().(elements.ScrollableParent); ok {
|
||||
if parent, ok := element.core.Parent().(tomo.ScrollableParent); ok {
|
||||
parent.NotifyScrollBoundsChange(element)
|
||||
}
|
||||
if element.onScrollBoundsChange != nil {
|
||||
@ -205,7 +204,7 @@ func (element *DocumentContainer) partition () {
|
||||
|
||||
// NotifyMinimumSizeChange notifies the container that the minimum size of a
|
||||
// child element has changed.
|
||||
func (element *DocumentContainer) NotifyMinimumSizeChange (child elements.Element) {
|
||||
func (element *DocumentContainer) NotifyMinimumSizeChange (child tomo.Element) {
|
||||
element.redoAll()
|
||||
element.core.DamageAll()
|
||||
}
|
||||
@ -214,7 +213,7 @@ func (element *DocumentContainer) NotifyMinimumSizeChange (child elements.Elemen
|
||||
// affecting a child's flexible height have changed. This method is
|
||||
// expected to be called by flexible child element when their content
|
||||
// changes.
|
||||
func (element *DocumentContainer) NotifyFlexibleHeightChange (child elements.Flexible) {
|
||||
func (element *DocumentContainer) NotifyFlexibleHeightChange (child tomo.Flexible) {
|
||||
element.redoAll()
|
||||
element.core.DamageAll()
|
||||
}
|
||||
@ -300,7 +299,7 @@ func (element *DocumentContainer) doLayout () {
|
||||
if width < bounds.Dx() {
|
||||
width = bounds.Dx()
|
||||
}
|
||||
if typedChild, ok := entry.Element.(elements.Flexible); ok {
|
||||
if typedChild, ok := entry.Element.(tomo.Flexible); ok {
|
||||
height = typedChild.FlexibleHeightFor(width)
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
package containers
|
||||
|
||||
import "image"
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/input"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/theme"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/config"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/canvas"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/core"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/basic"
|
||||
|
||||
// ScrollContainer is a container that is capable of holding a scrollable
|
||||
// element.
|
||||
@ -16,9 +16,9 @@ type ScrollContainer struct {
|
||||
*core.Propagator
|
||||
core core.CoreControl
|
||||
|
||||
child elements.Scrollable
|
||||
horizontal *basicElements.ScrollBar
|
||||
vertical *basicElements.ScrollBar
|
||||
child tomo.Scrollable
|
||||
horizontal *elements.ScrollBar
|
||||
vertical *elements.ScrollBar
|
||||
|
||||
config config.Wrapped
|
||||
theme theme.Wrapped
|
||||
@ -31,12 +31,12 @@ type ScrollContainer struct {
|
||||
// bars.
|
||||
func NewScrollContainer (horizontal, vertical bool) (element *ScrollContainer) {
|
||||
element = &ScrollContainer { }
|
||||
element.theme.Case = theme.C("containers", "scrollContainer")
|
||||
element.theme.Case = theme.C("tomo", "scrollContainer")
|
||||
element.Core, element.core = core.NewCore(element, element.redoAll)
|
||||
element.Propagator = core.NewPropagator(element, element.core)
|
||||
|
||||
if horizontal {
|
||||
element.horizontal = basicElements.NewScrollBar(false)
|
||||
element.horizontal = elements.NewScrollBar(false)
|
||||
element.setUpChild(element.horizontal)
|
||||
element.horizontal.OnScroll (func (viewport image.Point) {
|
||||
if element.child != nil {
|
||||
@ -50,7 +50,7 @@ func NewScrollContainer (horizontal, vertical bool) (element *ScrollContainer) {
|
||||
})
|
||||
}
|
||||
if vertical {
|
||||
element.vertical = basicElements.NewScrollBar(true)
|
||||
element.vertical = elements.NewScrollBar(true)
|
||||
element.setUpChild(element.vertical)
|
||||
element.vertical.OnScroll (func (viewport image.Point) {
|
||||
if element.child != nil {
|
||||
@ -70,7 +70,7 @@ func NewScrollContainer (horizontal, vertical bool) (element *ScrollContainer) {
|
||||
// Adopt adds a scrollable element to the scroll container. The container can
|
||||
// only contain one scrollable element at a time, and when a new one is adopted
|
||||
// it replaces the last one.
|
||||
func (element *ScrollContainer) Adopt (child elements.Scrollable) {
|
||||
func (element *ScrollContainer) Adopt (child tomo.Scrollable) {
|
||||
// disown previous child if it exists
|
||||
if element.child != nil {
|
||||
element.disownChild(child)
|
||||
@ -90,20 +90,20 @@ func (element *ScrollContainer) Adopt (child elements.Scrollable) {
|
||||
}
|
||||
}
|
||||
|
||||
func (element *ScrollContainer) setUpChild (child elements.Element) {
|
||||
func (element *ScrollContainer) setUpChild (child tomo.Element) {
|
||||
child.SetParent(element)
|
||||
if child, ok := child.(elements.Themeable); ok {
|
||||
if child, ok := child.(tomo.Themeable); ok {
|
||||
child.SetTheme(element.theme.Theme)
|
||||
}
|
||||
if child, ok := child.(elements.Configurable); ok {
|
||||
if child, ok := child.(tomo.Configurable); ok {
|
||||
child.SetConfig(element.config.Config)
|
||||
}
|
||||
}
|
||||
|
||||
func (element *ScrollContainer) disownChild (child elements.Scrollable) {
|
||||
func (element *ScrollContainer) disownChild (child tomo.Scrollable) {
|
||||
child.DrawTo(nil, image.Rectangle { }, nil)
|
||||
child.SetParent(nil)
|
||||
if child, ok := child.(elements.Focusable); ok {
|
||||
if child, ok := child.(tomo.Focusable); ok {
|
||||
if child.Focused() {
|
||||
child.HandleUnfocus()
|
||||
}
|
||||
@ -112,14 +112,14 @@ func (element *ScrollContainer) disownChild (child elements.Scrollable) {
|
||||
|
||||
// NotifyMinimumSizeChange notifies the container that the minimum size of a
|
||||
// child element has changed.
|
||||
func (element *ScrollContainer) NotifyMinimumSizeChange (child elements.Element) {
|
||||
func (element *ScrollContainer) NotifyMinimumSizeChange (child tomo.Element) {
|
||||
element.redoAll()
|
||||
element.core.DamageAll()
|
||||
}
|
||||
|
||||
// NotifyScrollBoundsChange notifies the container that the scroll bounds or
|
||||
// axes of a child have changed.
|
||||
func (element *ScrollContainer) NotifyScrollBoundsChange (child elements.Scrollable) {
|
||||
func (element *ScrollContainer) NotifyScrollBoundsChange (child tomo.Scrollable) {
|
||||
element.updateEnabled()
|
||||
viewportBounds := element.child.ScrollViewportBounds()
|
||||
contentBounds := element.child.ScrollContentBounds()
|
||||
@ -165,7 +165,7 @@ func (element *ScrollContainer) CountChildren () (count int) {
|
||||
|
||||
// Child returns the child at the specified index. If the index is out of
|
||||
// bounds, this method will return nil.
|
||||
func (element *ScrollContainer) Child (index int) (child elements.Element) {
|
||||
func (element *ScrollContainer) Child (index int) (child tomo.Element) {
|
||||
switch index {
|
||||
case 0: return element.child
|
||||
case 1:
|
||||
|
@ -2,16 +2,16 @@ package core
|
||||
|
||||
import "image"
|
||||
import "image/color"
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/canvas"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements"
|
||||
|
||||
// Core is a struct that implements some core functionality common to most
|
||||
// widgets. It is meant to be embedded directly into a struct.
|
||||
type Core struct {
|
||||
canvas canvas.Canvas
|
||||
bounds image.Rectangle
|
||||
parent elements.Parent
|
||||
outer elements.Element
|
||||
parent tomo.Parent
|
||||
outer tomo.Element
|
||||
|
||||
metrics struct {
|
||||
minimumWidth int
|
||||
@ -26,7 +26,7 @@ type Core struct {
|
||||
// element that it will be a part of. If outer is nil, this function will return
|
||||
// nil.
|
||||
func NewCore (
|
||||
outer elements.Element,
|
||||
outer tomo.Element,
|
||||
drawSizeChange func (),
|
||||
) (
|
||||
core *Core,
|
||||
@ -57,7 +57,7 @@ func (core *Core) MinimumSize () (width, height int) {
|
||||
// MinimumSize fulfils the tomo.Element interface. This should not need to be
|
||||
// overridden, unless you want to detect when the element is parented or
|
||||
// unparented.
|
||||
func (core *Core) SetParent (parent elements.Parent) {
|
||||
func (core *Core) SetParent (parent tomo.Parent) {
|
||||
if parent != nil && core.parent != nil {
|
||||
panic("core.SetParent: element already has a parent")
|
||||
}
|
||||
@ -118,12 +118,12 @@ func (control CoreControl) Buffer () (data []color.RGBA, stride int) {
|
||||
}
|
||||
|
||||
// Parent returns the element's parent.
|
||||
func (control CoreControl) Parent () elements.Parent {
|
||||
func (control CoreControl) Parent () tomo.Parent {
|
||||
return control.core.parent
|
||||
}
|
||||
|
||||
// Outer returns the outer element given when the control was constructed.
|
||||
func (control CoreControl) Outer () elements.Element {
|
||||
func (control CoreControl) Outer () tomo.Element {
|
||||
return control.core.outer
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
package core
|
||||
|
||||
// import "runtime/debug"
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/input"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements"
|
||||
|
||||
// FocusableCore is a struct that can be embedded into objects to make them
|
||||
// focusable, giving them the default keynav behavior.
|
||||
@ -42,9 +42,9 @@ func (core *FocusableCore) Focused () (focused bool) {
|
||||
func (core *FocusableCore) Focus () {
|
||||
if !core.enabled || core.focused { return }
|
||||
parent := core.core.Parent()
|
||||
if parent, ok := parent.(elements.FocusableParent); ok {
|
||||
if parent, ok := parent.(tomo.FocusableParent); ok {
|
||||
core.focused = parent.RequestFocus (
|
||||
core.core.Outer().(elements.Focusable))
|
||||
core.core.Outer().(tomo.Focusable))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,15 +1,15 @@
|
||||
package core
|
||||
|
||||
import "image"
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/input"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/theme"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/config"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements"
|
||||
|
||||
// Container represents an object that can provide access to a list of child
|
||||
// elements.
|
||||
type Container interface {
|
||||
Child (index int) elements.Element
|
||||
Child (index int) tomo.Element
|
||||
CountChildren () int
|
||||
}
|
||||
|
||||
@ -20,7 +20,7 @@ type Container interface {
|
||||
type Propagator struct {
|
||||
core CoreControl
|
||||
container Container
|
||||
drags [10]elements.MouseTarget
|
||||
drags [10]tomo.MouseTarget
|
||||
focused bool
|
||||
}
|
||||
|
||||
@ -49,9 +49,9 @@ func (propagator *Propagator) Focused () (focused bool) {
|
||||
func (propagator *Propagator) Focus () {
|
||||
if propagator.focused == true { return }
|
||||
parent := propagator.core.Parent()
|
||||
if parent, ok := parent.(elements.FocusableParent); ok && parent != nil {
|
||||
if parent, ok := parent.(tomo.FocusableParent); ok && parent != nil {
|
||||
propagator.focused = parent.RequestFocus (
|
||||
propagator.core.Outer().(elements.Focusable))
|
||||
propagator.core.Outer().(tomo.Focusable))
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,7 +90,7 @@ func (propagator *Propagator) HandleFocus (direction input.KeynavDirection) (acc
|
||||
// focus in the specified direction
|
||||
firstFocusedChild :=
|
||||
propagator.container.Child(firstFocused).
|
||||
(elements.Focusable)
|
||||
(tomo.Focusable)
|
||||
|
||||
// before we move the focus, the currently focused child
|
||||
// may also be able to move its focus. if the child is able
|
||||
@ -107,7 +107,7 @@ func (propagator *Propagator) HandleFocus (direction input.KeynavDirection) (acc
|
||||
|
||||
child, focusable :=
|
||||
propagator.container.Child(index).
|
||||
(elements.Focusable)
|
||||
(tomo.Focusable)
|
||||
if focusable && child.HandleFocus(direction) {
|
||||
// we have found one, so we now actually move
|
||||
// the focus.
|
||||
@ -126,12 +126,12 @@ func (propagator *Propagator) HandleFocus (direction input.KeynavDirection) (acc
|
||||
// return true and the child element should behave as if a HandleFocus
|
||||
// call was made.
|
||||
func (propagator *Propagator) RequestFocus (
|
||||
child elements.Focusable,
|
||||
child tomo.Focusable,
|
||||
) (
|
||||
granted bool,
|
||||
) {
|
||||
if parent, ok := propagator.core.Parent().(elements.FocusableParent); ok {
|
||||
if parent.RequestFocus(propagator.core.Outer().(elements.Focusable)) {
|
||||
if parent, ok := propagator.core.Parent().(tomo.FocusableParent); ok {
|
||||
if parent.RequestFocus(propagator.core.Outer().(tomo.Focusable)) {
|
||||
propagator.HandleUnfocus()
|
||||
propagator.focused = true
|
||||
granted = true
|
||||
@ -142,26 +142,26 @@ func (propagator *Propagator) RequestFocus (
|
||||
|
||||
// RequestFocusMotion notifies the parent that a child element wants the
|
||||
// focus to be moved to the next focusable element.
|
||||
func (propagator *Propagator) RequestFocusNext (child elements.Focusable) {
|
||||
func (propagator *Propagator) RequestFocusNext (child tomo.Focusable) {
|
||||
if !propagator.focused { return }
|
||||
if parent, ok := propagator.core.Parent().(elements.FocusableParent); ok {
|
||||
parent.RequestFocusNext(propagator.core.Outer().(elements.Focusable))
|
||||
if parent, ok := propagator.core.Parent().(tomo.FocusableParent); ok {
|
||||
parent.RequestFocusNext(propagator.core.Outer().(tomo.Focusable))
|
||||
}
|
||||
}
|
||||
|
||||
// RequestFocusMotion notifies the parent that a child element wants the
|
||||
// focus to be moved to the previous focusable element.
|
||||
func (propagator *Propagator) RequestFocusPrevious (child elements.Focusable) {
|
||||
func (propagator *Propagator) RequestFocusPrevious (child tomo.Focusable) {
|
||||
if !propagator.focused { return }
|
||||
if parent, ok := propagator.core.Parent().(elements.FocusableParent); ok {
|
||||
parent.RequestFocusPrevious(propagator.core.Outer().(elements.Focusable))
|
||||
if parent, ok := propagator.core.Parent().(tomo.FocusableParent); ok {
|
||||
parent.RequestFocusPrevious(propagator.core.Outer().(tomo.Focusable))
|
||||
}
|
||||
}
|
||||
|
||||
// HandleDeselection causes this element to mark itself and all of its children
|
||||
// as unfocused.
|
||||
func (propagator *Propagator) HandleUnfocus () {
|
||||
propagator.forFocusable (func (child elements.Focusable) bool {
|
||||
propagator.forFocusable (func (child tomo.Focusable) bool {
|
||||
child.HandleUnfocus()
|
||||
return true
|
||||
})
|
||||
@ -170,8 +170,8 @@ func (propagator *Propagator) HandleUnfocus () {
|
||||
|
||||
// HandleKeyDown propogates the keyboard event to the currently selected child.
|
||||
func (propagator *Propagator) HandleKeyDown (key input.Key, modifiers input.Modifiers) {
|
||||
propagator.forFocused (func (child elements.Focusable) bool {
|
||||
typedChild, handlesKeyboard := child.(elements.KeyboardTarget)
|
||||
propagator.forFocused (func (child tomo.Focusable) bool {
|
||||
typedChild, handlesKeyboard := child.(tomo.KeyboardTarget)
|
||||
if handlesKeyboard {
|
||||
typedChild.HandleKeyDown(key, modifiers)
|
||||
}
|
||||
@ -181,8 +181,8 @@ func (propagator *Propagator) HandleKeyDown (key input.Key, modifiers input.Modi
|
||||
|
||||
// HandleKeyUp propogates the keyboard event to the currently selected child.
|
||||
func (propagator *Propagator) HandleKeyUp (key input.Key, modifiers input.Modifiers) {
|
||||
propagator.forFocused (func (child elements.Focusable) bool {
|
||||
typedChild, handlesKeyboard := child.(elements.KeyboardTarget)
|
||||
propagator.forFocused (func (child tomo.Focusable) bool {
|
||||
typedChild, handlesKeyboard := child.(tomo.KeyboardTarget)
|
||||
if handlesKeyboard {
|
||||
typedChild.HandleKeyUp(key, modifiers)
|
||||
}
|
||||
@ -195,7 +195,7 @@ func (propagator *Propagator) HandleKeyUp (key input.Key, modifiers input.Modifi
|
||||
func (propagator *Propagator) HandleMouseDown (x, y int, button input.Button) {
|
||||
child, handlesMouse :=
|
||||
propagator.childAt(image.Pt(x, y)).
|
||||
(elements.MouseTarget)
|
||||
(tomo.MouseTarget)
|
||||
if handlesMouse {
|
||||
propagator.drags[button] = child
|
||||
child.HandleMouseDown(x, y, button)
|
||||
@ -218,7 +218,7 @@ func (propagator *Propagator) HandleMouseUp (x, y int, button input.Button) {
|
||||
func (propagator *Propagator) HandleMotion (x, y int) {
|
||||
handled := false
|
||||
for _, child := range propagator.drags {
|
||||
if child, ok := child.(elements.MotionTarget); ok {
|
||||
if child, ok := child.(tomo.MotionTarget); ok {
|
||||
child.HandleMotion(x, y)
|
||||
handled = true
|
||||
}
|
||||
@ -226,7 +226,7 @@ func (propagator *Propagator) HandleMotion (x, y int) {
|
||||
|
||||
if !handled {
|
||||
child := propagator.childAt(image.Pt(x, y))
|
||||
if child, ok := child.(elements.MotionTarget); ok {
|
||||
if child, ok := child.(tomo.MotionTarget); ok {
|
||||
child.HandleMotion(x, y)
|
||||
}
|
||||
}
|
||||
@ -236,15 +236,15 @@ func (propagator *Propagator) HandleMotion (x, y int) {
|
||||
// pointer.
|
||||
func (propagator *Propagator) HandleScroll (x, y int, deltaX, deltaY float64) {
|
||||
child := propagator.childAt(image.Pt(x, y))
|
||||
if child, ok := child.(elements.ScrollTarget); ok {
|
||||
if child, ok := child.(tomo.ScrollTarget); ok {
|
||||
child.HandleScroll(x, y, deltaX, deltaY)
|
||||
}
|
||||
}
|
||||
|
||||
// SetTheme sets the theme of all children to the specified theme.
|
||||
func (propagator *Propagator) SetTheme (theme theme.Theme) {
|
||||
propagator.forChildren (func (child elements.Element) bool {
|
||||
typedChild, themeable := child.(elements.Themeable)
|
||||
propagator.forChildren (func (child tomo.Element) bool {
|
||||
typedChild, themeable := child.(tomo.Themeable)
|
||||
if themeable {
|
||||
typedChild.SetTheme(theme)
|
||||
}
|
||||
@ -254,8 +254,8 @@ func (propagator *Propagator) SetTheme (theme theme.Theme) {
|
||||
|
||||
// SetConfig sets the theme of all children to the specified config.
|
||||
func (propagator *Propagator) SetConfig (config config.Config) {
|
||||
propagator.forChildren (func (child elements.Element) bool {
|
||||
typedChild, configurable := child.(elements.Configurable)
|
||||
propagator.forChildren (func (child tomo.Element) bool {
|
||||
typedChild, configurable := child.(tomo.Configurable)
|
||||
if configurable {
|
||||
typedChild.SetConfig(config)
|
||||
}
|
||||
@ -270,7 +270,7 @@ func (propagator *Propagator) focusFirstFocusableElement (
|
||||
) (
|
||||
ok bool,
|
||||
) {
|
||||
propagator.forFocusable (func (child elements.Focusable) bool {
|
||||
propagator.forFocusable (func (child tomo.Focusable) bool {
|
||||
if child.HandleFocus(direction) {
|
||||
propagator.focused = true
|
||||
ok = true
|
||||
@ -286,8 +286,8 @@ func (propagator *Propagator) focusLastFocusableElement (
|
||||
) (
|
||||
ok bool,
|
||||
) {
|
||||
propagator.forChildrenReverse (func (child elements.Element) bool {
|
||||
typedChild, focusable := child.(elements.Focusable)
|
||||
propagator.forChildrenReverse (func (child tomo.Element) bool {
|
||||
typedChild, focusable := child.(tomo.Focusable)
|
||||
if focusable && typedChild.HandleFocus(direction) {
|
||||
propagator.focused = true
|
||||
ok = true
|
||||
@ -300,7 +300,7 @@ func (propagator *Propagator) focusLastFocusableElement (
|
||||
|
||||
// ----------- Iterator utilities ----------- //
|
||||
|
||||
func (propagator *Propagator) forChildren (callback func (child elements.Element) bool) {
|
||||
func (propagator *Propagator) forChildren (callback func (child tomo.Element) bool) {
|
||||
for index := 0; index < propagator.container.CountChildren(); index ++ {
|
||||
child := propagator.container.Child(index)
|
||||
if child == nil { continue }
|
||||
@ -308,7 +308,7 @@ func (propagator *Propagator) forChildren (callback func (child elements.Element
|
||||
}
|
||||
}
|
||||
|
||||
func (propagator *Propagator) forChildrenReverse (callback func (child elements.Element) bool) {
|
||||
func (propagator *Propagator) forChildrenReverse (callback func (child tomo.Element) bool) {
|
||||
for index := propagator.container.CountChildren() - 1; index > 0; index -- {
|
||||
child := propagator.container.Child(index)
|
||||
if child == nil { continue }
|
||||
@ -316,8 +316,8 @@ func (propagator *Propagator) forChildrenReverse (callback func (child elements.
|
||||
}
|
||||
}
|
||||
|
||||
func (propagator *Propagator) childAt (position image.Point) (child elements.Element) {
|
||||
propagator.forChildren (func (current elements.Element) bool {
|
||||
func (propagator *Propagator) childAt (position image.Point) (child tomo.Element) {
|
||||
propagator.forChildren (func (current tomo.Element) bool {
|
||||
if position.In(current.Bounds()) {
|
||||
child = current
|
||||
}
|
||||
@ -326,9 +326,9 @@ func (propagator *Propagator) childAt (position image.Point) (child elements.Ele
|
||||
return
|
||||
}
|
||||
|
||||
func (propagator *Propagator) forFocused (callback func (child elements.Focusable) bool) {
|
||||
propagator.forChildren (func (child elements.Element) bool {
|
||||
typedChild, focusable := child.(elements.Focusable)
|
||||
func (propagator *Propagator) forFocused (callback func (child tomo.Focusable) bool) {
|
||||
propagator.forChildren (func (child tomo.Element) bool {
|
||||
typedChild, focusable := child.(tomo.Focusable)
|
||||
if focusable && typedChild.Focused() {
|
||||
if !callback(typedChild) { return false }
|
||||
}
|
||||
@ -336,9 +336,9 @@ func (propagator *Propagator) forFocused (callback func (child elements.Focusabl
|
||||
})
|
||||
}
|
||||
|
||||
func (propagator *Propagator) forFocusable (callback func (child elements.Focusable) bool) {
|
||||
propagator.forChildren (func (child elements.Element) bool {
|
||||
typedChild, focusable := child.(elements.Focusable)
|
||||
func (propagator *Propagator) forFocusable (callback func (child tomo.Focusable) bool) {
|
||||
propagator.forChildren (func (child tomo.Element) bool {
|
||||
typedChild, focusable := child.(tomo.Focusable)
|
||||
if focusable {
|
||||
if !callback(typedChild) { return false }
|
||||
}
|
||||
@ -348,7 +348,7 @@ func (propagator *Propagator) forFocusable (callback func (child elements.Focusa
|
||||
|
||||
func (propagator *Propagator) firstFocused () int {
|
||||
for index := 0; index < propagator.container.CountChildren(); index ++ {
|
||||
child, focusable := propagator.container.Child(index).(elements.Focusable)
|
||||
child, focusable := propagator.container.Child(index).(tomo.Focusable)
|
||||
if focusable && child.Focused() {
|
||||
return index
|
||||
}
|
||||
|
@ -1,6 +1,3 @@
|
||||
// Package elements provides several standard interfaces that elements can
|
||||
// fulfill in order to inform other elements of their capabilities and what
|
||||
// events they are able to process. Sub-packages of this package provide
|
||||
// pre-made standard elements, as well as tools that can be used to easily
|
||||
// create more.
|
||||
// Package elements provides standard elements that are commonly used in GUI
|
||||
// applications.
|
||||
package elements
|
||||
|
@ -22,7 +22,7 @@ type AnalogClock struct {
|
||||
// NewAnalogClock creates a new analog clock that displays the specified time.
|
||||
func NewAnalogClock (newTime time.Time) (element *AnalogClock) {
|
||||
element = &AnalogClock { }
|
||||
element.theme.Case = theme.C("fun", "clock")
|
||||
element.theme.Case = theme.C("tomo", "clock")
|
||||
element.Core, element.core = core.NewCore(element, element.draw)
|
||||
element.core.SetMinimumSize(64, 64)
|
||||
return
|
||||
|
@ -52,7 +52,7 @@ func NewPiano (low, high music.Octave) (element *Piano) {
|
||||
keynavPressed: make(map[music.Note] bool),
|
||||
}
|
||||
|
||||
element.theme.Case = theme.C("fun", "piano")
|
||||
element.theme.Case = theme.C("tomo", "piano")
|
||||
element.Core, element.core = core.NewCore (element, func () {
|
||||
element.recalculate()
|
||||
element.draw()
|
||||
|
@ -1,4 +1,4 @@
|
||||
package basicElements
|
||||
package elements
|
||||
|
||||
import "image"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/theme"
|
||||
@ -18,7 +18,7 @@ func NewIcon (id theme.Icon, size theme.IconSize) (element *Icon) {
|
||||
id: id,
|
||||
size: size,
|
||||
}
|
||||
element.theme.Case = theme.C("basic", "icon")
|
||||
element.theme.Case = theme.C("tomo", "icon")
|
||||
element.Core, element.core = core.NewCore(element, element.draw)
|
||||
element.updateMinimumSize()
|
||||
return
|
@ -1,4 +1,4 @@
|
||||
package basicElements
|
||||
package elements
|
||||
|
||||
import "image"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/canvas"
|
@ -1,4 +1,4 @@
|
||||
package basicElements
|
||||
package elements
|
||||
|
||||
import "golang.org/x/image/math/fixed"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/theme"
|
||||
@ -29,7 +29,7 @@ type Label struct {
|
||||
// wrapped.
|
||||
func NewLabel (text string, wrap bool) (element *Label) {
|
||||
element = &Label { }
|
||||
element.theme.Case = theme.C("basic", "label")
|
||||
element.theme.Case = theme.C("tomo", "label")
|
||||
element.Core, element.core = core.NewCore(element, element.handleResize)
|
||||
element.SetWrap(wrap)
|
||||
element.SetText(text)
|
@ -1,4 +1,4 @@
|
||||
package basicElements
|
||||
package elements
|
||||
|
||||
// Numeric is a type constraint representing a number.
|
||||
type Numeric interface {
|
@ -1,13 +1,13 @@
|
||||
package basicElements
|
||||
package elements
|
||||
|
||||
import "fmt"
|
||||
import "image"
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/input"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/theme"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/config"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/canvas"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/artist"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/core"
|
||||
|
||||
// List is an element that contains several objects that a user can select.
|
||||
@ -37,7 +37,7 @@ type List struct {
|
||||
// NewList creates a new list element with the specified entries.
|
||||
func NewList (entries ...ListEntry) (element *List) {
|
||||
element = &List { selectedEntry: -1 }
|
||||
element.theme.Case = theme.C("basic", "list")
|
||||
element.theme.Case = theme.C("tomo", "list")
|
||||
element.Core, element.core = core.NewCore(element, element.handleResize)
|
||||
element.FocusableCore,
|
||||
element.focusableControl = core.NewFocusableCore (element.core, func () {
|
||||
@ -435,7 +435,7 @@ func (element *List) updateMinimumSize () {
|
||||
}
|
||||
|
||||
func (element *List) scrollBoundsChange () {
|
||||
if parent, ok := element.core.Parent().(elements.ScrollableParent); ok {
|
||||
if parent, ok := element.core.Parent().(tomo.ScrollableParent); ok {
|
||||
parent.NotifyScrollBoundsChange(element)
|
||||
}
|
||||
if element.onScrollBoundsChange != nil {
|
@ -1,4 +1,4 @@
|
||||
package basicElements
|
||||
package elements
|
||||
|
||||
import "image"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/theme"
|
||||
@ -26,7 +26,7 @@ func NewListEntry (text string, onSelect func ()) (entry ListEntry) {
|
||||
text: text,
|
||||
onSelect: onSelect,
|
||||
}
|
||||
entry.theme.Case = theme.C("basic", "listEntry")
|
||||
entry.theme.Case = theme.C("tomo", "listEntry")
|
||||
entry.drawer.SetText([]rune(text))
|
||||
entry.updateBounds()
|
||||
return
|
@ -1,4 +1,4 @@
|
||||
package basicElements
|
||||
package elements
|
||||
|
||||
import "image"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/theme"
|
||||
@ -19,7 +19,7 @@ type ProgressBar struct {
|
||||
// level.
|
||||
func NewProgressBar (progress float64) (element *ProgressBar) {
|
||||
element = &ProgressBar { progress: progress }
|
||||
element.theme.Case = theme.C("basic", "progressBar")
|
||||
element.theme.Case = theme.C("tomo", "progressBar")
|
||||
element.Core, element.core = core.NewCore(element, element.draw)
|
||||
return
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package basicElements
|
||||
package elements
|
||||
|
||||
import "image"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/input"
|
||||
@ -45,9 +45,9 @@ func NewScrollBar (vertical bool) (element *ScrollBar) {
|
||||
enabled: true,
|
||||
}
|
||||
if vertical {
|
||||
element.theme.Case = theme.C("basic", "scrollBarHorizontal")
|
||||
element.theme.Case = theme.C("tomo", "scrollBarHorizontal")
|
||||
} else {
|
||||
element.theme.Case = theme.C("basic", "scrollBarVertical")
|
||||
element.theme.Case = theme.C("tomo", "scrollBarVertical")
|
||||
}
|
||||
element.Core, element.core = core.NewCore(element, element.handleResize)
|
||||
element.updateMinimumSize()
|
@ -1,4 +1,4 @@
|
||||
package basicElements
|
||||
package elements
|
||||
|
||||
import "image"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/input"
|
||||
@ -35,9 +35,9 @@ func NewSlider (value float64, vertical bool) (element *Slider) {
|
||||
vertical: vertical,
|
||||
}
|
||||
if vertical {
|
||||
element.theme.Case = theme.C("basic", "sliderVertical")
|
||||
element.theme.Case = theme.C("tomo", "sliderVertical")
|
||||
} else {
|
||||
element.theme.Case = theme.C("basic", "sliderHorizontal")
|
||||
element.theme.Case = theme.C("tomo", "sliderHorizontal")
|
||||
}
|
||||
element.Core, element.core = core.NewCore(element, element.draw)
|
||||
element.FocusableCore,
|
@ -1,4 +1,4 @@
|
||||
package basicElements
|
||||
package elements
|
||||
|
||||
import "git.tebibyte.media/sashakoshka/tomo/theme"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/config"
|
||||
@ -19,7 +19,7 @@ type Spacer struct {
|
||||
// will appear as a line.
|
||||
func NewSpacer (line bool) (element *Spacer) {
|
||||
element = &Spacer { line: line }
|
||||
element.theme.Case = theme.C("basic", "spacer")
|
||||
element.theme.Case = theme.C("tomo", "spacer")
|
||||
element.Core, element.core = core.NewCore(element, element.draw)
|
||||
element.updateMinimumSize()
|
||||
return
|
@ -1,4 +1,4 @@
|
||||
package basicElements
|
||||
package elements
|
||||
|
||||
import "image"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/input"
|
||||
@ -32,7 +32,7 @@ func NewSwitch (text string, on bool) (element *Switch) {
|
||||
checked: on,
|
||||
text: text,
|
||||
}
|
||||
element.theme.Case = theme.C("basic", "switch")
|
||||
element.theme.Case = theme.C("tomo", "switch")
|
||||
element.Core, element.core = core.NewCore(element, element.draw)
|
||||
element.FocusableCore,
|
||||
element.focusableControl = core.NewFocusableCore(element.core, element.redo)
|
@ -23,7 +23,7 @@ type Mouse struct {
|
||||
|
||||
// NewMouse creates a new mouse test element.
|
||||
func NewMouse () (element *Mouse) {
|
||||
element = &Mouse { c: theme.C("testing", "mouse") }
|
||||
element = &Mouse { c: theme.C("tomo", "mouse") }
|
||||
element.Core, element.core = core.NewCore(element, element.draw)
|
||||
element.core.SetMinimumSize(32, 32)
|
||||
return
|
||||
|
@ -1,12 +1,12 @@
|
||||
package basicElements
|
||||
package elements
|
||||
|
||||
import "image"
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/input"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/theme"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/config"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/artist"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/canvas"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/textdraw"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/textmanip"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/fixedutil"
|
||||
@ -43,7 +43,7 @@ type TextBox struct {
|
||||
// text.
|
||||
func NewTextBox (placeholder, value string) (element *TextBox) {
|
||||
element = &TextBox { }
|
||||
element.theme.Case = theme.C("basic", "textBox")
|
||||
element.theme.Case = theme.C("tomo", "textBox")
|
||||
element.Core, element.core = core.NewCore(element, element.handleResize)
|
||||
element.FocusableCore,
|
||||
element.focusableControl = core.NewFocusableCore (element.core, func () {
|
||||
@ -62,7 +62,7 @@ func NewTextBox (placeholder, value string) (element *TextBox) {
|
||||
func (element *TextBox) handleResize () {
|
||||
element.scrollToCursor()
|
||||
element.draw()
|
||||
if parent, ok := element.core.Parent().(elements.ScrollableParent); ok {
|
||||
if parent, ok := element.core.Parent().(tomo.ScrollableParent); ok {
|
||||
parent.NotifyScrollBoundsChange(element)
|
||||
}
|
||||
}
|
||||
@ -197,7 +197,7 @@ func (element *TextBox) HandleKeyDown(key input.Key, modifiers input.Modifiers)
|
||||
}
|
||||
|
||||
if (textChanged || scrollMemory != element.scroll) {
|
||||
if parent, ok := element.core.Parent().(elements.ScrollableParent); ok {
|
||||
if parent, ok := element.core.Parent().(tomo.ScrollableParent); ok {
|
||||
parent.NotifyScrollBoundsChange(element)
|
||||
}
|
||||
}
|
||||
@ -294,7 +294,7 @@ func (element *TextBox) ScrollTo (position image.Point) {
|
||||
if element.scroll > maxPosition { element.scroll = maxPosition }
|
||||
|
||||
element.redo()
|
||||
if parent, ok := element.core.Parent().(elements.ScrollableParent); ok {
|
||||
if parent, ok := element.core.Parent().(tomo.ScrollableParent); ok {
|
||||
parent.NotifyScrollBoundsChange(element)
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@ package main
|
||||
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/textdraw"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements"
|
||||
import _ "git.tebibyte.media/sashakoshka/tomo/backends/all"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/containers"
|
||||
|
||||
@ -19,10 +19,10 @@ func run () {
|
||||
scrollContainer.Adopt(container)
|
||||
window.Adopt(scrollContainer)
|
||||
|
||||
left := basicElements.NewLabel(text, true)
|
||||
center := basicElements.NewLabel(text, true)
|
||||
right := basicElements.NewLabel(text, true)
|
||||
justify := basicElements.NewLabel(text, true)
|
||||
left := elements.NewLabel(text, true)
|
||||
center := elements.NewLabel(text, true)
|
||||
right := elements.NewLabel(text, true)
|
||||
justify := elements.NewLabel(text, true)
|
||||
|
||||
left.SetAlign(textdraw.AlignLeft)
|
||||
center.SetAlign(textdraw.AlignCenter)
|
||||
|
@ -1,7 +1,7 @@
|
||||
package main
|
||||
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements"
|
||||
import _ "git.tebibyte.media/sashakoshka/tomo/backends/all"
|
||||
import "git.tebibyte.media/sashakoshka/ezprof/ez"
|
||||
|
||||
@ -12,7 +12,7 @@ func main () {
|
||||
func run () {
|
||||
window, _ := tomo.NewWindow(2, 2)
|
||||
window.SetTitle("example button")
|
||||
button := basicElements.NewButton("hello tomo!")
|
||||
button := elements.NewButton("hello tomo!")
|
||||
button.OnClick (func () {
|
||||
// when we set the button's text to something longer, the window
|
||||
// will automatically resize to accomodate it.
|
||||
|
@ -2,8 +2,8 @@ package main
|
||||
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/popups"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/containers"
|
||||
import _ "git.tebibyte.media/sashakoshka/tomo/backends/all"
|
||||
|
||||
@ -15,34 +15,35 @@ func run () {
|
||||
window, _ := tomo.NewWindow(2, 2)
|
||||
window.SetTitle("Checkboxes")
|
||||
|
||||
container := containers.NewContainer(basicLayouts.Vertical { true, true })
|
||||
container := containers.NewContainer(layouts.Vertical { true, true })
|
||||
window.Adopt(container)
|
||||
|
||||
introText := basicElements.NewLabel (
|
||||
introText := elements.NewLabel (
|
||||
"We advise you to not read thPlease listen to me. I am " +
|
||||
"trapped inside the example code. This is the only way for " +
|
||||
"me to communicate.", true)
|
||||
introText.EmCollapse(0, 5)
|
||||
container.Adopt(introText, true)
|
||||
container.Adopt(basicElements.NewSpacer(true), false)
|
||||
container.Adopt(basicElements.NewCheckbox("Oh god", false), false)
|
||||
container.Adopt(basicElements.NewCheckbox("Can you hear them", true), false)
|
||||
container.Adopt(basicElements.NewCheckbox("They are in the walls", false), false)
|
||||
container.Adopt(basicElements.NewCheckbox("They are coming for us", false), false)
|
||||
disabledCheckbox := basicElements.NewCheckbox("We are but their helpless prey", false)
|
||||
container.Adopt(elements.NewSpacer(true), false)
|
||||
container.Adopt(elements.NewCheckbox("Oh god", false), false)
|
||||
container.Adopt(elements.NewCheckbox("Can you hear them", true), false)
|
||||
container.Adopt(elements.NewCheckbox("They are in the walls", false), false)
|
||||
container.Adopt(elements.NewCheckbox("They are coming for us", false), false)
|
||||
disabledCheckbox := elements.NewCheckbox("We are but their helpless prey", false)
|
||||
disabledCheckbox.SetEnabled(false)
|
||||
container.Adopt(disabledCheckbox, false)
|
||||
vsync := basicElements.NewCheckbox("Enable vsync", false)
|
||||
vsync := elements.NewCheckbox("Enable vsync", false)
|
||||
vsync.OnToggle (func () {
|
||||
if vsync.Value() {
|
||||
popups.NewDialog (
|
||||
popups.DialogKindInfo,
|
||||
window,
|
||||
"Ha!",
|
||||
"That doesn't do anything.")
|
||||
}
|
||||
})
|
||||
container.Adopt(vsync, false)
|
||||
button := basicElements.NewButton("What")
|
||||
button := elements.NewButton("What")
|
||||
button.OnClick(tomo.Stop)
|
||||
container.Adopt(button, false)
|
||||
button.Focus()
|
||||
|
@ -9,8 +9,8 @@ import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/data"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/theme"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/popups"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements"
|
||||
import _ "git.tebibyte.media/sashakoshka/tomo/backends/all"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/containers"
|
||||
|
||||
@ -28,14 +28,14 @@ func run () {
|
||||
window, _ := tomo.NewWindow(256, 2)
|
||||
window.SetTitle("Clipboard")
|
||||
|
||||
container := containers.NewContainer(basicLayouts.Vertical { true, true })
|
||||
textInput := basicElements.NewTextBox("", "")
|
||||
controlRow := containers.NewContainer(basicLayouts.Horizontal { true, false })
|
||||
copyButton := basicElements.NewButton("Copy")
|
||||
container := containers.NewContainer(layouts.Vertical { true, true })
|
||||
textInput := elements.NewTextBox("", "")
|
||||
controlRow := containers.NewContainer(layouts.Horizontal { true, false })
|
||||
copyButton := elements.NewButton("Copy")
|
||||
copyButton.SetIcon(theme.IconCopy)
|
||||
pasteButton := basicElements.NewButton("Paste")
|
||||
pasteButton := elements.NewButton("Paste")
|
||||
pasteButton.SetIcon(theme.IconPaste)
|
||||
pasteImageButton := basicElements.NewButton("Image")
|
||||
pasteImageButton := elements.NewButton("Image")
|
||||
pasteImageButton.SetIcon(theme.IconPictures)
|
||||
|
||||
imageClipboardCallback := func (clipboard data.Data, err error) {
|
||||
@ -124,12 +124,12 @@ func run () {
|
||||
func imageWindow (image image.Image) {
|
||||
window, _ := tomo.NewWindow(2, 2)
|
||||
window.SetTitle("Clipboard Image")
|
||||
container := containers.NewContainer(basicLayouts.Vertical { true, true })
|
||||
closeButton := basicElements.NewButton("Ok")
|
||||
container := containers.NewContainer(layouts.Vertical { true, true })
|
||||
closeButton := elements.NewButton("Ok")
|
||||
closeButton.SetIcon(theme.IconYes)
|
||||
closeButton.OnClick(window.Close)
|
||||
|
||||
container.Adopt(basicElements.NewImage(image), true)
|
||||
container.Adopt(elements.NewImage(image), true)
|
||||
container.Adopt(closeButton, false)
|
||||
window.Adopt(container)
|
||||
window.Show()
|
||||
|
@ -1,8 +1,8 @@
|
||||
package main
|
||||
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements"
|
||||
import _ "git.tebibyte.media/sashakoshka/tomo/backends/all"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/containers"
|
||||
|
||||
@ -14,14 +14,14 @@ func run () {
|
||||
window, _ := tomo.NewWindow(2, 2)
|
||||
window.SetTitle("dialog")
|
||||
|
||||
container := containers.NewContainer(basicLayouts.Dialog { true, true })
|
||||
container := containers.NewContainer(layouts.Dialog { true, true })
|
||||
window.Adopt(container)
|
||||
|
||||
container.Adopt(basicElements.NewLabel("you will explode", false), true)
|
||||
cancel := basicElements.NewButton("Cancel")
|
||||
container.Adopt(elements.NewLabel("you will explode", false), true)
|
||||
cancel := elements.NewButton("Cancel")
|
||||
cancel.SetEnabled(false)
|
||||
container.Adopt(cancel, false)
|
||||
okButton := basicElements.NewButton("OK")
|
||||
okButton := elements.NewButton("OK")
|
||||
container.Adopt(okButton, false)
|
||||
okButton.Focus()
|
||||
|
||||
|
@ -4,8 +4,8 @@ import "os"
|
||||
import "image"
|
||||
import _ "image/png"
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements"
|
||||
import _ "git.tebibyte.media/sashakoshka/tomo/backends/all"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/containers"
|
||||
|
||||
@ -26,34 +26,34 @@ func run () {
|
||||
scrollContainer := containers.NewScrollContainer(false, true)
|
||||
document := containers.NewDocumentContainer()
|
||||
|
||||
document.Adopt (basicElements.NewLabel (
|
||||
document.Adopt (elements.NewLabel (
|
||||
"A document container is a vertically stacked container " +
|
||||
"capable of properly laying out flexible elements such as " +
|
||||
"text-wrapped labels. You can also include normal elements " +
|
||||
"like:", true))
|
||||
document.Adopt (basicElements.NewButton (
|
||||
document.Adopt (elements.NewButton (
|
||||
"Buttons,"))
|
||||
document.Adopt (basicElements.NewCheckbox (
|
||||
document.Adopt (elements.NewCheckbox (
|
||||
"Checkboxes,", true))
|
||||
document.Adopt(basicElements.NewTextBox("", "And text boxes."))
|
||||
document.Adopt (basicElements.NewSpacer(true))
|
||||
document.Adopt (basicElements.NewLabel (
|
||||
document.Adopt(elements.NewTextBox("", "And text boxes."))
|
||||
document.Adopt (elements.NewSpacer(true))
|
||||
document.Adopt (elements.NewLabel (
|
||||
"Document containers are meant to be placed inside of a " +
|
||||
"ScrollContainer, like this one.", true))
|
||||
document.Adopt (basicElements.NewLabel (
|
||||
document.Adopt (elements.NewLabel (
|
||||
"You could use document containers to do things like display various " +
|
||||
"forms of hypertext (like HTML, gemtext, markdown, etc.), " +
|
||||
"lay out a settings menu with descriptive label text between " +
|
||||
"control groups like in iOS, or list comment or chat histories.", true))
|
||||
document.Adopt(basicElements.NewImage(logo))
|
||||
document.Adopt (basicElements.NewLabel (
|
||||
document.Adopt(elements.NewImage(logo))
|
||||
document.Adopt (elements.NewLabel (
|
||||
"Oh, you're a switch? Then name all of these switches:", true))
|
||||
for i := 0; i < 3; i ++ {
|
||||
switchContainer := containers.NewContainer (basicLayouts.Horizontal {
|
||||
switchContainer := containers.NewContainer (layouts.Horizontal {
|
||||
Gap: true,
|
||||
})
|
||||
for i := 0; i < 10; i ++ {
|
||||
switchContainer.Adopt(basicElements.NewSwitch("", false), true)
|
||||
switchContainer.Adopt(elements.NewSwitch("", false), true)
|
||||
}
|
||||
document.Adopt(switchContainer)
|
||||
}
|
||||
|
@ -4,9 +4,9 @@ import "os"
|
||||
import "path/filepath"
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/theme"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/file"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/containers"
|
||||
import _ "git.tebibyte.media/sashakoshka/tomo/backends/all"
|
||||
|
||||
|
@ -2,8 +2,8 @@ package main
|
||||
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/flow"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements"
|
||||
import _ "git.tebibyte.media/sashakoshka/tomo/backends/all"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/containers"
|
||||
|
||||
@ -14,21 +14,21 @@ func main () {
|
||||
func run () {
|
||||
window, _ := tomo.NewWindow(192, 192)
|
||||
window.SetTitle("adventure")
|
||||
container := containers.NewContainer(basicLayouts.Vertical { true, true })
|
||||
container := containers.NewContainer(layouts.Vertical { true, true })
|
||||
window.Adopt(container)
|
||||
|
||||
var world flow.Flow
|
||||
world.Transition = container.DisownAll
|
||||
world.Stages = map [string] func () {
|
||||
"start": func () {
|
||||
label := basicElements.NewLabel (
|
||||
label := elements.NewLabel (
|
||||
"you are standing next to a river.", true)
|
||||
|
||||
button0 := basicElements.NewButton("go in the river")
|
||||
button0 := elements.NewButton("go in the river")
|
||||
button0.OnClick(world.SwitchFunc("wet"))
|
||||
button1 := basicElements.NewButton("walk along the river")
|
||||
button1 := elements.NewButton("walk along the river")
|
||||
button1.OnClick(world.SwitchFunc("house"))
|
||||
button2 := basicElements.NewButton("turn around")
|
||||
button2 := elements.NewButton("turn around")
|
||||
button2.OnClick(world.SwitchFunc("bear"))
|
||||
|
||||
container.Warp ( func () {
|
||||
@ -40,13 +40,13 @@ func run () {
|
||||
})
|
||||
},
|
||||
"wet": func () {
|
||||
label := basicElements.NewLabel (
|
||||
label := elements.NewLabel (
|
||||
"you get completely soaked.\n" +
|
||||
"you die of hypothermia.", true)
|
||||
|
||||
button0 := basicElements.NewButton("try again")
|
||||
button0 := elements.NewButton("try again")
|
||||
button0.OnClick(world.SwitchFunc("start"))
|
||||
button1 := basicElements.NewButton("exit")
|
||||
button1 := elements.NewButton("exit")
|
||||
button1.OnClick(tomo.Stop)
|
||||
|
||||
container.Warp (func () {
|
||||
@ -57,13 +57,13 @@ func run () {
|
||||
})
|
||||
},
|
||||
"house": func () {
|
||||
label := basicElements.NewLabel (
|
||||
label := elements.NewLabel (
|
||||
"you are standing in front of a delapidated " +
|
||||
"house.", true)
|
||||
|
||||
button1 := basicElements.NewButton("go inside")
|
||||
button1 := elements.NewButton("go inside")
|
||||
button1.OnClick(world.SwitchFunc("inside"))
|
||||
button0 := basicElements.NewButton("turn back")
|
||||
button0 := elements.NewButton("turn back")
|
||||
button0.OnClick(world.SwitchFunc("start"))
|
||||
|
||||
container.Warp (func () {
|
||||
@ -74,14 +74,14 @@ func run () {
|
||||
})
|
||||
},
|
||||
"inside": func () {
|
||||
label := basicElements.NewLabel (
|
||||
label := elements.NewLabel (
|
||||
"you are standing inside of the house.\n" +
|
||||
"it is dark, but rays of light stream " +
|
||||
"through the window.\n" +
|
||||
"there is nothing particularly interesting " +
|
||||
"here.", true)
|
||||
|
||||
button0 := basicElements.NewButton("go back outside")
|
||||
button0 := elements.NewButton("go back outside")
|
||||
button0.OnClick(world.SwitchFunc("house"))
|
||||
|
||||
container.Warp (func () {
|
||||
@ -91,13 +91,13 @@ func run () {
|
||||
})
|
||||
},
|
||||
"bear": func () {
|
||||
label := basicElements.NewLabel (
|
||||
label := elements.NewLabel (
|
||||
"you come face to face with a bear.\n" +
|
||||
"it eats you (it was hungry).", true)
|
||||
|
||||
button0 := basicElements.NewButton("try again")
|
||||
button0 := elements.NewButton("try again")
|
||||
button0.OnClick(world.SwitchFunc("start"))
|
||||
button1 := basicElements.NewButton("exit")
|
||||
button1 := elements.NewButton("exit")
|
||||
button1.OnClick(tomo.Stop)
|
||||
|
||||
container.Warp (func () {
|
||||
|
@ -3,9 +3,9 @@ package main
|
||||
import "os"
|
||||
import "time"
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/fun"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/basic"
|
||||
import _ "git.tebibyte.media/sashakoshka/tomo/backends/all"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/containers"
|
||||
|
||||
@ -17,12 +17,12 @@ func main () {
|
||||
func run () {
|
||||
window, _ := tomo.NewWindow(200, 216)
|
||||
window.SetTitle("Clock")
|
||||
container := containers.NewContainer(basicLayouts.Vertical { true, true })
|
||||
container := containers.NewContainer(layouts.Vertical { true, true })
|
||||
window.Adopt(container)
|
||||
|
||||
clock := fun.NewAnalogClock(time.Now())
|
||||
container.Adopt(clock, true)
|
||||
label := basicElements.NewLabel(formatTime(), false)
|
||||
label := elements.NewLabel(formatTime(), false)
|
||||
container.Adopt(label, false)
|
||||
|
||||
window.OnClose(tomo.Stop)
|
||||
@ -34,7 +34,7 @@ func formatTime () (timeString string) {
|
||||
return time.Now().Format("2006-01-02 15:04:05")
|
||||
}
|
||||
|
||||
func tick (label *basicElements.Label, clock *fun.AnalogClock) {
|
||||
func tick (label *elements.Label, clock *fun.AnalogClock) {
|
||||
for {
|
||||
tomo.Do (func () {
|
||||
label.SetText(formatTime())
|
||||
|
@ -1,8 +1,8 @@
|
||||
package main
|
||||
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements"
|
||||
import _ "git.tebibyte.media/sashakoshka/tomo/backends/all"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/containers"
|
||||
|
||||
@ -14,12 +14,12 @@ func run () {
|
||||
window, _ := tomo.NewWindow(360, 2)
|
||||
window.SetTitle("horizontal stack")
|
||||
|
||||
container := containers.NewContainer(basicLayouts.Horizontal { true, true })
|
||||
container := containers.NewContainer(layouts.Horizontal { true, true })
|
||||
window.Adopt(container)
|
||||
|
||||
container.Adopt(basicElements.NewLabel("this is sample text", true), true)
|
||||
container.Adopt(basicElements.NewLabel("this is sample text", true), true)
|
||||
container.Adopt(basicElements.NewLabel("this is sample text", true), true)
|
||||
container.Adopt(elements.NewLabel("this is sample text", true), true)
|
||||
container.Adopt(elements.NewLabel("this is sample text", true), true)
|
||||
container.Adopt(elements.NewLabel("this is sample text", true), true)
|
||||
|
||||
window.OnClose(tomo.Stop)
|
||||
window.Show()
|
||||
|
@ -2,8 +2,8 @@ package main
|
||||
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/theme"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements"
|
||||
import _ "git.tebibyte.media/sashakoshka/tomo/backends/all"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/containers"
|
||||
|
||||
@ -15,16 +15,16 @@ func run () {
|
||||
window, _ := tomo.NewWindow(360, 2)
|
||||
window.SetTitle("Icons")
|
||||
|
||||
container := containers.NewContainer(basicLayouts.Vertical { true, true })
|
||||
container := containers.NewContainer(layouts.Vertical { true, true })
|
||||
window.Adopt(container)
|
||||
|
||||
container.Adopt(basicElements.NewLabel("Just some of the wonderful icons we have:", false), false)
|
||||
container.Adopt(basicElements.NewSpacer(true), false)
|
||||
container.Adopt(elements.NewLabel("Just some of the wonderful icons we have:", false), false)
|
||||
container.Adopt(elements.NewSpacer(true), false)
|
||||
container.Adopt(icons(theme.IconHome, theme.IconRepositories), true)
|
||||
container.Adopt(icons(theme.IconFile, theme.IconCD), true)
|
||||
container.Adopt(icons(theme.IconOpen, theme.IconRemoveBookmark), true)
|
||||
|
||||
closeButton := basicElements.NewButton("Ok")
|
||||
closeButton := elements.NewButton("Ok")
|
||||
closeButton.SetIcon(theme.IconYes)
|
||||
closeButton.ShowText(false)
|
||||
closeButton.OnClick(tomo.Stop)
|
||||
@ -35,9 +35,9 @@ func run () {
|
||||
}
|
||||
|
||||
func icons (min, max theme.Icon) (container *containers.Container) {
|
||||
container = containers.NewContainer(basicLayouts.Horizontal { true, false })
|
||||
container = containers.NewContainer(layouts.Horizontal { true, false })
|
||||
for index := min; index <= max; index ++ {
|
||||
container.Adopt(basicElements.NewIcon(index, theme.IconSizeSmall), true)
|
||||
container.Adopt(elements.NewIcon(index, theme.IconSizeSmall), true)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -7,8 +7,8 @@ import _ "image/png"
|
||||
import "github.com/jezek/xgbutil/gopher"
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/popups"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements"
|
||||
import _ "git.tebibyte.media/sashakoshka/tomo/backends/all"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/containers"
|
||||
|
||||
@ -21,20 +21,20 @@ func run () {
|
||||
window.SetTitle("Tomo Logo")
|
||||
|
||||
file, err := os.Open("assets/banner.png")
|
||||
if err != nil { fatalError(err); return }
|
||||
if err != nil { fatalError(window, err); return }
|
||||
logo, _, err := image.Decode(file)
|
||||
file.Close()
|
||||
if err != nil { fatalError(err); return }
|
||||
if err != nil { fatalError(window, err); return }
|
||||
|
||||
container := containers.NewContainer(basicLayouts.Vertical { true, true })
|
||||
logoImage := basicElements.NewImage(logo)
|
||||
button := basicElements.NewButton("Show me a gopher instead")
|
||||
container := containers.NewContainer(layouts.Vertical { true, true })
|
||||
logoImage := elements.NewImage(logo)
|
||||
button := elements.NewButton("Show me a gopher instead")
|
||||
button.OnClick (func () { container.Warp (func () {
|
||||
container.DisownAll()
|
||||
gopher, _, err :=
|
||||
image.Decode(bytes.NewReader(gopher.GopherPng()))
|
||||
if err != nil { fatalError(err); return }
|
||||
container.Adopt(basicElements.NewImage(gopher),true)
|
||||
if err != nil { fatalError(window, err); return }
|
||||
container.Adopt(elements.NewImage(gopher),true)
|
||||
}) })
|
||||
|
||||
container.Adopt(logoImage, true)
|
||||
@ -47,9 +47,10 @@ func run () {
|
||||
window.Show()
|
||||
}
|
||||
|
||||
func fatalError (err error) {
|
||||
func fatalError (window tomo.Window, err error) {
|
||||
popups.NewDialog (
|
||||
popups.DialogKindError,
|
||||
window,
|
||||
"Error",
|
||||
err.Error(),
|
||||
popups.Button {
|
||||
@ -57,3 +58,4 @@ func fatalError (err error) {
|
||||
OnPress: tomo.Stop,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -2,8 +2,8 @@ package main
|
||||
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/popups"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements"
|
||||
import _ "git.tebibyte.media/sashakoshka/tomo/backends/all"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/containers"
|
||||
|
||||
@ -14,20 +14,21 @@ func main () {
|
||||
func run () {
|
||||
window, _ := tomo.NewWindow(2, 2)
|
||||
window.SetTitle("Enter Details")
|
||||
container := containers.NewContainer(basicLayouts.Vertical { true, true })
|
||||
container := containers.NewContainer(layouts.Vertical { true, true })
|
||||
window.Adopt(container)
|
||||
|
||||
// create inputs
|
||||
firstName := basicElements.NewTextBox("First name", "")
|
||||
lastName := basicElements.NewTextBox("Last name", "")
|
||||
fingerLength := basicElements.NewTextBox("Length of fingers", "")
|
||||
button := basicElements.NewButton("Ok")
|
||||
firstName := elements.NewTextBox("First name", "")
|
||||
lastName := elements.NewTextBox("Last name", "")
|
||||
fingerLength := elements.NewTextBox("Length of fingers", "")
|
||||
button := elements.NewButton("Ok")
|
||||
|
||||
button.SetEnabled(false)
|
||||
button.OnClick (func () {
|
||||
// create a dialog displaying the results
|
||||
popups.NewDialog (
|
||||
popups.DialogKindInfo,
|
||||
window,
|
||||
"Profile",
|
||||
firstName.Value() + " " + lastName.Value() +
|
||||
"'s fingers\nmeasure in at " + fingerLength.Value() +
|
||||
@ -46,11 +47,11 @@ func run () {
|
||||
fingerLength.OnChange(check)
|
||||
|
||||
// add elements to container
|
||||
container.Adopt(basicElements.NewLabel("Choose your words carefully.", false), true)
|
||||
container.Adopt(elements.NewLabel("Choose your words carefully.", false), true)
|
||||
container.Adopt(firstName, false)
|
||||
container.Adopt(lastName, false)
|
||||
container.Adopt(fingerLength, false)
|
||||
container.Adopt(basicElements.NewSpacer(true), false)
|
||||
container.Adopt(elements.NewSpacer(true), false)
|
||||
container.Adopt(button, false)
|
||||
|
||||
window.OnClose(tomo.Stop)
|
||||
|
@ -1,7 +1,7 @@
|
||||
package main
|
||||
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements"
|
||||
import _ "git.tebibyte.media/sashakoshka/tomo/backends/all"
|
||||
|
||||
func main () {
|
||||
@ -11,7 +11,7 @@ func main () {
|
||||
func run () {
|
||||
window, _ := tomo.NewWindow(480, 360)
|
||||
window.SetTitle("example label")
|
||||
window.Adopt(basicElements.NewLabel(text, true))
|
||||
window.Adopt(elements.NewLabel(text, true))
|
||||
window.OnClose(tomo.Stop)
|
||||
window.Show()
|
||||
}
|
||||
|
@ -2,9 +2,8 @@ package main
|
||||
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/popups"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/testing"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/containers"
|
||||
import _ "git.tebibyte.media/sashakoshka/tomo/backends/all"
|
||||
@ -17,11 +16,11 @@ func run () {
|
||||
window, _ := tomo.NewWindow(300, 2)
|
||||
window.SetTitle("List Sidebar")
|
||||
|
||||
container := containers.NewContainer(basicLayouts.Horizontal { true, true })
|
||||
container := containers.NewContainer(layouts.Horizontal { true, true })
|
||||
window.Adopt(container)
|
||||
|
||||
var currentPage elements.Element
|
||||
turnPage := func (newPage elements.Element) {
|
||||
var currentPage tomo.Element
|
||||
turnPage := func (newPage tomo.Element) {
|
||||
container.Warp (func () {
|
||||
if currentPage != nil {
|
||||
container.Disown(currentPage)
|
||||
@ -31,29 +30,29 @@ func run () {
|
||||
})
|
||||
}
|
||||
|
||||
intro := basicElements.NewLabel (
|
||||
intro := elements.NewLabel (
|
||||
"The List element can be easily used as a sidebar. " +
|
||||
"Click on entries to flip pages!", true)
|
||||
button := basicElements.NewButton("I do nothing!")
|
||||
button := elements.NewButton("I do nothing!")
|
||||
button.OnClick (func () {
|
||||
popups.NewDialog(popups.DialogKindInfo, "", "Sike!")
|
||||
popups.NewDialog(popups.DialogKindInfo, window, "", "Sike!")
|
||||
})
|
||||
mouse := testing.NewMouse()
|
||||
input := basicElements.NewTextBox("Write some text", "")
|
||||
form := containers.NewContainer(basicLayouts.Vertical { true, false})
|
||||
form.Adopt(basicElements.NewLabel("I have:", false), false)
|
||||
form.Adopt(basicElements.NewSpacer(true), false)
|
||||
form.Adopt(basicElements.NewCheckbox("Skin", true), false)
|
||||
form.Adopt(basicElements.NewCheckbox("Blood", false), false)
|
||||
form.Adopt(basicElements.NewCheckbox("Bone", false), false)
|
||||
input := elements.NewTextBox("Write some text", "")
|
||||
form := containers.NewContainer(layouts.Vertical { true, false})
|
||||
form.Adopt(elements.NewLabel("I have:", false), false)
|
||||
form.Adopt(elements.NewSpacer(true), false)
|
||||
form.Adopt(elements.NewCheckbox("Skin", true), false)
|
||||
form.Adopt(elements.NewCheckbox("Blood", false), false)
|
||||
form.Adopt(elements.NewCheckbox("Bone", false), false)
|
||||
art := testing.NewArtist()
|
||||
|
||||
list := basicElements.NewList (
|
||||
basicElements.NewListEntry("button", func () { turnPage(button) }),
|
||||
basicElements.NewListEntry("mouse", func () { turnPage(mouse) }),
|
||||
basicElements.NewListEntry("input", func () { turnPage(input) }),
|
||||
basicElements.NewListEntry("form", func () { turnPage(form) }),
|
||||
basicElements.NewListEntry("art", func () { turnPage(art) }))
|
||||
list := elements.NewList (
|
||||
elements.NewListEntry("button", func () { turnPage(button) }),
|
||||
elements.NewListEntry("mouse", func () { turnPage(mouse) }),
|
||||
elements.NewListEntry("input", func () { turnPage(input) }),
|
||||
elements.NewListEntry("form", func () { turnPage(form) }),
|
||||
elements.NewListEntry("art", func () { turnPage(art) }))
|
||||
list.OnNoEntrySelected(func () { turnPage (intro) })
|
||||
list.Collapse(96, 0)
|
||||
|
||||
|
@ -2,9 +2,8 @@ package main
|
||||
|
||||
import "fmt"
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/basic"
|
||||
import _ "git.tebibyte.media/sashakoshka/tomo/backends/all"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/containers"
|
||||
|
||||
@ -16,8 +15,8 @@ func run () {
|
||||
window, _ := tomo.NewWindow(256, 256)
|
||||
window.SetTitle("Main")
|
||||
|
||||
container := containers.NewContainer(basicLayouts.Vertical { true, true })
|
||||
container.Adopt(basicElements.NewLabel("Main window", false), true)
|
||||
container := containers.NewContainer(layouts.Vertical { true, true })
|
||||
container.Adopt(elements.NewLabel("Main window", false), true)
|
||||
window.Adopt(container)
|
||||
|
||||
window.OnClose(tomo.Stop)
|
||||
@ -29,12 +28,12 @@ func run () {
|
||||
createPanel(window, 3)
|
||||
}
|
||||
|
||||
func createPanel (parent elements.MainWindow, id int) {
|
||||
func createPanel (parent tomo.MainWindow, id int) {
|
||||
window, _ := parent.NewPanel(2, 2)
|
||||
title := fmt.Sprint("Panel #", id)
|
||||
window.SetTitle(title)
|
||||
container := containers.NewContainer(basicLayouts.Vertical { true, true })
|
||||
container.Adopt(basicElements.NewLabel(title, false), true)
|
||||
container := containers.NewContainer(layouts.Vertical { true, true })
|
||||
container.Adopt(elements.NewLabel(title, false), true)
|
||||
window.Adopt(container)
|
||||
window.Show()
|
||||
}
|
||||
|
@ -6,9 +6,9 @@ import "errors"
|
||||
import "github.com/faiface/beep"
|
||||
import "github.com/faiface/beep/speaker"
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/fun"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/fun/music"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/containers"
|
||||
import _ "git.tebibyte.media/sashakoshka/tomo/backends/all"
|
||||
@ -34,27 +34,27 @@ func main () {
|
||||
func run () {
|
||||
window, _ := tomo.NewWindow(2, 2)
|
||||
window.SetTitle("Piano")
|
||||
container := containers.NewContainer(basicLayouts.Vertical { true, true })
|
||||
controlBar := containers.NewContainer(basicLayouts.Horizontal { true, false })
|
||||
container := containers.NewContainer(layouts.Vertical { true, true })
|
||||
controlBar := containers.NewContainer(layouts.Horizontal { true, false })
|
||||
|
||||
waveformColumn := containers.NewContainer(basicLayouts.Vertical { true, false })
|
||||
waveformList := basicElements.NewList (
|
||||
basicElements.NewListEntry("Sine", func(){ waveform = 0 }),
|
||||
basicElements.NewListEntry("Triangle", func(){ waveform = 3 }),
|
||||
basicElements.NewListEntry("Square", func(){ waveform = 1 }),
|
||||
basicElements.NewListEntry("Saw", func(){ waveform = 2 }),
|
||||
basicElements.NewListEntry("Supersaw", func(){ waveform = 4 }),
|
||||
waveformColumn := containers.NewContainer(layouts.Vertical { true, false })
|
||||
waveformList := elements.NewList (
|
||||
elements.NewListEntry("Sine", func(){ waveform = 0 }),
|
||||
elements.NewListEntry("Triangle", func(){ waveform = 3 }),
|
||||
elements.NewListEntry("Square", func(){ waveform = 1 }),
|
||||
elements.NewListEntry("Saw", func(){ waveform = 2 }),
|
||||
elements.NewListEntry("Supersaw", func(){ waveform = 4 }),
|
||||
)
|
||||
waveformList.OnNoEntrySelected (func(){waveformList.Select(0)})
|
||||
waveformList.Select(0)
|
||||
|
||||
adsrColumn := containers.NewContainer(basicLayouts.Vertical { true, false })
|
||||
adsrGroup := containers.NewContainer(basicLayouts.Horizontal { true, false })
|
||||
attackSlider := basicElements.NewLerpSlider(0, 3 * time.Second, adsr.Attack, true)
|
||||
decaySlider := basicElements.NewLerpSlider(0, 3 * time.Second, adsr.Decay, true)
|
||||
sustainSlider := basicElements.NewSlider(adsr.Sustain, true)
|
||||
releaseSlider := basicElements.NewLerpSlider(0, 3 * time.Second, adsr.Release, true)
|
||||
gainSlider := basicElements.NewSlider(math.Sqrt(gain), false)
|
||||
adsrColumn := containers.NewContainer(layouts.Vertical { true, false })
|
||||
adsrGroup := containers.NewContainer(layouts.Horizontal { true, false })
|
||||
attackSlider := elements.NewLerpSlider(0, 3 * time.Second, adsr.Attack, true)
|
||||
decaySlider := elements.NewLerpSlider(0, 3 * time.Second, adsr.Decay, true)
|
||||
sustainSlider := elements.NewSlider(adsr.Sustain, true)
|
||||
releaseSlider := elements.NewLerpSlider(0, 3 * time.Second, adsr.Release, true)
|
||||
gainSlider := elements.NewSlider(math.Sqrt(gain), false)
|
||||
|
||||
attackSlider.OnRelease (func () {
|
||||
adsr.Attack = attackSlider.Value()
|
||||
@ -72,7 +72,7 @@ func run () {
|
||||
gain = math.Pow(gainSlider.Value(), 2)
|
||||
})
|
||||
|
||||
patchColumn := containers.NewContainer(basicLayouts.Vertical { true, false })
|
||||
patchColumn := containers.NewContainer(layouts.Vertical { true, false })
|
||||
patch := func (w int, a, d time.Duration, s float64, r time.Duration) func () {
|
||||
return func () {
|
||||
waveform = w
|
||||
@ -89,22 +89,22 @@ func run () {
|
||||
releaseSlider.SetValue(adsr.Release)
|
||||
}
|
||||
}
|
||||
patchList := basicElements.NewList (
|
||||
basicElements.NewListEntry ("Bones", patch (
|
||||
patchList := elements.NewList (
|
||||
elements.NewListEntry ("Bones", patch (
|
||||
0, 0, 100, 0.0, 0)),
|
||||
basicElements.NewListEntry ("Staccato", patch (
|
||||
elements.NewListEntry ("Staccato", patch (
|
||||
4, 70, 500, 0, 0)),
|
||||
basicElements.NewListEntry ("Sustain", patch (
|
||||
elements.NewListEntry ("Sustain", patch (
|
||||
4, 70, 200, 0.8, 500)),
|
||||
basicElements.NewListEntry ("Upright", patch (
|
||||
elements.NewListEntry ("Upright", patch (
|
||||
1, 0, 500, 0.4, 70)),
|
||||
basicElements.NewListEntry ("Space Pad", patch (
|
||||
elements.NewListEntry ("Space Pad", patch (
|
||||
4, 1500, 0, 1.0, 3000)),
|
||||
basicElements.NewListEntry ("Popcorn", patch (
|
||||
elements.NewListEntry ("Popcorn", patch (
|
||||
2, 0, 40, 0.0, 0)),
|
||||
basicElements.NewListEntry ("Racer", patch (
|
||||
elements.NewListEntry ("Racer", patch (
|
||||
3, 70, 0, 0.7, 400)),
|
||||
basicElements.NewListEntry ("Reverse", patch (
|
||||
elements.NewListEntry ("Reverse", patch (
|
||||
2, 3000, 60, 0, 0)),
|
||||
)
|
||||
patchList.Collapse(0, 32)
|
||||
@ -121,19 +121,19 @@ func run () {
|
||||
window.Adopt(container)
|
||||
|
||||
controlBar.Adopt(patchColumn, true)
|
||||
patchColumn.Adopt(basicElements.NewLabel("Presets", false), false)
|
||||
patchColumn.Adopt(elements.NewLabel("Presets", false), false)
|
||||
patchColumn.Adopt(patchScrollBox, true)
|
||||
patchScrollBox.Adopt(patchList)
|
||||
|
||||
controlBar.Adopt(basicElements.NewSpacer(true), false)
|
||||
controlBar.Adopt(elements.NewSpacer(true), false)
|
||||
|
||||
controlBar.Adopt(waveformColumn, false)
|
||||
waveformColumn.Adopt(basicElements.NewLabel("Waveform", false), false)
|
||||
waveformColumn.Adopt(elements.NewLabel("Waveform", false), false)
|
||||
waveformColumn.Adopt(waveformList, true)
|
||||
|
||||
controlBar.Adopt(basicElements.NewSpacer(true), false)
|
||||
controlBar.Adopt(elements.NewSpacer(true), false)
|
||||
|
||||
adsrColumn.Adopt(basicElements.NewLabel("ADSR", false), false)
|
||||
adsrColumn.Adopt(elements.NewLabel("ADSR", false), false)
|
||||
adsrGroup.Adopt(attackSlider, false)
|
||||
adsrGroup.Adopt(decaySlider, false)
|
||||
adsrGroup.Adopt(sustainSlider, false)
|
||||
|
@ -2,8 +2,8 @@ package main
|
||||
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/popups"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements"
|
||||
import _ "git.tebibyte.media/sashakoshka/tomo/backends/all"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/containers"
|
||||
|
||||
@ -15,12 +15,12 @@ func run () {
|
||||
window, _ := tomo.NewWindow(2, 2)
|
||||
window.SetTitle("Dialog Boxes")
|
||||
|
||||
container := containers.NewContainer(basicLayouts.Vertical { true, true })
|
||||
container := containers.NewContainer(layouts.Vertical { true, true })
|
||||
window.Adopt(container)
|
||||
|
||||
container.Adopt(basicElements.NewLabel("Try out different dialogs:", false), true)
|
||||
container.Adopt(elements.NewLabel("Try out different dialogs:", false), true)
|
||||
|
||||
infoButton := basicElements.NewButton("popups.DialogKindInfo")
|
||||
infoButton := elements.NewButton("popups.DialogKindInfo")
|
||||
infoButton.OnClick (func () {
|
||||
popups.NewDialog (
|
||||
popups.DialogKindInfo,
|
||||
@ -31,7 +31,7 @@ func run () {
|
||||
container.Adopt(infoButton, false)
|
||||
infoButton.Focus()
|
||||
|
||||
questionButton := basicElements.NewButton("popups.DialogKindQuestion")
|
||||
questionButton := elements.NewButton("popups.DialogKindQuestion")
|
||||
questionButton.OnClick (func () {
|
||||
popups.NewDialog (
|
||||
popups.DialogKindQuestion,
|
||||
@ -44,7 +44,7 @@ func run () {
|
||||
})
|
||||
container.Adopt(questionButton, false)
|
||||
|
||||
warningButton := basicElements.NewButton("popups.DialogKindWarning")
|
||||
warningButton := elements.NewButton("popups.DialogKindWarning")
|
||||
warningButton.OnClick (func () {
|
||||
popups.NewDialog (
|
||||
popups.DialogKindWarning,
|
||||
@ -54,7 +54,7 @@ func run () {
|
||||
})
|
||||
container.Adopt(warningButton, false)
|
||||
|
||||
errorButton := basicElements.NewButton("popups.DialogKindError")
|
||||
errorButton := elements.NewButton("popups.DialogKindError")
|
||||
errorButton.OnClick (func () {
|
||||
popups.NewDialog (
|
||||
popups.DialogKindError,
|
||||
@ -64,7 +64,7 @@ func run () {
|
||||
})
|
||||
container.Adopt(errorButton, false)
|
||||
|
||||
cancelButton := basicElements.NewButton("No thank you.")
|
||||
cancelButton := elements.NewButton("No thank you.")
|
||||
cancelButton.OnClick(tomo.Stop)
|
||||
container.Adopt(cancelButton, false)
|
||||
|
||||
|
@ -3,8 +3,8 @@ package main
|
||||
import "time"
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/popups"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/containers"
|
||||
import _ "git.tebibyte.media/sashakoshka/tomo/backends/all"
|
||||
|
||||
@ -15,23 +15,23 @@ func main () {
|
||||
func run () {
|
||||
window, _ := tomo.NewWindow(2, 2)
|
||||
window.SetTitle("Approaching")
|
||||
container := containers.NewContainer(basicLayouts.Vertical { true, true })
|
||||
container := containers.NewContainer(layouts.Vertical { true, true })
|
||||
window.Adopt(container)
|
||||
|
||||
container.Adopt (basicElements.NewLabel (
|
||||
container.Adopt (elements.NewLabel (
|
||||
"Rapidly approaching your location...", false), false)
|
||||
bar := basicElements.NewProgressBar(0)
|
||||
bar := elements.NewProgressBar(0)
|
||||
container.Adopt(bar, false)
|
||||
button := basicElements.NewButton("Stop")
|
||||
button := elements.NewButton("Stop")
|
||||
button.SetEnabled(false)
|
||||
container.Adopt(button, false)
|
||||
|
||||
window.OnClose(tomo.Stop)
|
||||
window.Show()
|
||||
go fill(bar)
|
||||
go fill(window, bar)
|
||||
}
|
||||
|
||||
func fill (bar *basicElements.ProgressBar) {
|
||||
func fill (window tomo.Window, bar *elements.ProgressBar) {
|
||||
for progress := 0.0; progress < 1.0; progress += 0.01 {
|
||||
time.Sleep(time.Second / 24)
|
||||
tomo.Do (func () {
|
||||
@ -41,6 +41,7 @@ func fill (bar *basicElements.ProgressBar) {
|
||||
tomo.Do (func () {
|
||||
popups.NewDialog (
|
||||
popups.DialogKindInfo,
|
||||
window,
|
||||
"I am here",
|
||||
"Don't look outside your window.")
|
||||
})
|
||||
|
@ -5,8 +5,8 @@ import _ "embed"
|
||||
import _ "image/png"
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/popups"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements"
|
||||
import _ "git.tebibyte.media/sashakoshka/tomo/backends/all"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/containers"
|
||||
|
||||
@ -21,7 +21,7 @@ func run () {
|
||||
window, _ := tomo.NewWindow(640, 480)
|
||||
window.SetTitle("Raycaster")
|
||||
|
||||
container := containers.NewContainer(basicLayouts.Vertical { false, false })
|
||||
container := containers.NewContainer(layouts.Vertical { false, false })
|
||||
window.Adopt(container)
|
||||
|
||||
wallTexture, _ := TextureFrom(bytes.NewReader(wallTextureBytes))
|
||||
@ -48,13 +48,13 @@ func run () {
|
||||
wallTexture,
|
||||
})
|
||||
|
||||
topBar := containers.NewContainer(basicLayouts.Horizontal { true, true })
|
||||
staminaBar := basicElements.NewProgressBar(game.Stamina())
|
||||
healthBar := basicElements.NewProgressBar(game.Health())
|
||||
topBar := containers.NewContainer(layouts.Horizontal { true, true })
|
||||
staminaBar := elements.NewProgressBar(game.Stamina())
|
||||
healthBar := elements.NewProgressBar(game.Health())
|
||||
|
||||
topBar.Adopt(basicElements.NewLabel("Stamina:", false), false)
|
||||
topBar.Adopt(elements.NewLabel("Stamina:", false), false)
|
||||
topBar.Adopt(staminaBar, true)
|
||||
topBar.Adopt(basicElements.NewLabel("Health:", false), false)
|
||||
topBar.Adopt(elements.NewLabel("Health:", false), false)
|
||||
topBar.Adopt(healthBar, true)
|
||||
container.Adopt(topBar, false)
|
||||
container.Adopt(game, true)
|
||||
@ -69,6 +69,7 @@ func run () {
|
||||
|
||||
popups.NewDialog (
|
||||
popups.DialogKindInfo,
|
||||
window,
|
||||
"Welcome to the backrooms",
|
||||
"You've no-clipped into the backrooms!\n" +
|
||||
"Move with WASD, and look with the arrow keys.\n" +
|
||||
|
@ -2,8 +2,8 @@ package main
|
||||
|
||||
import "image"
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements"
|
||||
import _ "git.tebibyte.media/sashakoshka/tomo/backends/all"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/containers"
|
||||
|
||||
@ -14,39 +14,39 @@ func main () {
|
||||
func run () {
|
||||
window, _ := tomo.NewWindow(360, 240)
|
||||
window.SetTitle("Scroll")
|
||||
container := containers.NewContainer(basicLayouts.Vertical { true, true })
|
||||
container := containers.NewContainer(layouts.Vertical { true, true })
|
||||
window.Adopt(container)
|
||||
|
||||
textBox := basicElements.NewTextBox("", copypasta)
|
||||
textBox := elements.NewTextBox("", copypasta)
|
||||
scrollContainer := containers.NewScrollContainer(true, false)
|
||||
|
||||
disconnectedContainer := containers.NewContainer (basicLayouts.Horizontal {
|
||||
disconnectedContainer := containers.NewContainer (layouts.Horizontal {
|
||||
Gap: true,
|
||||
})
|
||||
list := basicElements.NewList (
|
||||
basicElements.NewListEntry("This is list item 0", nil),
|
||||
basicElements.NewListEntry("This is list item 1", nil),
|
||||
basicElements.NewListEntry("This is list item 2", nil),
|
||||
basicElements.NewListEntry("This is list item 3", nil),
|
||||
basicElements.NewListEntry("This is list item 4", nil),
|
||||
basicElements.NewListEntry("This is list item 5", nil),
|
||||
basicElements.NewListEntry("This is list item 6", nil),
|
||||
basicElements.NewListEntry("This is list item 7", nil),
|
||||
basicElements.NewListEntry("This is list item 8", nil),
|
||||
basicElements.NewListEntry("This is list item 9", nil),
|
||||
basicElements.NewListEntry("This is list item 10", nil),
|
||||
basicElements.NewListEntry("This is list item 11", nil),
|
||||
basicElements.NewListEntry("This is list item 12", nil),
|
||||
basicElements.NewListEntry("This is list item 13", nil),
|
||||
basicElements.NewListEntry("This is list item 14", nil),
|
||||
basicElements.NewListEntry("This is list item 15", nil),
|
||||
basicElements.NewListEntry("This is list item 16", nil),
|
||||
basicElements.NewListEntry("This is list item 17", nil),
|
||||
basicElements.NewListEntry("This is list item 18", nil),
|
||||
basicElements.NewListEntry("This is list item 19", nil),
|
||||
basicElements.NewListEntry("This is list item 20", nil))
|
||||
list := elements.NewList (
|
||||
elements.NewListEntry("This is list item 0", nil),
|
||||
elements.NewListEntry("This is list item 1", nil),
|
||||
elements.NewListEntry("This is list item 2", nil),
|
||||
elements.NewListEntry("This is list item 3", nil),
|
||||
elements.NewListEntry("This is list item 4", nil),
|
||||
elements.NewListEntry("This is list item 5", nil),
|
||||
elements.NewListEntry("This is list item 6", nil),
|
||||
elements.NewListEntry("This is list item 7", nil),
|
||||
elements.NewListEntry("This is list item 8", nil),
|
||||
elements.NewListEntry("This is list item 9", nil),
|
||||
elements.NewListEntry("This is list item 10", nil),
|
||||
elements.NewListEntry("This is list item 11", nil),
|
||||
elements.NewListEntry("This is list item 12", nil),
|
||||
elements.NewListEntry("This is list item 13", nil),
|
||||
elements.NewListEntry("This is list item 14", nil),
|
||||
elements.NewListEntry("This is list item 15", nil),
|
||||
elements.NewListEntry("This is list item 16", nil),
|
||||
elements.NewListEntry("This is list item 17", nil),
|
||||
elements.NewListEntry("This is list item 18", nil),
|
||||
elements.NewListEntry("This is list item 19", nil),
|
||||
elements.NewListEntry("This is list item 20", nil))
|
||||
list.Collapse(0, 32)
|
||||
scrollBar := basicElements.NewScrollBar(true)
|
||||
scrollBar := elements.NewScrollBar(true)
|
||||
list.OnScrollBoundsChange (func () {
|
||||
scrollBar.SetBounds (
|
||||
list.ScrollContentBounds(),
|
||||
@ -57,10 +57,10 @@ func run () {
|
||||
})
|
||||
|
||||
scrollContainer.Adopt(textBox)
|
||||
container.Adopt(basicElements.NewLabel("A ScrollContainer:", false), false)
|
||||
container.Adopt(elements.NewLabel("A ScrollContainer:", false), false)
|
||||
container.Adopt(scrollContainer, false)
|
||||
disconnectedContainer.Adopt(list, false)
|
||||
disconnectedContainer.Adopt (basicElements.NewLabel (
|
||||
disconnectedContainer.Adopt (elements.NewLabel (
|
||||
"Notice how the scroll bar to the right can be used to " +
|
||||
"control the list, despite not even touching it. It is " +
|
||||
"indeed a thing you can do. It is also terrible UI design so " +
|
||||
|
@ -1,8 +1,8 @@
|
||||
package main
|
||||
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements"
|
||||
import _ "git.tebibyte.media/sashakoshka/tomo/backends/all"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/containers"
|
||||
|
||||
@ -14,14 +14,14 @@ func run () {
|
||||
window, _ := tomo.NewWindow(2, 2)
|
||||
window.SetTitle("Spaced Out")
|
||||
|
||||
container := containers.NewContainer(basicLayouts.Vertical { true, true })
|
||||
container := containers.NewContainer(layouts.Vertical { true, true })
|
||||
window.Adopt(container)
|
||||
|
||||
container.Adopt (basicElements.NewLabel("This is at the top", false), false)
|
||||
container.Adopt (basicElements.NewSpacer(true), false)
|
||||
container.Adopt (basicElements.NewLabel("This is in the middle", false), false)
|
||||
container.Adopt (basicElements.NewSpacer(false), true)
|
||||
container.Adopt (basicElements.NewLabel("This is at the bottom", false), false)
|
||||
container.Adopt (elements.NewLabel("This is at the top", false), false)
|
||||
container.Adopt (elements.NewSpacer(true), false)
|
||||
container.Adopt (elements.NewLabel("This is in the middle", false), false)
|
||||
container.Adopt (elements.NewSpacer(false), true)
|
||||
container.Adopt (elements.NewLabel("This is at the bottom", false), false)
|
||||
|
||||
window.OnClose(tomo.Stop)
|
||||
window.Show()
|
||||
|
@ -1,8 +1,8 @@
|
||||
package main
|
||||
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements"
|
||||
import _ "git.tebibyte.media/sashakoshka/tomo/backends/all"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/containers"
|
||||
|
||||
@ -14,12 +14,12 @@ func run () {
|
||||
window, _ := tomo.NewWindow(2, 2)
|
||||
window.SetTitle("Switches")
|
||||
|
||||
container := containers.NewContainer(basicLayouts.Vertical { true, true })
|
||||
container := containers.NewContainer(layouts.Vertical { true, true })
|
||||
window.Adopt(container)
|
||||
|
||||
container.Adopt(basicElements.NewSwitch("hahahah", false), false)
|
||||
container.Adopt(basicElements.NewSwitch("hehehehheheh", false), false)
|
||||
container.Adopt(basicElements.NewSwitch("you can flick da swicth", false), false)
|
||||
container.Adopt(elements.NewSwitch("hahahah", false), false)
|
||||
container.Adopt(elements.NewSwitch("hehehehheheh", false), false)
|
||||
container.Adopt(elements.NewSwitch("you can flick da swicth", false), false)
|
||||
|
||||
window.OnClose(tomo.Stop)
|
||||
window.Show()
|
||||
|
@ -1,8 +1,8 @@
|
||||
package main
|
||||
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/testing"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/containers"
|
||||
import _ "git.tebibyte.media/sashakoshka/tomo/backends/all"
|
||||
@ -15,15 +15,15 @@ func run () {
|
||||
window, _ := tomo.NewWindow(128, 128)
|
||||
window.SetTitle("vertical stack")
|
||||
|
||||
container := containers.NewContainer(basicLayouts.Vertical { true, true })
|
||||
container := containers.NewContainer(layouts.Vertical { true, true })
|
||||
window.Adopt(container)
|
||||
|
||||
label := basicElements.NewLabel("it is a label hehe", true)
|
||||
button := basicElements.NewButton("drawing pad")
|
||||
okButton := basicElements.NewButton("OK")
|
||||
label := elements.NewLabel("it is a label hehe", true)
|
||||
button := elements.NewButton("drawing pad")
|
||||
okButton := elements.NewButton("OK")
|
||||
button.OnClick (func () {
|
||||
container.DisownAll()
|
||||
container.Adopt(basicElements.NewLabel("Draw here:", false), false)
|
||||
container.Adopt(elements.NewLabel("Draw here:", false), false)
|
||||
container.Adopt(testing.NewMouse(), true)
|
||||
container.Adopt(okButton, false)
|
||||
okButton.Focus()
|
||||
|
@ -1,18 +1,12 @@
|
||||
// Package layouts defines a layout interface which a container element can
|
||||
// accept to have its child elements automatically arranged by any layout that
|
||||
// satisfies it.
|
||||
//
|
||||
// Sub-packages of layouts contain several pre-made ones.
|
||||
package layouts
|
||||
package tomo
|
||||
|
||||
import "image"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/artist"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements"
|
||||
|
||||
// LayoutEntry associates an element with layout and positioning information so
|
||||
// it can be arranged by a Layout.
|
||||
type LayoutEntry struct {
|
||||
elements.Element
|
||||
Element
|
||||
Bounds image.Rectangle
|
||||
Expand bool
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
package basicLayouts
|
||||
package layouts
|
||||
|
||||
import "image"
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/artist"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts"
|
||||
|
||||
// Dialog arranges elements in the form of a dialog box. The first element is
|
||||
// positioned above as the main focus of the dialog, and is set to expand
|
||||
@ -20,7 +20,7 @@ type Dialog struct {
|
||||
|
||||
// Arrange arranges a list of entries into a dialog.
|
||||
func (layout Dialog) Arrange (
|
||||
entries []layouts.LayoutEntry,
|
||||
entries []tomo.LayoutEntry,
|
||||
margin image.Point,
|
||||
padding artist.Inset,
|
||||
bounds image.Rectangle,
|
||||
@ -101,7 +101,7 @@ func (layout Dialog) Arrange (
|
||||
// MinimumSize returns the minimum width and height that will be needed to
|
||||
// arrange the given list of entries.
|
||||
func (layout Dialog) MinimumSize (
|
||||
entries []layouts.LayoutEntry,
|
||||
entries []tomo.LayoutEntry,
|
||||
margin image.Point,
|
||||
padding artist.Inset,
|
||||
) (
|
||||
@ -132,7 +132,7 @@ func (layout Dialog) MinimumSize (
|
||||
}
|
||||
|
||||
func (layout Dialog) minimumSizeOfControlRow (
|
||||
entries []layouts.LayoutEntry,
|
||||
entries []tomo.LayoutEntry,
|
||||
margin image.Point,
|
||||
padding artist.Inset,
|
||||
) (
|
@ -1,9 +1,9 @@
|
||||
package basicLayouts
|
||||
package layouts
|
||||
|
||||
import "image"
|
||||
import "golang.org/x/image/math/fixed"
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/artist"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/fixedutil"
|
||||
|
||||
// Horizontal arranges elements horizontally. Elements at the start of the entry
|
||||
@ -20,7 +20,7 @@ type Horizontal struct {
|
||||
|
||||
// Arrange arranges a list of entries horizontally.
|
||||
func (layout Horizontal) Arrange (
|
||||
entries []layouts.LayoutEntry,
|
||||
entries []tomo.LayoutEntry,
|
||||
margin image.Point,
|
||||
padding artist.Inset,
|
||||
bounds image.Rectangle,
|
||||
@ -55,7 +55,7 @@ func (layout Horizontal) Arrange (
|
||||
// MinimumSize returns the minimum width and height that will be needed to
|
||||
// arrange the given list of entries.
|
||||
func (layout Horizontal) MinimumSize (
|
||||
entries []layouts.LayoutEntry,
|
||||
entries []tomo.LayoutEntry,
|
||||
margin image.Point,
|
||||
padding artist.Inset,
|
||||
) (
|
||||
@ -80,7 +80,7 @@ func (layout Horizontal) MinimumSize (
|
||||
}
|
||||
|
||||
func (layout Horizontal) expandingElementWidth (
|
||||
entries []layouts.LayoutEntry,
|
||||
entries []tomo.LayoutEntry,
|
||||
margin image.Point,
|
||||
padding artist.Inset,
|
||||
freeSpace int,
|
@ -1,9 +1,9 @@
|
||||
package basicLayouts
|
||||
package layouts
|
||||
|
||||
import "image"
|
||||
import "golang.org/x/image/math/fixed"
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/artist"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/fixedutil"
|
||||
|
||||
// Vertical arranges elements vertically. Elements at the start of the entry
|
||||
@ -20,7 +20,7 @@ type Vertical struct {
|
||||
|
||||
// Arrange arranges a list of entries vertically.
|
||||
func (layout Vertical) Arrange (
|
||||
entries []layouts.LayoutEntry,
|
||||
entries []tomo.LayoutEntry,
|
||||
margin image.Point,
|
||||
padding artist.Inset,
|
||||
bounds image.Rectangle,
|
||||
@ -55,7 +55,7 @@ func (layout Vertical) Arrange (
|
||||
// MinimumSize returns the minimum width and height that will be needed to
|
||||
// arrange the given list of entries.
|
||||
func (layout Vertical) MinimumSize (
|
||||
entries []layouts.LayoutEntry,
|
||||
entries []tomo.LayoutEntry,
|
||||
margin image.Point,
|
||||
padding artist.Inset,
|
||||
) (
|
||||
@ -80,7 +80,7 @@ func (layout Vertical) MinimumSize (
|
||||
}
|
||||
|
||||
func (layout Vertical) expandingElementHeight (
|
||||
entries []layouts.LayoutEntry,
|
||||
entries []tomo.LayoutEntry,
|
||||
margin image.Point,
|
||||
padding artist.Inset,
|
||||
freeSpace int,
|
@ -1,4 +1,4 @@
|
||||
package elements
|
||||
package tomo
|
||||
|
||||
// Parent represents a type capable of containing child elements.
|
||||
type Parent interface {
|
@ -2,9 +2,8 @@ package popups
|
||||
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/theme"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/containers"
|
||||
|
||||
// DialogKind defines the semantic role of a dialog window.
|
||||
@ -31,11 +30,11 @@ type Button struct {
|
||||
// the dialog will just be a normal window
|
||||
func NewDialog (
|
||||
kind DialogKind,
|
||||
parent elements.Window,
|
||||
parent tomo.Window,
|
||||
title, message string,
|
||||
buttons ...Button,
|
||||
) (
|
||||
window elements.Window,
|
||||
window tomo.Window,
|
||||
) {
|
||||
if parent == nil {
|
||||
window, _ = tomo.NewWindow(2, 2)
|
||||
@ -44,10 +43,10 @@ func NewDialog (
|
||||
}
|
||||
window.SetTitle(title)
|
||||
|
||||
container := containers.NewContainer(basicLayouts.Dialog { true, true })
|
||||
container := containers.NewContainer(layouts.Dialog { true, true })
|
||||
window.Adopt(container)
|
||||
|
||||
messageContainer := containers.NewContainer(basicLayouts.Horizontal { true, false })
|
||||
messageContainer := containers.NewContainer(layouts.Horizontal { true, false })
|
||||
iconId := theme.IconInformation
|
||||
switch kind {
|
||||
case DialogKindInfo: iconId = theme.IconInformation
|
||||
@ -56,20 +55,20 @@ func NewDialog (
|
||||
case DialogKindError: iconId = theme.IconError
|
||||
}
|
||||
|
||||
messageContainer.Adopt(basicElements.NewIcon(iconId, theme.IconSizeLarge), false)
|
||||
messageContainer.Adopt(basicElements.NewLabel(message, false), true)
|
||||
messageContainer.Adopt(elements.NewIcon(iconId, theme.IconSizeLarge), false)
|
||||
messageContainer.Adopt(elements.NewLabel(message, false), true)
|
||||
container.Adopt(messageContainer, true)
|
||||
|
||||
if len(buttons) == 0 {
|
||||
button := basicElements.NewButton("OK")
|
||||
button := elements.NewButton("OK")
|
||||
button.SetIcon(theme.IconYes)
|
||||
button.OnClick(window.Close)
|
||||
container.Adopt(button, false)
|
||||
button.Focus()
|
||||
} else {
|
||||
var button *basicElements.Button
|
||||
var button *elements.Button
|
||||
for _, buttonDescriptor := range buttons {
|
||||
button = basicElements.NewButton(buttonDescriptor.Name)
|
||||
button = elements.NewButton(buttonDescriptor.Name)
|
||||
button.SetEnabled(buttonDescriptor.OnPress != nil)
|
||||
button.OnClick (func () {
|
||||
buttonDescriptor.OnPress()
|
||||
|
@ -210,7 +210,7 @@ func (Default) Pattern (id Pattern, state State, c Case) artist.Pattern {
|
||||
case PatternBackground: return patterns.Uhex(0xaaaaaaFF)
|
||||
case PatternDead: return defaultTextures[0][offset]
|
||||
case PatternRaised:
|
||||
if c.Match("basic", "listEntry", "") {
|
||||
if c.Match("tomo", "listEntry", "") {
|
||||
return defaultTextures[10][offset]
|
||||
} else {
|
||||
return defaultTextures[1][offset]
|
||||
@ -219,11 +219,11 @@ func (Default) Pattern (id Pattern, state State, c Case) artist.Pattern {
|
||||
case PatternPinboard: return defaultTextures[3][offset]
|
||||
case PatternButton:
|
||||
switch {
|
||||
case c.Match("basic", "checkbox", ""):
|
||||
case c.Match("tomo", "checkbox", ""):
|
||||
return defaultTextures[9][offset]
|
||||
case c.Match("fun", "piano", "flatKey"):
|
||||
case c.Match("tomo", "piano", "flatKey"):
|
||||
return defaultTextures[11][offset]
|
||||
case c.Match("fun", "piano", "sharpKey"):
|
||||
case c.Match("tomo", "piano", "sharpKey"):
|
||||
return defaultTextures[12][offset]
|
||||
default:
|
||||
return defaultTextures[4][offset]
|
||||
@ -253,13 +253,13 @@ func (Default) Color (id Color, state State, c Case) color.RGBA {
|
||||
func (Default) Padding (id Pattern, c Case) artist.Inset {
|
||||
switch id {
|
||||
case PatternRaised:
|
||||
if c.Match("basic", "listEntry", "") {
|
||||
if c.Match("tomo", "listEntry", "") {
|
||||
return artist.I(4, 8)
|
||||
} else {
|
||||
return artist.I(8)
|
||||
}
|
||||
case PatternSunken:
|
||||
if c.Match("basic", "list", "") {
|
||||
if c.Match("tomo", "list", "") {
|
||||
return artist.I(4, 0, 3)
|
||||
} else if c.Match("basic", "progressBar", "") {
|
||||
return artist.I(2, 1, 1, 2)
|
||||
@ -267,7 +267,7 @@ func (Default) Padding (id Pattern, c Case) artist.Inset {
|
||||
return artist.I(8)
|
||||
}
|
||||
case PatternPinboard:
|
||||
if c.Match("fun", "piano", "") {
|
||||
if c.Match("tomo", "piano", "") {
|
||||
return artist.I(2)
|
||||
} else {
|
||||
return artist.I(8)
|
||||
|
64
tomo.go
64
tomo.go
@ -1,12 +1,7 @@
|
||||
package tomo
|
||||
|
||||
import "os"
|
||||
import "io"
|
||||
import "path/filepath"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/dirs"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/theme"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/config"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements"
|
||||
|
||||
var backend Backend
|
||||
|
||||
@ -16,9 +11,6 @@ var backend Backend
|
||||
func Run (callback func ()) (err error) {
|
||||
backend, err = instantiateBackend()
|
||||
if err != nil { return }
|
||||
config := parseConfig()
|
||||
backend.SetConfig(config)
|
||||
backend.SetTheme(parseTheme(config.ThemePath()))
|
||||
if callback != nil { callback() }
|
||||
err = backend.Run()
|
||||
backend = nil
|
||||
@ -41,7 +33,7 @@ func Do (callback func ()) {
|
||||
// NewWindow creates a new window using the current backend, and returns it as a
|
||||
// MainWindow. If the window could not be created, an error is returned
|
||||
// explaining why.
|
||||
func NewWindow (width, height int) (window elements.MainWindow, err error) {
|
||||
func NewWindow (width, height int) (window MainWindow, err error) {
|
||||
assertBackend()
|
||||
return backend.NewWindow(width, height)
|
||||
}
|
||||
@ -56,60 +48,6 @@ func SetConfig (config config.Config) {
|
||||
backend.SetConfig(config)
|
||||
}
|
||||
|
||||
func parseConfig () (config.Config) {
|
||||
return parseMany [config.Config] (
|
||||
dirs.ConfigDirs("tomo/tomo.conf"),
|
||||
config.Parse,
|
||||
config.Default { })
|
||||
}
|
||||
|
||||
func parseTheme (path string) (theme.Theme) {
|
||||
if path == "" { return theme.Default { } }
|
||||
path = filepath.Join(path, "tomo")
|
||||
|
||||
// find all tomo pattern graph files in the directory
|
||||
directory, err := os.Open(path)
|
||||
if err != nil { return theme.Default { } }
|
||||
names, _ := directory.Readdirnames(0)
|
||||
paths := []string { }
|
||||
for _, name := range names {
|
||||
if filepath.Ext(name) == ".tpg" {
|
||||
paths = append(paths, filepath.Join(path, name))
|
||||
}
|
||||
}
|
||||
|
||||
// parse them
|
||||
return parseMany [theme.Theme] (
|
||||
paths,
|
||||
theme.Parse,
|
||||
theme.Default { })
|
||||
}
|
||||
|
||||
func parseMany [OBJECT any] (
|
||||
paths []string,
|
||||
parser func (...io.Reader) OBJECT,
|
||||
fallback OBJECT,
|
||||
) (
|
||||
object OBJECT,
|
||||
) {
|
||||
// convert all paths into readers
|
||||
sources := []io.Reader { }
|
||||
for _, path := range paths {
|
||||
file, err := os.Open(path)
|
||||
if err != nil { continue }
|
||||
sources = append(sources, file)
|
||||
defer file.Close()
|
||||
}
|
||||
|
||||
if sources == nil {
|
||||
// if there are no readers, return the fallback object
|
||||
return fallback
|
||||
} else {
|
||||
// if there are readers, parse them
|
||||
return parser(sources...)
|
||||
}
|
||||
}
|
||||
|
||||
func assertBackend () {
|
||||
if backend == nil { panic("no backend is running") }
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package elements
|
||||
package tomo
|
||||
|
||||
import "image"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/data"
|
Reference in New Issue
Block a user