diff --git a/elements/container.go b/elements/container.go new file mode 100644 index 0000000..036c87b --- /dev/null +++ b/elements/container.go @@ -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) +} diff --git a/elements/element.go b/elements/element.go index 3df2466..5f6d298 100644 --- a/elements/element.go +++ b/elements/element.go @@ -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 diff --git a/elements/window.go b/elements/window.go index 618d795..95f0f0c 100644 --- a/elements/window.go +++ b/elements/window.go @@ -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