Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8546f11471 | |||
| 46f4c50381 | |||
| b88e32fa49 | |||
| 8f43fa310c | |||
| 20c7e0fdb1 | |||
| d8a8ad7e0a | |||
| 3feba5f811 | |||
| 75c654d4ae | |||
| da38e5411f | |||
| d47b525e42 | |||
| 862e08edf1 | |||
| 47b2231acd | |||
| b05e1f5d50 |
19
attribute.go
19
attribute.go
@@ -13,6 +13,8 @@ type Attr interface {
|
||||
attr ()
|
||||
}
|
||||
|
||||
// AttrKind enumerates all attribute kinds. There is one of these for each
|
||||
// attribute type.
|
||||
type AttrKind int; const (
|
||||
AttrKindColor AttrKind = iota
|
||||
AttrKindTexture
|
||||
@@ -28,6 +30,7 @@ type AttrKind int; const (
|
||||
AttrKindAlign
|
||||
AttrKindOverflow
|
||||
AttrKindLayout
|
||||
AttrKindCursor
|
||||
)
|
||||
|
||||
// AttrColor sets the background color of a box.
|
||||
@@ -58,6 +61,8 @@ type AttrAlign struct { X, Y Align }
|
||||
type AttrOverflow struct { X, Y bool }
|
||||
// AttrLayout sets the layout, if the box is a ContentBox.
|
||||
type AttrLayout struct { Layout }
|
||||
// AttrCursor sets the mouse cursor shape.
|
||||
type AttrCursor Cursor
|
||||
|
||||
// AColor is a convenience constructor for the color attribute.
|
||||
func AColor (col color.Color) AttrColor {
|
||||
@@ -115,6 +120,10 @@ func AOverflow (x, y bool) AttrOverflow {
|
||||
func ALayout (layout Layout) AttrLayout {
|
||||
return AttrLayout { Layout: layout }
|
||||
}
|
||||
// ACursor is a convenience constructor for the cursor attribute.
|
||||
func ACursor (cursor Cursor) AttrCursor {
|
||||
return AttrCursor(cursor)
|
||||
}
|
||||
|
||||
// Equals returns true if both attributes can reasonably be declared equal.
|
||||
func (this AttrColor) Equals (other Attr) bool {
|
||||
@@ -233,6 +242,14 @@ func (this AttrLayout) Equals (other Attr) bool {
|
||||
// two layouts cannot "reasonably" be declared equal
|
||||
return false
|
||||
}
|
||||
// Equals returns true if both attributes can reasonably be declared equal.
|
||||
func (this AttrCursor) Equals (other Attr) bool {
|
||||
if other, ok := other.(AttrCursor); ok {
|
||||
return this == other
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (AttrColor) Kind () AttrKind { return AttrKindColor }
|
||||
func (AttrTexture) Kind () AttrKind { return AttrKindTexture }
|
||||
@@ -248,6 +265,7 @@ func (AttrWrap) Kind () AttrKind { return AttrKindWrap }
|
||||
func (AttrAlign) Kind () AttrKind { return AttrKindAlign }
|
||||
func (AttrOverflow) Kind () AttrKind { return AttrKindOverflow }
|
||||
func (AttrLayout) Kind () AttrKind { return AttrKindLayout }
|
||||
func (AttrCursor) Kind () AttrKind { return AttrKindCursor }
|
||||
|
||||
func (AttrColor) attr () { }
|
||||
func (AttrTexture) attr () { }
|
||||
@@ -263,3 +281,4 @@ func (AttrWrap) attr () { }
|
||||
func (AttrAlign) attr () { }
|
||||
func (AttrOverflow) attr () { }
|
||||
func (AttrLayout) attr () { }
|
||||
func (AttrCursor) attr () { }
|
||||
|
||||
@@ -18,12 +18,7 @@ type Backend interface {
|
||||
NewContainerBox () ContainerBox
|
||||
|
||||
// NewWindow creates a normal Window and returns it.
|
||||
NewWindow (image.Rectangle) (Window, error)
|
||||
|
||||
// NewPlainWindow creates an undecorated window that does not appear in
|
||||
// window lists and returns it. This is intended for making things like
|
||||
// panels, docks, etc.
|
||||
NewPlainWindow (image.Rectangle) (Window, error)
|
||||
NewWindow (WindowKind, image.Rectangle) (Window, error)
|
||||
|
||||
// NewTexture creates a new texture from an image. The backend must
|
||||
// reject any texture that was not made by it.
|
||||
|
||||
15
config/config.go
Normal file
15
config/config.go
Normal file
@@ -0,0 +1,15 @@
|
||||
// Package config stores common configuration parameters. These are unmanaged,
|
||||
// and must be queried each time they are used. These are intended to be set by
|
||||
// things like application frameworks. Values set by objects or applications are
|
||||
// subject to being overridden.
|
||||
package config
|
||||
|
||||
import "time"
|
||||
|
||||
// DoubleClickDelay is the maximum amount of time that can pass between two
|
||||
// consecutive clicks for them to be considered a double-click.
|
||||
var DoubleClickDelay time.Duration = time.Second
|
||||
|
||||
// ScrollSpeed is how many units (pixels at a scale of 1.0) the content of a
|
||||
// ContentBox should be moved in response to a scroll delta of 1.0.
|
||||
var ScrollSpeed int = 16
|
||||
35
cursor.go
Normal file
35
cursor.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package tomo
|
||||
|
||||
// Cursor represents a mouse cursor shape.
|
||||
type Cursor string
|
||||
|
||||
// A list of standard cursor shapes. This is based off of the XDG Cursor
|
||||
// Conventions Specification
|
||||
// (https://www.freedesktop.org/wiki/Specifications/cursor-spec/)
|
||||
const (
|
||||
CursorUnknown Cursor = ""
|
||||
CursorDefault Cursor = "Default"
|
||||
CursorText Cursor = "Text"
|
||||
CursorPointer Cursor = "Pointer"
|
||||
CursorHelp Cursor = "Help"
|
||||
CursorProgress Cursor = "Progress"
|
||||
CursorWait Cursor = "Wait"
|
||||
CursorCopy Cursor = "Copy"
|
||||
CursorAlias Cursor = "Alias"
|
||||
CursorNoDrop Cursor = "NoDrop"
|
||||
CursorNotAllowed Cursor = "NotAllowed"
|
||||
CursorAllScroll Cursor = "AllScroll"
|
||||
CursorRowResize Cursor = "RowResize"
|
||||
CursorColResize Cursor = "ColResize"
|
||||
CursorEResize Cursor = "EResize"
|
||||
CursorNEResize Cursor = "NEResize"
|
||||
CursorNWResize Cursor = "NWResize"
|
||||
CursorNResize Cursor = "NResize"
|
||||
CursorSEResize Cursor = "SEResize"
|
||||
CursorSWResize Cursor = "SWResize"
|
||||
CursorSResize Cursor = "SResize"
|
||||
CursorWResize Cursor = "WResize"
|
||||
CursorVerticalText Cursor = "VerticalText"
|
||||
CursorCrosshair Cursor = "Crosshair"
|
||||
CursorCell Cursor = "Cell"
|
||||
)
|
||||
@@ -2,11 +2,36 @@
|
||||
// handlers.
|
||||
package event
|
||||
|
||||
import "io"
|
||||
import "errors"
|
||||
|
||||
// A cookie is returned when you add an event handler so you can remove it
|
||||
// later if you so choose.
|
||||
type Cookie interface {
|
||||
// Close removes the event handler this cookie is for.
|
||||
Close ()
|
||||
// later if you so choose. When the Close behavior is called, the handler must
|
||||
// be removed, even if an error is returned.
|
||||
type Cookie io.Closer
|
||||
|
||||
// FuncCookie is a cookie that calls a function (itself) when closed.
|
||||
type FuncCookie func () error
|
||||
func (cookie FuncCookie) Close () error { return cookie () }
|
||||
|
||||
// NoCookie is a cookie that does nothing when closed.
|
||||
type NoCookie struct { }
|
||||
func (NoCookie) Close () error { return nil }
|
||||
|
||||
type multiCookie []Cookie
|
||||
|
||||
// MultiCookie creates a single cookie that, when closed, closes a list of other
|
||||
// cookies.
|
||||
func MultiCookie (cookies ...Cookie) Cookie {
|
||||
return multiCookie(cookies)
|
||||
}
|
||||
|
||||
func (cookies multiCookie) Close () error {
|
||||
errs := make([]error, len(cookies))
|
||||
for index, cookie := range cookies {
|
||||
errs[index] = cookie.Close()
|
||||
}
|
||||
return errors.Join(errs...)
|
||||
}
|
||||
|
||||
// Broadcaster manages event listeners.
|
||||
@@ -31,9 +56,9 @@ func (broadcaster *Broadcaster[L]) Listeners () map[int] L {
|
||||
return broadcaster.listeners
|
||||
}
|
||||
|
||||
func (broadcaster *Broadcaster[L]) newCookie () cookie[L] {
|
||||
func (broadcaster *Broadcaster[L]) newCookie () broadcasterCookie[L] {
|
||||
broadcaster.lastID ++
|
||||
return cookie[L] {
|
||||
return broadcasterCookie[L] {
|
||||
id: broadcaster.lastID,
|
||||
broadcaster: broadcaster,
|
||||
}
|
||||
@@ -45,17 +70,14 @@ func (broadcaster *Broadcaster[L]) ensure () {
|
||||
}
|
||||
}
|
||||
|
||||
// NoCookie is a cookie that does nothing when closed.
|
||||
type NoCookie struct { }
|
||||
func (NoCookie) Close () { }
|
||||
|
||||
type cookie[L any] struct {
|
||||
type broadcasterCookie[L any] struct {
|
||||
id int
|
||||
broadcaster *Broadcaster[L]
|
||||
}
|
||||
|
||||
func (cookie cookie[L]) Close () {
|
||||
func (cookie broadcasterCookie[L]) Close () error {
|
||||
delete(cookie.broadcaster.listeners, cookie.id)
|
||||
return nil
|
||||
}
|
||||
|
||||
// FuncBroadcaster is a broadcaster that manages functions with no arguments.
|
||||
@@ -69,17 +91,3 @@ func (broadcaster *FuncBroadcaster) Broadcast () {
|
||||
listener()
|
||||
}
|
||||
}
|
||||
|
||||
type multiCookie []Cookie
|
||||
|
||||
// MultiCookie creates a single cookie that, when closed, closes a list of other
|
||||
// cookies.
|
||||
func MultiCookie (cookies ...Cookie) Cookie {
|
||||
return multiCookie(cookies)
|
||||
}
|
||||
|
||||
func (cookies multiCookie) Close () {
|
||||
for _, cookie := range cookies {
|
||||
cookie.Close()
|
||||
}
|
||||
}
|
||||
|
||||
2
icon.go
2
icon.go
@@ -93,7 +93,7 @@ const (
|
||||
IconListRemove Icon = "ListRemove"
|
||||
IconListChoose Icon = "ListChoose"
|
||||
IconListExpand Icon = "ListExpand"
|
||||
IconListContract Icon = "ListExpand"
|
||||
IconListContract Icon = "ListContract"
|
||||
// actions: mail
|
||||
IconMailForward Icon = "MailForward"
|
||||
IconMailMarkImportant Icon = "MailMarkImportant"
|
||||
|
||||
46
object.go
46
object.go
@@ -283,6 +283,32 @@ type BoxArranger interface {
|
||||
SetBounds (index int, bounds image.Rectangle)
|
||||
}
|
||||
|
||||
// WindowKind specifies a window's kind, which determines how it is displayed
|
||||
// and managed by the operating system.
|
||||
type WindowKind string; const (
|
||||
// Normal is a normal window.
|
||||
WindowKindNormal WindowKind = "Normal"
|
||||
// Plain is an undecorated window that does not appear in window lists.
|
||||
// It is intended for things like docks, panels, etc.
|
||||
WindowKindPlain WindowKind = "Plain"
|
||||
// Utility is a small window for toolboxes, command palletes, etc. It is
|
||||
// usually given special styling and management by the OS.
|
||||
WindowKindUtility WindowKind = "Utility"
|
||||
// Toolbar is a small window for menus and window panes which have been
|
||||
// "torn off" from their main window or position. It is usually given
|
||||
// special styling and management by the OS.
|
||||
WindowKindToolbar WindowKind = "Toolbar"
|
||||
// Menu is an undecorated window for drop down menus, context menus,
|
||||
// etc. It closes once the user interacts outside of it.
|
||||
WindowKindMenu WindowKind = "Menu"
|
||||
// Modal, while open, blocks all user input from reaching its parent
|
||||
// window, forcing the user's attention. It is usually given special
|
||||
// styling and management by the OS. Note that in some environments it
|
||||
// will not be given window controls, so it should contain some "Close"
|
||||
// or "Cancel" button.
|
||||
WindowKindModal WindowKind = "Modal"
|
||||
)
|
||||
|
||||
// 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.
|
||||
@@ -310,15 +336,8 @@ type Window interface {
|
||||
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)
|
||||
// linked to it via some other means.
|
||||
NewChild (WindowKind, image.Rectangle) (Window, error)
|
||||
// Modifiers returns which modifier keys on the keyboard are currently
|
||||
// being held down.
|
||||
Modifiers () input.Modifiers
|
||||
@@ -335,8 +354,13 @@ type Window interface {
|
||||
SetVisible (bool)
|
||||
// Visible returns whether or not this window is visible.
|
||||
Visible () bool
|
||||
// Close closes the window.
|
||||
Close ()
|
||||
// Close closes the window. This does not trigger the TryClose event.
|
||||
Close () error
|
||||
// OnTryClose specifies a function to be called when the user attempts
|
||||
// to close the window. If any registered handlers returns false, the
|
||||
// window will not be closed. This can be used to display some sort of
|
||||
// "Unsaved changes" warning to the user.
|
||||
OnTryClose (func () bool) event.Cookie
|
||||
// OnClose specifies a function to be called when the window is closed.
|
||||
OnClose (func ()) event.Cookie
|
||||
}
|
||||
|
||||
12
tomo.go
12
tomo.go
@@ -42,17 +42,9 @@ func Do (callback func ()) {
|
||||
}
|
||||
|
||||
// NewWindow creates and returns a window within the specified bounds on screen.
|
||||
func NewWindow (bounds image.Rectangle) (Window, error) {
|
||||
func NewWindow (kind WindowKind, bounds image.Rectangle) (Window, error) {
|
||||
assertBackend()
|
||||
return backend.NewWindow(bounds)
|
||||
}
|
||||
|
||||
// NewPlainWindow is like NewWindow, but it creates an undecorated window that
|
||||
// does not appear in window lists. It is intended for creating things like
|
||||
// docks, panels, etc.
|
||||
func NewPlainWindow (bounds image.Rectangle) (Window, error) {
|
||||
assertBackend()
|
||||
return backend.NewPlainWindow(bounds)
|
||||
return backend.NewWindow(kind, bounds)
|
||||
}
|
||||
|
||||
// NewBox creates and returns a basic Box.
|
||||
|
||||
Reference in New Issue
Block a user