mirror of
https://github.com/vsariola/sointu.git
synced 2025-07-22 15:04:36 -04:00
drafting multiparamas
This commit is contained in:
parent
c3caa8de11
commit
89b728a269
@ -24,6 +24,7 @@ type (
|
|||||||
instrument sointu.Instrument
|
instrument sointu.Instrument
|
||||||
instrumentIndex int
|
instrumentIndex int
|
||||||
unitIndex int
|
unitIndex int
|
||||||
|
params []Parameter
|
||||||
|
|
||||||
// map param by Name
|
// map param by Name
|
||||||
forParameter map[string]derivedForParameter
|
forParameter map[string]derivedForParameter
|
||||||
@ -159,6 +160,7 @@ func (m *Model) updateDerivedPatchData() {
|
|||||||
unitIndex: u,
|
unitIndex: u,
|
||||||
instrument: instr,
|
instrument: instr,
|
||||||
instrumentIndex: i,
|
instrumentIndex: i,
|
||||||
|
params: m.deriveParams(&instr.Units[u]),
|
||||||
forParameter: make(map[string]derivedForParameter),
|
forParameter: make(map[string]derivedForParameter),
|
||||||
}
|
}
|
||||||
m.updateDerivedParameterData(unit)
|
m.updateDerivedParameterData(unit)
|
||||||
@ -166,6 +168,38 @@ func (m *Model) updateDerivedPatchData() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Model) deriveParams(unit *sointu.Unit) []Parameter {
|
||||||
|
ret := make([]Parameter, 0, 10)
|
||||||
|
unitType, ok := sointu.UnitTypes[unit.Type]
|
||||||
|
if !ok {
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
for i, up := range unitType {
|
||||||
|
if !up.CanSet {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if unit.Type == "oscillator" && unit.Parameters["type"] != sointu.Sample && (up.Name == "samplestart" || up.Name == "loopstart" || up.Name == "looplength") {
|
||||||
|
continue // don't show the sample related params unless necessary
|
||||||
|
}
|
||||||
|
ret = append(ret, Parameter{m: m, unit: unit, up: &unitType[i], vtable: &namedParameter{}})
|
||||||
|
}
|
||||||
|
if unit.Type == "oscillator" && unit.Parameters["type"] == sointu.Sample {
|
||||||
|
ret = append(ret, Parameter{m: m, unit: unit, vtable: &gmDlsEntryParameter{}})
|
||||||
|
}
|
||||||
|
if unit.Type == "delay" {
|
||||||
|
if unit.Parameters["stereo"] == 1 && len(unit.VarArgs)%2 == 1 {
|
||||||
|
unit.VarArgs = append(unit.VarArgs, 1)
|
||||||
|
}
|
||||||
|
ret = append(ret,
|
||||||
|
Parameter{m: m, unit: unit, vtable: &reverbParameter{}},
|
||||||
|
Parameter{m: m, unit: unit, vtable: &delayLinesParameter{}})
|
||||||
|
for i := range unit.VarArgs {
|
||||||
|
ret = append(ret, Parameter{m: m, unit: unit, index: i, vtable: &delayTimeParameter{}})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
func (m *Model) updateDerivedParameterData(unit sointu.Unit) {
|
func (m *Model) updateDerivedParameterData(unit sointu.Unit) {
|
||||||
fu := m.derived.forUnit[unit.ID]
|
fu := m.derived.forUnit[unit.ID]
|
||||||
for name := range fu.unit.Parameters {
|
for name := range fu.unit.Parameters {
|
||||||
|
@ -478,7 +478,7 @@ func (ul *UnitList) update(gtx C, t *Tracker) {
|
|||||||
if e, ok := event.(key.Event); ok && e.State == key.Press {
|
if e, ok := event.(key.Event); ok && e.State == key.Press {
|
||||||
switch e.Name {
|
switch e.Name {
|
||||||
case key.NameRightArrow:
|
case key.NameRightArrow:
|
||||||
t.PatchPanel.unitEditor.sliderList.Focus()
|
t.PatchPanel.unitEditor.paramTable.Focus()
|
||||||
case key.NameDeleteBackward:
|
case key.NameDeleteBackward:
|
||||||
t.Units().SetSelectedType("")
|
t.Units().SetSelectedType("")
|
||||||
t.UnitSearching().SetValue(true)
|
t.UnitSearching().SetValue(true)
|
||||||
|
@ -7,12 +7,15 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
|
"gioui.org/f32"
|
||||||
"gioui.org/io/clipboard"
|
"gioui.org/io/clipboard"
|
||||||
"gioui.org/io/event"
|
"gioui.org/io/event"
|
||||||
"gioui.org/io/key"
|
"gioui.org/io/key"
|
||||||
"gioui.org/io/pointer"
|
"gioui.org/io/pointer"
|
||||||
"gioui.org/layout"
|
"gioui.org/layout"
|
||||||
|
"gioui.org/op"
|
||||||
"gioui.org/op/clip"
|
"gioui.org/op/clip"
|
||||||
|
"gioui.org/op/paint"
|
||||||
"gioui.org/text"
|
"gioui.org/text"
|
||||||
"gioui.org/unit"
|
"gioui.org/unit"
|
||||||
"gioui.org/widget"
|
"gioui.org/widget"
|
||||||
@ -26,9 +29,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type UnitEditor struct {
|
type UnitEditor struct {
|
||||||
sliderList *DragList
|
paramTable *ScrollTable
|
||||||
searchList *DragList
|
searchList *DragList
|
||||||
Parameters []*ParameterWidget
|
Parameters [][]*ParameterWidget
|
||||||
DeleteUnitBtn *Clickable
|
DeleteUnitBtn *Clickable
|
||||||
CopyUnitBtn *Clickable
|
CopyUnitBtn *Clickable
|
||||||
ClearUnitBtn *Clickable
|
ClearUnitBtn *Clickable
|
||||||
@ -52,7 +55,7 @@ func NewUnitEditor(m *tracker.Model) *UnitEditor {
|
|||||||
CopyUnitBtn: new(Clickable),
|
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),
|
paramTable: NewScrollTable(m.Params().Table(), m.ParamVertList().List(), m.Units().List()),
|
||||||
searchList: NewDragList(m.SearchResults().List(), layout.Vertical),
|
searchList: NewDragList(m.SearchResults().List(), layout.Vertical),
|
||||||
searching: m.UnitSearching(),
|
searching: m.UnitSearching(),
|
||||||
}
|
}
|
||||||
@ -80,7 +83,7 @@ func (pe *UnitEditor) Layout(gtx C) D {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (pe *UnitEditor) showingChooser() bool {
|
func (pe *UnitEditor) showingChooser() bool {
|
||||||
return pe.searching.Value() || pe.sliderList.TrackerList.Count() == 0
|
return pe.searching.Value()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pe *UnitEditor) update(gtx C, t *Tracker) {
|
func (pe *UnitEditor) update(gtx C, t *Tracker) {
|
||||||
@ -110,17 +113,17 @@ func (pe *UnitEditor) update(gtx C, t *Tracker) {
|
|||||||
}
|
}
|
||||||
for {
|
for {
|
||||||
e, ok := gtx.Event(
|
e, ok := gtx.Event(
|
||||||
key.Filter{Focus: pe.sliderList, Name: key.NameLeftArrow, Optional: key.ModShift},
|
key.Filter{Focus: pe.paramTable, Name: key.NameLeftArrow, Required: key.ModShift},
|
||||||
key.Filter{Focus: pe.sliderList, Name: key.NameRightArrow, Optional: key.ModShift},
|
key.Filter{Focus: pe.paramTable, Name: key.NameRightArrow, Required: key.ModShift},
|
||||||
key.Filter{Focus: pe.sliderList, Name: key.NameDeleteBackward},
|
key.Filter{Focus: pe.paramTable, Name: key.NameDeleteBackward},
|
||||||
key.Filter{Focus: pe.sliderList, Name: key.NameDeleteForward},
|
key.Filter{Focus: pe.paramTable, Name: key.NameDeleteForward},
|
||||||
)
|
)
|
||||||
if !ok {
|
if !ok {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
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.SelectedItem()
|
item := params.Item(params.Cursor())
|
||||||
switch e.Name {
|
switch e.Name {
|
||||||
case key.NameLeftArrow:
|
case key.NameLeftArrow:
|
||||||
if e.Modifiers.Contain(key.ModShift) {
|
if e.Modifiers.Contain(key.ModShift) {
|
||||||
@ -150,32 +153,56 @@ func (pe *UnitEditor) ChooseUnitType(t *Tracker) {
|
|||||||
|
|
||||||
func (pe *UnitEditor) layoutSliders(gtx C) D {
|
func (pe *UnitEditor) layoutSliders(gtx C) D {
|
||||||
t := TrackerFromContext(gtx)
|
t := TrackerFromContext(gtx)
|
||||||
numItems := pe.sliderList.TrackerList.Count()
|
|
||||||
// create enough parameter widget to match the number of parameters
|
// create enough parameter widget to match the number of parameters
|
||||||
for len(pe.Parameters) < numItems {
|
width := pe.paramTable.Table.Width()
|
||||||
pe.Parameters = append(pe.Parameters, new(ParameterWidget))
|
for len(pe.Parameters) < pe.paramTable.Table.Height() {
|
||||||
|
pe.Parameters = append(pe.Parameters, make([]*ParameterWidget, 0))
|
||||||
}
|
}
|
||||||
|
for i := range pe.Parameters {
|
||||||
index := 0
|
for len(pe.Parameters[i]) < width {
|
||||||
for param := range t.Model.Params().Iterate {
|
pe.Parameters[i] = append(pe.Parameters[i], &ParameterWidget{})
|
||||||
pe.Parameters[index].Parameter = param
|
}
|
||||||
index++
|
|
||||||
}
|
}
|
||||||
element := func(gtx C, index int) D {
|
coltitle := func(gtx C, x int) D {
|
||||||
if index < 0 || index >= numItems {
|
return D{Size: image.Pt(gtx.Dp(100), gtx.Dp(10))}
|
||||||
|
}
|
||||||
|
rowtitle := func(gtx C, y int) D {
|
||||||
|
h := gtx.Dp(100)
|
||||||
|
//defer op.Offset(image.Pt(0, -2)).Push(gtx.Ops).Pop()
|
||||||
|
defer op.Affine(f32.Affine2D{}.Rotate(f32.Pt(0, 0), -90*math.Pi/180).Offset(f32.Point{X: 0, Y: float32(h)})).Push(gtx.Ops).Pop()
|
||||||
|
gtx.Constraints = layout.Exact(image.Pt(1e6, 1e6))
|
||||||
|
Label(t.Theme, &t.Theme.OrderEditor.TrackTitle, t.Units().Item(y).Type).Layout(gtx)
|
||||||
|
return D{Size: image.Pt(gtx.Dp(patternCellWidth), h)}
|
||||||
|
}
|
||||||
|
cursor := t.Model.Params().Cursor()
|
||||||
|
cell := func(gtx C, x, y int) D {
|
||||||
|
gtx.Constraints = layout.Exact(image.Pt(gtx.Dp(100), gtx.Dp(100)))
|
||||||
|
point := tracker.Point{X: x, Y: y}
|
||||||
|
if y < 0 || y >= len(pe.Parameters) || x < 0 || x >= len(pe.Parameters[y]) {
|
||||||
return D{}
|
return D{}
|
||||||
}
|
}
|
||||||
paramStyle := t.ParamStyle(t.Theme, pe.Parameters[index])
|
if point == cursor {
|
||||||
paramStyle.Focus = pe.sliderList.TrackerList.Selected() == index
|
c := t.Theme.Cursor.Inactive
|
||||||
|
if gtx.Focused(pe.paramTable) {
|
||||||
|
c = t.Theme.Cursor.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())
|
||||||
|
}
|
||||||
|
|
||||||
|
param := t.Model.Params().Item(tracker.Point{X: x, Y: y})
|
||||||
|
pe.Parameters[y][x].Parameter = param
|
||||||
|
paramStyle := t.ParamStyle(t.Theme, pe.Parameters[y][x])
|
||||||
|
paramStyle.Focus = pe.paramTable.Table.Cursor() == tracker.Point{X: x, Y: y}
|
||||||
dims := paramStyle.Layout(gtx)
|
dims := paramStyle.Layout(gtx)
|
||||||
return D{Size: image.Pt(gtx.Constraints.Max.X, dims.Size.Y)}
|
return D{Size: image.Pt(gtx.Constraints.Max.X, dims.Size.Y)}
|
||||||
}
|
}
|
||||||
|
table := FilledScrollTable(t.Theme, pe.paramTable)
|
||||||
|
table.RowTitleWidth = 10
|
||||||
|
table.ColumnTitleHeight = 10
|
||||||
|
table.CellWidth = 100
|
||||||
|
table.CellHeight = 100
|
||||||
|
return table.Layout(gtx, cell, coltitle, rowtitle, nil, nil)
|
||||||
|
|
||||||
fdl := FilledDragList(t.Theme, pe.sliderList)
|
|
||||||
dims := fdl.Layout(gtx, element, nil)
|
|
||||||
gtx.Constraints = layout.Exact(dims.Size)
|
|
||||||
fdl.LayoutScrollBar(gtx)
|
|
||||||
return dims
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pe *UnitEditor) layoutFooter(gtx C) D {
|
func (pe *UnitEditor) layoutFooter(gtx C) D {
|
||||||
@ -234,9 +261,9 @@ func (pe *UnitEditor) layoutUnitTypeChooser(gtx C) D {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *UnitEditor) Tags(level int, yield TagYieldFunc) bool {
|
func (t *UnitEditor) Tags(level int, yield TagYieldFunc) bool {
|
||||||
widget := t.sliderList
|
widget := event.Tag(t.paramTable)
|
||||||
if t.showingChooser() {
|
if t.showingChooser() {
|
||||||
widget = t.searchList
|
widget = event.Tag(t.searchList)
|
||||||
}
|
}
|
||||||
return yield(level, widget) && yield(level+1, &t.commentEditor.widgetEditor)
|
return yield(level, widget) && yield(level+1, &t.commentEditor.widgetEditor)
|
||||||
}
|
}
|
||||||
@ -299,8 +326,6 @@ func (p ParameterStyle) Layout(gtx C) D {
|
|||||||
p.w.Parameter.SetValue(p.w.Parameter.Value() - int(delta))
|
p.w.Parameter.SetValue(p.w.Parameter.Value() - int(delta))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gtx.Constraints.Min.X = gtx.Dp(unit.Dp(200))
|
|
||||||
gtx.Constraints.Min.Y = gtx.Dp(unit.Dp(40))
|
|
||||||
ra := p.w.Parameter.Range()
|
ra := p.w.Parameter.Range()
|
||||||
if !p.w.floatWidget.Dragging() {
|
if !p.w.floatWidget.Dragging() {
|
||||||
p.w.floatWidget.Value = (float32(p.w.Parameter.Value()) - float32(ra.Min)) / float32(ra.Max-ra.Min)
|
p.w.floatWidget.Value = (float32(p.w.Parameter.Value()) - float32(ra.Min)) / float32(ra.Max-ra.Min)
|
||||||
@ -319,8 +344,6 @@ func (p ParameterStyle) Layout(gtx C) D {
|
|||||||
p.w.Parameter.SetValue(int(p.w.floatWidget.Value*float32(ra.Max-ra.Min) + float32(ra.Min) + 0.5))
|
p.w.Parameter.SetValue(int(p.w.floatWidget.Value*float32(ra.Max-ra.Min) + float32(ra.Min) + 0.5))
|
||||||
return dims
|
return dims
|
||||||
case tracker.BoolParameter:
|
case tracker.BoolParameter:
|
||||||
gtx.Constraints.Min.X = gtx.Dp(unit.Dp(60))
|
|
||||||
gtx.Constraints.Min.Y = gtx.Dp(unit.Dp(40))
|
|
||||||
ra := p.w.Parameter.Range()
|
ra := p.w.Parameter.Range()
|
||||||
p.w.boolWidget.Value = p.w.Parameter.Value() > ra.Min
|
p.w.boolWidget.Value = p.w.Parameter.Value() > ra.Min
|
||||||
boolStyle := material.Switch(&p.Theme.Material, &p.w.boolWidget, "Toggle boolean parameter")
|
boolStyle := material.Switch(&p.Theme.Material, &p.w.boolWidget, "Toggle boolean parameter")
|
||||||
@ -334,8 +357,6 @@ func (p ParameterStyle) Layout(gtx C) D {
|
|||||||
}
|
}
|
||||||
return dims
|
return dims
|
||||||
case tracker.IDParameter:
|
case tracker.IDParameter:
|
||||||
gtx.Constraints.Min.X = gtx.Dp(unit.Dp(200))
|
|
||||||
gtx.Constraints.Min.Y = gtx.Dp(unit.Dp(40))
|
|
||||||
instrItems := make([]ActionMenuItem, p.tracker.Instruments().Count())
|
instrItems := make([]ActionMenuItem, p.tracker.Instruments().Count())
|
||||||
for i := range instrItems {
|
for i := range instrItems {
|
||||||
i := i
|
i := i
|
||||||
|
@ -320,6 +320,21 @@ func (v *Units) Iterate(yield UnitYieldFunc) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v *Units) Item(index int) UnitListItem {
|
||||||
|
if index < 0 || index >= v.Count() {
|
||||||
|
return UnitListItem{}
|
||||||
|
}
|
||||||
|
unit := v.d.Song.Patch[v.d.InstrIndex].Units[index]
|
||||||
|
return UnitListItem{
|
||||||
|
Type: unit.Type,
|
||||||
|
Comment: unit.Comment,
|
||||||
|
Disabled: unit.Disabled,
|
||||||
|
StackNeed: unit.StackNeed(),
|
||||||
|
StackBefore: 0,
|
||||||
|
StackAfter: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (v *Units) Selected() int {
|
func (v *Units) Selected() int {
|
||||||
return max(min(v.d.UnitIndex, v.Count()-1), 0)
|
return max(min(v.d.UnitIndex, v.Count()-1), 0)
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,9 @@ type (
|
|||||||
Reset(*Parameter)
|
Reset(*Parameter)
|
||||||
}
|
}
|
||||||
|
|
||||||
Params Model
|
Params Model
|
||||||
|
ParamVertList Model
|
||||||
|
|
||||||
// different parameter vtables to handle different types of parameters.
|
// different parameter vtables to handle different types of parameters.
|
||||||
// Casting struct{} to interface does not cause allocations.
|
// Casting struct{} to interface does not cause allocations.
|
||||||
namedParameter struct{}
|
namedParameter struct{}
|
||||||
@ -121,78 +123,82 @@ func (p *Parameter) Reset() {
|
|||||||
p.vtable.Reset(p)
|
p.vtable.Reset(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
func (m *Model) ParamVertList() *ParamVertList { return (*ParamVertList)(m) }
|
||||||
|
func (pt *ParamVertList) List() List { return List{pt} }
|
||||||
|
func (pt *ParamVertList) Selected() int { return pt.d.ParamIndex }
|
||||||
|
func (pt *ParamVertList) Selected2() int { return pt.d.ParamIndex }
|
||||||
|
func (pt *ParamVertList) SetSelected(index int) { pt.d.ParamIndex = index }
|
||||||
|
func (pt *ParamVertList) SetSelected2(index int) {}
|
||||||
|
func (pt *ParamVertList) Count() int { return (*Params)(pt).Width() }
|
||||||
|
|
||||||
// Model and Params methods
|
// Model and Params methods
|
||||||
|
|
||||||
func (m *Model) Params() *Params { return (*Params)(m) }
|
func (m *Model) Params() *Params { return (*Params)(m) }
|
||||||
func (pl *Params) List() List { return List{pl} }
|
func (pt *Params) Table() Table { return Table{pt} }
|
||||||
func (pl *Params) Selected() int { return pl.d.ParamIndex }
|
func (pt *Params) Cursor() Point { return Point{pt.d.ParamIndex, pt.d.UnitIndex} }
|
||||||
func (pl *Params) Selected2() int { return pl.Selected() }
|
func (pt *Params) Cursor2() Point { return pt.Cursor() }
|
||||||
func (pl *Params) SetSelected(value int) { pl.d.ParamIndex = max(min(value, pl.Count()-1), 0) }
|
func (pt *Params) SetCursor(p Point) {
|
||||||
func (pl *Params) SetSelected2(value int) {}
|
pt.d.ParamIndex = p.X
|
||||||
|
pt.d.UnitIndex = p.Y
|
||||||
func (pl *Params) Count() int {
|
|
||||||
count := 0
|
|
||||||
for range pl.Iterate {
|
|
||||||
count++
|
|
||||||
}
|
|
||||||
return count
|
|
||||||
}
|
}
|
||||||
|
func (pt *Params) SetCursor2(p Point) {}
|
||||||
func (pl *Params) SelectedItem() (ret Parameter) {
|
func (pt *Params) Width() int {
|
||||||
index := pl.Selected()
|
if pt.d.InstrIndex < 0 || pt.d.InstrIndex >= len(pt.d.Song.Patch) {
|
||||||
for param := range pl.Iterate {
|
return 0
|
||||||
if index == 0 {
|
|
||||||
ret = param
|
|
||||||
}
|
|
||||||
index--
|
|
||||||
}
|
}
|
||||||
return
|
ret := 0
|
||||||
|
for _, unit := range pt.d.Song.Patch[pt.d.InstrIndex].Units {
|
||||||
|
ret = max(ret, len(pt.derived.forUnit[unit.ID].params))
|
||||||
|
}
|
||||||
|
return ret
|
||||||
}
|
}
|
||||||
|
func (pt *Params) Height() int { return (*Model)(pt).Units().Count() }
|
||||||
func (pl *Params) Iterate(yield ParamYieldFunc) {
|
func (pt *Params) MoveCursor(dx, dy int) (ok bool) {
|
||||||
if pl.d.InstrIndex < 0 || pl.d.InstrIndex >= len(pl.d.Song.Patch) {
|
if pt.d.InstrIndex < 0 || pt.d.InstrIndex >= len(pt.d.Song.Patch) {
|
||||||
return
|
return false
|
||||||
}
|
}
|
||||||
if pl.d.UnitIndex < 0 || pl.d.UnitIndex >= len(pl.d.Song.Patch[pl.d.InstrIndex].Units) {
|
pt.d.ParamIndex += dx
|
||||||
return
|
pt.d.UnitIndex += dy
|
||||||
|
pt.d.ParamIndex = clamp(pt.d.ParamIndex, 0, 7)
|
||||||
|
pt.d.UnitIndex = clamp(pt.d.UnitIndex, 0, len(pt.d.Song.Patch[pt.d.InstrIndex].Units)-1)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
func (pt *Params) Item(p Point) Parameter {
|
||||||
|
if pt.d.InstrIndex < 0 || pt.d.InstrIndex >= len(pt.d.Song.Patch) ||
|
||||||
|
p.Y < 0 || p.Y >= len(pt.d.Song.Patch[pt.d.InstrIndex].Units) {
|
||||||
|
return Parameter{}
|
||||||
}
|
}
|
||||||
unit := &pl.d.Song.Patch[pl.d.InstrIndex].Units[pl.d.UnitIndex]
|
id := pt.d.Song.Patch[pt.d.InstrIndex].Units[p.Y].ID
|
||||||
unitType, ok := sointu.UnitTypes[unit.Type]
|
if p.X < 0 || p.X >= len(pt.derived.forUnit[id].params) {
|
||||||
if !ok {
|
return Parameter{}
|
||||||
return
|
|
||||||
}
|
|
||||||
for i, up := range unitType {
|
|
||||||
if !up.CanSet {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if unit.Type == "oscillator" && unit.Parameters["type"] != sointu.Sample && (up.Name == "samplestart" || up.Name == "loopstart" || up.Name == "looplength") {
|
|
||||||
continue // don't show the sample related params unless necessary
|
|
||||||
}
|
|
||||||
if !yield(Parameter{m: (*Model)(pl), unit: unit, up: &unitType[i], vtable: &namedParameter{}}) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if unit.Type == "oscillator" && unit.Parameters["type"] == sointu.Sample {
|
|
||||||
if !yield(Parameter{m: (*Model)(pl), unit: unit, vtable: &gmDlsEntryParameter{}}) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if unit.Type == "delay" {
|
|
||||||
if unit.Parameters["stereo"] == 1 && len(unit.VarArgs)%2 == 1 {
|
|
||||||
unit.VarArgs = append(unit.VarArgs, 1)
|
|
||||||
}
|
|
||||||
if !yield(Parameter{m: (*Model)(pl), unit: unit, vtable: &reverbParameter{}}) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !yield(Parameter{m: (*Model)(pl), unit: unit, vtable: &delayLinesParameter{}}) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for i := range unit.VarArgs {
|
|
||||||
if !yield(Parameter{m: (*Model)(pl), unit: unit, index: i, vtable: &delayTimeParameter{}}) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return pt.derived.forUnit[id].params[p.X]
|
||||||
|
}
|
||||||
|
func (pt *Params) clear(p Point) {
|
||||||
|
panic("NOT IMPLEMENTED")
|
||||||
|
}
|
||||||
|
func (pt *Params) set(p Point, value int) {
|
||||||
|
panic("NOT IMPLEMENTED")
|
||||||
|
}
|
||||||
|
func (pt *Params) add(rect Rect, delta int) (ok bool) {
|
||||||
|
panic("NOT IMPLEMENTED")
|
||||||
|
}
|
||||||
|
func (pt *Params) marshal(rect Rect) (data []byte, ok bool) {
|
||||||
|
panic("NOT IMPLEMENTED")
|
||||||
|
}
|
||||||
|
func (pt *Params) unmarshalAtCursor(data []byte) (ok bool) {
|
||||||
|
panic("NOT IMPLEMENTED")
|
||||||
|
}
|
||||||
|
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")
|
||||||
|
}
|
||||||
|
func (pt *Params) cancel() {
|
||||||
|
panic("NOT IMPLEMENTED")
|
||||||
}
|
}
|
||||||
|
|
||||||
// namedParameter vtable
|
// namedParameter vtable
|
||||||
|
Reference in New Issue
Block a user