mirror of
https://github.com/vsariola/sointu.git
synced 2025-06-03 17:18:20 -04:00
feat(tracker/gioui): add tooltips
Currently, only iconbtns and numeric updowns have tooltips. Closes #84
This commit is contained in:
parent
cafb43f8c8
commit
5884a8d195
@ -5,10 +5,28 @@ import (
|
||||
"gioui.org/unit"
|
||||
"gioui.org/widget"
|
||||
"gioui.org/widget/material"
|
||||
"gioui.org/x/component"
|
||||
)
|
||||
|
||||
func IconButton(th *material.Theme, w *widget.Clickable, icon []byte, enabled bool) material.IconButtonStyle {
|
||||
ret := material.IconButton(th, w, widgetForIcon(icon), "")
|
||||
type TipClickable struct {
|
||||
Clickable widget.Clickable
|
||||
TipArea component.TipArea
|
||||
}
|
||||
|
||||
type TipIconButtonStyle struct {
|
||||
IconButtonStyle material.IconButtonStyle
|
||||
Tooltip component.Tooltip
|
||||
tipArea *component.TipArea
|
||||
}
|
||||
|
||||
func Tooltip(th *material.Theme, tip string) component.Tooltip {
|
||||
tooltip := component.PlatformTooltip(th, tip)
|
||||
tooltip.Bg = black
|
||||
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 {
|
||||
@ -16,7 +34,15 @@ func IconButton(th *material.Theme, w *widget.Clickable, icon []byte, enabled bo
|
||||
} else {
|
||||
ret.Color = disabledTextColor
|
||||
}
|
||||
return ret
|
||||
return TipIconButtonStyle{
|
||||
IconButtonStyle: ret,
|
||||
Tooltip: Tooltip(th, tip),
|
||||
tipArea: &w.TipArea,
|
||||
}
|
||||
}
|
||||
|
||||
func (t *TipIconButtonStyle) Layout(gtx C) D {
|
||||
return t.tipArea.Layout(gtx, t.Tooltip, t.IconButtonStyle.Layout)
|
||||
}
|
||||
|
||||
func LowEmphasisButton(th *material.Theme, w *widget.Clickable, text string) material.ButtonStyle {
|
||||
|
@ -26,14 +26,14 @@ import (
|
||||
)
|
||||
|
||||
type InstrumentEditor struct {
|
||||
newInstrumentBtn *widget.Clickable
|
||||
enlargeBtn *widget.Clickable
|
||||
deleteInstrumentBtn *widget.Clickable
|
||||
copyInstrumentBtn *widget.Clickable
|
||||
saveInstrumentBtn *widget.Clickable
|
||||
loadInstrumentBtn *widget.Clickable
|
||||
addUnitBtn *widget.Clickable
|
||||
commentExpandBtn *widget.Clickable
|
||||
newInstrumentBtn *TipClickable
|
||||
enlargeBtn *TipClickable
|
||||
deleteInstrumentBtn *TipClickable
|
||||
copyInstrumentBtn *TipClickable
|
||||
saveInstrumentBtn *TipClickable
|
||||
loadInstrumentBtn *TipClickable
|
||||
addUnitBtn *TipClickable
|
||||
commentExpandBtn *TipClickable
|
||||
commentEditor *widget.Editor
|
||||
nameEditor *widget.Editor
|
||||
unitTypeEditor *widget.Editor
|
||||
@ -52,14 +52,14 @@ type InstrumentEditor struct {
|
||||
|
||||
func NewInstrumentEditor() *InstrumentEditor {
|
||||
return &InstrumentEditor{
|
||||
newInstrumentBtn: new(widget.Clickable),
|
||||
enlargeBtn: new(widget.Clickable),
|
||||
deleteInstrumentBtn: new(widget.Clickable),
|
||||
copyInstrumentBtn: new(widget.Clickable),
|
||||
saveInstrumentBtn: new(widget.Clickable),
|
||||
loadInstrumentBtn: new(widget.Clickable),
|
||||
addUnitBtn: new(widget.Clickable),
|
||||
commentExpandBtn: new(widget.Clickable),
|
||||
newInstrumentBtn: new(TipClickable),
|
||||
enlargeBtn: new(TipClickable),
|
||||
deleteInstrumentBtn: new(TipClickable),
|
||||
copyInstrumentBtn: new(TipClickable),
|
||||
saveInstrumentBtn: new(TipClickable),
|
||||
loadInstrumentBtn: new(TipClickable),
|
||||
addUnitBtn: new(TipClickable),
|
||||
commentExpandBtn: new(TipClickable),
|
||||
commentEditor: new(widget.Editor),
|
||||
nameEditor: &widget.Editor{SingleLine: true, Submit: true, Alignment: text.Middle},
|
||||
unitTypeEditor: &widget.Editor{SingleLine: true, Submit: true, Alignment: text.Start},
|
||||
@ -103,30 +103,28 @@ func (ie *InstrumentEditor) Layout(gtx C, t *Tracker) D {
|
||||
}.Add(gtx.Ops)
|
||||
area.Pop()
|
||||
|
||||
var icon []byte
|
||||
enlargeTip := "Enlarge"
|
||||
icon := icons.NavigationFullscreen
|
||||
if t.InstrEnlarged() {
|
||||
icon = icons.NavigationFullscreenExit
|
||||
} else {
|
||||
icon = icons.NavigationFullscreen
|
||||
enlargeTip = "Shrink"
|
||||
}
|
||||
fullscreenBtnStyle := IconButton(t.Theme, ie.enlargeBtn, icon, true)
|
||||
for ie.enlargeBtn.Clicked() {
|
||||
fullscreenBtnStyle := IconButton(t.Theme, ie.enlargeBtn, icon, true, enlargeTip)
|
||||
for ie.enlargeBtn.Clickable.Clicked() {
|
||||
t.SetInstrEnlarged(!t.InstrEnlarged())
|
||||
}
|
||||
for ie.newInstrumentBtn.Clicked() {
|
||||
for ie.newInstrumentBtn.Clickable.Clicked() {
|
||||
t.AddInstrument(true)
|
||||
}
|
||||
octave := func(gtx C) D {
|
||||
in := layout.UniformInset(unit.Dp(1))
|
||||
t.OctaveNumberInput.Value = t.Octave()
|
||||
numStyle := NumericUpDown(t.Theme, t.OctaveNumberInput, 0, 9)
|
||||
gtx.Constraints.Min.Y = gtx.Dp(unit.Dp(20))
|
||||
gtx.Constraints.Min.X = gtx.Dp(unit.Dp(70))
|
||||
numStyle := NumericUpDown(t.Theme, t.OctaveNumberInput, 0, 9, "Octave down (<) or up (>)")
|
||||
dims := in.Layout(gtx, numStyle.Layout)
|
||||
t.SetOctave(t.OctaveNumberInput.Value)
|
||||
return dims
|
||||
}
|
||||
newBtnStyle := IconButton(t.Theme, ie.newInstrumentBtn, icons.ContentAdd, t.CanAddInstrument())
|
||||
newBtnStyle := IconButton(t.Theme, ie.newInstrumentBtn, icons.ContentAdd, t.CanAddInstrument(), "Add\ninstrument")
|
||||
ret := layout.Flex{Axis: layout.Vertical}.Layout(gtx,
|
||||
layout.Rigid(func(gtx C) D {
|
||||
return layout.Flex{}.Layout(
|
||||
@ -170,15 +168,17 @@ func (ie *InstrumentEditor) Layout(gtx C, t *Tracker) D {
|
||||
func (ie *InstrumentEditor) layoutInstrumentHeader(gtx C, t *Tracker) D {
|
||||
header := func(gtx C) D {
|
||||
collapseIcon := icons.NavigationExpandLess
|
||||
commentTip := "Collapse comment"
|
||||
if !ie.commentExpanded {
|
||||
collapseIcon = icons.NavigationExpandMore
|
||||
commentTip = "Expand comment"
|
||||
}
|
||||
|
||||
commentExpandBtnStyle := IconButton(t.Theme, ie.commentExpandBtn, collapseIcon, true)
|
||||
copyInstrumentBtnStyle := IconButton(t.Theme, ie.copyInstrumentBtn, icons.ContentContentCopy, true)
|
||||
saveInstrumentBtnStyle := IconButton(t.Theme, ie.saveInstrumentBtn, icons.ContentSave, true)
|
||||
loadInstrumentBtnStyle := IconButton(t.Theme, ie.loadInstrumentBtn, icons.FileFolderOpen, true)
|
||||
deleteInstrumentBtnStyle := IconButton(t.Theme, ie.deleteInstrumentBtn, icons.ActionDelete, t.CanDeleteInstrument())
|
||||
commentExpandBtnStyle := IconButton(t.Theme, ie.commentExpandBtn, collapseIcon, true, commentTip)
|
||||
copyInstrumentBtnStyle := IconButton(t.Theme, ie.copyInstrumentBtn, icons.ContentContentCopy, true, "Copy instrument")
|
||||
saveInstrumentBtnStyle := IconButton(t.Theme, ie.saveInstrumentBtn, icons.ContentSave, true, "Save instrument")
|
||||
loadInstrumentBtnStyle := IconButton(t.Theme, ie.loadInstrumentBtn, icons.FileFolderOpen, true, "Load instrument")
|
||||
deleteInstrumentBtnStyle := IconButton(t.Theme, ie.deleteInstrumentBtn, icons.ActionDelete, t.CanDeleteInstrument(), "Delete\ninstrument")
|
||||
|
||||
header := func(gtx C) D {
|
||||
return layout.Flex{Axis: layout.Horizontal, Alignment: layout.Middle}.Layout(gtx,
|
||||
@ -186,9 +186,7 @@ func (ie *InstrumentEditor) layoutInstrumentHeader(gtx C, t *Tracker) D {
|
||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||
maxRemain := t.MaxInstrumentVoices()
|
||||
t.InstrumentVoices.Value = t.Instrument().NumVoices
|
||||
numStyle := NumericUpDown(t.Theme, t.InstrumentVoices, 0, maxRemain)
|
||||
gtx.Constraints.Min.Y = gtx.Dp(unit.Dp(20))
|
||||
gtx.Constraints.Min.X = gtx.Dp(unit.Dp(70))
|
||||
numStyle := NumericUpDown(t.Theme, t.InstrumentVoices, 0, maxRemain, "Number of voices for this instrument")
|
||||
dims := numStyle.Layout(gtx)
|
||||
t.SetInstrumentVoices(t.InstrumentVoices.Value)
|
||||
return dims
|
||||
@ -200,7 +198,7 @@ func (ie *InstrumentEditor) layoutInstrumentHeader(gtx C, t *Tracker) D {
|
||||
layout.Rigid(copyInstrumentBtnStyle.Layout),
|
||||
layout.Rigid(deleteInstrumentBtnStyle.Layout))
|
||||
}
|
||||
for ie.commentExpandBtn.Clicked() {
|
||||
for ie.commentExpandBtn.Clickable.Clicked() {
|
||||
ie.commentExpanded = !ie.commentExpanded
|
||||
if !ie.commentExpanded {
|
||||
key.FocusOp{Tag: &ie.tag}.Add(gtx.Ops) // clear focus
|
||||
@ -236,14 +234,14 @@ func (ie *InstrumentEditor) layoutInstrumentHeader(gtx C, t *Tracker) D {
|
||||
}
|
||||
return header(gtx)
|
||||
}
|
||||
for ie.copyInstrumentBtn.Clicked() {
|
||||
for ie.copyInstrumentBtn.Clickable.Clicked() {
|
||||
contents, err := yaml.Marshal(t.Instrument())
|
||||
if err == nil {
|
||||
clipboard.WriteOp{Text: string(contents)}.Add(gtx.Ops)
|
||||
t.Alert.Update("Instrument copied to clipboard", Notify, time.Second*3)
|
||||
}
|
||||
}
|
||||
for ie.deleteInstrumentBtn.Clicked() {
|
||||
for ie.deleteInstrumentBtn.Clickable.Clicked() {
|
||||
if t.CanDeleteInstrument() {
|
||||
dialogStyle := ConfirmDialog(t.Theme, ie.confirmInstrDelete, "Are you sure you want to delete this instrument?")
|
||||
ie.confirmInstrDelete.Visible = true
|
||||
@ -257,11 +255,11 @@ func (ie *InstrumentEditor) layoutInstrumentHeader(gtx C, t *Tracker) D {
|
||||
for ie.confirmInstrDelete.BtnCancel.Clicked() {
|
||||
t.ModalDialog = nil
|
||||
}
|
||||
for ie.saveInstrumentBtn.Clicked() {
|
||||
for ie.saveInstrumentBtn.Clickable.Clicked() {
|
||||
t.SaveInstrument()
|
||||
}
|
||||
|
||||
for ie.loadInstrumentBtn.Clicked() {
|
||||
for ie.loadInstrumentBtn.Clickable.Clicked() {
|
||||
t.LoadInstrument()
|
||||
}
|
||||
return Surface{Gray: 37, Focus: ie.wasFocused}.Layout(gtx, header)
|
||||
@ -362,14 +360,14 @@ func (ie *InstrumentEditor) layoutInstrumentNames(gtx C, t *Tracker) D {
|
||||
return dims
|
||||
}
|
||||
func (ie *InstrumentEditor) layoutInstrumentEditor(gtx C, t *Tracker) D {
|
||||
for ie.addUnitBtn.Clicked() {
|
||||
for ie.addUnitBtn.Clickable.Clicked() {
|
||||
t.AddUnit(true)
|
||||
ie.unitDragList.Focus()
|
||||
}
|
||||
addUnitBtnStyle := material.IconButton(t.Theme, ie.addUnitBtn, widgetForIcon(icons.ContentAdd), "Add unit")
|
||||
addUnitBtnStyle.Color = t.Theme.ContrastFg
|
||||
addUnitBtnStyle.Background = t.Theme.Fg
|
||||
addUnitBtnStyle.Inset = layout.UniformInset(unit.Dp(4))
|
||||
addUnitBtnStyle := IconButton(t.Theme, ie.addUnitBtn, icons.ContentAdd, true, "Add unit (Ctrl+Enter)")
|
||||
addUnitBtnStyle.IconButtonStyle.Color = t.Theme.ContrastFg
|
||||
addUnitBtnStyle.IconButtonStyle.Background = t.Theme.Fg
|
||||
addUnitBtnStyle.IconButtonStyle.Inset = layout.UniformInset(unit.Dp(4))
|
||||
|
||||
units := t.Instrument().Units
|
||||
for len(ie.stackUse) < len(units) {
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
"gioui.org/op/clip"
|
||||
"gioui.org/op/paint"
|
||||
"gioui.org/widget"
|
||||
"gioui.org/x/component"
|
||||
|
||||
"gioui.org/gesture"
|
||||
"gioui.org/io/pointer"
|
||||
@ -27,6 +28,7 @@ type NumberInput struct {
|
||||
dragStartXY float32
|
||||
clickDecrease gesture.Click
|
||||
clickIncrease gesture.Click
|
||||
tipArea component.TipArea
|
||||
}
|
||||
|
||||
type NumericUpDownStyle struct {
|
||||
@ -43,10 +45,13 @@ type NumericUpDownStyle struct {
|
||||
Border unit.Dp
|
||||
ButtonWidth unit.Dp
|
||||
UnitsPerStep unit.Dp
|
||||
Tooltip component.Tooltip
|
||||
Width unit.Dp
|
||||
Height unit.Dp
|
||||
shaper text.Shaper
|
||||
}
|
||||
|
||||
func NumericUpDown(th *material.Theme, number *NumberInput, min, max int) NumericUpDownStyle {
|
||||
func NumericUpDown(th *material.Theme, number *NumberInput, min, max int, tooltip string) NumericUpDownStyle {
|
||||
bgColor := th.Palette.Fg
|
||||
bgColor.R /= 4
|
||||
bgColor.G /= 4
|
||||
@ -64,12 +69,23 @@ func NumericUpDown(th *material.Theme, number *NumberInput, min, max int) Numeri
|
||||
Border: unit.Dp(1),
|
||||
UnitsPerStep: unit.Dp(8),
|
||||
TextSize: th.TextSize * 14 / 16,
|
||||
Tooltip: Tooltip(th, tooltip),
|
||||
Width: unit.Dp(70),
|
||||
Height: unit.Dp(20),
|
||||
shaper: *th.Shaper,
|
||||
}
|
||||
}
|
||||
|
||||
func (s NumericUpDownStyle) Layout(gtx C) D {
|
||||
size := gtx.Constraints.Min
|
||||
if s.Tooltip.Text.Text != "" {
|
||||
return s.NumberInput.tipArea.Layout(gtx, s.Tooltip, s.actualLayout)
|
||||
}
|
||||
return s.actualLayout(gtx)
|
||||
}
|
||||
|
||||
func (s NumericUpDownStyle) actualLayout(gtx C) D {
|
||||
size := image.Pt(gtx.Dp(s.Width), gtx.Dp(s.Height))
|
||||
gtx.Constraints.Min = size
|
||||
rr := gtx.Dp(s.CornerRadius)
|
||||
border := gtx.Dp(s.Border)
|
||||
c := clip.UniformRRect(image.Rectangle{Max: gtx.Constraints.Min}, rr).Push(gtx.Ops)
|
||||
|
@ -24,9 +24,9 @@ type ParamEditor struct {
|
||||
list *layout.List
|
||||
scrollBar *ScrollBar
|
||||
Parameters []*ParameterWidget
|
||||
DeleteUnitBtn *widget.Clickable
|
||||
CopyUnitBtn *widget.Clickable
|
||||
ClearUnitBtn *widget.Clickable
|
||||
DeleteUnitBtn *TipClickable
|
||||
CopyUnitBtn *TipClickable
|
||||
ClearUnitBtn *TipClickable
|
||||
ChooseUnitTypeBtns []*widget.Clickable
|
||||
tag bool
|
||||
focused bool
|
||||
@ -43,9 +43,9 @@ func (pe *ParamEditor) Focused() bool {
|
||||
|
||||
func NewParamEditor() *ParamEditor {
|
||||
ret := &ParamEditor{
|
||||
DeleteUnitBtn: new(widget.Clickable),
|
||||
ClearUnitBtn: new(widget.Clickable),
|
||||
CopyUnitBtn: new(widget.Clickable),
|
||||
DeleteUnitBtn: new(TipClickable),
|
||||
ClearUnitBtn: new(TipClickable),
|
||||
CopyUnitBtn: new(TipClickable),
|
||||
list: &layout.List{Axis: layout.Vertical},
|
||||
scrollBar: &ScrollBar{Axis: layout.Vertical},
|
||||
}
|
||||
@ -173,17 +173,17 @@ func (pe *ParamEditor) layoutUnitSliders(gtx C, t *Tracker) D {
|
||||
|
||||
func (pe *ParamEditor) layoutUnitFooter(t *Tracker) layout.Widget {
|
||||
return func(gtx C) D {
|
||||
for pe.ClearUnitBtn.Clicked() {
|
||||
for pe.ClearUnitBtn.Clickable.Clicked() {
|
||||
t.SetUnitType("")
|
||||
op.InvalidateOp{}.Add(gtx.Ops)
|
||||
t.InstrumentEditor.unitDragList.Focus()
|
||||
}
|
||||
for pe.DeleteUnitBtn.Clicked() {
|
||||
for pe.DeleteUnitBtn.Clickable.Clicked() {
|
||||
t.DeleteUnit(false)
|
||||
op.InvalidateOp{}.Add(gtx.Ops)
|
||||
t.InstrumentEditor.unitDragList.Focus()
|
||||
}
|
||||
for pe.CopyUnitBtn.Clicked() {
|
||||
for pe.CopyUnitBtn.Clickable.Clicked() {
|
||||
op.InvalidateOp{}.Add(gtx.Ops)
|
||||
contents, err := yaml.Marshal(t.Unit())
|
||||
if err == nil {
|
||||
@ -191,8 +191,8 @@ func (pe *ParamEditor) layoutUnitFooter(t *Tracker) layout.Widget {
|
||||
t.Alert.Update("Unit copied to clipboard", Notify, time.Second*3)
|
||||
}
|
||||
}
|
||||
copyUnitBtnStyle := IconButton(t.Theme, pe.CopyUnitBtn, icons.ContentContentCopy, true)
|
||||
deleteUnitBtnStyle := IconButton(t.Theme, pe.DeleteUnitBtn, icons.ActionDelete, t.CanDeleteUnit())
|
||||
copyUnitBtnStyle := IconButton(t.Theme, pe.CopyUnitBtn, icons.ContentContentCopy, true, "Copy unit (Ctrl+C)")
|
||||
deleteUnitBtnStyle := IconButton(t.Theme, pe.DeleteUnitBtn, icons.ActionDelete, t.CanDeleteUnit(), "Delete unit (Del)")
|
||||
text := t.Unit().Type
|
||||
if text == "" {
|
||||
text = "Choose unit type"
|
||||
@ -206,7 +206,7 @@ func (pe *ParamEditor) layoutUnitFooter(t *Tracker) layout.Widget {
|
||||
layout.Rigid(func(gtx C) D {
|
||||
var dims D
|
||||
if t.Unit().Type != "" {
|
||||
clearUnitBtnStyle := IconButton(t.Theme, pe.ClearUnitBtn, icons.ContentClear, true)
|
||||
clearUnitBtnStyle := IconButton(t.Theme, pe.ClearUnitBtn, icons.ContentClear, true, "Clear unit")
|
||||
dims = clearUnitBtnStyle.Layout(gtx)
|
||||
}
|
||||
return D{Size: image.Pt(gtx.Dp(unit.Dp(48)), dims.Size.Y)}
|
||||
|
@ -148,7 +148,7 @@ func (t *Tracker) layoutSongOptions(gtx C) D {
|
||||
layout.Rigid(Label("LEN:", white)),
|
||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||
t.SongLength.Value = t.Song().Score.Length
|
||||
numStyle := NumericUpDown(t.Theme, t.SongLength, 1, math.MaxInt32)
|
||||
numStyle := NumericUpDown(t.Theme, t.SongLength, 1, math.MaxInt32, "Song length")
|
||||
gtx.Constraints.Min.Y = gtx.Dp(unit.Dp(20))
|
||||
gtx.Constraints.Min.X = gtx.Dp(unit.Dp(70))
|
||||
dims := in.Layout(gtx, numStyle.Layout)
|
||||
@ -162,7 +162,7 @@ func (t *Tracker) layoutSongOptions(gtx C) D {
|
||||
layout.Rigid(Label("BPM:", white)),
|
||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||
t.BPM.Value = t.Song().BPM
|
||||
numStyle := NumericUpDown(t.Theme, t.BPM, 1, 999)
|
||||
numStyle := NumericUpDown(t.Theme, t.BPM, 1, 999, "Beats per minute")
|
||||
gtx.Constraints.Min.Y = gtx.Dp(unit.Dp(20))
|
||||
gtx.Constraints.Min.X = gtx.Dp(unit.Dp(70))
|
||||
dims := in.Layout(gtx, numStyle.Layout)
|
||||
@ -176,7 +176,7 @@ func (t *Tracker) layoutSongOptions(gtx C) D {
|
||||
layout.Rigid(Label("RPP:", white)),
|
||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||
t.RowsPerPattern.Value = t.Song().Score.RowsPerPattern
|
||||
numStyle := NumericUpDown(t.Theme, t.RowsPerPattern, 1, 255)
|
||||
numStyle := NumericUpDown(t.Theme, t.RowsPerPattern, 1, 255, "Rows per pattern")
|
||||
gtx.Constraints.Min.Y = gtx.Dp(unit.Dp(20))
|
||||
gtx.Constraints.Min.X = gtx.Dp(unit.Dp(70))
|
||||
dims := in.Layout(gtx, numStyle.Layout)
|
||||
@ -190,7 +190,7 @@ func (t *Tracker) layoutSongOptions(gtx C) D {
|
||||
layout.Rigid(Label("RPB:", white)),
|
||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||
t.RowsPerBeat.Value = t.Song().RowsPerBeat
|
||||
numStyle := NumericUpDown(t.Theme, t.RowsPerBeat, 1, 32)
|
||||
numStyle := NumericUpDown(t.Theme, t.RowsPerBeat, 1, 32, "Rows per beat")
|
||||
gtx.Constraints.Min.Y = gtx.Dp(unit.Dp(20))
|
||||
gtx.Constraints.Min.X = gtx.Dp(unit.Dp(70))
|
||||
dims := in.Layout(gtx, numStyle.Layout)
|
||||
@ -203,10 +203,8 @@ func (t *Tracker) layoutSongOptions(gtx C) D {
|
||||
return layout.Flex{Axis: layout.Horizontal}.Layout(gtx,
|
||||
layout.Rigid(Label("STP:", white)),
|
||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||
numStyle := NumericUpDown(t.Theme, t.Step, 0, 8)
|
||||
numStyle := NumericUpDown(t.Theme, t.Step, 0, 8, "Cursor step")
|
||||
numStyle.UnitsPerStep = unit.Dp(20)
|
||||
gtx.Constraints.Min.Y = gtx.Dp(unit.Dp(20))
|
||||
gtx.Constraints.Min.X = gtx.Dp(unit.Dp(70))
|
||||
dims := in.Layout(gtx, numStyle.Layout)
|
||||
return dims
|
||||
}),
|
||||
|
@ -25,8 +25,8 @@ const patmarkWidth = 16
|
||||
|
||||
type TrackEditor struct {
|
||||
TrackVoices *NumberInput
|
||||
NewTrackBtn *widget.Clickable
|
||||
DeleteTrackBtn *widget.Clickable
|
||||
NewTrackBtn *TipClickable
|
||||
DeleteTrackBtn *TipClickable
|
||||
AddSemitoneBtn *widget.Clickable
|
||||
SubtractSemitoneBtn *widget.Clickable
|
||||
AddOctaveBtn *widget.Clickable
|
||||
@ -42,8 +42,8 @@ type TrackEditor struct {
|
||||
func NewTrackEditor() *TrackEditor {
|
||||
return &TrackEditor{
|
||||
TrackVoices: new(NumberInput),
|
||||
NewTrackBtn: new(widget.Clickable),
|
||||
DeleteTrackBtn: new(widget.Clickable),
|
||||
NewTrackBtn: new(TipClickable),
|
||||
DeleteTrackBtn: new(TipClickable),
|
||||
AddSemitoneBtn: new(widget.Clickable),
|
||||
SubtractSemitoneBtn: new(widget.Clickable),
|
||||
AddOctaveBtn: new(widget.Clickable),
|
||||
@ -61,7 +61,7 @@ func (te *TrackEditor) Focused() bool {
|
||||
}
|
||||
|
||||
func (te *TrackEditor) ChildFocused() bool {
|
||||
return te.AddOctaveBtn.Focused() || te.AddSemitoneBtn.Focused() || te.DeleteTrackBtn.Focused() || te.NewTrackBtn.Focused() || te.NoteOffBtn.Focused() || te.SubtractOctaveBtn.Focused() || te.SubtractSemitoneBtn.Focused() || te.SubtractSemitoneBtn.Focused() || te.SubtractSemitoneBtn.Focused()
|
||||
return te.AddOctaveBtn.Focused() || te.AddSemitoneBtn.Focused() || te.DeleteTrackBtn.Clickable.Focused() || te.NewTrackBtn.Clickable.Focused() || te.NoteOffBtn.Focused() || te.SubtractOctaveBtn.Focused() || te.SubtractSemitoneBtn.Focused() || te.SubtractSemitoneBtn.Focused() || te.SubtractSemitoneBtn.Focused()
|
||||
}
|
||||
|
||||
var trackerEditorKeys key.Set = "+|-|←|→|↑|↓|Ctrl-←|Ctrl-→|Ctrl-↑|Ctrl-↓|Shift-←|Shift-→|Shift-↑|Shift-↓|⏎|⇱|⇲|⌫|⌦|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|0|1|2|3|4|5|6|7|8|9|,|."
|
||||
@ -191,11 +191,11 @@ func (te *TrackEditor) Layout(gtx layout.Context, t *Tracker) layout.Dimensions
|
||||
|
||||
rowMarkers := layout.Rigid(t.layoutRowMarkers)
|
||||
|
||||
for te.NewTrackBtn.Clicked() {
|
||||
for te.NewTrackBtn.Clickable.Clicked() {
|
||||
t.AddTrack(true)
|
||||
}
|
||||
|
||||
for te.DeleteTrackBtn.Clicked() {
|
||||
for te.DeleteTrackBtn.Clickable.Clicked() {
|
||||
t.DeleteTrack(false)
|
||||
}
|
||||
|
||||
@ -234,15 +234,13 @@ func (te *TrackEditor) Layout(gtx layout.Context, t *Tracker) layout.Dimensions
|
||||
addOctaveBtnStyle := LowEmphasisButton(t.Theme, te.AddOctaveBtn, "+12")
|
||||
subtractOctaveBtnStyle := LowEmphasisButton(t.Theme, te.SubtractOctaveBtn, "-12")
|
||||
noteOffBtnStyle := LowEmphasisButton(t.Theme, te.NoteOffBtn, "Note Off")
|
||||
deleteTrackBtnStyle := IconButton(t.Theme, te.DeleteTrackBtn, icons.ActionDelete, t.CanDeleteTrack())
|
||||
newTrackBtnStyle := IconButton(t.Theme, te.NewTrackBtn, icons.ContentAdd, t.CanAddTrack())
|
||||
deleteTrackBtnStyle := IconButton(t.Theme, te.DeleteTrackBtn, icons.ActionDelete, t.CanDeleteTrack(), "Delete track")
|
||||
newTrackBtnStyle := IconButton(t.Theme, te.NewTrackBtn, icons.ContentAdd, t.CanAddTrack(), "Add track")
|
||||
n := t.Song().Score.Tracks[t.Cursor().Track].NumVoices
|
||||
te.TrackVoices.Value = n
|
||||
in := layout.UniformInset(unit.Dp(1))
|
||||
voiceUpDown := func(gtx C) D {
|
||||
numStyle := NumericUpDown(t.Theme, te.TrackVoices, 1, t.MaxTrackVoices())
|
||||
gtx.Constraints.Min.Y = gtx.Dp(unit.Dp(20))
|
||||
gtx.Constraints.Min.X = gtx.Dp(unit.Dp(70))
|
||||
numStyle := NumericUpDown(t.Theme, te.TrackVoices, 1, t.MaxTrackVoices(), "Number of voices for this track")
|
||||
return in.Layout(gtx, numStyle.Layout)
|
||||
}
|
||||
t.TrackHexCheckBox.Value = t.Song().Score.Tracks[t.Cursor().Track].Effect
|
||||
|
Loading…
x
Reference in New Issue
Block a user