This commit is contained in:
5684185+vsariola@users.noreply.github.com
2025-07-06 01:38:07 +03:00
parent 53af773815
commit e1aa9c0d26
11 changed files with 218 additions and 102 deletions

View File

@ -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 {

View File

@ -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)
}
}

View File

@ -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) {

View File

@ -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)

View File

@ -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:

View File

@ -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

View File

@ -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 }

View File

@ -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 {