drafting buttons

This commit is contained in:
5684185+vsariola@users.noreply.github.com
2025-06-22 21:58:00 +03:00
parent 64ec5f17f3
commit 9c3274c02e
7 changed files with 109 additions and 113 deletions

View File

@ -27,10 +27,6 @@ type (
history []widget.Press history []widget.Press
requestClicks int requestClicks int
}
ClickableTip struct {
Clickable
component.TipArea component.TipArea
} }
@ -59,7 +55,7 @@ type (
Style ButtonStyle Style ButtonStyle
Text string Text string
Tip string Tip string
*ClickableTip *Clickable
} }
ActionButton struct { ActionButton struct {
@ -80,7 +76,7 @@ type (
Style IconButtonStyle Style IconButtonStyle
Icon *widget.Icon Icon *widget.Icon
Tip string Tip string
*ClickableTip *Clickable
} }
ActionIconButton struct { ActionIconButton struct {
@ -98,17 +94,17 @@ type (
} }
) )
func Btn(th *Theme, st *ButtonStyle, b *ClickableTip, txt string, tip string) Button { func Btn(th *Theme, st *ButtonStyle, b *Clickable, txt string, tip string) Button {
return Button{ return Button{
Theme: th, Theme: th,
Style: *st, Style: *st,
ClickableTip: b, Clickable: b,
Text: txt, Text: txt,
Tip: tip, Tip: tip,
} }
} }
func ActionBtn(act tracker.Action, th *Theme, b *ClickableTip, txt string, tip string) ActionButton { func ActionBtn(act tracker.Action, th *Theme, b *Clickable, txt string, tip string) ActionButton {
return ActionButton{ return ActionButton{
act: act, act: act,
DisabledStyle: th.Button.Disabled, DisabledStyle: th.Button.Disabled,
@ -116,7 +112,7 @@ func ActionBtn(act tracker.Action, th *Theme, b *ClickableTip, txt string, tip s
} }
} }
func ToggleBtn(b tracker.Bool, th *Theme, c *ClickableTip, text string, tip string) ToggleButton { func ToggleBtn(b tracker.Bool, th *Theme, c *Clickable, text string, tip string) ToggleButton {
return ToggleButton{ return ToggleButton{
b: b, b: b,
DisabledStyle: th.Button.Disabled, DisabledStyle: th.Button.Disabled,
@ -125,17 +121,17 @@ func ToggleBtn(b tracker.Bool, th *Theme, c *ClickableTip, text string, tip stri
} }
} }
func IconBtn(th *Theme, st *IconButtonStyle, b *ClickableTip, icon []byte, tip string) IconButton { func IconBtn(th *Theme, st *IconButtonStyle, b *Clickable, icon []byte, tip string) IconButton {
return IconButton{ return IconButton{
Theme: th, Theme: th,
Style: *st, Style: *st,
ClickableTip: b, Clickable: b,
Icon: th.Icon(icon), Icon: th.Icon(icon),
Tip: tip, Tip: tip,
} }
} }
func ActionIconBtn(act tracker.Action, th *Theme, b *ClickableTip, icon []byte, tip string) ActionIconButton { func ActionIconBtn(act tracker.Action, th *Theme, b *Clickable, icon []byte, tip string) ActionIconButton {
return ActionIconButton{ return ActionIconButton{
act: act, act: act,
DisabledStyle: th.IconButton.Disabled, DisabledStyle: th.IconButton.Disabled,
@ -143,7 +139,7 @@ func ActionIconBtn(act tracker.Action, th *Theme, b *ClickableTip, icon []byte,
} }
} }
func ToggleIconBtn(b tracker.Bool, th *Theme, c *ClickableTip, offIcon, onIcon []byte, offTip, onTip string) ToggleIconButton { func ToggleIconBtn(b tracker.Bool, th *Theme, c *Clickable, offIcon, onIcon []byte, offTip, onTip string) ToggleIconButton {
return ToggleIconButton{ return ToggleIconButton{
b: b, b: b,
DisabledStyle: th.IconButton.Disabled, DisabledStyle: th.IconButton.Disabled,
@ -155,7 +151,7 @@ func ToggleIconBtn(b tracker.Bool, th *Theme, c *ClickableTip, offIcon, onIcon [
func (b *Button) Layout(gtx C) D { func (b *Button) Layout(gtx C) D {
if b.Tip != "" { if b.Tip != "" {
return b.ClickableTip.TipArea.Layout(gtx, Tooltip(b.Theme, b.Tip), b.actualLayout) return b.Clickable.TipArea.Layout(gtx, Tooltip(b.Theme, b.Tip), b.actualLayout)
} }
return b.actualLayout(gtx) return b.actualLayout(gtx)
} }
@ -218,7 +214,7 @@ func (b *ToggleButton) Layout(gtx C) D {
func (i *IconButton) Layout(gtx C) D { func (i *IconButton) Layout(gtx C) D {
if i.Tip != "" { if i.Tip != "" {
return i.ClickableTip.TipArea.Layout(gtx, Tooltip(i.Theme, i.Tip), i.actualLayout) return i.Clickable.TipArea.Layout(gtx, Tooltip(i.Theme, i.Tip), i.actualLayout)
} }
return i.actualLayout(gtx) return i.actualLayout(gtx)
} }

View File

@ -23,19 +23,19 @@ import (
type ( type (
InstrumentEditor struct { InstrumentEditor struct {
newInstrumentBtn *ClickableTip newInstrumentBtn *Clickable
enlargeBtn *ClickableTip enlargeBtn *Clickable
deleteInstrumentBtn *ClickableTip deleteInstrumentBtn *Clickable
linkInstrTrackBtn *ClickableTip linkInstrTrackBtn *Clickable
splitInstrumentBtn *ClickableTip splitInstrumentBtn *Clickable
copyInstrumentBtn *ClickableTip copyInstrumentBtn *Clickable
saveInstrumentBtn *ClickableTip saveInstrumentBtn *Clickable
loadInstrumentBtn *ClickableTip loadInstrumentBtn *Clickable
addUnitBtn *ClickableTip addUnitBtn *Clickable
presetMenuBtn *ClickableTip presetMenuBtn *Clickable
commentExpandBtn *ClickableTip commentExpandBtn *Clickable
soloBtn *ClickableTip soloBtn *Clickable
muteBtn *ClickableTip muteBtn *Clickable
commentEditor *Editor commentEditor *Editor
commentString tracker.String commentString tracker.String
nameEditor *Editor nameEditor *Editor
@ -68,19 +68,19 @@ type (
func NewInstrumentEditor(model *tracker.Model) *InstrumentEditor { func NewInstrumentEditor(model *tracker.Model) *InstrumentEditor {
ret := &InstrumentEditor{ ret := &InstrumentEditor{
newInstrumentBtn: new(ClickableTip), newInstrumentBtn: new(Clickable),
enlargeBtn: new(ClickableTip), enlargeBtn: new(Clickable),
deleteInstrumentBtn: new(ClickableTip), deleteInstrumentBtn: new(Clickable),
linkInstrTrackBtn: new(ClickableTip), linkInstrTrackBtn: new(Clickable),
splitInstrumentBtn: new(ClickableTip), splitInstrumentBtn: new(Clickable),
copyInstrumentBtn: new(ClickableTip), copyInstrumentBtn: new(Clickable),
saveInstrumentBtn: new(ClickableTip), saveInstrumentBtn: new(Clickable),
loadInstrumentBtn: new(ClickableTip), loadInstrumentBtn: new(Clickable),
commentExpandBtn: new(ClickableTip), commentExpandBtn: new(Clickable),
presetMenuBtn: new(ClickableTip), presetMenuBtn: new(Clickable),
soloBtn: new(ClickableTip), soloBtn: new(Clickable),
muteBtn: new(ClickableTip), muteBtn: new(Clickable),
addUnitBtn: new(ClickableTip), addUnitBtn: new(Clickable),
commentEditor: NewEditor(false, false, text.Start), commentEditor: NewEditor(false, false, text.Start),
nameEditor: NewEditor(true, true, text.Middle), nameEditor: NewEditor(true, true, text.Middle),
searchEditor: NewEditor(true, true, text.Start), searchEditor: NewEditor(true, true, text.Start),
@ -133,8 +133,8 @@ func (ie *InstrumentEditor) Focused(gtx C) bool {
func (ie *InstrumentEditor) childFocused(gtx C) bool { func (ie *InstrumentEditor) childFocused(gtx C) bool {
return ie.unitEditor.sliderList.Focused(gtx) || return ie.unitEditor.sliderList.Focused(gtx) ||
ie.instrumentDragList.Focused(gtx) || gtx.Source.Focused(ie.commentEditor) || gtx.Source.Focused(ie.nameEditor) || gtx.Source.Focused(ie.searchEditor) || ie.instrumentDragList.Focused(gtx) || gtx.Source.Focused(ie.commentEditor) || gtx.Source.Focused(ie.nameEditor) || gtx.Source.Focused(ie.searchEditor) ||
gtx.Source.Focused(ie.addUnitBtn.Clickable) || gtx.Source.Focused(ie.commentExpandBtn.Clickable) || gtx.Source.Focused(ie.presetMenuBtn.Clickable) || gtx.Source.Focused(ie.addUnitBtn) || gtx.Source.Focused(ie.commentExpandBtn) || gtx.Source.Focused(ie.presetMenuBtn) ||
gtx.Source.Focused(ie.deleteInstrumentBtn.Clickable) || gtx.Source.Focused(ie.copyInstrumentBtn.Clickable) gtx.Source.Focused(ie.deleteInstrumentBtn) || gtx.Source.Focused(ie.copyInstrumentBtn)
} }
func (ie *InstrumentEditor) Layout(gtx C, t *Tracker) D { func (ie *InstrumentEditor) Layout(gtx C, t *Tracker) D {
@ -192,14 +192,14 @@ func (ie *InstrumentEditor) layoutInstrumentHeader(gtx C, t *Tracker) D {
header := func(gtx C) D { header := func(gtx C) D {
m := PopupMenu(t.Theme, &t.Theme.Menu.Text, &ie.presetMenu) m := PopupMenu(t.Theme, &t.Theme.Menu.Text, &ie.presetMenu)
for ie.copyInstrumentBtn.Clickable.Clicked(gtx) { for ie.copyInstrumentBtn.Clicked(gtx) {
if contents, ok := t.Instruments().List().CopyElements(); ok { if contents, ok := t.Instruments().List().CopyElements(); ok {
gtx.Execute(clipboard.WriteCmd{Type: "application/text", Data: io.NopCloser(bytes.NewReader(contents))}) gtx.Execute(clipboard.WriteCmd{Type: "application/text", Data: io.NopCloser(bytes.NewReader(contents))})
t.Alerts().Add("Instrument copied to clipboard", tracker.Info) t.Alerts().Add("Instrument copied to clipboard", tracker.Info)
} }
} }
for ie.saveInstrumentBtn.Clickable.Clicked(gtx) { for ie.saveInstrumentBtn.Clicked(gtx) {
writer, err := t.Explorer.CreateFile(t.InstrumentName().Value() + ".yml") writer, err := t.Explorer.CreateFile(t.InstrumentName().Value() + ".yml")
if err != nil { if err != nil {
continue continue
@ -207,7 +207,7 @@ func (ie *InstrumentEditor) layoutInstrumentHeader(gtx C, t *Tracker) D {
t.SaveInstrument(writer) t.SaveInstrument(writer)
} }
for ie.loadInstrumentBtn.Clickable.Clicked(gtx) { for ie.loadInstrumentBtn.Clicked(gtx) {
reader, err := t.Explorer.ChooseFile(".yml", ".json", ".4ki", ".4kp") reader, err := t.Explorer.ChooseFile(".yml", ".json", ".4ki", ".4kp")
if err != nil { if err != nil {
continue continue
@ -253,7 +253,7 @@ func (ie *InstrumentEditor) layoutInstrumentHeader(gtx C, t *Tracker) D {
) )
} }
for ie.presetMenuBtn.Clickable.Clicked(gtx) { for ie.presetMenuBtn.Clicked(gtx) {
ie.presetMenu.Visible = true ie.presetMenu.Visible = true
} }
@ -476,7 +476,7 @@ func (ie *InstrumentEditor) layoutUnitList(gtx C, t *Tracker) D {
return dims return dims
}), }),
layout.Stacked(func(gtx C) D { layout.Stacked(func(gtx C) D {
for ie.addUnitBtn.Clickable.Clicked(gtx) { for ie.addUnitBtn.Clicked(gtx) {
t.AddUnit(false).Do() t.AddUnit(false).Do()
} }
margin := layout.Inset{Right: unit.Dp(20), Bottom: unit.Dp(1)} margin := layout.Inset{Right: unit.Dp(20), Bottom: unit.Dp(1)}

View File

@ -161,7 +161,7 @@ func PopupMenu(th *Theme, s *LabelStyle, menu *Menu) MenuStyle {
} }
} }
func (tr *Tracker) layoutMenu(gtx C, title string, ct *ClickableTip, menu *Menu, width unit.Dp, items ...MenuItem) layout.Widget { func (tr *Tracker) layoutMenu(gtx C, title string, ct *Clickable, menu *Menu, width unit.Dp, items ...MenuItem) layout.Widget {
for ct.Clicked(gtx) { for ct.Clicked(gtx) {
menu.Visible = true menu.Visible = true
} }

View File

@ -52,18 +52,18 @@ func init() {
type NoteEditor struct { type NoteEditor struct {
TrackVoices *NumericUpDown TrackVoices *NumericUpDown
NewTrackBtn *ClickableTip NewTrackBtn *Clickable
DeleteTrackBtn *ClickableTip DeleteTrackBtn *Clickable
SplitTrackBtn *ClickableTip SplitTrackBtn *Clickable
AddSemitoneBtn *ClickableTip AddSemitoneBtn *Clickable
SubtractSemitoneBtn *ClickableTip SubtractSemitoneBtn *Clickable
AddOctaveBtn *ClickableTip AddOctaveBtn *Clickable
SubtractOctaveBtn *ClickableTip SubtractOctaveBtn *Clickable
NoteOffBtn *ClickableTip NoteOffBtn *Clickable
EffectBtn *ClickableTip EffectBtn *Clickable
UniqueBtn *ClickableTip UniqueBtn *Clickable
TrackMidiInBtn *ClickableTip TrackMidiInBtn *Clickable
scrollTable *ScrollTable scrollTable *ScrollTable
eventFilters []event.Filter eventFilters []event.Filter
@ -77,17 +77,17 @@ type NoteEditor struct {
func NewNoteEditor(model *tracker.Model) *NoteEditor { func NewNoteEditor(model *tracker.Model) *NoteEditor {
ret := &NoteEditor{ ret := &NoteEditor{
TrackVoices: NewNumericUpDown(), TrackVoices: NewNumericUpDown(),
NewTrackBtn: new(ClickableTip), NewTrackBtn: new(Clickable),
DeleteTrackBtn: new(ClickableTip), DeleteTrackBtn: new(Clickable),
SplitTrackBtn: new(ClickableTip), SplitTrackBtn: new(Clickable),
AddSemitoneBtn: new(ClickableTip), AddSemitoneBtn: new(Clickable),
SubtractSemitoneBtn: new(ClickableTip), SubtractSemitoneBtn: new(Clickable),
AddOctaveBtn: new(ClickableTip), AddOctaveBtn: new(Clickable),
SubtractOctaveBtn: new(ClickableTip), SubtractOctaveBtn: new(Clickable),
NoteOffBtn: new(ClickableTip), NoteOffBtn: new(Clickable),
EffectBtn: new(ClickableTip), EffectBtn: new(Clickable),
UniqueBtn: new(ClickableTip), UniqueBtn: new(Clickable),
TrackMidiInBtn: new(ClickableTip), TrackMidiInBtn: new(Clickable),
scrollTable: NewScrollTable( scrollTable: NewScrollTable(
model.Notes().Table(), model.Notes().Table(),
model.Tracks().List(), model.Tracks().List(),

View File

@ -17,8 +17,8 @@ import (
type ( type (
OscilloscopeState struct { OscilloscopeState struct {
onceBtn *ClickableTip onceBtn *Clickable
wrapBtn *ClickableTip wrapBtn *Clickable
lengthInBeatsNumber *NumericUpDown lengthInBeatsNumber *NumericUpDown
triggerChannelNumber *NumericUpDown triggerChannelNumber *NumericUpDown
xScale int xScale int
@ -38,8 +38,8 @@ type (
func NewOscilloscope(model *tracker.Model) *OscilloscopeState { func NewOscilloscope(model *tracker.Model) *OscilloscopeState {
return &OscilloscopeState{ return &OscilloscopeState{
onceBtn: new(ClickableTip), onceBtn: new(Clickable),
wrapBtn: new(ClickableTip), wrapBtn: new(Clickable),
lengthInBeatsNumber: NewNumericUpDown(), lengthInBeatsNumber: NewNumericUpDown(),
triggerChannelNumber: NewNumericUpDown(), triggerChannelNumber: NewNumericUpDown(),
} }

View File

@ -22,8 +22,8 @@ type SongPanel struct {
LoudnessExpander *Expander LoudnessExpander *Expander
PeakExpander *Expander PeakExpander *Expander
WeightingTypeBtn *ClickableTip WeightingTypeBtn *Clickable
OversamplingBtn *ClickableTip OversamplingBtn *Clickable
BPM *NumericUpDown BPM *NumericUpDown
RowsPerPattern *NumericUpDown RowsPerPattern *NumericUpDown
@ -48,8 +48,8 @@ func NewSongPanel(model *tracker.Model) *SongPanel {
MenuBar: NewMenuBar(model), MenuBar: NewMenuBar(model),
PlayBar: NewPlayBar(), PlayBar: NewPlayBar(),
WeightingTypeBtn: new(ClickableTip), WeightingTypeBtn: new(Clickable),
OversamplingBtn: new(ClickableTip), OversamplingBtn: new(Clickable),
SongSettingsExpander: &Expander{Expanded: true}, SongSettingsExpander: &Expander{Expanded: true},
ScopeExpander: &Expander{}, ScopeExpander: &Expander{},
@ -296,7 +296,7 @@ func (e *Expander) layoutHeader(gtx C, th *Theme, title string, smallWidget layo
} }
type MenuBar struct { type MenuBar struct {
Clickables []ClickableTip Clickables []Clickable
Menus []Menu Menus []Menu
fileMenuItems []MenuItem fileMenuItems []MenuItem
@ -304,14 +304,14 @@ type MenuBar struct {
midiMenuItems []MenuItem midiMenuItems []MenuItem
panicHint string panicHint string
PanicBtn *ClickableTip PanicBtn *Clickable
} }
func NewMenuBar(model *tracker.Model) *MenuBar { func NewMenuBar(model *tracker.Model) *MenuBar {
ret := &MenuBar{ ret := &MenuBar{
Clickables: make([]ClickableTip, 3), Clickables: make([]Clickable, 3),
Menus: make([]Menu, 3), Menus: make([]Menu, 3),
PanicBtn: new(ClickableTip), PanicBtn: new(Clickable),
panicHint: makeHint("Panic", " (%s)", "PanicToggle"), panicHint: makeHint("Panic", " (%s)", "PanicToggle"),
} }
ret.fileMenuItems = []MenuItem{ ret.fileMenuItems = []MenuItem{
@ -359,11 +359,11 @@ func (t *MenuBar) Layout(gtx C, tr *Tracker) D {
} }
type PlayBar struct { type PlayBar struct {
RewindBtn *ClickableTip RewindBtn *Clickable
PlayingBtn *ClickableTip PlayingBtn *Clickable
RecordBtn *ClickableTip RecordBtn *Clickable
FollowBtn *ClickableTip FollowBtn *Clickable
LoopBtn *ClickableTip LoopBtn *Clickable
// Hints // Hints
rewindHint string rewindHint string
playHint, stopHint string playHint, stopHint string
@ -374,11 +374,11 @@ type PlayBar struct {
func NewPlayBar() *PlayBar { func NewPlayBar() *PlayBar {
ret := &PlayBar{ ret := &PlayBar{
LoopBtn: new(ClickableTip), LoopBtn: new(Clickable),
RecordBtn: new(ClickableTip), RecordBtn: new(Clickable),
FollowBtn: new(ClickableTip), FollowBtn: new(Clickable),
PlayingBtn: new(ClickableTip), PlayingBtn: new(Clickable),
RewindBtn: new(ClickableTip), RewindBtn: new(Clickable),
} }
ret.rewindHint = makeHint("Rewind", "\n(%s)", "PlaySongStartUnfollow") ret.rewindHint = makeHint("Rewind", "\n(%s)", "PlaySongStartUnfollow")
ret.playHint = makeHint("Play", " (%s)", "PlayCurrentPosUnfollow") ret.playHint = makeHint("Play", " (%s)", "PlayCurrentPosUnfollow")

View File

@ -30,10 +30,10 @@ type UnitEditor struct {
sliderList *DragList sliderList *DragList
searchList *DragList searchList *DragList
Parameters []*ParameterWidget Parameters []*ParameterWidget
DeleteUnitBtn *ClickableTip DeleteUnitBtn *Clickable
CopyUnitBtn *ClickableTip CopyUnitBtn *Clickable
ClearUnitBtn *ClickableTip ClearUnitBtn *Clickable
DisableUnitBtn *ClickableTip DisableUnitBtn *Clickable
SelectTypeBtn *Clickable SelectTypeBtn *Clickable
commentEditor *Editor commentEditor *Editor
caser cases.Caser caser cases.Caser
@ -45,10 +45,10 @@ type UnitEditor struct {
func NewUnitEditor(m *tracker.Model) *UnitEditor { func NewUnitEditor(m *tracker.Model) *UnitEditor {
ret := &UnitEditor{ ret := &UnitEditor{
DeleteUnitBtn: new(ClickableTip), DeleteUnitBtn: new(Clickable),
ClearUnitBtn: new(ClickableTip), ClearUnitBtn: new(Clickable),
DisableUnitBtn: new(ClickableTip), DisableUnitBtn: new(Clickable),
CopyUnitBtn: new(ClickableTip), CopyUnitBtn: new(Clickable),
SelectTypeBtn: new(Clickable), SelectTypeBtn: new(Clickable),
commentEditor: NewEditor(true, true, text.Start), commentEditor: NewEditor(true, true, text.Start),
sliderList: NewDragList(m.Params().List(), layout.Vertical), sliderList: NewDragList(m.Params().List(), layout.Vertical),
@ -127,7 +127,7 @@ func (pe *UnitEditor) layoutSliders(gtx C, t *Tracker) D {
} }
func (pe *UnitEditor) layoutFooter(gtx C, t *Tracker) D { func (pe *UnitEditor) layoutFooter(gtx C, t *Tracker) D {
for pe.CopyUnitBtn.Clickable.Clicked(gtx) { for pe.CopyUnitBtn.Clicked(gtx) {
if contents, ok := t.Units().List().CopyElements(); ok { if contents, ok := t.Units().List().CopyElements(); ok {
gtx.Execute(clipboard.WriteCmd{Type: "application/text", Data: io.NopCloser(bytes.NewReader(contents))}) gtx.Execute(clipboard.WriteCmd{Type: "application/text", Data: io.NopCloser(bytes.NewReader(contents))})
t.Alerts().Add("Unit copied to clipboard", tracker.Info) t.Alerts().Add("Unit copied to clipboard", tracker.Info)
@ -223,9 +223,9 @@ func (pe *UnitEditor) command(e key.Event, t *Tracker) {
type ParameterWidget struct { type ParameterWidget struct {
floatWidget widget.Float floatWidget widget.Float
boolWidget widget.Bool boolWidget widget.Bool
instrBtn ClickableTip instrBtn Clickable
instrMenu Menu instrMenu Menu
unitBtn ClickableTip unitBtn Clickable
unitMenu Menu unitMenu Menu
Parameter tracker.Parameter Parameter tracker.Parameter
tipArea component.TipArea tipArea component.TipArea