diff --git a/tracker/gioui/buttons.go b/tracker/gioui/buttons.go index 62fbd62..cba4fc7 100644 --- a/tracker/gioui/buttons.go +++ b/tracker/gioui/buttons.go @@ -290,7 +290,6 @@ func Btn(th *Theme, style *ButtonStyle, button *Clickable, txt string) Button { Button: button, shaper: th.Material.Shaper, } - b.Font = labelDefaultFont return b } diff --git a/tracker/gioui/dialog.go b/tracker/gioui/dialog.go index 5a3326d..2aace09 100644 --- a/tracker/gioui/dialog.go +++ b/tracker/gioui/dialog.go @@ -105,7 +105,7 @@ func (d *DialogStyle) Layout(gtx C) D { gtx.Execute(key.FocusCmd{Tag: &d.dialog.BtnCancel}) } d.dialog.handleKeys(gtx) - paint.Fill(gtx.Ops, dialogBgColor) + paint.Fill(gtx.Ops, d.Theme.Dialog.Bg) visible := true return layout.Center.Layout(gtx, func(gtx C) D { return Popup(&visible).Layout(gtx, func(gtx C) D { diff --git a/tracker/gioui/instrument_editor.go b/tracker/gioui/instrument_editor.go index 70ba54c..9a85b67 100644 --- a/tracker/gioui/instrument_editor.go +++ b/tracker/gioui/instrument_editor.go @@ -9,7 +9,6 @@ import ( "strconv" "strings" - "gioui.org/font" "gioui.org/io/clipboard" "gioui.org/io/key" "gioui.org/layout" @@ -379,21 +378,20 @@ func (ie *InstrumentEditor) layoutUnitList(gtx C, t *Tracker) D { return layout.Dimensions{Size: gtx.Constraints.Min} } u := units[i] - var color color.NRGBA = t.Theme.InstrumentEditor.UnitList.Name.Color - f := labelDefaultFont + + labelStyle := t.Theme.InstrumentEditor.UnitList.Name + if u.Disabled { + labelStyle = t.Theme.InstrumentEditor.UnitList.NameDisabled + } stackText := strconv.FormatInt(int64(u.StackAfter), 10) if u.StackNeed > u.StackBefore { - color = errorColor + labelStyle.Color = t.Theme.InstrumentEditor.UnitList.Error (*tracker.Alerts)(t.Model).AddNamed("UnitNeedsInputs", fmt.Sprintf("%v needs at least %v input signals, got %v", u.Type, u.StackNeed, u.StackBefore), tracker.Error) } else if i == count-1 && u.StackAfter != 0 { - color = warningColor + labelStyle.Color = t.Theme.InstrumentEditor.UnitList.Warning (*tracker.Alerts)(t.Model).AddNamed("InstrumentLeavesSignals", fmt.Sprintf("Instrument leaves %v signal(s) on the stack", u.StackAfter), tracker.Warning) } - if u.Disabled { - color = disabledTextColor - f.Style = font.Italic - } stackLabel := Label(t.Theme, &t.Theme.InstrumentEditor.UnitList.Stack, stackText) @@ -422,8 +420,7 @@ func (ie *InstrumentEditor) layoutUnitList(gtx C, t *Tracker) D { ie.searchEditor.SetText(str.Value()) ie.unitDragList.Focus() } - style := MaterialEditor(t.Theme, &t.Theme.InstrumentEditor.UnitList.Name, ie.searchEditor, "---") - style.Color = color + style := MaterialEditor(t.Theme, &labelStyle, ie.searchEditor, "---") ret := style.Layout(gtx) str.Set(ie.searchEditor.Text()) return ret @@ -432,12 +429,11 @@ func (ie *InstrumentEditor) layoutUnitList(gtx C, t *Tracker) D { if text == "" { text = "---" } - return Label(t.Theme, &t.Theme.InstrumentEditor.UnitList.Name, text).Layout(gtx) + return Label(t.Theme, &labelStyle, text).Layout(gtx) } }), layout.Flexed(1, func(gtx C) D { unitNameLabel := Label(t.Theme, &t.Theme.InstrumentEditor.UnitList.Comment, u.Comment) - unitNameLabel.Color = color inset := layout.Inset{Left: unit.Dp(5)} return inset.Layout(gtx, unitNameLabel.Layout) }), diff --git a/tracker/gioui/note_editor.go b/tracker/gioui/note_editor.go index b78b398..d94e238 100644 --- a/tracker/gioui/note_editor.go +++ b/tracker/gioui/note_editor.go @@ -267,22 +267,20 @@ func (te *NoteEditor) layoutTracks(gtx C, t *Tracker) D { selection := te.scrollTable.Table.Range() hasTrackMidiIn := te.TrackMidiInBtn.Bool.Value() - trackerPatMarkerOp := colorOp(gtx, trackerPatMarker) - mediumEmphasisTextColorOp := colorOp(gtx, mediumEmphasisTextColor) - trackerActiveTextColorOp := colorOp(gtx, trackerActiveTextColor) - trackerInactiveTextColorOp := colorOp(gtx, trackerInactiveTextColor) + patternNoOp := colorOp(gtx, t.Theme.NoteEditor.PatternNo.Color) + uniqueOp := colorOp(gtx, t.Theme.NoteEditor.Unique.Color) + noteOp := colorOp(gtx, t.Theme.NoteEditor.Note.Color) cell := func(gtx C, x, y int) D { // draw the background, to indicate selection - color := transparent point := tracker.Point{X: x, Y: y} if drawSelection && selection.Contains(point) { - color = t.Theme.Selection.Inactive + color := t.Theme.Selection.Inactive if te.scrollTable.Focused() { color = t.Theme.Selection.Active } + paint.FillShape(gtx.Ops, color, clip.Rect{Min: image.Pt(0, 0), Max: image.Pt(gtx.Constraints.Min.X, gtx.Constraints.Min.Y)}.Op()) } - paint.FillShape(gtx.Ops, color, clip.Rect{Min: image.Pt(0, 0), Max: image.Pt(gtx.Constraints.Min.X, gtx.Constraints.Min.Y)}.Op()) // draw the cursor if point == cursor { c := t.Theme.Cursor.Inactive @@ -310,20 +308,17 @@ func (te *NoteEditor) layoutTracks(gtx C, t *Tracker) D { defer op.Offset(image.Pt(0, -2)).Push(gtx.Ops).Pop() s := t.Model.Order().Value(tracker.Point{X: x, Y: pat}) if row == 0 { // draw the pattern marker - widget.Label{}.Layout(gtx, t.Theme.Material.Shaper, trackerFont, trackerFontSize, patternIndexToString(s), trackerPatMarkerOp) + widget.Label{}.Layout(gtx, t.Theme.Material.Shaper, t.Theme.NoteEditor.PatternNo.Font, t.Theme.NoteEditor.PatternNo.TextSize, patternIndexToString(s), patternNoOp) } if row == 1 && t.Model.PatternUnique(x, s) { // draw a * if the pattern is unique - widget.Label{}.Layout(gtx, t.Theme.Material.Shaper, trackerFont, trackerFontSize, "*", mediumEmphasisTextColorOp) - } - op := trackerInactiveTextColorOp - if te.scrollTable.Table.Cursor() == point && te.scrollTable.Focused() { - op = trackerActiveTextColorOp + widget.Label{}.Layout(gtx, t.Theme.Material.Shaper, t.Theme.NoteEditor.Unique.Font, t.Theme.NoteEditor.Unique.TextSize, "*", uniqueOp) } + op := noteOp val := noteStr[byte(t.Model.Notes().Value(tracker.Point{X: x, Y: y}))] if t.Model.Notes().Effect(x) { val = hexStr[byte(t.Model.Notes().Value(tracker.Point{X: x, Y: y}))] } - widget.Label{Alignment: text.Middle}.Layout(gtx, t.Theme.Material.Shaper, trackerFont, trackerFontSize, val, op) + widget.Label{Alignment: text.Middle}.Layout(gtx, t.Theme.Material.Shaper, t.Theme.NoteEditor.Note.Font, t.Theme.NoteEditor.Note.TextSize, val, op) return D{Size: image.Pt(pxWidth, pxHeight)} } table := FilledScrollTable(t.Theme, te.scrollTable, cell, colTitle, rowTitle, nil, rowTitleBg) diff --git a/tracker/gioui/songpanel.go b/tracker/gioui/songpanel.go index c438f27..6da6dda 100644 --- a/tracker/gioui/songpanel.go +++ b/tracker/gioui/songpanel.go @@ -76,17 +76,7 @@ func (s *SongPanel) Layout(gtx C, t *Tracker) D { return s.MenuBar.Layout(gtx, t) }), layout.Rigid(func(gtx C) D { - return layout.Background{}.Layout(gtx, - func(gtx C) D { - // push defer clip op - defer clip.Rect(image.Rect(0, 0, gtx.Constraints.Min.X, gtx.Constraints.Min.Y)).Push(gtx.Ops).Pop() - paint.FillShape(gtx.Ops, songSurfaceColor, clip.Rect(image.Rect(0, 0, gtx.Constraints.Max.X, gtx.Constraints.Max.Y)).Op()) - return D{Size: image.Pt(gtx.Constraints.Min.X, gtx.Constraints.Min.Y)} - }, - func(gtx C) D { - return s.PlayBar.Layout(gtx, &t.Theme.Material) - }, - ) + return s.PlayBar.Layout(gtx, &t.Theme.Material) }), layout.Rigid(func(gtx C) D { return s.layoutSongOptions(gtx, t) @@ -95,7 +85,7 @@ func (s *SongPanel) Layout(gtx C, t *Tracker) D { } func (t *SongPanel) layoutSongOptions(gtx C, tr *Tracker) D { - paint.FillShape(gtx.Ops, songSurfaceColor, clip.Rect(image.Rect(0, 0, gtx.Constraints.Max.X, gtx.Constraints.Max.Y)).Op()) + paint.FillShape(gtx.Ops, tr.Theme.SongPanel.Bg, clip.Rect(image.Rect(0, 0, gtx.Constraints.Max.X, gtx.Constraints.Max.Y)).Op()) var weightingTxt string switch tracker.WeightingType(tr.Model.DetectorWeighting().Value()) { @@ -346,7 +336,7 @@ func (t *MenuBar) Layout(gtx C, tr *Tracker) D { panicBtnStyle := ToggleIcon(gtx, &tr.Theme.Material, t.PanicBtn, icons.AlertErrorOutline, icons.AlertError, t.panicHint, t.panicHint) if t.PanicBtn.Bool.Value() { - panicBtnStyle.IconButtonStyle.Color = errorColor + panicBtnStyle.IconButtonStyle.Color = tr.Theme.SongPanel.ErrorColor } menuLayouts := []layout.FlexChild{ layout.Rigid(tr.layoutMenu(gtx, "File", &t.Clickables[0], &t.Menus[0], unit.Dp(200), t.fileMenuItems...)), diff --git a/tracker/gioui/theme.go b/tracker/gioui/theme.go index d8edd2c..55c9e3e 100644 --- a/tracker/gioui/theme.go +++ b/tracker/gioui/theme.go @@ -5,9 +5,7 @@ import ( "fmt" "image/color" - "gioui.org/font/gofont" "gioui.org/text" - "gioui.org/unit" "gioui.org/widget" "gioui.org/widget/material" "golang.org/x/exp/shiny/materialdesign/icons" @@ -30,6 +28,7 @@ type Theme struct { Expander LabelStyle Version LabelStyle ErrorColor color.NRGBA + Bg color.NRGBA } Alert struct { Warning PopupAlertStyle @@ -40,11 +39,14 @@ type Theme struct { TrackTitle LabelStyle OrderRow LabelStyle PatternRow LabelStyle - Cell LabelStyle + Note LabelStyle + PatternNo LabelStyle + Unique LabelStyle Loop color.NRGBA Header LabelStyle } Dialog struct { + Bg color.NRGBA Title LabelStyle Text LabelStyle } @@ -69,10 +71,13 @@ type Theme struct { NameMuted LabelStyle } UnitList struct { - Name LabelStyle - Comment LabelStyle - Stack LabelStyle - Disabled LabelStyle + Name LabelStyle + NameDisabled LabelStyle + Comment LabelStyle + Stack LabelStyle + Disabled LabelStyle + Warning color.NRGBA + Error color.NRGBA } } UnitEditor struct { @@ -117,51 +122,29 @@ func mustIcon(ic *widget.Icon, err error) *widget.Icon { return ic } -var fontCollection []text.FontFace = gofont.Collection() - var white = color.NRGBA{R: 255, G: 255, B: 255, A: 255} var black = color.NRGBA{R: 0, G: 0, B: 0, A: 255} var transparent = color.NRGBA{A: 0} -var primaryColor = color.NRGBA{R: 206, G: 147, B: 216, A: 255} - -var highEmphasisTextColor = color.NRGBA{R: 222, G: 222, B: 222, A: 222} var mediumEmphasisTextColor = color.NRGBA{R: 153, G: 153, B: 153, A: 153} var disabledTextColor = color.NRGBA{R: 255, G: 255, B: 255, A: 97} -var backgroundColor = color.NRGBA{R: 18, G: 18, B: 18, A: 255} - -var labelDefaultFont = fontCollection[6].Font - -var trackerFont = fontCollection[6].Font -var trackerFontSize = unit.Sp(16) -var trackerInactiveTextColor = highEmphasisTextColor -var trackerActiveTextColor = color.NRGBA{R: 255, G: 255, B: 130, A: 255} var trackerPlayColor = color.NRGBA{R: 55, G: 55, B: 61, A: 255} -var trackerPatMarker = primaryColor var oneBeatHighlight = color.NRGBA{R: 31, G: 37, B: 38, A: 255} var twoBeatHighlight = color.NRGBA{R: 31, G: 51, B: 53, A: 255} var patternPlayColor = color.NRGBA{R: 55, G: 55, B: 61, A: 255} var patternCellColor = color.NRGBA{R: 255, G: 255, B: 255, A: 3} -var songSurfaceColor = color.NRGBA{R: 24, G: 24, B: 24, A: 255} - var popupSurfaceColor = color.NRGBA{R: 50, G: 50, B: 51, A: 255} var popupShadowColor = color.NRGBA{R: 0, G: 0, B: 0, A: 192} var cursorForTrackMidiInColor = color.NRGBA{R: 255, G: 100, B: 140, A: 48} var cursorNeighborForTrackMidiInColor = color.NRGBA{R: 255, G: 100, B: 140, A: 24} -var errorColor = color.NRGBA{R: 207, G: 102, B: 121, A: 255} - var menuHoverColor = color.NRGBA{R: 30, G: 31, B: 38, A: 255} var scrollBarColor = color.NRGBA{R: 255, G: 255, B: 255, A: 32} -var warningColor = color.NRGBA{R: 251, G: 192, B: 45, A: 255} - -var dialogBgColor = color.NRGBA{R: 0, G: 0, B: 0, A: 224} - var paramIsSendTargetColor = color.NRGBA{R: 120, G: 120, B: 210, A: 255} var paramValueInvalidColor = color.NRGBA{R: 120, G: 120, B: 120, A: 190} diff --git a/tracker/gioui/theme.yml b/tracker/gioui/theme.yml index e17cb64..9e32ae3 100644 --- a/tracker/gioui/theme.yml +++ b/tracker/gioui/theme.yml @@ -64,6 +64,7 @@ numericupdown: width: 70 height: 20 songpanel: + bg: { r: 24, g: 24, b: 24, A: 255 } rowheader: textsize: 14 color: *mediumemphasis @@ -88,6 +89,7 @@ alerts: bg: { r: 50, g: 50, b: 51, a: 255 } text: { textsize: 16, shadowcolor: *black } dialog: + bg: { r: 0, g: 0, b: 0, a: 224 } title: { textsize: 16, color: *highemphasis, shadowcolor: *black } text: { textsize: 16, color: *highemphasis, shadowcolor: *black } ordereditor: @@ -102,7 +104,11 @@ noteeditor: { textsize: 16, color: *secondarycolor, font: { typeface: "Go Mono" } } patternrow: { textsize: 16, color: *mediumemphasis, font: { typeface: "Go Mono" } } - cell: { textsize: 16, color: *primarycolor, font: { typeface: "Go Mono" } } + note: { textsize: 16, color: *highemphasis, font: { typeface: "Go Mono" } } + patternno: + { textsize: 16, color: *primarycolor, font: { typeface: "Go Mono" } } + unique: + { textsize: 16, color: *secondarycolor, font: { typeface: "Go Mono" } } loop: *loopcolor header: { textsize: 14, color: *disabled } menu: @@ -119,9 +125,16 @@ instrumenteditor: namemuted: { textsize: 12, color: *disabled } unitlist: name: { textsize: 12, color: *white, shadowcolor: *black } + namedisabled: + textsize: 12 + color: *disabled + shadowcolor: *black + font: { style: 1 } comment: { textsize: 12, color: *disabled } stack: { textsize: 12, color: *mediumemphasis, shadowcolor: *black } disabled: { textsize: 12, color: *disabled } + warning: *warningcolor + error: *errorcolor uniteditor: hint: { textsize: 16, color: *highemphasis, shadowcolor: *black } chooser: { textsize: 12, color: *white, shadowcolor: *black } diff --git a/tracker/gioui/tracker.go b/tracker/gioui/tracker.go index e0c574b..fb46f2c 100644 --- a/tracker/gioui/tracker.go +++ b/tracker/gioui/tracker.go @@ -8,6 +8,7 @@ import ( "time" "gioui.org/app" + "gioui.org/font/gofont" "gioui.org/io/event" "gioui.org/io/key" "gioui.org/io/pointer" @@ -94,7 +95,7 @@ func NewTracker(model *tracker.Model) *Tracker { filePathString: model.FilePath().String(), preferences: MakePreferences(), } - t.Theme.Material.Shaper = text.NewShaper(text.WithCollection(fontCollection)) + t.Theme.Material.Shaper = text.NewShaper(text.WithCollection(gofont.Collection())) t.PopupAlert = NewPopupAlert(model.Alerts()) if t.preferences.YmlError != nil { model.Alerts().Add( @@ -191,7 +192,7 @@ func (t *Tracker) Layout(gtx layout.Context, w *app.Window) { gtx.Metric.PxPerDp *= zoomFactor gtx.Metric.PxPerSp *= zoomFactor defer clip.Rect(image.Rectangle{Max: gtx.Constraints.Max}).Push(gtx.Ops).Pop() - paint.Fill(gtx.Ops, backgroundColor) + paint.Fill(gtx.Ops, t.Theme.Material.Bg) event.Op(gtx.Ops, t) // area for capturing scroll events if t.InstrumentEditor.enlargeBtn.Bool.Value() { diff --git a/tracker/gioui/vumeter.go b/tracker/gioui/vumeter.go deleted file mode 100644 index 7a47183..0000000 --- a/tracker/gioui/vumeter.go +++ /dev/null @@ -1,47 +0,0 @@ -package gioui - -import ( - "image" - - "gioui.org/op" - "gioui.org/op/clip" - "gioui.org/op/paint" - "gioui.org/unit" - "github.com/vsariola/sointu/tracker" -) - -type VuMeter struct { - Loudness tracker.Decibel - Peak [2]tracker.Decibel - Range float32 -} - -func (v VuMeter) Layout(gtx C) D { - defer op.Offset(image.Point{}).Push(gtx.Ops).Pop() - gtx.Constraints.Max.Y = gtx.Dp(unit.Dp(12)) - height := gtx.Dp(unit.Dp(6)) - for j := 0; j < 2; j++ { - value := float32(v.Loudness) + v.Range - if value > 0 { - x := int(value/v.Range*float32(gtx.Constraints.Max.X) + 0.5) - if x > gtx.Constraints.Max.X { - x = gtx.Constraints.Max.X - } - paint.FillShape(gtx.Ops, mediumEmphasisTextColor, clip.Rect(image.Rect(0, 0, x, height)).Op()) - } - valueMax := float32(v.Peak[j]) + v.Range - if valueMax > 0 { - color := white - if valueMax >= v.Range { - color = errorColor - } - x := int(valueMax/v.Range*float32(gtx.Constraints.Max.X) + 0.5) - if x > gtx.Constraints.Max.X { - x = gtx.Constraints.Max.X - } - paint.FillShape(gtx.Ops, color, clip.Rect(image.Rect(x-1, 0, x, height)).Op()) - } - op.Offset(image.Point{0, height}).Add(gtx.Ops) - } - return D{Size: gtx.Constraints.Max} -}