From 69e73a7b84fa87df03edd16da1d923b7e6016dc7 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Tue, 2 May 2023 22:19:29 -0400 Subject: [PATCH] Add gitignore --- .gitignore | 1 + elements/box.go | 36 ++++++++++++++++-------------------- elements/button.go | 14 +++++--------- elements/cell.go | 14 ++++---------- elements/checkbox.go | 14 +++++--------- elements/combobox.go | 12 ++++-------- elements/container.go | 3 ++- elements/directory.go | 18 ++++++------------ elements/document.go | 21 +++++++-------------- elements/file.go | 15 ++------------- elements/icon.go | 7 ++----- elements/image.go | 6 +++--- elements/label.go | 13 ++++--------- elements/list.go | 24 +++++++----------------- elements/progressbar.go | 17 ++--------------- elements/scroll.go | 26 +++++++++++--------------- elements/scrollbar.go | 12 ++++-------- elements/slider.go | 14 ++++---------- elements/spacer.go | 12 +++--------- elements/switch.go | 13 ++++--------- elements/testing/mouse.go | 5 ++--- elements/textbox.go | 16 ++-------------- elements/togglebutton.go | 13 ++++--------- examples/drawing/main.go | 14 +++++++++----- 24 files changed, 113 insertions(+), 227 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/build diff --git a/elements/box.go b/elements/box.go index cdfcc21..d6d3288 100644 --- a/elements/box.go +++ b/elements/box.go @@ -2,9 +2,11 @@ package elements import "image" import "git.tebibyte.media/sashakoshka/tomo" -import "git.tebibyte.media/sashakoshka/tomo/canvas" +import "git.tebibyte.media/sashakoshka/tomo/artist" import "git.tebibyte.media/sashakoshka/tomo/shatter" -import "git.tebibyte.media/sashakoshka/tomo/default/theme" +import "git.tebibyte.media/sashakoshka/tomo/ability" + +var boxCase = tomo.C("tomo", "box") // Space is a list of spacing configurations that can be passed to some // containers. @@ -27,7 +29,6 @@ func (space Space) Includes (sub Space) bool { // complex layouts. type Box struct { container - theme theme.Wrapped padding bool margin bool vertical bool @@ -39,10 +40,9 @@ func NewHBox (space Space, children ...tomo.Element) (element *Box) { padding: space.Includes(SpacePadding), margin: space.Includes(SpaceMargin), } - element.entity = tomo.NewEntity(element).(tomo.ContainerEntity) + element.entity = tomo.GetBackend().NewEntity(element) element.minimumSize = element.updateMinimumSize element.init() - element.theme.Case = tomo.C("tomo", "box") element.Adopt(children...) return } @@ -54,16 +54,15 @@ func NewVBox (space Space, children ...tomo.Element) (element *Box) { margin: space.Includes(SpaceMargin), vertical: true, } - element.entity = tomo.NewEntity(element).(tomo.ContainerEntity) + element.entity = tomo.GetBackend().NewEntity(element) element.minimumSize = element.updateMinimumSize element.init() - element.theme.Case = tomo.C("tomo", "box") element.Adopt(children...) return } // Draw causes the element to draw to the specified destination canvas. -func (element *Box) Draw (destination canvas.Canvas) { +func (element *Box) Draw (destination artist.Canvas) { rocks := make([]image.Rectangle, element.entity.CountChildren()) for index := 0; index < element.entity.CountChildren(); index ++ { rocks[index] = element.entity.Child(index).Entity().Bounds() @@ -71,14 +70,14 @@ func (element *Box) Draw (destination canvas.Canvas) { tiles := shatter.Shatter(element.entity.Bounds(), rocks...) for _, tile := range tiles { - element.entity.DrawBackground(canvas.Cut(destination, tile)) + element.entity.DrawBackground(artist.Cut(destination, tile)) } } // Layout causes this element to perform a layout operation. func (element *Box) Layout () { - margin := element.theme.Margin(tomo.PatternBackground) - padding := element.theme.Padding(tomo.PatternBackground) + margin := element.entity.Theme().Margin(tomo.PatternBackground, boxCase) + padding := element.entity.Theme().Padding(tomo.PatternBackground, boxCase) bounds := element.entity.Bounds() if element.padding { bounds = padding.Apply(bounds) } @@ -128,22 +127,19 @@ func (element *Box) AdoptExpand (children ...tomo.Element) { // DrawBackground draws this element's background pattern to the specified // destination canvas. -func (element *Box) DrawBackground (destination canvas.Canvas) { +func (element *Box) DrawBackground (destination artist.Canvas) { element.entity.DrawBackground(destination) } -// SetTheme sets the element's theme. -func (element *Box) SetTheme (theme tomo.Theme) { - if theme == element.theme.Theme { return } - element.theme.Theme = theme +func (element *Box) HandleThemeChange () { element.updateMinimumSize() element.entity.Invalidate() element.entity.InvalidateLayout() } func (element *Box) freeSpace () (space float64, nExpanding float64) { - margin := element.theme.Margin(tomo.PatternBackground) - padding := element.theme.Padding(tomo.PatternBackground) + margin := element.entity.Theme().Margin(tomo.PatternBackground, boxCase) + padding := element.entity.Theme().Padding(tomo.PatternBackground, boxCase) var marginSize int; if element.vertical { marginSize = margin.Y @@ -176,8 +172,8 @@ func (element *Box) freeSpace () (space float64, nExpanding float64) { } func (element *Box) updateMinimumSize () { - margin := element.theme.Margin(tomo.PatternBackground) - padding := element.theme.Padding(tomo.PatternBackground) + margin := element.entity.Theme().Margin(tomo.PatternBackground, boxCase) + padding := element.entity.Theme().Padding(tomo.PatternBackground, boxCase) var breadth, size int var marginSize int; if element.vertical { marginSize = margin.Y diff --git a/elements/button.go b/elements/button.go index 4968843..7738712 100644 --- a/elements/button.go +++ b/elements/button.go @@ -3,22 +3,18 @@ package elements import "image" import "git.tebibyte.media/sashakoshka/tomo" import "git.tebibyte.media/sashakoshka/tomo/input" -import "git.tebibyte.media/sashakoshka/tomo/canvas" -import "git.tebibyte.media/sashakoshka/tomo/default/theme" -import "git.tebibyte.media/sashakoshka/tomo/default/config" +import "git.tebibyte.media/sashakoshka/tomo/artist" +import "git.tebibyte.media/sashakoshka/tomo/ability" import "git.tebibyte.media/sashakoshka/tomo/textdraw" // Button is a clickable button. type Button struct { - entity tomo.FocusableEntity + entity tomo.Entity drawer textdraw.Drawer enabled bool pressed bool text string - - config config.Wrapped - theme theme.Wrapped showText bool hasIcon bool @@ -30,7 +26,7 @@ type Button struct { // NewButton creates a new button with the specified label text. func NewButton (text string) (element *Button) { element = &Button { showText: true, enabled: true } - element.entity = tomo.NewEntity(element).(tomo.FocusableEntity) + element.entity = tomo.NewEntity(element).(buttonEntity) element.theme.Case = tomo.C("tomo", "button") element.drawer.SetFace (element.theme.FontFace ( tomo.FontStyleRegular, @@ -45,7 +41,7 @@ func (element *Button) Entity () tomo.Entity { } // Draw causes the element to draw to the specified destination canvas. -func (element *Button) Draw (destination canvas.Canvas) { +func (element *Button) Draw (destination artist.Canvas) { state := element.state() bounds := element.entity.Bounds() pattern := element.theme.Pattern(tomo.PatternButton, state) diff --git a/elements/cell.go b/elements/cell.go index f9da0db..7032706 100644 --- a/elements/cell.go +++ b/elements/cell.go @@ -1,22 +1,16 @@ package elements import "git.tebibyte.media/sashakoshka/tomo" -import "git.tebibyte.media/sashakoshka/tomo/canvas" import "git.tebibyte.media/sashakoshka/tomo/artist" -import "git.tebibyte.media/sashakoshka/tomo/default/theme" +import "git.tebibyte.media/sashakoshka/tomo/ability" -type cellEntity interface { - tomo.ContainerEntity - tomo.SelectableEntity -} // Cell is a single-element container that satisfies tomo.Selectable. It // provides styling based on whether or not it is selected. type Cell struct { - entity cellEntity + entity tomo.Entity child tomo.Element enabled bool - theme theme.Wrapped onSelectionChange func () } @@ -38,7 +32,7 @@ func (element *Cell) Entity () tomo.Entity { } // Draw causes the element to draw to the specified destination canvas. -func (element *Cell) Draw (destination canvas.Canvas) { +func (element *Cell) Draw (destination artist.Canvas) { bounds := element.entity.Bounds() pattern := element.theme.Pattern(tomo.PatternTableCell, element.state()) if element.child == nil { @@ -62,7 +56,7 @@ func (element *Cell) Layout () { // DrawBackground draws this element's background pattern to the specified // destination canvas. -func (element *Cell) DrawBackground (destination canvas.Canvas) { +func (element *Cell) DrawBackground (destination artist.Canvas) { element.theme.Pattern(tomo.PatternTableCell, element.state()). Draw(destination, element.entity.Bounds()) } diff --git a/elements/checkbox.go b/elements/checkbox.go index 10a5124..ed12272 100644 --- a/elements/checkbox.go +++ b/elements/checkbox.go @@ -3,14 +3,13 @@ package elements import "image" import "git.tebibyte.media/sashakoshka/tomo" import "git.tebibyte.media/sashakoshka/tomo/input" -import "git.tebibyte.media/sashakoshka/tomo/canvas" +import "git.tebibyte.media/sashakoshka/tomo/artist" +import "git.tebibyte.media/sashakoshka/tomo/ability" import "git.tebibyte.media/sashakoshka/tomo/textdraw" -import "git.tebibyte.media/sashakoshka/tomo/default/theme" -import "git.tebibyte.media/sashakoshka/tomo/default/config" // Checkbox is a toggle-able checkbox with a label. type Checkbox struct { - entity tomo.FocusableEntity + entity tomo.Entity drawer textdraw.Drawer enabled bool @@ -18,16 +17,13 @@ type Checkbox struct { checked bool text string - config config.Wrapped - theme theme.Wrapped - onToggle func () } // NewCheckbox creates a new cbeckbox with the specified label text. func NewCheckbox (text string, checked bool) (element *Checkbox) { element = &Checkbox { checked: checked, enabled: true } - element.entity = tomo.NewEntity(element).(tomo.FocusableEntity) + element.entity = tomo.NewEntity(element).(checkboxEntity) element.theme.Case = tomo.C("tomo", "checkbox") element.drawer.SetFace (element.theme.FontFace ( tomo.FontStyleRegular, @@ -42,7 +38,7 @@ func (element *Checkbox) Entity () tomo.Entity { } // Draw causes the element to draw to the specified destination canvas. -func (element *Checkbox) Draw (destination canvas.Canvas) { +func (element *Checkbox) Draw (destination artist.Canvas) { bounds := element.entity.Bounds() boxBounds := image.Rect(0, 0, bounds.Dy(), bounds.Dy()).Add(bounds.Min) diff --git a/elements/combobox.go b/elements/combobox.go index aa87bc5..549b827 100644 --- a/elements/combobox.go +++ b/elements/combobox.go @@ -3,9 +3,8 @@ package elements import "image" import "git.tebibyte.media/sashakoshka/tomo" import "git.tebibyte.media/sashakoshka/tomo/input" -import "git.tebibyte.media/sashakoshka/tomo/canvas" -import "git.tebibyte.media/sashakoshka/tomo/default/theme" -import "git.tebibyte.media/sashakoshka/tomo/default/config" +import "git.tebibyte.media/sashakoshka/tomo/artist" +import "git.tebibyte.media/sashakoshka/tomo/ability" import "git.tebibyte.media/sashakoshka/tomo/textdraw" // Option specifies a ComboBox option. A blank option will display as "(None)". @@ -21,7 +20,7 @@ func (option Option) Title () string { // ComboBox is an input that can be one of several predetermined values. type ComboBox struct { - entity tomo.FocusableEntity + entity tomo.Entity drawer textdraw.Drawer options []Option @@ -30,9 +29,6 @@ type ComboBox struct { enabled bool pressed bool - config config.Wrapped - theme theme.Wrapped - onChange func () } @@ -55,7 +51,7 @@ func (element *ComboBox) Entity () tomo.Entity { } // Draw causes the element to draw to the specified destination canvas. -func (element *ComboBox) Draw (destination canvas.Canvas) { +func (element *ComboBox) Draw (destination artist.Canvas) { state := element.state() bounds := element.entity.Bounds() pattern := element.theme.Pattern(tomo.PatternButton, state) diff --git a/elements/container.go b/elements/container.go index b8a7f61..c483d16 100644 --- a/elements/container.go +++ b/elements/container.go @@ -1,6 +1,7 @@ package elements import "git.tebibyte.media/sashakoshka/tomo" +import "git.tebibyte.media/sashakoshka/tomo/ability" type scratchEntry struct { expand bool @@ -9,7 +10,7 @@ type scratchEntry struct { } type container struct { - entity tomo.ContainerEntity + entity tomo.Entity scratch map[tomo.Element] scratchEntry minimumSize func () } diff --git a/elements/directory.go b/elements/directory.go index f1b19b7..7c5a882 100644 --- a/elements/directory.go +++ b/elements/directory.go @@ -4,18 +4,13 @@ import "image" import "path/filepath" import "git.tebibyte.media/sashakoshka/tomo" import "git.tebibyte.media/sashakoshka/tomo/input" -import "git.tebibyte.media/sashakoshka/tomo/canvas" +import "git.tebibyte.media/sashakoshka/tomo/artist" +import "git.tebibyte.media/sashakoshka/tomo/ability" import "git.tebibyte.media/sashakoshka/tomo/shatter" -import "git.tebibyte.media/sashakoshka/tomo/default/theme" // TODO: base on flow implementation of list. also be able to switch to a table // variant for a more information dense view. -type directoryEntity interface { - tomo.ContainerEntity - tomo.ScrollableEntity -} - type historyEntry struct { location string filesystem ReadDirStatFS @@ -25,8 +20,7 @@ type historyEntry struct { // file system. type Directory struct { container - entity directoryEntity - theme theme.Wrapped + entity tomo.Entity scroll image.Point contentBounds image.Rectangle @@ -57,7 +51,7 @@ func NewDirectory ( return } -func (element *Directory) Draw (destination canvas.Canvas) { +func (element *Directory) Draw (destination artist.Canvas) { rocks := make([]image.Rectangle, element.entity.CountChildren()) for index := 0; index < element.entity.CountChildren(); index ++ { rocks[index] = element.entity.Child(index).Entity().Bounds() @@ -158,7 +152,7 @@ func (element *Directory) HandleChildMouseUp ( child tomo.Element, ) { } -func (element *Directory) HandleChildFlexibleHeightChange (child tomo.Flexible) { +func (element *Directory) HandleChildFlexibleHeightChange (child ability.Flexible) { element.updateMinimumSize() element.entity.Invalidate() element.entity.InvalidateLayout() @@ -204,7 +198,7 @@ func (element *Directory) ScrollAxes () (horizontal, vertical bool) { return false, true } -func (element *Directory) DrawBackground (destination canvas.Canvas) { +func (element *Directory) DrawBackground (destination artist.Canvas) { element.theme.Pattern(tomo.PatternPinboard, tomo.State { }). Draw(destination, element.entity.Bounds()) } diff --git a/elements/document.go b/elements/document.go index 30a368a..7a23d50 100644 --- a/elements/document.go +++ b/elements/document.go @@ -2,26 +2,19 @@ package elements import "image" import "git.tebibyte.media/sashakoshka/tomo" -import "git.tebibyte.media/sashakoshka/tomo/canvas" +import "git.tebibyte.media/sashakoshka/tomo/artist" +import "git.tebibyte.media/sashakoshka/tomo/ability" import "git.tebibyte.media/sashakoshka/tomo/shatter" -import "git.tebibyte.media/sashakoshka/tomo/default/theme" - -type documentEntity interface { - tomo.ContainerEntity - tomo.ScrollableEntity -} // Document is a scrollable container capcable of laying out flexible child // elements. Children can be added either inline (similar to an HTML/CSS inline // element), or expanding (similar to an HTML/CSS block element). type Document struct { container - entity documentEntity + entity tomo.Entity scroll image.Point contentBounds image.Rectangle - - theme theme.Wrapped onScrollBoundsChange func () } @@ -30,7 +23,7 @@ type Document struct { func NewDocument (children ...tomo.Element) (element *Document) { element = &Document { } element.theme.Case = tomo.C("tomo", "document") - element.entity = tomo.NewEntity(element).(documentEntity) + element.entity = tomo.NewEntity(element) element.container.entity = element.entity element.minimumSize = element.updateMinimumSize element.init() @@ -39,7 +32,7 @@ func NewDocument (children ...tomo.Element) (element *Document) { } // Draw causes the element to draw to the specified destination canvas. -func (element *Document) Draw (destination canvas.Canvas) { +func (element *Document) Draw (destination artist.Canvas) { rocks := make([]image.Rectangle, element.entity.CountChildren()) for index := 0; index < element.entity.CountChildren(); index ++ { rocks[index] = element.entity.Child(index).Entity().Bounds() @@ -130,7 +123,7 @@ func (element *Document) AdoptInline (children ...tomo.Element) { element.adopt(false, children...) } -func (element *Document) HandleChildFlexibleHeightChange (child tomo.Flexible) { +func (element *Document) HandleChildFlexibleHeightChange (child ability.Flexible) { element.updateMinimumSize() element.entity.Invalidate() element.entity.InvalidateLayout() @@ -138,7 +131,7 @@ func (element *Document) HandleChildFlexibleHeightChange (child tomo.Flexible) { // DrawBackground draws this element's background pattern to the specified // destination canvas. -func (element *Document) DrawBackground (destination canvas.Canvas) { +func (element *Document) DrawBackground (destination artist.Canvas) { element.entity.DrawBackground(destination) } diff --git a/elements/file.go b/elements/file.go index 7504944..5b701a9 100644 --- a/elements/file.go +++ b/elements/file.go @@ -6,22 +6,11 @@ import "image" import "git.tebibyte.media/sashakoshka/tomo" import "git.tebibyte.media/sashakoshka/tomo/input" import "git.tebibyte.media/sashakoshka/tomo/artist" -import "git.tebibyte.media/sashakoshka/tomo/canvas" -import "git.tebibyte.media/sashakoshka/tomo/default/theme" -import "git.tebibyte.media/sashakoshka/tomo/default/config" - -type fileEntity interface { - tomo.SelectableEntity - tomo.FocusableEntity -} // File displays an interactive visual representation of a file within any // file system. type File struct { - entity fileEntity - - config config.Wrapped - theme theme.Wrapped + entity tomo.Entity lastClick time.Time pressed bool @@ -55,7 +44,7 @@ func (element *File) Entity () tomo.Entity { } // Draw causes the element to draw to the specified destination canvas. -func (element *File) Draw (destination canvas.Canvas) { +func (element *File) Draw (destination artist.Canvas) { // background state := element.state() bounds := element.entity.Bounds() diff --git a/elements/icon.go b/elements/icon.go index 03f0e9c..dbb177a 100644 --- a/elements/icon.go +++ b/elements/icon.go @@ -2,14 +2,11 @@ package elements import "image" import "git.tebibyte.media/sashakoshka/tomo" -import "git.tebibyte.media/sashakoshka/tomo/canvas" import "git.tebibyte.media/sashakoshka/tomo/artist" -import "git.tebibyte.media/sashakoshka/tomo/default/theme" // Icon is an element capable of displaying a singular icon. type Icon struct { entity tomo.Entity - theme theme.Wrapped id tomo.Icon size tomo.IconSize } @@ -20,7 +17,7 @@ func NewIcon (id tomo.Icon, size tomo.IconSize) (element *Icon) { id: id, size: size, } - element.entity = tomo.NewEntity(element) + element.entity = tomo.NewEntity(element).(ability.ThemeableEntity) element.theme.Case = tomo.C("tomo", "icon") element.updateMinimumSize() return @@ -50,7 +47,7 @@ func (element *Icon) SetTheme (new tomo.Theme) { } // Draw causes the element to draw to the specified destination canvas. -func (element *Icon) Draw (destination canvas.Canvas) { +func (element *Icon) Draw (destination artist.Canvas) { if element.entity == nil { return } bounds := element.entity.Bounds() diff --git a/elements/image.go b/elements/image.go index 7ad3122..254e876 100644 --- a/elements/image.go +++ b/elements/image.go @@ -2,7 +2,7 @@ package elements import "image" import "git.tebibyte.media/sashakoshka/tomo" -import "git.tebibyte.media/sashakoshka/tomo/canvas" +import "git.tebibyte.media/sashakoshka/tomo/artist" import "git.tebibyte.media/sashakoshka/tomo/artist/patterns" // TODO: this element is lame need to make it better @@ -10,7 +10,7 @@ import "git.tebibyte.media/sashakoshka/tomo/artist/patterns" // Image is an element capable of displaying an image. type Image struct { entity tomo.Entity - buffer canvas.Canvas + buffer artist.Canvas } // NewImage creates a new image element. @@ -28,7 +28,7 @@ func (element *Image) Entity () tomo.Entity { } // Draw causes the element to draw to the specified destination canvas. -func (element *Image) Draw (destination canvas.Canvas) { +func (element *Image) Draw (destination artist.Canvas) { if element.entity == nil { return } (patterns.Texture { Canvas: element.buffer }). Draw(destination, element.entity.Bounds()) diff --git a/elements/label.go b/elements/label.go index 432c7e4..6853c33 100644 --- a/elements/label.go +++ b/elements/label.go @@ -5,14 +5,12 @@ import "golang.org/x/image/math/fixed" import "git.tebibyte.media/sashakoshka/tomo" import "git.tebibyte.media/sashakoshka/tomo/data" import "git.tebibyte.media/sashakoshka/tomo/input" -import "git.tebibyte.media/sashakoshka/tomo/canvas" +import "git.tebibyte.media/sashakoshka/tomo/artist" import "git.tebibyte.media/sashakoshka/tomo/textdraw" -import "git.tebibyte.media/sashakoshka/tomo/default/theme" -import "git.tebibyte.media/sashakoshka/tomo/default/config" // Label is a simple text box. type Label struct { - entity tomo.FlexibleEntity + entity tomo.Entity align textdraw.Align wrap bool @@ -22,16 +20,13 @@ type Label struct { forcedColumns int forcedRows int minHeight int - - config config.Wrapped - theme theme.Wrapped } // NewLabel creates a new label. func NewLabel (text string) (element *Label) { element = &Label { } element.theme.Case = tomo.C("tomo", "label") - element.entity = tomo.NewEntity(element).(tomo.FlexibleEntity) + element.entity = tomo.NewEntity(element) element.drawer.SetFace (element.theme.FontFace ( tomo.FontStyleRegular, tomo.FontSizeNormal)) @@ -52,7 +47,7 @@ func (element *Label) Entity () tomo.Entity { } // Draw causes the element to draw to the specified destination canvas. -func (element *Label) Draw (destination canvas.Canvas) { +func (element *Label) Draw (destination artist.Canvas) { bounds := element.entity.Bounds() if element.wrap { diff --git a/elements/list.go b/elements/list.go index 4fad816..dbae972 100644 --- a/elements/list.go +++ b/elements/list.go @@ -3,19 +3,11 @@ package elements import "image" import "git.tebibyte.media/sashakoshka/tomo" import "git.tebibyte.media/sashakoshka/tomo/input" -import "git.tebibyte.media/sashakoshka/tomo/canvas" import "git.tebibyte.media/sashakoshka/tomo/artist" -import "git.tebibyte.media/sashakoshka/tomo/default/theme" - -type listEntity interface { - tomo.ContainerEntity - tomo.ScrollableEntity - tomo.FocusableEntity -} type list struct { container - entity listEntity + entity tomo.Entity enabled bool scroll image.Point @@ -25,8 +17,6 @@ type list struct { forcedMinimumWidth int forcedMinimumHeight int - theme theme.Wrapped - onClick func () onSelectionChange func () onScrollBoundsChange func () @@ -43,7 +33,7 @@ type FlowList struct { func NewList (children ...tomo.Element) (element *List) { element = &List { } element.theme.Case = tomo.C("tomo", "list") - element.entity = tomo.NewEntity(element).(listEntity) + element.entity = tomo.NewEntity(element) element.container.entity = element.entity element.minimumSize = element.updateMinimumSize element.init(children...) @@ -67,7 +57,7 @@ func (element *list) init (children ...tomo.Element) { element.Adopt(children...) } -func (element *list) Draw (destination canvas.Canvas) { +func (element *list) Draw (destination artist.Canvas) { rocks := make([]image.Rectangle, element.entity.CountChildren()) for index := 0; index < element.entity.CountChildren(); index ++ { rocks[index] = element.entity.Child(index).Entity().Bounds() @@ -170,14 +160,14 @@ func (element *FlowList) Layout () { } } -func (element *list) Selected () tomo.Selectable { +func (element *list) Selected () ability.Selectable { if element.selected == -1 { return nil } child, ok := element.entity.Child(element.selected).(tomo.Selectable) if !ok { return nil } return child } -func (element *list) Select (child tomo.Selectable) { +func (element *list) Select (child ability.Selectable) { index := element.entity.IndexOf(child) if element.selected == index { return } element.selectNone() @@ -248,7 +238,7 @@ func (element *list) HandleChildMouseUp ( } } -func (element *list) HandleChildFlexibleHeightChange (child tomo.Flexible) { +func (element *list) HandleChildFlexibleHeightChange (child ability.Flexible) { element.minimumSize() element.entity.Invalidate() element.entity.InvalidateLayout() @@ -280,7 +270,7 @@ func (element *list) HandleKeyDown (key input.Key, modifiers input.Modifiers) { func (element *list) HandleKeyUp(key input.Key, modifiers input.Modifiers) { } -func (element *list) DrawBackground (destination canvas.Canvas) { +func (element *list) DrawBackground (destination artist.Canvas) { element.entity.DrawBackground(destination) } diff --git a/elements/progressbar.go b/elements/progressbar.go index 5c96daa..7179153 100644 --- a/elements/progressbar.go +++ b/elements/progressbar.go @@ -2,17 +2,12 @@ package elements import "image" import "git.tebibyte.media/sashakoshka/tomo" -import "git.tebibyte.media/sashakoshka/tomo/canvas" -import "git.tebibyte.media/sashakoshka/tomo/default/theme" -import "git.tebibyte.media/sashakoshka/tomo/default/config" +import "git.tebibyte.media/sashakoshka/tomo/artist" // ProgressBar displays a visual indication of how far along a task is. type ProgressBar struct { entity tomo.Entity progress float64 - - config config.Wrapped - theme theme.Wrapped } // NewProgressBar creates a new progress bar displaying the given progress @@ -33,7 +28,7 @@ func (element *ProgressBar) Entity () tomo.Entity { } // Draw causes the element to draw to the specified destination canvas. -func (element *ProgressBar) Draw (destination canvas.Canvas) { +func (element *ProgressBar) Draw (destination artist.Canvas) { bounds := element.entity.Bounds() pattern := element.theme.Pattern(tomo.PatternSunken, tomo.State { }) @@ -65,14 +60,6 @@ func (element *ProgressBar) SetTheme (new tomo.Theme) { element.entity.Invalidate() } -// SetConfig sets the element's configuration. -func (element *ProgressBar) SetConfig (new tomo.Config) { - if new == nil || new == element.config.Config { return } - element.config.Config = new - element.updateMinimumSize() - element.entity.Invalidate() -} - func (element *ProgressBar) updateMinimumSize() { padding := element.theme.Padding(tomo.PatternSunken) innerPadding := element.theme.Padding(tomo.PatternMercury) diff --git a/elements/scroll.go b/elements/scroll.go index 20b18b0..a32bc34 100644 --- a/elements/scroll.go +++ b/elements/scroll.go @@ -3,9 +3,8 @@ package elements import "image" import "git.tebibyte.media/sashakoshka/tomo" import "git.tebibyte.media/sashakoshka/tomo/input" -import "git.tebibyte.media/sashakoshka/tomo/canvas" -import "git.tebibyte.media/sashakoshka/tomo/default/theme" -import "git.tebibyte.media/sashakoshka/tomo/default/config" +import "git.tebibyte.media/sashakoshka/tomo/artist" +import "git.tebibyte.media/sashakoshka/tomo/ability" // ScrollMode specifies which sides of a Scroll have scroll bars. type ScrollMode int; const ( @@ -24,21 +23,18 @@ func (mode ScrollMode) Includes (sub ScrollMode) bool { // Scroll adds scroll bars to any scrollable element. It also captures scroll // wheel input. type Scroll struct { - entity tomo.ContainerEntity + entity tomo.Entity - child tomo.Scrollable + child ability.Scrollable horizontal *ScrollBar vertical *ScrollBar - - config config.Wrapped - theme theme.Wrapped } // NewScroll creates a new scroll element. -func NewScroll (mode ScrollMode, child tomo.Scrollable) (element *Scroll) { +func NewScroll (mode ScrollMode, child ability.Scrollable) (element *Scroll) { element = &Scroll { } element.theme.Case = tomo.C("tomo", "scroll") - element.entity = tomo.NewEntity(element).(tomo.ContainerEntity) + element.entity = tomo.NewEntity(element).(scrollEntity) if mode.Includes(ScrollHorizontal) { element.horizontal = NewHScrollBar() @@ -79,7 +75,7 @@ func (element *Scroll) Entity () tomo.Entity { } // Draw causes the element to draw to the specified destination canvas. -func (element *Scroll) Draw (destination canvas.Canvas) { +func (element *Scroll) Draw (destination artist.Canvas) { if element.horizontal != nil && element.vertical != nil { bounds := element.entity.Bounds() bounds.Min = image.Pt ( @@ -134,12 +130,12 @@ func (element *Scroll) Layout () { // DrawBackground draws this element's background pattern to the specified // destination canvas. -func (element *Scroll) DrawBackground (destination canvas.Canvas) { +func (element *Scroll) DrawBackground (destination artist.Canvas) { element.entity.DrawBackground(destination) } // Adopt sets this element's child. If nil is passed, any child is removed. -func (element *Scroll) Adopt (child tomo.Scrollable) { +func (element *Scroll) Adopt (child ability.Scrollable) { if element.child != nil { element.entity.Disown(element.entity.IndexOf(element.child)) } @@ -156,7 +152,7 @@ func (element *Scroll) Adopt (child tomo.Scrollable) { // Child returns this element's child. If there is no child, this method will // return nil. -func (element *Scroll) Child () tomo.Scrollable { +func (element *Scroll) Child () ability.Scrollable { return element.child } @@ -166,7 +162,7 @@ func (element *Scroll) HandleChildMinimumSizeChange (tomo.Element) { element.entity.InvalidateLayout() } -func (element *Scroll) HandleChildScrollBoundsChange (tomo.Scrollable) { +func (element *Scroll) HandleChildScrollBoundsChange (ability.Scrollable) { element.updateEnabled() viewportBounds := element.child.ScrollViewportBounds() contentBounds := element.child.ScrollContentBounds() diff --git a/elements/scrollbar.go b/elements/scrollbar.go index 2dbadfe..634a5b9 100644 --- a/elements/scrollbar.go +++ b/elements/scrollbar.go @@ -3,9 +3,8 @@ package elements import "image" import "git.tebibyte.media/sashakoshka/tomo" import "git.tebibyte.media/sashakoshka/tomo/input" -import "git.tebibyte.media/sashakoshka/tomo/canvas" -import "git.tebibyte.media/sashakoshka/tomo/default/theme" -import "git.tebibyte.media/sashakoshka/tomo/default/config" +import "git.tebibyte.media/sashakoshka/tomo/artist" +import "git.tebibyte.media/sashakoshka/tomo/ability" // ScrollBar is an element similar to Slider, but it has special behavior that // makes it well suited for controlling the viewport position on one axis of a @@ -31,9 +30,6 @@ type ScrollBar struct { contentBounds image.Rectangle viewportBounds image.Rectangle - config config.Wrapped - theme theme.Wrapped - onScroll func (viewport image.Point) } @@ -44,7 +40,7 @@ func NewVScrollBar () (element *ScrollBar) { enabled: true, } element.theme.Case = tomo.C("tomo", "scrollBarVertical") - element.entity = tomo.NewEntity(element).(tomo.Entity) + element.entity = tomo.NewEntity(element).(scrollBarEntity) element.updateMinimumSize() return } @@ -66,7 +62,7 @@ func (element *ScrollBar) Entity () tomo.Entity { } // Draw causes the element to draw to the specified destination canvas. -func (element *ScrollBar) Draw (destination canvas.Canvas) { +func (element *ScrollBar) Draw (destination artist.Canvas) { element.recalculate() bounds := element.entity.Bounds() diff --git a/elements/slider.go b/elements/slider.go index f42a181..f2b7ea1 100644 --- a/elements/slider.go +++ b/elements/slider.go @@ -3,9 +3,8 @@ package elements import "image" import "git.tebibyte.media/sashakoshka/tomo" import "git.tebibyte.media/sashakoshka/tomo/input" -import "git.tebibyte.media/sashakoshka/tomo/canvas" -import "git.tebibyte.media/sashakoshka/tomo/default/theme" -import "git.tebibyte.media/sashakoshka/tomo/default/config" +import "git.tebibyte.media/sashakoshka/tomo/artist" +import "git.tebibyte.media/sashakoshka/tomo/ability" // Slider is a slider control with a floating point value between zero and one. type Slider struct { @@ -23,14 +22,12 @@ func NewVSlider (value float64) (element *Slider) { func NewHSlider (value float64) (element *Slider) { element = &Slider { } element.value = value - element.entity = tomo.NewEntity(element).(tomo.FocusableEntity) + element.entity = tomo.NewEntity(element) element.construct() return } type slider struct { - entity tomo.FocusableEntity - value float64 vertical bool dragging bool @@ -39,9 +36,6 @@ type slider struct { track image.Rectangle bar image.Rectangle - config config.Wrapped - theme theme.Wrapped - onSlide func () onRelease func () } @@ -62,7 +56,7 @@ func (element *slider) Entity () tomo.Entity { } // Draw causes the element to draw to the specified destination canvas. -func (element *slider) Draw (destination canvas.Canvas) { +func (element *slider) Draw (destination artist.Canvas) { bounds := element.entity.Bounds() element.track = element.theme.Padding(tomo.PatternGutter).Apply(bounds) if element.vertical { diff --git a/elements/spacer.go b/elements/spacer.go index 9b0ff4d..0f6d73d 100644 --- a/elements/spacer.go +++ b/elements/spacer.go @@ -1,24 +1,18 @@ package elements import "git.tebibyte.media/sashakoshka/tomo" -import "git.tebibyte.media/sashakoshka/tomo/canvas" -import "git.tebibyte.media/sashakoshka/tomo/default/theme" -import "git.tebibyte.media/sashakoshka/tomo/default/config" +import "git.tebibyte.media/sashakoshka/tomo/artist" // Spacer can be used to put space between two elements.. type Spacer struct { entity tomo.Entity - line bool - - config config.Wrapped - theme theme.Wrapped } // NewSpacer creates a new spacer. func NewSpacer () (element *Spacer) { element = &Spacer { } - element.entity = tomo.NewEntity(element) + element.entity = tomo.NewEntity(element).(spacerEntity) element.theme.Case = tomo.C("tomo", "spacer") element.updateMinimumSize() return @@ -37,7 +31,7 @@ func (element *Spacer) Entity () tomo.Entity { } // Draw causes the element to draw to the specified destination canvas. -func (element *Spacer) Draw (destination canvas.Canvas) { +func (element *Spacer) Draw (destination artist.Canvas) { bounds := element.entity.Bounds() if element.line { diff --git a/elements/switch.go b/elements/switch.go index 45a8ef2..11d139f 100644 --- a/elements/switch.go +++ b/elements/switch.go @@ -3,15 +3,13 @@ package elements import "image" import "git.tebibyte.media/sashakoshka/tomo" import "git.tebibyte.media/sashakoshka/tomo/input" -import "git.tebibyte.media/sashakoshka/tomo/canvas" +import "git.tebibyte.media/sashakoshka/tomo/artist" import "git.tebibyte.media/sashakoshka/tomo/textdraw" -import "git.tebibyte.media/sashakoshka/tomo/default/theme" -import "git.tebibyte.media/sashakoshka/tomo/default/config" // Switch is a toggle-able on/off switch with an optional label. It is // functionally identical to Checkbox, but plays a different semantic role. type Switch struct { - entity tomo.FocusableEntity + entity tomo.Entity drawer textdraw.Drawer enabled bool @@ -19,9 +17,6 @@ type Switch struct { checked bool text string - config config.Wrapped - theme theme.Wrapped - onToggle func () } @@ -32,7 +27,7 @@ func NewSwitch (text string, on bool) (element *Switch) { text: text, enabled: true, } - element.entity = tomo.NewEntity(element).(tomo.FocusableEntity) + element.entity = tomo.NewEntity(element).(checkboxEntity) element.theme.Case = tomo.C("tomo", "switch") element.drawer.SetFace (element.theme.FontFace ( tomo.FontStyleRegular, @@ -48,7 +43,7 @@ func (element *Switch) Entity () tomo.Entity { } // Draw causes the element to draw to the specified destination canvas. -func (element *Switch) Draw (destination canvas.Canvas) { +func (element *Switch) Draw (destination artist.Canvas) { bounds := element.entity.Bounds() handleBounds := image.Rect(0, 0, bounds.Dy(), bounds.Dy()).Add(bounds.Min) gutterBounds := image.Rect(0, 0, bounds.Dy() * 2, bounds.Dy()).Add(bounds.Min) diff --git a/elements/testing/mouse.go b/elements/testing/mouse.go index 404b70f..29be390 100644 --- a/elements/testing/mouse.go +++ b/elements/testing/mouse.go @@ -4,7 +4,6 @@ import "image" import "git.tebibyte.media/sashakoshka/tomo" import "git.tebibyte.media/sashakoshka/tomo/input" import "git.tebibyte.media/sashakoshka/tomo/artist" -import "git.tebibyte.media/sashakoshka/tomo/ability" import "git.tebibyte.media/sashakoshka/tomo/artist/shapes" import "git.tebibyte.media/sashakoshka/tomo/artist/artutil" @@ -13,7 +12,7 @@ var mouseCase = tomo.C("tomo", "mouse") // Mouse is an element capable of testing mouse input. When the mouse is clicked // and dragged on it, it draws a trail. type Mouse struct { - entity ability.ThemeableEntity + entity tomo.Entity pressed bool lastMousePos image.Point } @@ -21,7 +20,7 @@ type Mouse struct { // NewMouse creates a new mouse test element. func NewMouse () (element *Mouse) { element = &Mouse { } - element.entity = tomo.GetBackend().NewEntity(element).(ability.ThemeableEntity) + element.entity = tomo.GetBackend().NewEntity(element) element.entity.SetMinimumSize(32, 32) return } diff --git a/elements/textbox.go b/elements/textbox.go index 5444ea0..fe1dfa3 100644 --- a/elements/textbox.go +++ b/elements/textbox.go @@ -7,23 +7,14 @@ import "git.tebibyte.media/sashakoshka/tomo" import "git.tebibyte.media/sashakoshka/tomo/data" import "git.tebibyte.media/sashakoshka/tomo/input" import "git.tebibyte.media/sashakoshka/tomo/artist" -import "git.tebibyte.media/sashakoshka/tomo/canvas" import "git.tebibyte.media/sashakoshka/tomo/textdraw" import "git.tebibyte.media/sashakoshka/tomo/textmanip" import "git.tebibyte.media/sashakoshka/tomo/fixedutil" import "git.tebibyte.media/sashakoshka/tomo/artist/shapes" -import "git.tebibyte.media/sashakoshka/tomo/default/theme" -import "git.tebibyte.media/sashakoshka/tomo/default/config" - -type textBoxEntity interface { - tomo.FocusableEntity - tomo.ScrollableEntity - tomo.LayoutEntity -} // TextBox is a single-line text input. type TextBox struct { - entity textBoxEntity + entity tomo.Entity enabled bool lastClick time.Time @@ -36,9 +27,6 @@ type TextBox struct { placeholderDrawer textdraw.Drawer valueDrawer textdraw.Drawer - config config.Wrapped - theme theme.Wrapped - onKeyDown func (key input.Key, modifiers input.Modifiers) (handled bool) onChange func () onEnter func () @@ -71,7 +59,7 @@ func (element *TextBox) Entity () tomo.Entity { } // Draw causes the element to draw to the specified destination canvas. -func (element *TextBox) Draw (destination canvas.Canvas) { +func (element *TextBox) Draw (destination artist.Canvas) { bounds := element.entity.Bounds() state := element.state() diff --git a/elements/togglebutton.go b/elements/togglebutton.go index 8ee204d..0187de7 100644 --- a/elements/togglebutton.go +++ b/elements/togglebutton.go @@ -3,23 +3,18 @@ package elements import "image" import "git.tebibyte.media/sashakoshka/tomo" import "git.tebibyte.media/sashakoshka/tomo/input" -import "git.tebibyte.media/sashakoshka/tomo/canvas" -import "git.tebibyte.media/sashakoshka/tomo/default/theme" -import "git.tebibyte.media/sashakoshka/tomo/default/config" +import "git.tebibyte.media/sashakoshka/tomo/artist" import "git.tebibyte.media/sashakoshka/tomo/textdraw" // ToggleButton is a togglable button. type ToggleButton struct { - entity tomo.FocusableEntity + entity tomo.Entity drawer textdraw.Drawer enabled bool pressed bool on bool text string - - config config.Wrapped - theme theme.Wrapped showText bool hasIcon bool @@ -35,7 +30,7 @@ func NewToggleButton (text string, on bool) (element *ToggleButton) { enabled: true, on: on, } - element.entity = tomo.NewEntity(element).(tomo.FocusableEntity) + element.entity = tomo.NewEntity(element) element.theme.Case = tomo.C("tomo", "toggleButton") element.drawer.SetFace (element.theme.FontFace ( tomo.FontStyleRegular, @@ -50,7 +45,7 @@ func (element *ToggleButton) Entity () tomo.Entity { } // Draw causes the element to draw to the specified destination canvas. -func (element *ToggleButton) Draw (destination canvas.Canvas) { +func (element *ToggleButton) Draw (destination artist.Canvas) { state := element.state() bounds := element.entity.Bounds() pattern := element.theme.Pattern(tomo.PatternButton, state) diff --git a/examples/drawing/main.go b/examples/drawing/main.go index 4c8db43..00e47bb 100644 --- a/examples/drawing/main.go +++ b/examples/drawing/main.go @@ -1,18 +1,22 @@ package main import "git.tebibyte.media/sashakoshka/tomo" +import "git.tebibyte.media/sashakoshka/tomo/nasin" import "git.tebibyte.media/sashakoshka/tomo/elements/testing" -import _ "git.tebibyte.media/sashakoshka/tomo/backends/all" import "git.tebibyte.media/sashakoshka/ezprof/ez" func main () { - tomo.Run(run) + nasin.Run(Application { }) } -func run () { - window, _ := tomo.NewWindow(tomo.Bounds(0, 0, 480, 360)) +type Application struct { } + +func (Application) Init () error { + window, err := nasin.NewWindow(tomo.Bounds(0, 0, 480, 360)) + if err != nil { return err } window.Adopt(testing.NewArtist()) - window.OnClose(tomo.Stop) + window.OnClose(nasin.Stop) window.Show() ez.Prof() + return nil }