mirror of
https://github.com/vsariola/sointu.git
synced 2025-07-14 02:54:37 -04:00
feat(tracker): move reset and load song into popup menu
This commit is contained in:
72
tracker/popup.go
Normal file
72
tracker/popup.go
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
package tracker
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image/color"
|
||||||
|
|
||||||
|
"gioui.org/f32"
|
||||||
|
"gioui.org/io/pointer"
|
||||||
|
"gioui.org/layout"
|
||||||
|
"gioui.org/op"
|
||||||
|
"gioui.org/op/clip"
|
||||||
|
"gioui.org/op/paint"
|
||||||
|
"gioui.org/unit"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PopupStyle struct {
|
||||||
|
Visible *bool
|
||||||
|
Contents layout.Widget
|
||||||
|
SurfaceColor color.NRGBA
|
||||||
|
SE, SW, NW, NE unit.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
func Popup(visible *bool, contents layout.Widget) PopupStyle {
|
||||||
|
return PopupStyle{
|
||||||
|
Visible: visible,
|
||||||
|
Contents: contents,
|
||||||
|
SurfaceColor: popupSurfaceColor,
|
||||||
|
SE: unit.Dp(6),
|
||||||
|
SW: unit.Dp(6),
|
||||||
|
NW: unit.Dp(6),
|
||||||
|
NE: unit.Dp(6),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s PopupStyle) Layout(gtx C) D {
|
||||||
|
if !*s.Visible {
|
||||||
|
return D{}
|
||||||
|
}
|
||||||
|
for _, ev := range gtx.Events(s.Visible) {
|
||||||
|
e, ok := ev.(pointer.Event)
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
switch e.Type {
|
||||||
|
case pointer.Press:
|
||||||
|
*s.Visible = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bg := func(gtx C) D {
|
||||||
|
pointer.InputOp{Tag: s.Visible,
|
||||||
|
Types: pointer.Press,
|
||||||
|
}.Add(gtx.Ops)
|
||||||
|
rrect := clip.RRect{
|
||||||
|
Rect: f32.Rectangle{Max: f32.Pt(float32(gtx.Constraints.Min.X), float32(gtx.Constraints.Min.Y))},
|
||||||
|
SE: float32(gtx.Px(s.SE)),
|
||||||
|
SW: float32(gtx.Px(s.SW)),
|
||||||
|
NW: float32(gtx.Px(s.NW)),
|
||||||
|
NE: float32(gtx.Px(s.NE)),
|
||||||
|
}
|
||||||
|
paint.FillShape(gtx.Ops, s.SurfaceColor, rrect.Op(gtx.Ops))
|
||||||
|
return D{Size: gtx.Constraints.Min}
|
||||||
|
}
|
||||||
|
macro := op.Record(gtx.Ops)
|
||||||
|
dims := layout.Stack{}.Layout(gtx,
|
||||||
|
layout.Expanded(bg),
|
||||||
|
layout.Stacked(s.Contents),
|
||||||
|
)
|
||||||
|
callop := macro.Stop()
|
||||||
|
op.Defer(gtx.Ops, callop)
|
||||||
|
return dims
|
||||||
|
}
|
@ -4,7 +4,9 @@ import (
|
|||||||
"image"
|
"image"
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
|
"gioui.org/f32"
|
||||||
"gioui.org/layout"
|
"gioui.org/layout"
|
||||||
|
"gioui.org/op"
|
||||||
"gioui.org/op/clip"
|
"gioui.org/op/clip"
|
||||||
"gioui.org/op/paint"
|
"gioui.org/op/paint"
|
||||||
"gioui.org/unit"
|
"gioui.org/unit"
|
||||||
@ -26,11 +28,13 @@ func (t *Tracker) layoutSongButtons(gtx C) D {
|
|||||||
//paint.FillShape(gtx.Ops, primaryColorDark, clip.Rect(image.Rect(0, 0, gtx.Constraints.Max.X, gtx.Constraints.Max.Y)).Op())
|
//paint.FillShape(gtx.Ops, primaryColorDark, clip.Rect(image.Rect(0, 0, gtx.Constraints.Max.X, gtx.Constraints.Max.Y)).Op())
|
||||||
|
|
||||||
for t.NewSongFileBtn.Clicked() {
|
for t.NewSongFileBtn.Clicked() {
|
||||||
t.LoadSong(defaultSong)
|
t.LoadSong(defaultSong.Copy())
|
||||||
|
t.FileMenuVisible = false
|
||||||
}
|
}
|
||||||
|
|
||||||
for t.LoadSongFileBtn.Clicked() {
|
for t.LoadSongFileBtn.Clicked() {
|
||||||
t.LoadSongFile()
|
t.LoadSongFile()
|
||||||
|
t.FileMenuVisible = false
|
||||||
}
|
}
|
||||||
|
|
||||||
for t.SaveSongFileBtn.Clicked() {
|
for t.SaveSongFileBtn.Clicked() {
|
||||||
@ -47,15 +51,42 @@ func (t *Tracker) layoutSongButtons(gtx C) D {
|
|||||||
loadBtnStyle.Inset = layout.UniformInset(unit.Dp(6))
|
loadBtnStyle.Inset = layout.UniformInset(unit.Dp(6))
|
||||||
loadBtnStyle.Color = primaryColor
|
loadBtnStyle.Color = primaryColor
|
||||||
|
|
||||||
|
menuContents := func(gtx C) D {
|
||||||
|
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
|
||||||
|
layout.Rigid(newBtnStyle.Layout),
|
||||||
|
layout.Rigid(loadBtnStyle.Layout),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fileMenu := Popup(&t.FileMenuVisible, menuContents)
|
||||||
|
|
||||||
saveBtnStyle := material.IconButton(t.Theme, t.SaveSongFileBtn, widgetForIcon(icons.ContentSave))
|
saveBtnStyle := material.IconButton(t.Theme, t.SaveSongFileBtn, widgetForIcon(icons.ContentSave))
|
||||||
saveBtnStyle.Background = transparent
|
saveBtnStyle.Background = transparent
|
||||||
saveBtnStyle.Inset = layout.UniformInset(unit.Dp(6))
|
saveBtnStyle.Inset = layout.UniformInset(unit.Dp(6))
|
||||||
saveBtnStyle.Color = primaryColor
|
saveBtnStyle.Color = primaryColor
|
||||||
|
|
||||||
|
fileMenuBtnStyle := material.IconButton(t.Theme, t.FileMenuBtn, widgetForIcon(icons.NavigationMoreVert))
|
||||||
|
fileMenuBtnStyle.Background = transparent
|
||||||
|
fileMenuBtnStyle.Inset = layout.UniformInset(unit.Dp(6))
|
||||||
|
fileMenuBtnStyle.Color = primaryColor
|
||||||
|
|
||||||
|
for t.FileMenuBtn.Clicked() {
|
||||||
|
t.FileMenuVisible = true
|
||||||
|
}
|
||||||
|
|
||||||
|
popupWidget := func(gtx C) D {
|
||||||
|
defer op.Save(gtx.Ops).Load()
|
||||||
|
dims := fileMenuBtnStyle.Layout(gtx)
|
||||||
|
op.Offset(f32.Pt(0, float32(dims.Size.Y))).Add(gtx.Ops)
|
||||||
|
gtx.Constraints.Max.X = 160
|
||||||
|
gtx.Constraints.Max.Y = 300
|
||||||
|
fileMenu.Layout(gtx)
|
||||||
|
return dims
|
||||||
|
}
|
||||||
|
|
||||||
layout.Flex{Axis: layout.Horizontal}.Layout(gtx,
|
layout.Flex{Axis: layout.Horizontal}.Layout(gtx,
|
||||||
layout.Rigid(newBtnStyle.Layout),
|
|
||||||
layout.Rigid(loadBtnStyle.Layout),
|
|
||||||
layout.Rigid(saveBtnStyle.Layout),
|
layout.Rigid(saveBtnStyle.Layout),
|
||||||
|
layout.Rigid(popupWidget),
|
||||||
)
|
)
|
||||||
|
|
||||||
return layout.Dimensions{Size: gtx.Constraints.Max}
|
return layout.Dimensions{Size: gtx.Constraints.Max}
|
||||||
|
@ -88,3 +88,5 @@ var inactiveBtnColor = color.NRGBA{R: 61, G: 55, B: 55, A: 255}
|
|||||||
var instrumentSurfaceColor = color.NRGBA{R: 37, G: 37, B: 38, A: 255}
|
var instrumentSurfaceColor = color.NRGBA{R: 37, G: 37, B: 38, A: 255}
|
||||||
|
|
||||||
var songSurfaceColor = color.NRGBA{R: 37, G: 37, B: 38, A: 255}
|
var songSurfaceColor = color.NRGBA{R: 37, G: 37, B: 38, A: 255}
|
||||||
|
|
||||||
|
var popupSurfaceColor = color.NRGBA{R: 45, G: 45, B: 46, A: 255}
|
||||||
|
@ -42,6 +42,8 @@ type Tracker struct {
|
|||||||
SubtractOctaveBtn *widget.Clickable
|
SubtractOctaveBtn *widget.Clickable
|
||||||
SongLength *NumberInput
|
SongLength *NumberInput
|
||||||
SaveSongFileBtn *widget.Clickable
|
SaveSongFileBtn *widget.Clickable
|
||||||
|
FileMenuBtn *widget.Clickable
|
||||||
|
FileMenuVisible bool
|
||||||
ParameterSliders []*widget.Float
|
ParameterSliders []*widget.Float
|
||||||
UnitBtns []*widget.Clickable
|
UnitBtns []*widget.Clickable
|
||||||
InstrumentBtns []*widget.Clickable
|
InstrumentBtns []*widget.Clickable
|
||||||
@ -384,6 +386,7 @@ func New(audioContext sointu.AudioContext) *Tracker {
|
|||||||
NewInstrumentBtn: new(widget.Clickable),
|
NewInstrumentBtn: new(widget.Clickable),
|
||||||
DeleteInstrumentBtn: new(widget.Clickable),
|
DeleteInstrumentBtn: new(widget.Clickable),
|
||||||
NewSongFileBtn: new(widget.Clickable),
|
NewSongFileBtn: new(widget.Clickable),
|
||||||
|
FileMenuBtn: new(widget.Clickable),
|
||||||
LoadSongFileBtn: new(widget.Clickable),
|
LoadSongFileBtn: new(widget.Clickable),
|
||||||
SaveSongFileBtn: new(widget.Clickable),
|
SaveSongFileBtn: new(widget.Clickable),
|
||||||
AddSemitoneBtn: new(widget.Clickable),
|
AddSemitoneBtn: new(widget.Clickable),
|
||||||
@ -408,7 +411,7 @@ func New(audioContext sointu.AudioContext) *Tracker {
|
|||||||
t.Theme.Palette.Fg = primaryColor
|
t.Theme.Palette.Fg = primaryColor
|
||||||
t.Theme.Palette.ContrastFg = black
|
t.Theme.Palette.ContrastFg = black
|
||||||
go t.sequencerLoop(t.closer)
|
go t.sequencerLoop(t.closer)
|
||||||
if err := t.LoadSong(defaultSong); err != nil {
|
if err := t.LoadSong(defaultSong.Copy()); err != nil {
|
||||||
panic(fmt.Errorf("cannot load default song: %w", err))
|
panic(fmt.Errorf("cannot load default song: %w", err))
|
||||||
}
|
}
|
||||||
return t
|
return t
|
||||||
|
Reference in New Issue
Block a user