Add theme setting nonsense
This commit is contained in:
parent
26b69d3e21
commit
995e6fd624
@ -19,7 +19,10 @@ type box struct {
|
|||||||
parent parent
|
parent parent
|
||||||
outer anyBox
|
outer anyBox
|
||||||
|
|
||||||
role tomo.Role
|
role tomo.Role
|
||||||
|
styleCookie event.Cookie
|
||||||
|
lastStyleNonce int
|
||||||
|
lastIconsNonce int
|
||||||
|
|
||||||
bounds image.Rectangle
|
bounds image.Rectangle
|
||||||
minSize image.Point
|
minSize image.Point
|
||||||
@ -44,19 +47,21 @@ type box struct {
|
|||||||
drawer canvas.Drawer
|
drawer canvas.Drawer
|
||||||
|
|
||||||
on struct {
|
on struct {
|
||||||
focusEnter event.FuncBroadcaster
|
focusEnter event.FuncBroadcaster
|
||||||
focusLeave event.FuncBroadcaster
|
focusLeave event.FuncBroadcaster
|
||||||
dndEnter event.FuncBroadcaster
|
dndEnter event.FuncBroadcaster
|
||||||
dndLeave event.FuncBroadcaster
|
dndLeave event.FuncBroadcaster
|
||||||
dndDrop event.Broadcaster[func (data.Data)]
|
dndDrop event.Broadcaster[func (data.Data)]
|
||||||
mouseEnter event.FuncBroadcaster
|
mouseEnter event.FuncBroadcaster
|
||||||
mouseLeave event.FuncBroadcaster
|
mouseLeave event.FuncBroadcaster
|
||||||
mouseMove event.FuncBroadcaster
|
mouseMove event.FuncBroadcaster
|
||||||
mouseDown event.Broadcaster[func (input.Button)]
|
mouseDown event.Broadcaster[func (input.Button)]
|
||||||
mouseUp event.Broadcaster[func (input.Button)]
|
mouseUp event.Broadcaster[func (input.Button)]
|
||||||
scroll event.Broadcaster[func (float64, float64)]
|
scroll event.Broadcaster[func (float64, float64)]
|
||||||
keyDown event.Broadcaster[func (input.Key, bool)]
|
keyDown event.Broadcaster[func (input.Key, bool)]
|
||||||
keyUp event.Broadcaster[func (input.Key, bool)]
|
keyUp event.Broadcaster[func (input.Key, bool)]
|
||||||
|
styleChange event.FuncBroadcaster
|
||||||
|
iconsChange event.FuncBroadcaster
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,6 +287,12 @@ func (this *box) OnKeyDown (callback func(key input.Key, numberPad bool)) event.
|
|||||||
func (this *box) OnKeyUp (callback func(key input.Key, numberPad bool)) event.Cookie {
|
func (this *box) OnKeyUp (callback func(key input.Key, numberPad bool)) event.Cookie {
|
||||||
return this.on.keyUp.Connect(callback)
|
return this.on.keyUp.Connect(callback)
|
||||||
}
|
}
|
||||||
|
func (this *box) OnStyleChange (callback func()) event.Cookie {
|
||||||
|
return this.on.styleChange.Connect(callback)
|
||||||
|
}
|
||||||
|
func (this *box) OnIconsChange (callback func()) event.Cookie {
|
||||||
|
return this.on.iconsChange.Connect(callback)
|
||||||
|
}
|
||||||
func (this *box) handleFocusEnter () {
|
func (this *box) handleFocusEnter () {
|
||||||
this.on.focusEnter.Broadcast()
|
this.on.focusEnter.Broadcast()
|
||||||
}
|
}
|
||||||
@ -451,7 +462,7 @@ func (this *box) doLayout () {
|
|||||||
// laycnt ++
|
// laycnt ++
|
||||||
|
|
||||||
this.innerClippingBounds = this.borderSum().Apply(this.bounds)
|
this.innerClippingBounds = this.borderSum().Apply(this.bounds)
|
||||||
this.loseCanvas()
|
this.outer.recursiveLoseCanvas()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *box) setParent (parent parent) {
|
func (this *box) setParent (parent parent) {
|
||||||
@ -481,7 +492,7 @@ func (this *box) recursiveRedo () {
|
|||||||
this.doDraw()
|
this.doDraw()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *box) loseCanvas () {
|
func (this *box) recursiveLoseCanvas () {
|
||||||
this.canvas.InvalidateTo(nil)
|
this.canvas.InvalidateTo(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -506,6 +517,28 @@ func (this *box) invalidateMinimum () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *box) recursiveReApply () {
|
||||||
|
// re-apply styling, icons *if needed*
|
||||||
|
|
||||||
|
// style
|
||||||
|
hierarchyStyleNonce := this.getStyleNonce()
|
||||||
|
if this.lastStyleNonce != hierarchyStyleNonce {
|
||||||
|
this.lastStyleNonce = hierarchyStyleNonce
|
||||||
|
if this.styleCookie != nil {
|
||||||
|
this.styleCookie.Close()
|
||||||
|
}
|
||||||
|
this.styleCookie = this.getStyle().Apply(this.outer)
|
||||||
|
this.on.styleChange.Broadcast()
|
||||||
|
}
|
||||||
|
|
||||||
|
// icons
|
||||||
|
hierarchyIconsNonce := this.getIconsNonce()
|
||||||
|
if this.lastIconsNonce != hierarchyIconsNonce {
|
||||||
|
this.lastIconsNonce = hierarchyIconsNonce
|
||||||
|
this.on.iconsChange.Broadcast()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (this *box) canBeFocused () bool {
|
func (this *box) canBeFocused () bool {
|
||||||
return this.focusable
|
return this.focusable
|
||||||
}
|
}
|
||||||
@ -539,7 +572,23 @@ func (this *box) getWindow () tomo.Window {
|
|||||||
return hierarchy.getWindow()
|
return hierarchy.getWindow()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *box) getStyle () tomo.Style {
|
||||||
|
hierarchy := this.getHierarchy()
|
||||||
|
if hierarchy == nil { return nil }
|
||||||
|
return hierarchy.getStyle()
|
||||||
|
}
|
||||||
|
|
||||||
func (this *box) getHierarchy () *Hierarchy {
|
func (this *box) getHierarchy () *Hierarchy {
|
||||||
if this.parent == nil { return nil }
|
if this.parent == nil { return nil }
|
||||||
return this.parent.getHierarchy()
|
return this.parent.getHierarchy()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *box) getStyleNonce () int {
|
||||||
|
// should panic if not in the tree
|
||||||
|
return this.getHierarchy().getStyleNonce()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *box) getIconsNonce () int {
|
||||||
|
// should panic if not in the tree
|
||||||
|
return this.getHierarchy().getIconsNonce()
|
||||||
|
}
|
||||||
|
@ -335,6 +335,20 @@ func (this *containerBox) recursiveRedo () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *containerBox) recursiveLoseCanvas () {
|
||||||
|
this.box.recursiveLoseCanvas()
|
||||||
|
for _, child := range this.children {
|
||||||
|
child.(anyBox).recursiveLoseCanvas()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *containerBox) recursiveReApply () {
|
||||||
|
this.box.recursiveReApply()
|
||||||
|
for _, child := range this.children {
|
||||||
|
child.(anyBox).recursiveReApply()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (this *containerBox) boxUnder (point image.Point, category eventCategory) anyBox {
|
func (this *containerBox) boxUnder (point image.Point, category eventCategory) anyBox {
|
||||||
if !point.In(this.bounds) { return nil }
|
if !point.In(this.bounds) { return nil }
|
||||||
|
|
||||||
|
@ -12,6 +12,10 @@ type Hierarchy struct {
|
|||||||
link WindowLink
|
link WindowLink
|
||||||
system *System
|
system *System
|
||||||
canvas canvas.Canvas
|
canvas canvas.Canvas
|
||||||
|
|
||||||
|
style tomo.Style
|
||||||
|
styleNonce int
|
||||||
|
iconsNonce int
|
||||||
|
|
||||||
root anyBox
|
root anyBox
|
||||||
focused anyBox
|
focused anyBox
|
||||||
@ -56,6 +60,7 @@ func (this *System) NewHierarchy (link WindowLink) *Hierarchy {
|
|||||||
needLayout: make(util.Set[anyBox]),
|
needLayout: make(util.Set[anyBox]),
|
||||||
needDraw: make(util.Set[anyBox]),
|
needDraw: make(util.Set[anyBox]),
|
||||||
}
|
}
|
||||||
|
this.hierarchies.Add(hierarchy)
|
||||||
return hierarchy
|
return hierarchy
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,7 +90,7 @@ func (this *Hierarchy) Empty () bool {
|
|||||||
// draw to. The Hierarchy will use the canvas.Canvas's bounds to lay itself out.
|
// draw to. The Hierarchy will use the canvas.Canvas's bounds to lay itself out.
|
||||||
func (this *Hierarchy) SetCanvas (can canvas.Canvas) {
|
func (this *Hierarchy) SetCanvas (can canvas.Canvas) {
|
||||||
this.canvas = can
|
this.canvas = can
|
||||||
if this.root != nil { this.root.loseCanvas() }
|
if this.root != nil { this.root.recursiveLoseCanvas() }
|
||||||
this.needRedo = true
|
this.needRedo = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,6 +140,23 @@ func (this *Hierarchy) AfterEvent () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Close closes the Hierarchy. This should be called when the Window that
|
||||||
|
// contains it has been closed.
|
||||||
|
func (this *Hierarchy) Close () {
|
||||||
|
this.system.removeHierarchy(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *Hierarchy) setStyle (style tomo.Style) {
|
||||||
|
this.style = style
|
||||||
|
this.styleNonce ++
|
||||||
|
if this.root != nil { this.root.recursiveReApply() }
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *Hierarchy) setIcons (icons tomo.Icons) {
|
||||||
|
this.iconsNonce ++
|
||||||
|
if this.root != nil { this.root.recursiveReApply() }
|
||||||
|
}
|
||||||
|
|
||||||
func (this *Hierarchy) getHierarchy () *Hierarchy {
|
func (this *Hierarchy) getHierarchy () *Hierarchy {
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
@ -143,6 +165,18 @@ func (this *Hierarchy) getWindow () tomo.Window {
|
|||||||
return this.link.GetWindow()
|
return this.link.GetWindow()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *Hierarchy) getStyle () tomo.Style {
|
||||||
|
return this.style
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *Hierarchy) getStyleNonce () int {
|
||||||
|
return this.styleNonce
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *Hierarchy) getIconsNonce () int {
|
||||||
|
return this.iconsNonce
|
||||||
|
}
|
||||||
|
|
||||||
func (this *Hierarchy) getCanvas () canvas.Canvas {
|
func (this *Hierarchy) getCanvas () canvas.Canvas {
|
||||||
return this.canvas
|
return this.canvas
|
||||||
}
|
}
|
||||||
|
@ -51,13 +51,17 @@ type anyBox interface {
|
|||||||
|
|
||||||
// flushActionQueue performs any queued actions, like invalidating the
|
// flushActionQueue performs any queued actions, like invalidating the
|
||||||
// minimum size or grabbing input focus.
|
// minimum size or grabbing input focus.
|
||||||
flushActionQueue ()
|
flushActionQueue ()
|
||||||
// recursiveRedo recursively recalculates the minimum size, layout, and
|
// recursiveRedo recursively recalculates the minimum size, layout, and
|
||||||
// re-paints this anyBox and all of its children.
|
// re-paints this anyBox and all of its children.
|
||||||
recursiveRedo ()
|
recursiveRedo ()
|
||||||
// loseCanvas causes this anyBox and its children (if applicable) to
|
// loseCanvas causes this anyBox and its children (if applicable) to
|
||||||
// lose their canvases and re-cut them as needed.
|
// lose their canvases and re-cut them as needed.
|
||||||
loseCanvas ()
|
recursiveLoseCanvas ()
|
||||||
|
// recursiveReAppply causes this anyBox and its children (if applicable)
|
||||||
|
// to check whether they have an outdated style or icon set, and if so,
|
||||||
|
// update it and trigger the appropriate event broadcasters.
|
||||||
|
recursiveReApply ()
|
||||||
|
|
||||||
// contentMinimum returns the minimum dimensions of this box's content
|
// contentMinimum returns the minimum dimensions of this box's content
|
||||||
contentMinimum () image.Point
|
contentMinimum () image.Point
|
||||||
@ -81,19 +85,19 @@ type anyBox interface {
|
|||||||
propagate (func (anyBox) bool) bool
|
propagate (func (anyBox) bool) bool
|
||||||
propagateAlt (func (anyBox) bool) bool
|
propagateAlt (func (anyBox) bool) bool
|
||||||
|
|
||||||
handleFocusEnter ()
|
handleFocusEnter ()
|
||||||
handleFocusLeave ()
|
handleFocusLeave ()
|
||||||
// handleDndEnter ()
|
// handleDndEnter ()
|
||||||
// handleDndLeave ()
|
// handleDndLeave ()
|
||||||
// handleDndDrop (data.Data)
|
// handleDndDrop (data.Data)
|
||||||
handleMouseEnter ()
|
handleMouseEnter ()
|
||||||
handleMouseLeave ()
|
handleMouseLeave ()
|
||||||
handleMouseMove ()
|
handleMouseMove ()
|
||||||
handleMouseDown (input.Button)
|
handleMouseDown (input.Button)
|
||||||
handleMouseUp (input.Button)
|
handleMouseUp (input.Button)
|
||||||
handleScroll (float64, float64)
|
handleScroll (float64, float64)
|
||||||
handleKeyDown (input.Key, bool)
|
handleKeyDown (input.Key, bool)
|
||||||
handleKeyUp (input.Key, bool)
|
handleKeyUp (input.Key, bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
func assertAnyBox (unknown tomo.Box) anyBox {
|
func assertAnyBox (unknown tomo.Box) anyBox {
|
||||||
|
@ -2,12 +2,15 @@ package system
|
|||||||
|
|
||||||
import "io"
|
import "io"
|
||||||
import "image"
|
import "image"
|
||||||
|
import "git.tebibyte.media/tomo/tomo"
|
||||||
import "git.tebibyte.media/tomo/tomo/canvas"
|
import "git.tebibyte.media/tomo/tomo/canvas"
|
||||||
|
import "git.tebibyte.media/tomo/backend/internal/util"
|
||||||
|
|
||||||
// System is coupled to a tomo.Backend implementation, and manages Hierarchies
|
// System is coupled to a tomo.Backend implementation, and manages Hierarchies
|
||||||
// and Boxes.
|
// and Boxes.
|
||||||
type System struct {
|
type System struct {
|
||||||
link BackendLink
|
link BackendLink
|
||||||
|
hierarchies util.Set[*Hierarchy]
|
||||||
}
|
}
|
||||||
|
|
||||||
// BackendLink allows the System to call up into the tomo.Backend implementation
|
// BackendLink allows the System to call up into the tomo.Backend implementation
|
||||||
@ -30,6 +33,26 @@ type SurfaceLink interface {
|
|||||||
// New creates a new System.
|
// New creates a new System.
|
||||||
func New (link BackendLink) *System {
|
func New (link BackendLink) *System {
|
||||||
return &System {
|
return &System {
|
||||||
link: link,
|
link: link,
|
||||||
|
hierarchies: make(util.Set[*Hierarchy]),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetStyle sets the tomo.Style that is applied to objects, and notifies them
|
||||||
|
// that the style has changed.
|
||||||
|
func (this *System) SetStyle (style tomo.Style) {
|
||||||
|
for hierarchy := range this.hierarchies {
|
||||||
|
hierarchy.setStyle(style)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetIcons notifies objects that the icons have changed.
|
||||||
|
func (this *System) SetIcons (icons tomo.Icons) {
|
||||||
|
for hierarchy := range this.hierarchies {
|
||||||
|
hierarchy.setIcons(icons)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *System) removeHierarchy (hierarchy *Hierarchy) {
|
||||||
|
delete(this.hierarchies, hierarchy)
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user