tomo/object.go

192 lines
5.0 KiB
Go

package tomo
import "image"
import "image/color"
import "golang.org/x/image/font"
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"
type Gap image.Point
// Side represents one side of a rectangle.
type Side int; const (
SideTop Side = iota
SideRight
SideBottom
SideLeft
)
type Inset [4]int
// I allows you to create an inset in a CSS-ish way:
//
// - One argument: all sides are set to this value
// - Two arguments: the top and bottom sides are set to the first value, and
// the left and right sides are set to the second value.
// - Three arguments: the top side is set by the first value, the left and
// right sides are set by the second vaue, and the bottom side is set by the
// third value.
// - Four arguments: each value corresponds to a side.
//
// This function will panic if an argument count that isn't one of these is
// given.
func I (sides ...int) Inset {
switch len(sides) {
case 1: return Inset { sides[0], sides[0], sides[0], sides[0] }
case 2: return Inset { sides[0], sides[1], sides[0], sides[1] }
case 3: return Inset { sides[0], sides[1], sides[2], sides[1] }
case 4: return Inset { sides[0], sides[1], sides[2], sides[3] }
default: panic("I: illegal argument count.")
}
}
// Apply returns the given rectangle, shrunk on all four sides by the given
// inset. If a measurment of the inset is negative, that side will instead be
// expanded outward. If the rectangle's dimensions cannot be reduced any
// further, an empty rectangle near its center will be returned.
func (inset Inset) Apply (bigger image.Rectangle) (smaller image.Rectangle) {
smaller = bigger
if smaller.Dx() < inset[3] + inset[1] {
smaller.Min.X = (smaller.Min.X + smaller.Max.X) / 2
smaller.Max.X = smaller.Min.X
} else {
smaller.Min.X += inset[3]
smaller.Max.X -= inset[1]
}
if smaller.Dy() < inset[0] + inset[2] {
smaller.Min.Y = (smaller.Min.Y + smaller.Max.Y) / 2
smaller.Max.Y = smaller.Min.Y
} else {
smaller.Min.Y += inset[0]
smaller.Max.Y -= inset[2]
}
return
}
// Inverse returns a negated version of the inset.
func (inset Inset) Inverse () (prime Inset) {
return Inset {
inset[0] * -1,
inset[1] * -1,
inset[2] * -1,
inset[3] * -1,
}
}
// Horizontal returns the sum of SideRight and SideLeft.
func (inset Inset) Horizontal () int {
return inset[SideRight] + inset[SideLeft]
}
// Vertical returns the sum of SideTop and SideBottom.
func (inset Inset) Vertical () int {
return inset[SideTop] + inset[SideBottom]
}
type Border struct {
Width Inset
Color [4]color.Color
}
type Align int; const (
AlignStart Align = iota // similar to left-aligned text
AlignMiddle // similar to center-aligned text
AlignEnd // similar to right-aligned text
AlignEven // similar to justified text
)
type Object interface {
Box () Box
}
type Box interface {
Object
Bounds () image.Rectangle
InnerBounds () image.Rectangle
SetBounds (image.Rectangle)
SetColor (color.Color)
SetBorder (...Border)
SetMinimumSize (int, int)
SetPadding (Inset)
SetDNDData (data.Data)
SetDNDAccept (...data.Mime)
SetFocused (bool)
SetFocusable (bool)
Focused () bool
Modifiers (func ()) input.Modifiers
MousePosition (func ()) image.Point
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
ContentBounds () image.Rectangle
ScrollTo (image.Point)
OnContentBoundsChange (func ()) event.Cookie
}
type TextBox interface {
Box
SetTextColor (color.Color)
SetFace (font.Face)
SetHAlign (Align)
SetVAlign (Align)
}
type CanvasBox interface {
Box
SetDrawer (canvas.Drawer)
Invalidate ()
}
type ContainerBox interface {
Box
SetGap (Gap)
Add (Object)
Delete (Object)
Insert (child Object, before Object)
Clear ()
Length () int
At (int) Object
SetLayout (Layout)
}
type Window interface {
SetRoot (Object)
SetTitle (string)
SetIcon (sizes []image.Image)
NewMenu (image.Rectangle) (Window, error)
NewModal (image.Rectangle) (Window, error)
Widget () (Window, error)
Copy (data.Data)
Paste (callback func (data.Data, error), accept ...data.Mime)
Show ()
Hide ()
Close ()
OnClose (func ()) event.Cookie
}
type MainWindow interface {
Window
NewChild (image.Rectangle) (Window, error)
}
type Layout interface {
Arrange (image.Rectangle, Gap, []Box)
}