Updated the core tomo interfaces to support the ECS architecture

This commit is contained in:
Sasha Koshka 2023-04-12 23:21:34 -04:00
parent a51372bd7b
commit fa898be046
4 changed files with 125 additions and 150 deletions

View File

@ -6,54 +6,33 @@ import "git.tebibyte.media/sashakoshka/tomo/canvas"
// Element represents a basic on-screen object.
type Element interface {
// Bounds reports the element's bounding box. This must reflect the
// bounding last given to the element by DrawTo.
Bounds () image.Rectangle
// Bind assigns an Entity to this element.
Bind (Entity)
// MinimumSize specifies the minimum amount of pixels this element's
// width and height may be set to. If the element is given a resize
// event with dimensions smaller than this, it will use its minimum
// instead of the offending dimension(s).
MinimumSize () (width, height int)
// SetParent sets the parent container of the element. This should only
// be called by the parent when the element is adopted. If parent is set
// to nil, it will mark itself as not having a parent. If this method is
// passed a non-nil value and the element already has a parent, it will
// panic.
SetParent (Parent)
// DrawTo gives the element a canvas to draw on, along with a bounding
// box to be used for laying out the element. This should only be called
// by the parent element. This is typically a region of the parent
// element's canvas.
DrawTo (canvas canvas.Canvas, bounds image.Rectangle, onDamage func (region image.Rectangle))
// Draw causes the element to draw to the specified canvas. The bounds
// of this canvas specify the area that is actually drawn to, while the
// Entity bounds specify the actual area of the element.
Draw (canvas.Canvas)
}
// Focusable represents an element that has keyboard navigation support. This
// includes inputs, buttons, sliders, etc. as well as any elements that have
// children (so keyboard navigation events can be propagated downward).
// Container is an element capable of containing child elements.
type Container interface {
Element
// Layout causes this element to arrange its children.
Layout ()
// DrawBackground draws this element's background pattern at the
// specified bounds to any canvas.
DrawBackground (destination canvas.Canvas, bounds image.Rectangle)
}
// Focusable represents an element that has keyboard navigation support.
type Focusable interface {
Element
// Focused returns whether or not this element or any of its children
// are currently focused.
Focused () bool
// Focus focuses this element, if its parent element grants the
// request.
Focus ()
// HandleFocus causes this element to mark itself as focused. If the
// element does not have children, it is disabled, or there are no more
// selectable children in the given direction, it should return false
// and do nothing. Otherwise, it should select itself and any children
// (if applicable) and return true.
HandleFocus (direction input.KeynavDirection) (accepted bool)
// HandleDeselection causes this element to mark itself and all of its
// children as unfocused.
HandleUnfocus ()
// HandleFocusChange is called when the element is focused or unfocused.
HandleFocusChange ()
}
// KeyboardTarget represents an element that can receive keyboard input.

104
entity.go Normal file
View File

@ -0,0 +1,104 @@
package tomo
import "image"
// Entity is a handle given to elements by the backend. Different types of
// entities may be assigned to elements that support different capabilities.
type Entity interface {
// Invalidate marks the element's current visual as invalid. At the end
// of every event, the backend will ask all invalid entities to redraw
// themselves.
Invalidate ()
// Bounds returns the bounds of the element to be used for drawing and
// layout.
Bounds () image.Rectangle
// Window returns the window that the element is in.
Window () Window
// SetMinimumSize reports to the system what the element's minimum size
// can be. The minimum size of child elements should be taken into
// account when calculating this.
SetMinimumSize (width, height int)
// DrawBackground asks the parent element to draw its background pattern
// within the specified rectangle. This should be used for transparent
// elements like text labels.
DrawBackground (bounds image.Rectangle)
}
// ContainerEntity is given to elements that support the Container interface.
type ContainerEntity interface {
Entity
// Adopt adds an element as a child.
Adopt (child Element)
// Insert inserts an element in the child list at the specified
// location.
Insert (index int, child Element)
// Disown removes the child at the specified index.
Disown (index int)
// IndexOf returns the index of the specified child.
IndexOf (child Element) int
// Child returns the child at the specified index.
Child (index int) Element
// CountChildren returns the amount of children the element has.
CountChildren () int
// PlaceChild sets the size and position of the child at the specified
// index to a bounding rectangle.
PlaceChild (index int, bounds image.Rectangle)
// ChildMinimumSize returns the minimum size of the child at the
// specified index.
ChildMinimumSize (index int) (width, height int)
}
// FocusableEntity is given to elements that support the Focusable interface.
type FocusableEntity interface {
Entity
// Focused returns whether the element currently has input focus.
Focused () bool
// Focus sets this element as focused. If this succeeds, the element will
// recieve a HandleFocus call.
Focus ()
// FocusNext causes the focus to move to the next element. If this
// succeeds, the element will recieve a HandleUnfocus call.
FocusNext ()
// FocusPrevious causes the focus to move to the next element. If this
// succeeds, the element will recieve a HandleUnfocus call.
FocusPrevious ()
}
// FlexibleEntity is given to elements that support the Flexible interface.
type FlexibleEntity interface {
Entity
// NotifyFlexibleHeightChange notifies the system that the parameters
// affecting a child's flexible height have changed. This method is
// expected to be called by flexible child element when their content
// changes.
NotifyFlexibleHeightChange (child Flexible)
}
// ScrollableEntity is given to elements that support the Scrollable interface.
type ScrollableEntity interface {
Entity
// NotifyScrollBoundsChange notifies the parent that a child's scroll
// content bounds or viewport bounds have changed. This is expected to
// be called by child elements when they change their supported scroll
// axes, their scroll position (either autonomously or as a result of a
// call to ScrollTo()), or their content size.
NotifyScrollBoundsChange (child Scrollable)
}

View File

@ -1,37 +0,0 @@
package tomo
import "image"
import "git.tebibyte.media/sashakoshka/tomo/artist"
// LayoutEntry associates an element with layout and positioning information so
// it can be arranged by a Layout.
type LayoutEntry struct {
Element
Bounds image.Rectangle
Expand bool
}
// Layout is capable of arranging elements within a container. It is also able
// to determine the minimum amount of room it needs to do so.
type Layout interface {
// Arrange takes in a slice of entries and a bounding width and height,
// and changes the position of the entiries in the slice so that they
// are properly laid out. The given width and height should not be less
// than what is returned by MinimumSize.
Arrange (
entries []LayoutEntry,
margin image.Point,
padding artist.Inset,
bounds image.Rectangle,
)
// MinimumSize returns the minimum width and height that the layout
// needs to properly arrange the given slice of layout entries.
MinimumSize (
entries []LayoutEntry,
margin image.Point,
padding artist.Inset,
) (
width, height int,
)
}

View File

@ -1,71 +0,0 @@
package tomo
import "image"
// Parent represents a type capable of containing child elements.
type Parent interface {
// NotifyMinimumSizeChange notifies the container that a child element's
// minimum size has changed. This method is expected to be called by
// child elements when their minimum size changes.
NotifyMinimumSizeChange (child Element)
// Window returns the window containing the parent.
Window () Window
}
// FocusableParent represents a parent with keyboard navigation support.
type FocusableParent interface {
Parent
// RequestFocus notifies the parent that a child element is requesting
// keyboard focus. If the parent grants the request, the method will
// return true and the child element should behave as if a HandleFocus
// call was made.
RequestFocus (child Focusable) (granted bool)
// RequestFocusMotion notifies the parent that a child element wants the
// focus to be moved to the next focusable element.
RequestFocusNext (child Focusable)
// RequestFocusMotion notifies the parent that a child element wants the
// focus to be moved to the previous focusable element.
RequestFocusPrevious (child Focusable)
}
// FlexibleParent represents a parent that accounts for elements with
// flexible height.
type FlexibleParent interface {
Parent
// NotifyFlexibleHeightChange notifies the parent that the parameters
// affecting a child's flexible height have changed. This method is
// expected to be called by flexible child element when their content
// changes.
NotifyFlexibleHeightChange (child Flexible)
}
// ScrollableParent represents a parent that can change the scroll
// position of its child element(s).
type ScrollableParent interface {
Parent
// NotifyScrollBoundsChange notifies the parent that a child's scroll
// content bounds or viewport bounds have changed. This is expected to
// be called by child elements when they change their supported scroll
// axes, their scroll position (either autonomously or as a result of a
// call to ScrollTo()), or their content size.
NotifyScrollBoundsChange (child Scrollable)
}
// BackgroundParent represents a parent that is able to re-draw a portion of its
// background upon request. This is intended to be used by transparent elements
// that want to adopt their parent's background pattern. If a parent implements
// this interface, it should call a child's DrawTo method when its area of the
// background is affected.
type BackgroundParent interface {
Parent
// DrawBackground draws a portion of the parent's background pattern
// within the specified bounds. The parent will not push these changes.
DrawBackground (bounds image.Rectangle)
}