mirror of
https://github.com/vsariola/sointu.git
synced 2025-07-22 23:14:59 -04:00
drafting
This commit is contained in:
parent
53af773815
commit
e1aa9c0d26
4
patch.go
4
patch.go
@ -380,8 +380,8 @@ var stackUseMonoStereo = map[string][2]StackUse{
|
||||
{Inputs: [][]int{{0, 2, 3}, {1, 2, 3}}, Modifies: []bool{false, false, true, true}, NumOutputs: 4}, // stereo
|
||||
},
|
||||
"pan": {
|
||||
{Inputs: [][]int{{0, 1}}, Modifies: []bool{true, true}, NumOutputs: 2}, // mono
|
||||
{Inputs: [][]int{{0, 1}, {0, 1}}, Modifies: []bool{true, true}, NumOutputs: 2}, // mono
|
||||
{Inputs: [][]int{{0, 1}}, Modifies: []bool{true, true}, NumOutputs: 2}, // mono
|
||||
{Inputs: [][]int{{0}, {1}}, Modifies: []bool{true, true}, NumOutputs: 2}, // mono
|
||||
},
|
||||
"speed": {
|
||||
{Inputs: [][]int{{0}}, Modifies: []bool{true}, NumOutputs: 0},
|
||||
|
@ -39,7 +39,7 @@ type (
|
||||
derivedInstrument struct {
|
||||
wires []Wire
|
||||
rails []Rail
|
||||
railsWidth int
|
||||
railWidth int
|
||||
params [][]Parameter
|
||||
paramsWidth int
|
||||
}
|
||||
@ -59,7 +59,7 @@ func (s *Model) RailWidth() int {
|
||||
if i < 0 || i >= len(s.derived.patch) {
|
||||
return 0
|
||||
}
|
||||
return s.derived.patch[i].railsWidth
|
||||
return s.derived.patch[i].railWidth
|
||||
}
|
||||
|
||||
func (m *Model) Wires(yield func(wire Wire) bool) {
|
||||
@ -121,9 +121,10 @@ func (m *Model) updateParams() {
|
||||
for i, instr := range m.d.Song.Patch {
|
||||
setSliceLength(&m.derived.patch[i].params, len(instr.Units))
|
||||
paramsWidth := 0
|
||||
for u, unit := range instr.Units {
|
||||
m.derived.patch[i].params[u] = m.deriveParams(&unit, m.derived.patch[i].params[u])
|
||||
paramsWidth = max(paramsWidth, len(m.derived.patch[i].params[u]))
|
||||
for u := range instr.Units {
|
||||
p := m.deriveParams(&instr.Units[u], m.derived.patch[i].params[u])
|
||||
m.derived.patch[i].params[u] = p
|
||||
paramsWidth = max(paramsWidth, len(p))
|
||||
}
|
||||
m.derived.patch[i].paramsWidth = paramsWidth
|
||||
}
|
||||
@ -264,7 +265,7 @@ func (m *Model) updateRails() {
|
||||
scratch = append(scratch, stackElem{instr: i, unit: u})
|
||||
}
|
||||
}
|
||||
m.derived.patch[i].railsWidth = maxWidth
|
||||
m.derived.patch[i].railWidth = maxWidth
|
||||
diff := len(scratch) - start
|
||||
if instr.NumVoices > 1 && diff != 0 {
|
||||
if diff < 0 {
|
||||
@ -314,7 +315,7 @@ func (m *Model) updateWires() {
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
_, tX, ok := sointu.FindParamForModulationPort(m.d.Song.Patch[tI].Units[tU].Type, unit.Parameters["port"])
|
||||
up, tX, ok := sointu.FindParamForModulationPort(m.d.Song.Patch[tI].Units[tU].Type, unit.Parameters["port"])
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
@ -325,20 +326,28 @@ func (m *Model) updateWires() {
|
||||
FromSet: true,
|
||||
To: Point{X: tX, Y: tU},
|
||||
ToSet: true,
|
||||
Hint: "TBW",
|
||||
})
|
||||
} else {
|
||||
// remote send
|
||||
m.derived.patch[i].wires = append(m.derived.patch[i].wires, Wire{
|
||||
From: u,
|
||||
FromSet: true,
|
||||
Hint: "TBW",
|
||||
Hint: fmt.Sprintf("To instrument #%d (%s), unit #%d (%s), port %s", tI, m.d.Song.Patch[tI].Name, tU, m.d.Song.Patch[tI].Units[tU].Type, up.Name),
|
||||
})
|
||||
toPt := Point{X: tX, Y: tU}
|
||||
hint := fmt.Sprintf("From instrument #%d (%s), send #%d", i, m.d.Song.Patch[i].Name, u)
|
||||
for i, w := range m.derived.patch[tI].wires {
|
||||
if !w.FromSet && w.ToSet && w.To == toPt {
|
||||
m.derived.patch[tI].wires[i].Hint += "; " + hint
|
||||
goto skipAppend
|
||||
}
|
||||
}
|
||||
m.derived.patch[tI].wires = append(m.derived.patch[tI].wires, Wire{
|
||||
To: Point{X: tX, Y: tU},
|
||||
To: toPt,
|
||||
ToSet: true,
|
||||
Hint: "TBW",
|
||||
Hint: hint,
|
||||
})
|
||||
skipAppend:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -111,6 +111,8 @@ func (s FilledDragListStyle) Layout(gtx C, element, bg func(gtx C, i int) D) D {
|
||||
case key.FocusEvent:
|
||||
if !ke.Focus {
|
||||
s.dragList.TrackerList.SetSelected2(s.dragList.TrackerList.Selected())
|
||||
} else {
|
||||
s.dragList.EnsureVisible(s.dragList.TrackerList.Selected())
|
||||
}
|
||||
case key.Event:
|
||||
if ke.State != key.Press {
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"gioui.org/f32"
|
||||
"gioui.org/gesture"
|
||||
"gioui.org/io/event"
|
||||
"gioui.org/io/key"
|
||||
"gioui.org/io/pointer"
|
||||
"gioui.org/layout"
|
||||
"gioui.org/op/clip"
|
||||
@ -142,8 +143,8 @@ func (k *KnobWidget) update(gtx C) {
|
||||
break
|
||||
}
|
||||
if ev, ok := e.(pointer.Event); ok && ev.Kind == pointer.Scroll {
|
||||
delta := math.Min(math.Max(float64(ev.Scroll.Y), -1), 1)
|
||||
k.Value.SetValue(k.Value.Value() - int(delta))
|
||||
delta := -int(math.Min(math.Max(float64(ev.Scroll.Y), -1), 1))
|
||||
k.Value.Add(delta, ev.Modifiers.Contain(key.ModShortcut))
|
||||
k.State.tipArea.Appear(gtx.Now)
|
||||
}
|
||||
}
|
||||
|
@ -120,7 +120,9 @@ func (oe *OrderEditor) Layout(gtx C) D {
|
||||
table := FilledScrollTable(t.Theme, oe.scrollTable)
|
||||
table.ColumnTitleHeight = orderTitleHeight
|
||||
|
||||
return table.Layout(gtx, cell, colTitle, rowTitle, nil, rowTitleBg)
|
||||
return Surface{Gray: 24, Focus: oe.scrollTable.TreeFocused(gtx)}.Layout(gtx, func(gtx C) D {
|
||||
return table.Layout(gtx, cell, colTitle, rowTitle, nil, rowTitleBg)
|
||||
})
|
||||
}
|
||||
|
||||
func (oe *OrderEditor) handleEvents(gtx C, t *Tracker) {
|
||||
|
@ -444,7 +444,7 @@ func (ul *UnitList) update(gtx C, t *Tracker) {
|
||||
if e, ok := event.(key.Event); ok && e.State == key.Press {
|
||||
switch e.Name {
|
||||
case key.NameRightArrow:
|
||||
t.PatchPanel.unitEditor.paramTable.Focus()
|
||||
t.PatchPanel.unitEditor.paramTable.RowTitleList.Focus()
|
||||
case key.NameDeleteBackward:
|
||||
t.Units().SetSelectedType("")
|
||||
t.UnitSearching().SetValue(true)
|
||||
|
@ -176,12 +176,17 @@ func (s *ScrollTableStyle) handleEvents(gtx layout.Context, p image.Point) {
|
||||
}
|
||||
case key.Event:
|
||||
if e.State == key.Press {
|
||||
s.ScrollTable.command(gtx, e)
|
||||
s.ScrollTable.command(gtx, e, p)
|
||||
}
|
||||
case transfer.DataEvent:
|
||||
if b, err := io.ReadAll(e.Open()); err == nil {
|
||||
s.ScrollTable.Table.Paste(b)
|
||||
}
|
||||
case key.FocusEvent:
|
||||
if e.Focus {
|
||||
s.ScrollTable.ColTitleList.EnsureVisible(s.ScrollTable.Table.Cursor().X)
|
||||
s.ScrollTable.RowTitleList.EnsureVisible(s.ScrollTable.Table.Cursor().Y)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -250,7 +255,7 @@ func (s *ScrollTableStyle) layoutColTitles(gtx C, p image.Point, fg, bg func(gtx
|
||||
s.ColTitleStyle.Layout(gtx, fg, bg)
|
||||
}
|
||||
|
||||
func (s *ScrollTable) command(gtx C, e key.Event) {
|
||||
func (s *ScrollTable) command(gtx C, e key.Event, p image.Point) {
|
||||
stepX := 1
|
||||
stepY := 1
|
||||
if e.Modifiers.Contain(key.ModAlt) {
|
||||
@ -265,13 +270,13 @@ func (s *ScrollTable) command(gtx C, e key.Event) {
|
||||
s.Table.Clear()
|
||||
return
|
||||
case key.NameUpArrow:
|
||||
if !s.Table.MoveCursor(0, -stepY) && stepY == 1 {
|
||||
if !s.Table.MoveCursor(0, -stepY) && stepY == 1 && p.Y > 0 {
|
||||
s.ColTitleList.Focus()
|
||||
}
|
||||
case key.NameDownArrow:
|
||||
s.Table.MoveCursor(0, stepY)
|
||||
case key.NameLeftArrow:
|
||||
if !s.Table.MoveCursor(-stepX, 0) && stepX == 1 {
|
||||
if !s.Table.MoveCursor(-stepX, 0) && stepX == 1 && p.X > 0 {
|
||||
s.RowTitleList.Focus()
|
||||
}
|
||||
case key.NameRightArrow:
|
||||
|
@ -98,7 +98,8 @@ type Theme struct {
|
||||
Disabled LabelStyle
|
||||
Error color.NRGBA
|
||||
}
|
||||
Error color.NRGBA
|
||||
Error color.NRGBA
|
||||
Divider color.NRGBA
|
||||
}
|
||||
Cursor CursorStyle
|
||||
Selection CursorStyle
|
||||
|
@ -220,6 +220,7 @@ uniteditor:
|
||||
disabled:
|
||||
{ textsize: 12, color: *disabled, font: { style: 1 }, alignment: 2 }
|
||||
error: *errorcolor
|
||||
divider: { r: 255, g: 255, b: 255, a: 5 }
|
||||
knob:
|
||||
diameter: 36
|
||||
value: { textsize: 12, color: *highemphasis }
|
||||
@ -237,4 +238,4 @@ signalrail:
|
||||
port:
|
||||
diameter: 36
|
||||
strokewidth: 4
|
||||
color: *secondarycolor
|
||||
color: { r: 32, g: 55, b: 58, a: 255 }
|
||||
|
@ -10,7 +10,6 @@ import (
|
||||
|
||||
"gioui.org/f32"
|
||||
"gioui.org/io/clipboard"
|
||||
"gioui.org/io/event"
|
||||
"gioui.org/io/key"
|
||||
"gioui.org/io/pointer"
|
||||
"gioui.org/layout"
|
||||
@ -127,22 +126,23 @@ func (pe *UnitEditor) update(gtx C, t *Tracker) {
|
||||
item := params.Item(params.Cursor())
|
||||
switch e.Name {
|
||||
case key.NameLeftArrow:
|
||||
if e.Modifiers.Contain(key.ModShortcut) {
|
||||
item.SetValue(item.Value() - item.LargeStep())
|
||||
} else {
|
||||
item.SetValue(item.Value() - 1)
|
||||
}
|
||||
item.Add(-1, e.Modifiers.Contain(key.ModShortcut))
|
||||
case key.NameRightArrow:
|
||||
if e.Modifiers.Contain(key.ModShortcut) {
|
||||
item.SetValue(item.Value() + item.LargeStep())
|
||||
} else {
|
||||
item.SetValue(item.Value() + 1)
|
||||
}
|
||||
item.Add(1, e.Modifiers.Contain(key.ModShortcut))
|
||||
case key.NameDeleteBackward, key.NameDeleteForward:
|
||||
item.Reset()
|
||||
}
|
||||
}
|
||||
}
|
||||
for {
|
||||
e, ok := gtx.Event(key.Filter{Focus: pe.paramTable.RowTitleList, Name: key.NameLeftArrow})
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
if e, ok := e.(key.Event); ok && e.State == key.Press {
|
||||
t.PatchPanel.unitList.dragList.Focus()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (pe *UnitEditor) ChooseUnitType(t *Tracker) {
|
||||
@ -174,10 +174,6 @@ func (pe *UnitEditor) layoutRack(gtx C) D {
|
||||
coltitle := func(gtx C, x int) D {
|
||||
return D{Size: image.Pt(cellWidth, columnTitleHeight)}
|
||||
}
|
||||
rowTitleBg := func(gtx C, j int) D {
|
||||
paint.FillShape(gtx.Ops, t.Theme.NoteEditor.Play, clip.Rect{Max: image.Pt(gtx.Constraints.Max.X, 1)}.Op())
|
||||
return D{}
|
||||
}
|
||||
rowtitle := func(gtx C, y int) D {
|
||||
if y < 0 || y >= len(pe.Parameters) {
|
||||
return D{}
|
||||
@ -223,8 +219,9 @@ func (pe *UnitEditor) layoutRack(gtx C) D {
|
||||
table.ColumnTitleHeight = 0
|
||||
table.CellWidth = t.Theme.UnitEditor.Width
|
||||
table.CellHeight = t.Theme.UnitEditor.Height
|
||||
pe.drawBackGround(gtx)
|
||||
pe.drawSignals(gtx, rowTitleWidth)
|
||||
dims := table.Layout(gtx, cell, coltitle, rowtitle, nil, rowTitleBg)
|
||||
dims := table.Layout(gtx, cell, coltitle, rowtitle, nil, nil)
|
||||
return dims
|
||||
}
|
||||
|
||||
@ -238,27 +235,71 @@ func (pe *UnitEditor) drawSignals(gtx C, rowTitleWidth int) {
|
||||
defer clip.Rect(image.Rectangle{Max: gtx.Constraints.Max}).Push(gtx.Ops).Pop()
|
||||
defer op.Offset(image.Pt(-colP.Offset, -rowP.Offset)).Push(gtx.Ops).Pop()
|
||||
for wire := range t.Wires {
|
||||
pe.drawSignal(gtx, wire, colP.First, rowP.First)
|
||||
switch {
|
||||
case wire.FromSet && !wire.ToSet:
|
||||
pe.drawRemoteSendSignal(gtx, wire, colP.First, rowP.First)
|
||||
case !wire.FromSet && wire.ToSet:
|
||||
pe.drawRemoteReceiveSignal(gtx, wire, colP.First, rowP.First)
|
||||
case wire.FromSet && wire.ToSet:
|
||||
pe.drawSignal(gtx, wire, colP.First, rowP.First)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (pe *UnitEditor) drawBackGround(gtx C) {
|
||||
t := TrackerFromContext(gtx)
|
||||
rowP := pe.paramTable.RowTitleList.List.Position
|
||||
defer op.Offset(image.Pt(0, -rowP.Offset)).Push(gtx.Ops).Pop()
|
||||
for range pe.paramTable.RowTitleList.List.Position.Count + 1 {
|
||||
paint.FillShape(gtx.Ops, t.Theme.UnitEditor.Divider, clip.Rect{Max: image.Pt(gtx.Constraints.Max.X, 1)}.Op())
|
||||
op.Offset(image.Pt(0, gtx.Dp(t.Theme.UnitEditor.Height))).Add(gtx.Ops)
|
||||
}
|
||||
}
|
||||
|
||||
func (pe *UnitEditor) drawRemoteSendSignal(gtx C, wire tracker.Wire, col, row int) {
|
||||
sy := wire.From - row
|
||||
t := TrackerFromContext(gtx)
|
||||
defer op.Offset(image.Pt(0, (sy+1)*gtx.Dp(t.Theme.UnitEditor.Height)-gtx.Dp(16))).Push(gtx.Ops).Pop()
|
||||
Label(t.Theme, &t.Theme.UnitEditor.WireHint, wire.Hint).Layout(gtx)
|
||||
}
|
||||
|
||||
func (pe *UnitEditor) drawRemoteReceiveSignal(gtx C, wire tracker.Wire, col, row int) {
|
||||
ex := wire.To.X - col
|
||||
ey := wire.To.Y - row
|
||||
t := TrackerFromContext(gtx)
|
||||
width := float32(gtx.Dp(t.Theme.UnitEditor.Width))
|
||||
height := float32(gtx.Dp(t.Theme.UnitEditor.Height))
|
||||
topLeft := f32.Pt(float32(ex)*width, float32(ey)*height)
|
||||
center := topLeft.Add(f32.Pt(width/2, height/2))
|
||||
c := float32(gtx.Dp(t.Theme.Knob.Diameter)) / 2 / float32(math.Sqrt2)
|
||||
from := f32.Pt(c, c).Add(center)
|
||||
q := c
|
||||
c1 := f32.Pt(c+q, c+q).Add(center)
|
||||
o := float32(gtx.Dp(8))
|
||||
c2 := f32.Pt(width-q, height-o).Add(topLeft)
|
||||
to := f32.Pt(width, height-o).Add(topLeft)
|
||||
var path clip.Path
|
||||
path.Begin(gtx.Ops)
|
||||
path.MoveTo(from)
|
||||
path.CubeTo(c1, c2, to)
|
||||
paint.FillShape(gtx.Ops, t.Theme.UnitEditor.WireColor,
|
||||
clip.Stroke{
|
||||
Path: path.End(),
|
||||
Width: float32(gtx.Dp(t.Theme.SignalRail.LineWidth)),
|
||||
}.Op())
|
||||
defer op.Offset(image.Pt((ex+1)*gtx.Dp(t.Theme.UnitEditor.Width)+gtx.Dp(5), (ey+1)*gtx.Dp(t.Theme.UnitEditor.Height)-gtx.Dp(16))).Push(gtx.Ops).Pop()
|
||||
Label(t.Theme, &t.Theme.UnitEditor.WireHint, wire.Hint).Layout(gtx)
|
||||
}
|
||||
|
||||
func (pe *UnitEditor) drawSignal(gtx C, wire tracker.Wire, col, row int) {
|
||||
sy := wire.From - row
|
||||
ex := wire.To.X - col
|
||||
ey := wire.To.Y - row
|
||||
t := TrackerFromContext(gtx)
|
||||
if wire.FromSet && !wire.ToSet {
|
||||
defer op.Offset(image.Pt(0, (sy+1)*gtx.Dp(t.Theme.UnitEditor.Height)-gtx.Dp(16))).Push(gtx.Ops).Pop()
|
||||
Label(t.Theme, &t.Theme.UnitEditor.WireHint, wire.Hint).Layout(gtx)
|
||||
return
|
||||
}
|
||||
if !wire.FromSet && wire.ToSet {
|
||||
Label(t.Theme, &t.Theme.UnitEditor.WireHint, wire.Hint).Layout(gtx)
|
||||
return
|
||||
}
|
||||
diam := gtx.Dp(t.Theme.Knob.Diameter)
|
||||
c := float32(diam) / 2 / float32(math.Sqrt2)
|
||||
width := float32(gtx.Dp(t.Theme.UnitEditor.Width))
|
||||
height := float32(gtx.Dp(t.Theme.UnitEditor.Height))
|
||||
diam := gtx.Dp(t.Theme.Knob.Diameter)
|
||||
from := f32.Pt(0, float32((sy+1)*gtx.Dp(t.Theme.UnitEditor.Height))-float32(gtx.Dp(t.Theme.SignalRail.SignalWidth)/2))
|
||||
corner := f32.Pt(1, 1)
|
||||
if ex > 0 {
|
||||
@ -267,7 +308,6 @@ func (pe *UnitEditor) drawSignal(gtx C, wire tracker.Wire, col, row int) {
|
||||
if sy < ey {
|
||||
corner.Y = -corner.Y
|
||||
}
|
||||
c := float32(diam) / 2 / float32(math.Sqrt2)
|
||||
topLeft := f32.Pt(float32(ex)*width, float32(ey)*height)
|
||||
center := topLeft.Add(f32.Pt(width/2, height/2))
|
||||
to := mulVec(corner, f32.Pt(c, c)).Add(center)
|
||||
@ -277,7 +317,6 @@ func (pe *UnitEditor) drawSignal(gtx C, wire tracker.Wire, col, row int) {
|
||||
p1 = f32.Pt(p2.X, (float32(sy)+0.5)*float32(gtx.Dp(t.Theme.UnitEditor.Height))+float32(diam)/2)
|
||||
}
|
||||
k := float32(width) / 4
|
||||
//toTan := mulVec(corner, f32.Pt(-k, -k))
|
||||
p2Tan := mulVec(corner, f32.Pt(-k, -k))
|
||||
p1Tan := f32.Pt(k, p2Tan.Y)
|
||||
fromTan := f32.Pt(k, 0)
|
||||
@ -353,11 +392,10 @@ func (pe *UnitEditor) layoutUnitTypeChooser(gtx C) D {
|
||||
}
|
||||
|
||||
func (t *UnitEditor) Tags(level int, yield TagYieldFunc) bool {
|
||||
widget := event.Tag(t.paramTable)
|
||||
if t.showingChooser() {
|
||||
widget = event.Tag(t.searchList)
|
||||
return yield(level, t.searchList) && yield(level+1, &t.commentEditor.widgetEditor)
|
||||
}
|
||||
return yield(level, widget) && yield(level+1, &t.commentEditor.widgetEditor)
|
||||
return yield(level+1, t.paramTable.RowTitleList) && yield(level, t.paramTable) && yield(level+1, &t.commentEditor.widgetEditor)
|
||||
}
|
||||
|
||||
type ParameterState struct {
|
||||
|
@ -30,8 +30,8 @@ type (
|
||||
Type(*Parameter) ParameterType
|
||||
Name(*Parameter) string
|
||||
Hint(*Parameter) ParameterHint
|
||||
LargeStep(*Parameter) int
|
||||
Reset(*Parameter)
|
||||
RoundToGrid(*Parameter, int, bool) int
|
||||
}
|
||||
|
||||
Params Model
|
||||
@ -87,6 +87,17 @@ func (p *Parameter) SetValue(value int) bool {
|
||||
}
|
||||
return p.vtable.SetValue(p, value)
|
||||
}
|
||||
func (p *Parameter) Add(delta int, snapToGrid bool) bool {
|
||||
if p.vtable == nil {
|
||||
return false
|
||||
}
|
||||
newVal := p.Value() + delta
|
||||
if snapToGrid && p.vtable != nil {
|
||||
newVal = p.vtable.RoundToGrid(p, newVal, delta > 0)
|
||||
}
|
||||
return p.SetValue(newVal)
|
||||
}
|
||||
|
||||
func (p *Parameter) Range() IntRange {
|
||||
if p.vtable == nil {
|
||||
return IntRange{}
|
||||
@ -111,12 +122,6 @@ func (p *Parameter) Hint() ParameterHint {
|
||||
}
|
||||
return p.vtable.Hint(p)
|
||||
}
|
||||
func (p *Parameter) LargeStep() int {
|
||||
if p.vtable == nil {
|
||||
return 1
|
||||
}
|
||||
return p.vtable.LargeStep(p)
|
||||
}
|
||||
func (p *Parameter) Reset() {
|
||||
if p.vtable == nil {
|
||||
return
|
||||
@ -173,13 +178,24 @@ func (pt *Params) Item(p Point) Parameter {
|
||||
return pt.derived.patch[pt.d.InstrIndex].params[p.Y][p.X]
|
||||
}
|
||||
func (pt *Params) clear(p Point) {
|
||||
panic("NOT IMPLEMENTED")
|
||||
q := pt.Item(p)
|
||||
q.Reset()
|
||||
}
|
||||
func (pt *Params) set(p Point, value int) {
|
||||
panic("NOT IMPLEMENTED")
|
||||
q := pt.Item(p)
|
||||
q.SetValue(value)
|
||||
}
|
||||
func (pt *Params) add(rect Rect, delta int) (ok bool) {
|
||||
panic("NOT IMPLEMENTED")
|
||||
for y := rect.TopLeft.Y; y <= rect.BottomRight.Y; y++ {
|
||||
for x := rect.TopLeft.X; x <= rect.BottomRight.X; x++ {
|
||||
p := Point{x, y}
|
||||
q := pt.Item(p)
|
||||
if !q.SetValue(q.Value() + delta) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
func (pt *Params) marshal(rect Rect) (data []byte, ok bool) {
|
||||
panic("NOT IMPLEMENTED")
|
||||
@ -191,10 +207,10 @@ func (pt *Params) unmarshalRange(rect Rect, data []byte) (ok bool) {
|
||||
panic("NOT IMPLEMENTED")
|
||||
}
|
||||
func (pt *Params) change(kind string, severity ChangeSeverity) func() {
|
||||
panic("NOT IMPLEMENTED")
|
||||
return (*Model)(pt).change(kind, PatchChange, severity)
|
||||
}
|
||||
func (pt *Params) cancel() {
|
||||
panic("NOT IMPLEMENTED")
|
||||
pt.changeCancel = true
|
||||
}
|
||||
|
||||
// namedParameter vtable
|
||||
@ -232,11 +248,12 @@ func (n *namedParameter) Hint(p *Parameter) ParameterHint {
|
||||
}
|
||||
return ParameterHint{label, true}
|
||||
}
|
||||
func (n *namedParameter) LargeStep(p *Parameter) int {
|
||||
func (n *namedParameter) RoundToGrid(p *Parameter, val int, up bool) int {
|
||||
grid := 16
|
||||
if p.up.Name == "transpose" {
|
||||
return 12
|
||||
grid = 12
|
||||
}
|
||||
return 16
|
||||
return roundToGrid(val, grid, up)
|
||||
}
|
||||
func (n *namedParameter) Reset(p *Parameter) {
|
||||
v, ok := defaultUnits[p.unit.Type].Parameters[p.up.Name]
|
||||
@ -288,13 +305,30 @@ func (g *gmDlsEntryParameter) Hint(p *Parameter) ParameterHint {
|
||||
}
|
||||
return ParameterHint{label, true}
|
||||
}
|
||||
func (g *gmDlsEntryParameter) LargeStep(p *Parameter) int {
|
||||
return 16
|
||||
func (g *gmDlsEntryParameter) RoundToGrid(p *Parameter, val int, up bool) int {
|
||||
return roundToGrid(val, 16, up)
|
||||
}
|
||||
func (g *gmDlsEntryParameter) Reset(p *Parameter) {}
|
||||
|
||||
// delayTimeParameter vtable
|
||||
|
||||
var delayNoteTrackGrid, delayBpmTrackGrid []int
|
||||
|
||||
func init() {
|
||||
for st := -48; st <= 48; st++ {
|
||||
gridVal := int(math.Exp2(-float64(st)/12)*10787 + 0.5)
|
||||
delayNoteTrackGrid = append(delayNoteTrackGrid, gridVal)
|
||||
}
|
||||
for i := 0; i < 16; i++ {
|
||||
delayBpmTrackGrid = append(delayBpmTrackGrid, 1<<i)
|
||||
delayBpmTrackGrid = append(delayBpmTrackGrid, 3<<i)
|
||||
delayBpmTrackGrid = append(delayBpmTrackGrid, 9<<i)
|
||||
}
|
||||
slices.Sort(delayBpmTrackGrid)
|
||||
}
|
||||
|
||||
func (d *delayTimeParameter) Type(p *Parameter) ParameterType { return IntegerParameter }
|
||||
func (d *delayTimeParameter) Name(p *Parameter) string { return "delaytime" }
|
||||
func (d *delayTimeParameter) Value(p *Parameter) int {
|
||||
if p.index < 0 || p.index >= len(p.unit.VarArgs) {
|
||||
return 1
|
||||
@ -312,12 +346,6 @@ func (d *delayTimeParameter) Range(p *Parameter) IntRange {
|
||||
}
|
||||
return IntRange{Min: 1, Max: 65535}
|
||||
}
|
||||
func (d *delayTimeParameter) Type(p *Parameter) ParameterType {
|
||||
return IntegerParameter
|
||||
}
|
||||
func (d *delayTimeParameter) Name(p *Parameter) string {
|
||||
return "delaytime"
|
||||
}
|
||||
func (d *delayTimeParameter) Hint(p *Parameter) ParameterHint {
|
||||
val := d.Value(p)
|
||||
var text string
|
||||
@ -350,7 +378,7 @@ func (d *delayTimeParameter) Hint(p *Parameter) ParameterHint {
|
||||
text = fmt.Sprintf(" (1/%d dotted)", 1<<(5-k))
|
||||
}
|
||||
}
|
||||
text = fmt.Sprintf("%v / %.3f beats%s", val, float32(val)/48.0, text)
|
||||
text = fmt.Sprintf("%.3f beats%s", float32(val)/48.0, text)
|
||||
}
|
||||
if p.unit.Parameters["stereo"] == 1 {
|
||||
if p.index < len(p.unit.VarArgs)/2 {
|
||||
@ -361,8 +389,15 @@ func (d *delayTimeParameter) Hint(p *Parameter) ParameterHint {
|
||||
}
|
||||
return ParameterHint{text, true}
|
||||
}
|
||||
func (d *delayTimeParameter) LargeStep(p *Parameter) int {
|
||||
return 16
|
||||
func (d *delayTimeParameter) RoundToGrid(p *Parameter, val int, up bool) int {
|
||||
switch p.unit.Parameters["notetracking"] {
|
||||
default:
|
||||
return roundToGrid(val, 16, up)
|
||||
case 1:
|
||||
return roundToSliceGrid(val, delayNoteTrackGrid, up)
|
||||
case 2:
|
||||
return roundToSliceGrid(val, delayBpmTrackGrid, up)
|
||||
}
|
||||
}
|
||||
func (d *delayTimeParameter) Reset(p *Parameter) {}
|
||||
|
||||
@ -387,15 +422,10 @@ func (d *delayLinesParameter) SetValue(p *Parameter, v int) bool {
|
||||
p.unit.VarArgs = p.unit.VarArgs[:targetLines]
|
||||
return true
|
||||
}
|
||||
func (d *delayLinesParameter) Range(p *Parameter) IntRange {
|
||||
return IntRange{Min: 1, Max: 32}
|
||||
}
|
||||
func (d *delayLinesParameter) Type(p *Parameter) ParameterType {
|
||||
return IntegerParameter
|
||||
}
|
||||
func (d *delayLinesParameter) Name(p *Parameter) string {
|
||||
return "delaylines"
|
||||
}
|
||||
func (d *delayLinesParameter) Range(p *Parameter) IntRange { return IntRange{Min: 1, Max: 32} }
|
||||
func (d *delayLinesParameter) Type(p *Parameter) ParameterType { return IntegerParameter }
|
||||
func (d *delayLinesParameter) Name(p *Parameter) string { return "delaylines" }
|
||||
func (r *delayLinesParameter) RoundToGrid(p *Parameter, val int, up bool) int { return val }
|
||||
func (d *delayLinesParameter) Hint(p *Parameter) ParameterHint {
|
||||
return ParameterHint{strconv.Itoa(d.Value(p)), true}
|
||||
}
|
||||
@ -424,15 +454,11 @@ func (r *reverbParameter) SetValue(p *Parameter, v int) bool {
|
||||
copy(p.unit.VarArgs, entry.varArgs)
|
||||
return true
|
||||
}
|
||||
func (r *reverbParameter) Range(p *Parameter) IntRange {
|
||||
return IntRange{Min: 0, Max: len(reverbs)}
|
||||
}
|
||||
func (r *reverbParameter) Type(p *Parameter) ParameterType {
|
||||
return IntegerParameter
|
||||
}
|
||||
func (r *reverbParameter) Name(p *Parameter) string {
|
||||
return "reverb"
|
||||
}
|
||||
func (r *reverbParameter) Range(p *Parameter) IntRange { return IntRange{Min: 0, Max: len(reverbs)} }
|
||||
func (r *reverbParameter) Type(p *Parameter) ParameterType { return IntegerParameter }
|
||||
func (r *reverbParameter) Name(p *Parameter) string { return "reverb" }
|
||||
func (r *reverbParameter) RoundToGrid(p *Parameter, val int, up bool) int { return val }
|
||||
func (r *reverbParameter) Reset(p *Parameter) {}
|
||||
func (r *reverbParameter) Hint(p *Parameter) ParameterHint {
|
||||
i := r.Value(p)
|
||||
label := "custom"
|
||||
@ -441,7 +467,38 @@ func (r *reverbParameter) Hint(p *Parameter) ParameterHint {
|
||||
}
|
||||
return ParameterHint{label, true}
|
||||
}
|
||||
func (r *reverbParameter) LargeStep(p *Parameter) int {
|
||||
return 1
|
||||
|
||||
func roundToGrid(value, grid int, up bool) int {
|
||||
if up {
|
||||
return value + mod(-value, grid)
|
||||
}
|
||||
return value - mod(value, grid)
|
||||
}
|
||||
|
||||
func mod(a, b int) int {
|
||||
m := a % b
|
||||
if a < 0 && b < 0 {
|
||||
m -= b
|
||||
}
|
||||
if a < 0 && b > 0 {
|
||||
m += b
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func roundToSliceGrid(value int, grid []int, up bool) int {
|
||||
if up {
|
||||
for _, v := range grid {
|
||||
if value < v {
|
||||
return v
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for i := len(grid) - 1; i >= 0; i-- {
|
||||
if value > grid[i] {
|
||||
return grid[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
return value
|
||||
}
|
||||
func (r *reverbParameter) Reset(p *Parameter) {}
|
||||
|
Reference in New Issue
Block a user