mirror of
https://github.com/vsariola/sointu.git
synced 2025-07-24 16:04:51 -04:00
drafting
This commit is contained in:
parent
57926d4b0e
commit
5a11b290a2
@ -294,7 +294,7 @@ func (m *Model) updateRails() {
|
|||||||
m.derived.railError = RailError{
|
m.derived.railError = RailError{
|
||||||
InstrIndex: scratch[0].instr,
|
InstrIndex: scratch[0].instr,
|
||||||
UnitIndex: scratch[0].unit,
|
UnitIndex: scratch[0].unit,
|
||||||
Err: fmt.Errorf("instrument %d / %s unit %d / %s leave %d signals on stack, but no more signals available", scratch[0].instr, patch[scratch[0].instr].Name, scratch[0].unit, patch[scratch[0].instr].Units[scratch[0].unit].Type, len(scratch)),
|
Err: fmt.Errorf("instrument %d / %s unit %d / %s leaves a signal on stack", scratch[0].instr, patch[scratch[0].instr].Name, scratch[0].unit, patch[scratch[0].instr].Units[scratch[0].unit].Type),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if m.derived.railError.Err != nil {
|
if m.derived.railError.Err != nil {
|
||||||
|
@ -2,9 +2,7 @@ package gioui
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
|
||||||
"image"
|
"image"
|
||||||
"image/color"
|
|
||||||
"io"
|
"io"
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
@ -16,8 +14,6 @@ import (
|
|||||||
"gioui.org/op/clip"
|
"gioui.org/op/clip"
|
||||||
"gioui.org/op/paint"
|
"gioui.org/op/paint"
|
||||||
"gioui.org/text"
|
"gioui.org/text"
|
||||||
"gioui.org/widget"
|
|
||||||
"github.com/vsariola/sointu"
|
|
||||||
"github.com/vsariola/sointu/tracker"
|
"github.com/vsariola/sointu/tracker"
|
||||||
"golang.org/x/exp/shiny/materialdesign/icons"
|
"golang.org/x/exp/shiny/materialdesign/icons"
|
||||||
"golang.org/x/text/cases"
|
"golang.org/x/text/cases"
|
||||||
@ -128,14 +124,19 @@ func (pe *UnitEditor) update(gtx C, t *Tracker) {
|
|||||||
}
|
}
|
||||||
if e, ok := e.(key.Event); ok && e.State == key.Press {
|
if e, ok := e.(key.Event); ok && e.State == key.Press {
|
||||||
params := t.Model.Params()
|
params := t.Model.Params()
|
||||||
item := params.Item(params.Cursor())
|
doRange := func(f func(p tracker.Parameter)) {
|
||||||
|
for i := params.Table().Range().TopLeft.Y; i <= params.Table().Range().BottomRight.Y; i++ {
|
||||||
|
item := params.Item(tracker.Point{X: params.Table().Range().TopLeft.X, Y: i})
|
||||||
|
f(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
switch e.Name {
|
switch e.Name {
|
||||||
case key.NameLeftArrow:
|
case key.NameLeftArrow:
|
||||||
item.Add(-1, e.Modifiers.Contain(key.ModShortcut))
|
doRange(func(item tracker.Parameter) { item.Add(-1, e.Modifiers.Contain(key.ModShortcut)) })
|
||||||
case key.NameRightArrow:
|
case key.NameRightArrow:
|
||||||
item.Add(1, e.Modifiers.Contain(key.ModShortcut))
|
doRange(func(item tracker.Parameter) { item.Add(1, e.Modifiers.Contain(key.ModShortcut)) })
|
||||||
case key.NameDeleteBackward, key.NameDeleteForward:
|
case key.NameDeleteBackward, key.NameDeleteForward:
|
||||||
item.Reset()
|
doRange(func(item tracker.Parameter) { item.Reset() })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -222,12 +223,19 @@ func (pe *UnitEditor) layoutRack(gtx C) D {
|
|||||||
if y < 0 || y >= len(pe.Parameters) || x < 0 || x >= len(pe.Parameters[y]) {
|
if y < 0 || y >= len(pe.Parameters) || x < 0 || x >= len(pe.Parameters[y]) {
|
||||||
return D{}
|
return D{}
|
||||||
}
|
}
|
||||||
if point == cursor {
|
selection := pe.paramTable.Table.Range()
|
||||||
c := t.Theme.Cursor.Inactive
|
if selection.Contains(point) {
|
||||||
|
color := t.Theme.Selection.Inactive
|
||||||
if gtx.Focused(pe.paramTable) {
|
if gtx.Focused(pe.paramTable) {
|
||||||
c = t.Theme.Cursor.Active
|
color = t.Theme.Selection.Active
|
||||||
}
|
}
|
||||||
paint.FillShape(gtx.Ops, c, clip.Rect{Min: image.Pt(0, 0), Max: image.Pt(gtx.Constraints.Min.X, gtx.Constraints.Min.Y)}.Op())
|
if point == cursor {
|
||||||
|
color = t.Theme.Cursor.Inactive
|
||||||
|
if gtx.Focused(pe.paramTable) {
|
||||||
|
color = t.Theme.Cursor.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())
|
||||||
}
|
}
|
||||||
|
|
||||||
param := t.Model.Params().Item(point)
|
param := t.Model.Params().Item(point)
|
||||||
@ -420,10 +428,9 @@ func (t *UnitEditor) Tags(level int, yield TagYieldFunc) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ParameterState struct {
|
type ParameterState struct {
|
||||||
knobState KnobState
|
knobState KnobState
|
||||||
boolWidget widget.Bool
|
clickable Clickable
|
||||||
clickable Clickable
|
portState PortState
|
||||||
portState PortState
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type ParameterStyle struct {
|
type ParameterStyle struct {
|
||||||
@ -443,7 +450,6 @@ func (t *Tracker) ParamStyle(Parameter tracker.Parameter, th *Theme, paramWidget
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p ParameterStyle) Layout(gtx C) D {
|
func (p ParameterStyle) Layout(gtx C) D {
|
||||||
//_, _ := p.w.Parameter.Info()
|
|
||||||
title := Label(p.Theme, &p.Theme.UnitEditor.Name, p.Parameter.Name())
|
title := Label(p.Theme, &p.Theme.UnitEditor.Name, p.Parameter.Name())
|
||||||
t := TrackerFromContext(gtx)
|
t := TrackerFromContext(gtx)
|
||||||
widget := func(gtx C) D {
|
widget := func(gtx C) D {
|
||||||
@ -464,46 +470,6 @@ func (p ParameterStyle) Layout(gtx C) D {
|
|||||||
case tracker.IDParameter:
|
case tracker.IDParameter:
|
||||||
btn := ActionBtn(t.ChooseSendSource(p.Parameter.UnitID()), t.Theme, &p.State.clickable, "Set", p.Parameter.Hint().Label)
|
btn := ActionBtn(t.ChooseSendSource(p.Parameter.UnitID()), t.Theme, &p.State.clickable, "Set", p.Parameter.Hint().Label)
|
||||||
return btn.Layout(gtx)
|
return btn.Layout(gtx)
|
||||||
/*instrItems := make([]ActionMenuItem, p.tracker.Instruments().Count())
|
|
||||||
for i := range instrItems {
|
|
||||||
i := i
|
|
||||||
name, _, _, _ := p.tracker.Instruments().Item(i)
|
|
||||||
instrItems[i].Text = name
|
|
||||||
instrItems[i].Icon = icons.NavigationChevronRight
|
|
||||||
instrItems[i].Action = tracker.MakeEnabledAction((tracker.DoFunc)(func() {
|
|
||||||
if id, ok := p.tracker.Instruments().FirstID(i); ok {
|
|
||||||
p.w.Parameter.SetValue(id)
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
var unitItems []ActionMenuItem
|
|
||||||
instrName := "<instr>"
|
|
||||||
unitName := "<unit>"
|
|
||||||
targetInstrName, units, targetUnitIndex, ok := p.tracker.UnitInfo(p.w.Parameter.Value())
|
|
||||||
if ok {
|
|
||||||
instrName = targetInstrName
|
|
||||||
unitName = buildUnitLabel(targetUnitIndex, units[targetUnitIndex])
|
|
||||||
unitItems = make([]ActionMenuItem, len(units))
|
|
||||||
for j, unit := range units {
|
|
||||||
id := unit.ID
|
|
||||||
unitItems[j].Text = buildUnitLabel(j, unit)
|
|
||||||
unitItems[j].Icon = icons.NavigationChevronRight
|
|
||||||
unitItems[j].Action = tracker.MakeEnabledAction((tracker.DoFunc)(func() {
|
|
||||||
p.w.Parameter.SetValue(id)
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
defer pointer.PassOp{}.Push(gtx.Ops).Pop()
|
|
||||||
instrBtn := MenuBtn(p.tracker.Theme, &p.w.instrMenu, &p.w.instrBtn, instrName)
|
|
||||||
unitBtn := MenuBtn(p.tracker.Theme, &p.w.unitMenu, &p.w.unitBtn, unitName)
|
|
||||||
return layout.Flex{Axis: layout.Horizontal}.Layout(gtx,
|
|
||||||
layout.Rigid(func(gtx C) D {
|
|
||||||
return instrBtn.Layout(gtx, instrItems...)
|
|
||||||
}),
|
|
||||||
layout.Rigid(func(gtx C) D {
|
|
||||||
return unitBtn.Layout(gtx, unitItems...)
|
|
||||||
}),
|
|
||||||
)*/
|
|
||||||
}
|
}
|
||||||
if _, ok := p.Parameter.Port(); ok {
|
if _, ok := p.Parameter.Port(); ok {
|
||||||
k := Port(p.Theme, &p.State.portState)
|
k := Port(p.Theme, &p.State.portState)
|
||||||
@ -514,34 +480,4 @@ func (p ParameterStyle) Layout(gtx C) D {
|
|||||||
title.Layout(gtx)
|
title.Layout(gtx)
|
||||||
layout.Center.Layout(gtx, widget)
|
layout.Center.Layout(gtx, widget)
|
||||||
return D{Size: image.Pt(gtx.Constraints.Max.X, gtx.Constraints.Max.Y)}
|
return D{Size: image.Pt(gtx.Constraints.Max.X, gtx.Constraints.Max.Y)}
|
||||||
/* layout.Rigid(func(gtx C) D {
|
|
||||||
if p.w.Parameter.Type() != tracker.IDParameter {
|
|
||||||
hint := p.w.Parameter.Hint()
|
|
||||||
label := Label(p.tracker.Theme, &p.tracker.Theme.UnitEditor.Hint, hint.Label)
|
|
||||||
label.Alignment = text.Middle
|
|
||||||
if !hint.Valid {
|
|
||||||
label.Color = p.tracker.Theme.UnitEditor.InvalidParam
|
|
||||||
}
|
|
||||||
if info == "" {
|
|
||||||
return label.Layout(gtx)
|
|
||||||
}
|
|
||||||
tooltip := component.PlatformTooltip(p.SendTargetTheme, info)
|
|
||||||
return p.w.tipArea.Layout(gtx, tooltip, label.Layout)
|
|
||||||
}
|
|
||||||
return D{}
|
|
||||||
}),*/
|
|
||||||
}
|
|
||||||
|
|
||||||
func drawCircle(gtx C, i int, nRGBA color.NRGBA) D {
|
|
||||||
defer clip.Ellipse(image.Rectangle{Max: image.Pt(i, i)}).Push(gtx.Ops).Pop()
|
|
||||||
paint.FillShape(gtx.Ops, nRGBA, clip.Ellipse{Max: image.Pt(i, i)}.Op(gtx.Ops))
|
|
||||||
return D{Size: image.Pt(i, i)}
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildUnitLabel(index int, u sointu.Unit) string {
|
|
||||||
text := u.Type
|
|
||||||
if u.Comment != "" {
|
|
||||||
text = fmt.Sprintf("%s \"%s\"", text, u.Comment)
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("%d: %s", index, text)
|
|
||||||
}
|
}
|
||||||
|
@ -159,13 +159,15 @@ func (pt *ParamVertList) Count() int { return (*Params)(pt).Width()
|
|||||||
func (m *Model) Params() *Params { return (*Params)(m) }
|
func (m *Model) Params() *Params { return (*Params)(m) }
|
||||||
func (pt *Params) Table() Table { return Table{pt} }
|
func (pt *Params) Table() Table { return Table{pt} }
|
||||||
func (pt *Params) Cursor() Point { return Point{pt.d.ParamIndex, pt.d.UnitIndex} }
|
func (pt *Params) Cursor() Point { return Point{pt.d.ParamIndex, pt.d.UnitIndex} }
|
||||||
func (pt *Params) Cursor2() Point { return pt.Cursor() }
|
func (pt *Params) Cursor2() Point { return Point{pt.d.ParamIndex, pt.d.UnitIndex2} }
|
||||||
func (pt *Params) SetCursor(p Point) {
|
func (pt *Params) SetCursor(p Point) {
|
||||||
pt.d.ParamIndex = max(min(p.X, pt.Width()-1), 0)
|
pt.d.ParamIndex = max(min(p.X, pt.Width()-1), 0)
|
||||||
pt.d.UnitIndex = max(min(p.Y, pt.Height()-1), 0)
|
pt.d.UnitIndex = max(min(p.Y, pt.Height()-1), 0)
|
||||||
pt.d.UnitIndex2 = pt.d.UnitIndex
|
|
||||||
}
|
}
|
||||||
func (pt *Params) SetCursor2(p Point) {}
|
func (pt *Params) SetCursor2(p Point) {
|
||||||
|
pt.d.ParamIndex = max(min(p.X, pt.Width()-1), 0)
|
||||||
|
pt.d.UnitIndex2 = max(min(p.Y, pt.Height()-1), 0)
|
||||||
|
}
|
||||||
func (pt *Params) Width() int {
|
func (pt *Params) Width() int {
|
||||||
if pt.d.InstrIndex < 0 || pt.d.InstrIndex >= len(pt.derived.patch) {
|
if pt.d.InstrIndex < 0 || pt.d.InstrIndex >= len(pt.derived.patch) {
|
||||||
return 0
|
return 0
|
||||||
|
@ -157,6 +157,7 @@ func (m LoadPreset) Do() {
|
|||||||
m.d.Song.Patch = append(m.d.Song.Patch, defaultInstrument.Copy())
|
m.d.Song.Patch = append(m.d.Song.Patch, defaultInstrument.Copy())
|
||||||
}
|
}
|
||||||
newInstr := instrumentPresets[m.Index].Copy()
|
newInstr := instrumentPresets[m.Index].Copy()
|
||||||
|
newInstr.NumVoices = clamp(m.d.Song.Patch[m.d.InstrIndex].NumVoices, 1, vm.MAX_VOICES)
|
||||||
m.Model.assignUnitIDs(newInstr.Units)
|
m.Model.assignUnitIDs(newInstr.Units)
|
||||||
m.d.Song.Patch[m.d.InstrIndex] = newInstr
|
m.d.Song.Patch[m.d.InstrIndex] = newInstr
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user