diff --git a/element.go b/element.go index b86a876..5045462 100644 --- a/element.go +++ b/element.go @@ -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. diff --git a/entity.go b/entity.go new file mode 100644 index 0000000..27bddab --- /dev/null +++ b/entity.go @@ -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) +} diff --git a/layout.go b/layout.go deleted file mode 100644 index 0eff659..0000000 --- a/layout.go +++ /dev/null @@ -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, - ) -} diff --git a/parent.go b/parent.go deleted file mode 100644 index 57aa45d..0000000 --- a/parent.go +++ /dev/null @@ -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) -}