robust-parenting #12

Merged
sashakoshka merged 17 commits from robust-parenting into main 2023-03-15 22:34:08 -06:00
3 changed files with 84 additions and 52 deletions
Showing only changes of commit b08cbea320 - Show all commits

47
elements/container.go Normal file
View 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)
}

View File

@ -10,27 +10,26 @@ import "git.tebibyte.media/sashakoshka/tomo/config"
type Element interface {
// Bounds reports the element's bounding box. This must reflect the
// bounding last given to the element by DrawTo.
Bounds () (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))
Bounds () image.Rectangle
// 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)
// OnMinimumSizeChange sets a function to be called when the element's
// minimum size is changed.
OnMinimumSizeChange (callback func ())
// 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))
}
// 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
// are currently focused.
Focused () (selected bool)
Focused () bool
// Focus focuses this element, if its parent element grants the
// request.
@ -57,20 +56,6 @@ type Focusable interface {
// HandleDeselection causes this element to mark itself and all of its
// children as unfocused.
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.
@ -93,9 +78,6 @@ type KeyboardTarget interface {
type MouseTarget interface {
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
// element.
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
// originally pressed down on this element.
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
// 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
// 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
@ -132,11 +124,7 @@ type Flexible interface {
//
// It is important to note that if a parent container checks for
// flexible chilren, it itself will likely need to be flexible.
FlexibleHeightFor (width int) (height int)
// OnFlexibleHeightChange sets a function to be called when the
// parameters affecting this element's flexible height are changed.
OnFlexibleHeightChange (callback func ())
FlexibleHeightFor (width int) int
}
// Scrollable represents an element that can be scrolled. It acts as a viewport
@ -145,11 +133,11 @@ type Scrollable interface {
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
// viewport relative to ScrollBounds.
ScrollViewportBounds () (bounds image.Rectangle)
ScrollViewportBounds () image.Rectangle
// ScrollTo scrolls the viewport to the specified point relative to
// ScrollBounds.
@ -157,10 +145,6 @@ type Scrollable interface {
// ScrollAxes returns the supported axes for scrolling.
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

View File

@ -4,19 +4,20 @@ import "image"
// 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
// be explicitly shown with the Show() method. If it contains no element, it
// displays a black (or transprent) background.
// be explicitly shown with the Show() method.
type Window interface {
Parent
// Adopt sets the root element of the window. There can only be one of
// these at one time.
Adopt (child Element)
Adopt (Element)
// 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
// 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
// the best one to display on the window title bar, dock, or whatever is