Overhauled the element interfaces
Instead of the previous parenting model where parents would set child callbacks during adoption by probing for callback setters, child elements will instead probe their parents for notify methods listed in the standard parent interfaces. This means that an element cannot be half-parented to something, nor can it be parented to two things at once. Parent elements may themselves fulfill these interfaces, or they can pass a hook that fulfills them to the child.
This commit is contained in:
parent
9d84c50db3
commit
b08cbea320
47
elements/container.go
Normal file
47
elements/container.go
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
package element
|
||||||
|
|
||||||
|
import "git.tebibyte.media/sashakoshka/tomo/input"
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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, direction input.KeynavDirection) (granted bool)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
@ -10,27 +10,26 @@ import "git.tebibyte.media/sashakoshka/tomo/config"
|
|||||||
type Element interface {
|
type Element interface {
|
||||||
// Bounds reports the element's bounding box. This must reflect the
|
// Bounds reports the element's bounding box. This must reflect the
|
||||||
// bounding last given to the element by DrawTo.
|
// bounding last given to the element by DrawTo.
|
||||||
Bounds () (bounds image.Rectangle)
|
Bounds () image.Rectangle
|
||||||
|
|
||||||
// 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 sets a function to be called when an area of the element is
|
|
||||||
// drawn on and should be pushed to the screen.
|
|
||||||
OnDamage (callback func (region canvas.Canvas))
|
|
||||||
|
|
||||||
// MinimumSize specifies the minimum amount of pixels this element's
|
// MinimumSize specifies the minimum amount of pixels this element's
|
||||||
// width and height may be set to. If the element is given a resize
|
// 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
|
// event with dimensions smaller than this, it will use its minimum
|
||||||
// instead of the offending dimension(s).
|
// instead of the offending dimension(s).
|
||||||
MinimumSize () (width, height int)
|
MinimumSize () (width, height int)
|
||||||
|
|
||||||
// OnMinimumSizeChange sets a function to be called when the element's
|
// SetParent sets the parent container of the element. This should only
|
||||||
// minimum size is changed.
|
// be called by the parent when the element is adopted. If parent is set
|
||||||
OnMinimumSizeChange (callback func ())
|
// 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))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Focusable represents an element that has keyboard navigation support. This
|
// Focusable represents an element that has keyboard navigation support. This
|
||||||
@ -41,7 +40,7 @@ type Focusable interface {
|
|||||||
|
|
||||||
// Focused returns whether or not this element or any of its children
|
// Focused returns whether or not this element or any of its children
|
||||||
// are currently focused.
|
// are currently focused.
|
||||||
Focused () (selected bool)
|
Focused () bool
|
||||||
|
|
||||||
// Focus focuses this element, if its parent element grants the
|
// Focus focuses this element, if its parent element grants the
|
||||||
// request.
|
// request.
|
||||||
@ -57,20 +56,6 @@ type Focusable interface {
|
|||||||
// HandleDeselection causes this element to mark itself and all of its
|
// HandleDeselection causes this element to mark itself and all of its
|
||||||
// children as unfocused.
|
// children as unfocused.
|
||||||
HandleUnfocus ()
|
HandleUnfocus ()
|
||||||
|
|
||||||
// OnFocusRequest sets a function to be called when this element wants
|
|
||||||
// its parent element to focus it. Parent elements should return true if
|
|
||||||
// the request was granted, and false if it was not. If the parent
|
|
||||||
// element returns true, the element must act as if a HandleFocus call
|
|
||||||
// was made with KeynavDirectionNeutral.
|
|
||||||
OnFocusRequest (func () (granted bool))
|
|
||||||
|
|
||||||
// OnFocusMotionRequest sets a function to be called when this
|
|
||||||
// element wants its parent element to focus the element behind or in
|
|
||||||
// front of it, depending on the specified direction. Parent elements
|
|
||||||
// should return true if the request was granted, and false if it was
|
|
||||||
// not.
|
|
||||||
OnFocusMotionRequest (func (direction input.KeynavDirection) (granted bool))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// KeyboardTarget represents an element that can receive keyboard input.
|
// KeyboardTarget represents an element that can receive keyboard input.
|
||||||
@ -93,9 +78,6 @@ type KeyboardTarget interface {
|
|||||||
type MouseTarget interface {
|
type MouseTarget interface {
|
||||||
Element
|
Element
|
||||||
|
|
||||||
// Each of these handler methods is passed the position of the mouse
|
|
||||||
// cursor at the time of the event as x, y.
|
|
||||||
|
|
||||||
// HandleMouseDown is called when a mouse button is pressed down on this
|
// HandleMouseDown is called when a mouse button is pressed down on this
|
||||||
// element.
|
// element.
|
||||||
HandleMouseDown (x, y int, button input.Button)
|
HandleMouseDown (x, y int, button input.Button)
|
||||||
@ -103,15 +85,25 @@ type MouseTarget interface {
|
|||||||
// HandleMouseUp is called when a mouse button is released that was
|
// HandleMouseUp is called when a mouse button is released that was
|
||||||
// originally pressed down on this element.
|
// originally pressed down on this element.
|
||||||
HandleMouseUp (x, y int, button input.Button)
|
HandleMouseUp (x, y int, button input.Button)
|
||||||
|
}
|
||||||
|
|
||||||
// HandleMouseMove is called when the mouse is moved over this element,
|
// MotionTarget represents an element that can receive mouse motion events.
|
||||||
|
type MotionTarget interface {
|
||||||
|
Element
|
||||||
|
|
||||||
|
// HandleMotion is called when the mouse is moved over this element,
|
||||||
// or the mouse is moving while being held down and originally pressed
|
// or the mouse is moving while being held down and originally pressed
|
||||||
// down on this element.
|
// down on this element.
|
||||||
HandleMouseMove (x, y int)
|
HandleMotion (x, y int)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ScrollTarget represents an element that can receive mouse scroll events.
|
||||||
|
type ScrollTarget interface {
|
||||||
|
Element
|
||||||
|
|
||||||
// HandleScroll is called when the mouse is scrolled. The X and Y
|
// HandleScroll is called when the mouse is scrolled. The X and Y
|
||||||
// direction of the scroll event are passed as deltaX and deltaY.
|
// direction of the scroll event are passed as deltaX and deltaY.
|
||||||
HandleMouseScroll (x, y int, deltaX, deltaY float64)
|
HandleScroll (x, y int, deltaX, deltaY float64)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flexible represents an element who's preferred minimum height can change in
|
// Flexible represents an element who's preferred minimum height can change in
|
||||||
@ -132,11 +124,7 @@ type Flexible interface {
|
|||||||
//
|
//
|
||||||
// It is important to note that if a parent container checks for
|
// It is important to note that if a parent container checks for
|
||||||
// flexible chilren, it itself will likely need to be flexible.
|
// flexible chilren, it itself will likely need to be flexible.
|
||||||
FlexibleHeightFor (width int) (height int)
|
FlexibleHeightFor (width int) int
|
||||||
|
|
||||||
// OnFlexibleHeightChange sets a function to be called when the
|
|
||||||
// parameters affecting this element's flexible height are changed.
|
|
||||||
OnFlexibleHeightChange (callback func ())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scrollable represents an element that can be scrolled. It acts as a viewport
|
// Scrollable represents an element that can be scrolled. It acts as a viewport
|
||||||
@ -145,11 +133,11 @@ type Scrollable interface {
|
|||||||
Element
|
Element
|
||||||
|
|
||||||
// ScrollContentBounds returns the full content size of the element.
|
// ScrollContentBounds returns the full content size of the element.
|
||||||
ScrollContentBounds () (bounds image.Rectangle)
|
ScrollContentBounds () image.Rectangle
|
||||||
|
|
||||||
// ScrollViewportBounds returns the size and position of the element's
|
// ScrollViewportBounds returns the size and position of the element's
|
||||||
// viewport relative to ScrollBounds.
|
// viewport relative to ScrollBounds.
|
||||||
ScrollViewportBounds () (bounds image.Rectangle)
|
ScrollViewportBounds () image.Rectangle
|
||||||
|
|
||||||
// ScrollTo scrolls the viewport to the specified point relative to
|
// ScrollTo scrolls the viewport to the specified point relative to
|
||||||
// ScrollBounds.
|
// ScrollBounds.
|
||||||
@ -157,10 +145,6 @@ type Scrollable interface {
|
|||||||
|
|
||||||
// ScrollAxes returns the supported axes for scrolling.
|
// ScrollAxes returns the supported axes for scrolling.
|
||||||
ScrollAxes () (horizontal, vertical bool)
|
ScrollAxes () (horizontal, vertical bool)
|
||||||
|
|
||||||
// OnScrollBoundsChange sets a function to be called when the element's
|
|
||||||
// ScrollContentBounds, ScrollViewportBounds, or ScrollAxes are changed.
|
|
||||||
OnScrollBoundsChange (callback func ())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collapsible represents an element who's minimum width and height can be
|
// Collapsible represents an element who's minimum width and height can be
|
||||||
|
@ -4,19 +4,20 @@ import "image"
|
|||||||
|
|
||||||
// Window represents a top-level container generated by the currently running
|
// Window represents a top-level container generated by the currently running
|
||||||
// backend. It can contain a single element. It is hidden by default, and must
|
// backend. It can contain a single element. It is hidden by default, and must
|
||||||
// be explicitly shown with the Show() method. If it contains no element, it
|
// be explicitly shown with the Show() method.
|
||||||
// displays a black (or transprent) background.
|
|
||||||
type Window interface {
|
type Window interface {
|
||||||
|
Parent
|
||||||
|
|
||||||
// Adopt sets the root element of the window. There can only be one of
|
// Adopt sets the root element of the window. There can only be one of
|
||||||
// these at one time.
|
// these at one time.
|
||||||
Adopt (child Element)
|
Adopt (Element)
|
||||||
|
|
||||||
// Child returns the root element of the window.
|
// Child returns the root element of the window.
|
||||||
Child () (child Element)
|
Child () Element
|
||||||
|
|
||||||
// SetTitle sets the title that appears on the window's title bar. This
|
// SetTitle sets the title that appears on the window's title bar. This
|
||||||
// method might have no effect with some backends.
|
// method might have no effect with some backends.
|
||||||
SetTitle (title string)
|
SetTitle (string)
|
||||||
|
|
||||||
// SetIcon taks in a list different sizes of the same icon and selects
|
// SetIcon taks in a list different sizes of the same icon and selects
|
||||||
// the best one to display on the window title bar, dock, or whatever is
|
// the best one to display on the window title bar, dock, or whatever is
|
||||||
|
Reference in New Issue
Block a user