feat!: rewrote the GUI and model for better testability

The Model was getting unmaintanable mess. This is an attempt to refactor/rewrite the Model so that data of certain type is exposed in standardized way, offering certain standard manipulations for that data type, and on the GUI side, certain standard widgets to tied to that data.

This rewrite closes #72, #106 and #120.
This commit is contained in:
5684185+vsariola@users.noreply.github.com
2023-10-24 13:35:43 +03:00
parent 6d3c65e11d
commit d92426a100
53 changed files with 5992 additions and 4507 deletions

View File

@ -6,17 +6,43 @@ import (
"gioui.org/widget"
"gioui.org/widget/material"
"gioui.org/x/component"
"github.com/vsariola/sointu/tracker"
)
type TipClickable struct {
Clickable widget.Clickable
TipArea component.TipArea
type (
TipClickable struct {
Clickable widget.Clickable
TipArea component.TipArea
}
ActionClickable struct {
Action tracker.Action
TipClickable
}
TipIconButtonStyle struct {
TipArea *component.TipArea
IconButtonStyle material.IconButtonStyle
Tooltip component.Tooltip
}
BoolClickable struct {
Clickable widget.Clickable
TipArea component.TipArea
Bool tracker.Bool
}
)
func NewActionClickable(a tracker.Action) *ActionClickable {
return &ActionClickable{
Action: a,
}
}
type TipIconButtonStyle struct {
IconButtonStyle material.IconButtonStyle
Tooltip component.Tooltip
tipArea *component.TipArea
func NewBoolClickable(b tracker.Bool) *BoolClickable {
return &BoolClickable{
Bool: b,
}
}
func Tooltip(th *material.Theme, tip string) component.Tooltip {
@ -25,24 +51,86 @@ func Tooltip(th *material.Theme, tip string) component.Tooltip {
return tooltip
}
func IconButton(th *material.Theme, w *TipClickable, icon []byte, enabled bool, tip string) TipIconButtonStyle {
ret := material.IconButton(th, &w.Clickable, widgetForIcon(icon), "")
ret.Background = transparent
ret.Inset = layout.UniformInset(unit.Dp(6))
if enabled {
ret.Color = primaryColor
} else {
ret.Color = disabledTextColor
func ActionIcon(th *material.Theme, w *ActionClickable, icon []byte, tip string) TipIconButtonStyle {
ret := TipIcon(th, &w.TipClickable, icon, tip)
for w.Clickable.Clicked() {
w.Action.Do()
}
if !w.Action.Allowed() {
ret.IconButtonStyle.Color = disabledTextColor
}
return ret
}
func TipIcon(th *material.Theme, w *TipClickable, icon []byte, tip string) TipIconButtonStyle {
iconButtonStyle := material.IconButton(th, &w.Clickable, widgetForIcon(icon), "")
iconButtonStyle.Color = primaryColor
iconButtonStyle.Background = transparent
iconButtonStyle.Inset = layout.UniformInset(unit.Dp(6))
return TipIconButtonStyle{
TipArea: &w.TipArea,
IconButtonStyle: iconButtonStyle,
Tooltip: Tooltip(th, tip),
}
}
func ToggleIcon(th *material.Theme, w *BoolClickable, offIcon, onIcon []byte, offTip, onTip string) TipIconButtonStyle {
icon := offIcon
tip := offTip
if w.Bool.Value() {
icon = onIcon
tip = onTip
}
for w.Clickable.Clicked() {
w.Bool.Toggle()
}
ibStyle := material.IconButton(th, &w.Clickable, widgetForIcon(icon), "")
ibStyle.Background = transparent
ibStyle.Inset = layout.UniformInset(unit.Dp(6))
ibStyle.Color = primaryColor
if !w.Bool.Enabled() {
ibStyle.Color = disabledTextColor
}
return TipIconButtonStyle{
IconButtonStyle: ret,
TipArea: &w.TipArea,
IconButtonStyle: ibStyle,
Tooltip: Tooltip(th, tip),
tipArea: &w.TipArea,
}
}
func (t *TipIconButtonStyle) Layout(gtx C) D {
return t.tipArea.Layout(gtx, t.Tooltip, t.IconButtonStyle.Layout)
return t.TipArea.Layout(gtx, t.Tooltip, t.IconButtonStyle.Layout)
}
func ActionButton(th *material.Theme, w *ActionClickable, text string) material.ButtonStyle {
for w.Clickable.Clicked() {
w.Action.Do()
}
ret := material.Button(th, &w.Clickable, text)
ret.Color = th.Palette.Fg
if !w.Action.Allowed() {
ret.Color = disabledTextColor
}
ret.Background = transparent
ret.Inset = layout.UniformInset(unit.Dp(6))
return ret
}
func ToggleButton(th *material.Theme, b *BoolClickable, text string) material.ButtonStyle {
for b.Clickable.Clicked() {
b.Bool.Toggle()
}
ret := material.Button(th, &b.Clickable, text)
ret.Background = transparent
ret.Inset = layout.UniformInset(unit.Dp(6))
if b.Bool.Value() {
ret.Color = th.Palette.ContrastFg
ret.Background = th.Palette.Fg
} else {
ret.Color = th.Palette.Fg
ret.Background = transparent
}
return ret
}
func LowEmphasisButton(th *material.Theme, w *widget.Clickable, text string) material.ButtonStyle {