tomo/object.go

349 lines
14 KiB
Go

package tomo
import "image"
import "image/color"
import "golang.org/x/image/font"
import "git.tebibyte.media/tomo/tomo/text"
import "git.tebibyte.media/tomo/tomo/data"
import "git.tebibyte.media/tomo/tomo/event"
import "git.tebibyte.media/tomo/tomo/input"
import "git.tebibyte.media/tomo/tomo/canvas"
// Object is any onscreen object that is linked to a box (or is that box).
// Unlike the Box interface and associated interfaces, Object implementations
// may originate from anywhere.
type Object interface {
GetBox () Box
}
// ContentObject is an object that has some kind of content.
type ContentObject interface {
Object
// ContentBounds returns the bounds of the inner content of the Box
// relative to the Box's InnerBounds.
ContentBounds () image.Rectangle
// ScrollTo shifts the origin of the Box's content to the origin of the
// Box's InnerBounds, offset by the given point.
ScrollTo (image.Point)
// OnContentBoundsChange specifies a function to be called when the
// Box's ContentBounds or InnerBounds changes.
OnContentBoundsChange (func ()) event.Cookie
}
// Box is a basic styled box. Implementations of Box, as well as any interface
// that embed Box, may only originate from a Backend.
type Box interface {
Object
// Window returns the Window this Box is a part of.
Window () Window
// Bounds returns the outer bounding rectangle of the Box relative to
// the Window.
Bounds () image.Rectangle
// InnerBounds returns the inner bounding rectangle of the box. It is
// the value of Bounds inset by the Box's border and padding.
InnerBounds () image.Rectangle
// MinimumSize returns the minimum width and height this Box's bounds
// can be set to. This will return the value of whichever of these is
// greater:
// - The size as set by SetMinimumSize
// - The size taken up by the Box's border and padding. If there is
// internal content that does not overflow, the size of that is also
// taken into account here.
MinimumSize () image.Point
// Role returns this Box's role as set by SetRole.
Role () Role
// SetBounds sets the bounding rectangle of this Box relative to the
// Window.
SetBounds (image.Rectangle)
// SetColor sets the background color of this Box.
SetColor (color.Color)
// SetTextureTile sets a repeating background texture. If the texture is
// transparent, it will be overlayed atop the color specified by
// SetColor(). This will remove any previous texture set by this method
// or another method.
SetTextureTile (canvas.Texture)
// SetTextureCenter sets a centered background texture. If the texture
// is transparent, it will be overlayed atop the color specified by
// SetColor(). This will remove any previous texture set by this method
// or another method.
SetTextureCenter (canvas.Texture)
// SetBorder sets the Border(s) of the box. The first Border will be the
// most outset, and the last Border will be the most inset.
SetBorder (...Border)
// SetMinimumSize sets the minimum width and height of the box, as
// described in MinimumSize.
SetMinimumSize (image.Point)
// SetPadding sets the padding between the Box's innermost Border and
// its content.
SetPadding (Inset)
// SetRole sets what role this Box takes on. It is used to apply styling
// from a theme.
SetRole (Role)
// SetDNDData sets the data that will be picked up if this Box is
// dragged. If this is nil (which is the default), this Box will not be
// picked up.
SetDNDData (data.Data)
// SetDNDAccept sets the type of data that can be dropped onto this Box.
// If this is nil (which is the default), this Box will reject all
// drops.
SetDNDAccept (...data.Mime)
// SetFocused sets whether or not this Box has keyboard focus. If set to
// true, this method will steal focus away from whichever Object
// currently has focus.
SetFocused (bool)
// SetFocusable sets whether or not this Box can receive keyboard focus.
// If set to false and the Box is already focused. the focus is removed.
SetFocusable (bool)
// Focused returns whether or not this Box has keyboard focus.
Focused () bool
// Modifiers returns which modifier keys on the keyboard are currently
// being held down.
Modifiers () input.Modifiers
// MousePosition returns the position of the mouse pointer relative to
// the Window.
MousePosition () image.Point
// These are event subscription functions that allow callbacks to be
// connected to particular events. Multiple callbacks may be connected
// to the same event at once. Callbacks can be removed by closing the
// returned cookie.
OnFocusEnter (func ()) event.Cookie
OnFocusLeave (func ()) event.Cookie
OnDNDEnter (func ()) event.Cookie
OnDNDLeave (func ()) event.Cookie
OnDNDDrop (func (data.Data)) event.Cookie
OnMouseEnter (func ()) event.Cookie
OnMouseLeave (func ()) event.Cookie
OnMouseMove (func ()) event.Cookie
OnMouseDown (func (input.Button)) event.Cookie
OnMouseUp (func (input.Button)) event.Cookie
OnScroll (func (deltaX, deltaY float64)) event.Cookie
OnKeyDown (func (key input.Key, numberPad bool)) event.Cookie
OnKeyUp (func (key input.Key, numberPad bool)) event.Cookie
OnStyleChange (func ()) event.Cookie
OnIconsChange (func ()) event.Cookie
}
// CanvasBox is a box that can be drawn to.
type CanvasBox interface {
Box
// SetDrawer sets the Drawer that will be called upon to draw the Box's
// content when it is invalidated. The Canvas passed to the drawer will
// have these properties:
// - It will have the same origin (0, 0) as the window which contains
// the CanvasBox
// - The Canvas bounds will describe the portion of the CanvasBox
// visible on screen
SetDrawer (canvas.Drawer)
// Invalidate causes the Box's area to be redrawn at the end of the
// event cycle, even if it wouldn't be otherwise.
Invalidate ()
}
// SurfaceBox is a box that can be drawn to via a hardware accelerated (or
// platform-specific) graphics context.
type SurfaceBox interface {
Box
// Surface returns the underlying graphics context. The result must be
// asserted to the expected type or passed through a type switch before
// use. The exact type returned here depends on the backend being used,
// and it is up to the application author to ensure that the application
// and backend agree on it. Applications should fail gracefully if the
// expected type was not found.
Surface () any
// Invalidate causes the data within the surface to be pushed to the
// screen at the end of the event cycle, even if it wouldn't be
// otherwise.
Invalidate ()
// OnSizeChange specifies a function to be called when the size of the
// Box is changed, or the surface is re-allocated. The application must
// call Surface() each time this event fires in order to not draw to a
// closed surface.
OnSizeChange (func ())
}
// ContentBox is a box that has some kind of content.
type ContentBox interface {
Box
// SetOverflow sets whether or not the Box's content overflows
// horizontally and vertically. Overflowing content is clipped to the
// bounds of the Box inset by all Borders (but not padding).
SetOverflow (horizontal, vertical bool)
// SetAlign sets how the Box's content is distributed horizontally and
// vertically.
SetAlign (x, y Align)
// ContentBounds returns the bounds of the inner content of the Box
// relative to the Box's InnerBounds.
ContentBounds () image.Rectangle
// RecommendedHeight returns the recommended height for a given width,
// if supported by the current content or layout. Otherwise, it should
// just return the minimum height.
RecommendedHeight (width int) int
// RecommendedWidth returns the recommended width for a given height, if
// supported by the current content or layout. Otherwise, it should just
// return the minimum width.
RecommendedWidth (height int) int
// ScrollTo shifts the origin of the Box's content to the origin of the
// Box's InnerBounds, offset by the given point.
ScrollTo (image.Point)
// OnContentBoundsChange specifies a function to be called when the
// Box's ContentBounds or InnerBounds changes.
OnContentBoundsChange (func ()) event.Cookie
}
// TextBox is a box that contains text content.
type TextBox interface {
ContentBox
// SetText sets the text content of the Box.
SetText (string)
// SetTextColor sets the text color.
SetTextColor (color.Color)
// SetFace sets the font face text is rendered in.
SetFace (font.Face)
// SetWrap sets whether or not the text wraps.
SetWrap (bool)
// SetSelectable sets whether or not the text content can be
// highlighted/selected.
SetSelectable (bool)
// SetDotColor sets the highlight color of selected text.
SetDotColor (color.Color)
// Select sets the text cursor or selection.
Select (text.Dot)
// Dot returns the text cursor or selection.
Dot () text.Dot
// OnDotChange specifies a function to be called when the text cursor or
// selection changes.
OnDotChange (func ()) event.Cookie
}
// ContentBox is a box that can contain child Objects. It arranges them
// according to a layout rule.
type ContainerBox interface {
ContentBox
// SetGap sets the gap between child Objects.
SetGap (image.Point)
// Add appends a child Object. If the object is already a child of
// another object, it will be removed from that object first.
Add (Object)
// Remove removes a child Object, if it is a child of this Box.
Remove (Object)
// Insert inserts a child Object before a specified Object. If the
// before Object is nil or is not contained within this Box, the
// inserted Object is appended.
Insert (child Object, before Object)
// Clear removes all child Objects.
Clear ()
// Length returns the amount of child Objects.
Length () int
// At returns the child Object at the specified index.
At (int) Object
// SetLayout sets the layout of this Box. Child Objects will be
// positioned according to it.
SetLayout (Layout)
// These methods control whether certain user input events get
// propagated to child Objects. If set to true, the relevant events will
// be sent to this container. If set to false (which is the default),
// the events will be sent to the appropriate child Object.
CaptureDND (bool)
CaptureMouse (bool)
CaptureScroll (bool)
CaptureKeyboard (bool)
}
// LayoutHints are passed to a layout to tell it how to arrange child boxes.
type LayoutHints struct {
// Bounds is the bounding rectangle that children should be placed
// within. Any padding values are already applied.
Bounds image.Rectangle
// OverflowX and OverflowY control whether child Boxes may be positioned
// outside of Bounds.
OverflowX bool
OverflowY bool
// AlignX and AlignY control how child Boxes are aligned horizontally
// and vertically. The effect of this may vary depending on the Layout.
AlignX Align
AlignY Align
// Gap controls the amount of horizontal and vertical spacing in-between
// child Boxes.
Gap image.Point
}
// A Layout can be given to a ContainerBox to arrange child objects.
type Layout interface {
// MinimumSize returns the minimum width and height of
// LayoutHints.Bounds needed to properly lay out all child Boxes.
MinimumSize (LayoutHints, []Box) image.Point
// Arrange arranges child boxes according to the given LayoutHints.
Arrange (LayoutHints, []Box)
// RecommendedHeight returns the recommended height for a given width,
// if supported. Otherwise, it should just return the minimum height.
// The result of this behavior may or may not be respected, depending on
// the situation.
RecommendedHeight (LayoutHints, []Box, int) int
// RecommendedWidth returns the recommended width for a given height, if
// supported. Otherwise, it should just return the minimum width. The
// result of this behavior may or may not be respected, depending on the
// situation.
RecommendedWidth (LayoutHints, []Box, int) int
}
// Window is an operating system window. It can contain one object. Windows
// themselves are completely transparent, and become opaque once an opaque
// object is added as their root.
type Window interface {
// SetRoot sets the root child of the window. There can only be one at
// a time, and setting it will remove the current child if there is one.
SetRoot (Object)
// SetTitle sets the title of the window.
SetTitle (string)
// SetIcon sets the icon of the window. When multiple icon sizes are
// provided, the best fitting one is chosen for display.
SetIcon (... canvas.Texture)
// SetResizable sets whether the window can be resized by the user in
// the X and Y directions. If one or both axes are false, the ones that
// are will be shrunk to the window's minimum size.
SetResizable (x, y bool)
// SetBounds sets this window's bounds. This may or may not have any
// effect on the window's position on screen depending on the platform.
SetBounds (image.Rectangle)
// NewChild creates a new window that is semantically a child of this
// window. It does not actually reside within this window, but it may be
// linked to it via some other means. This is intended for things like
// toolboxes and tear-off menus.
NewChild (image.Rectangle) (Window, error)
// NewMenu creates a new menu window. This window is undecorated and
// will close once the user clicks outside of it.
NewMenu (image.Rectangle) (Window, error)
// NewModal creates a new modal window that blocks all input to this
// window until it is closed.
NewModal (image.Rectangle) (Window, error)
// Copy copies data to the clipboard.
Copy (data.Data)
// Paste reads data from the clipboard. When the data is available or an
// error has occurred, the provided function will be called.
Paste (callback func (data.Data, error), accept ...data.Mime)
// SetVisible sets whether or not this window is visible. Windows are
// invisible by default.
SetVisible (bool)
// Visible returns whether or not this window is visible.
Visible () bool
// Close closes the window.
Close ()
// OnClose specifies a function to be called when the window is closed.
OnClose (func ()) event.Cookie
}