diff options
Diffstat (limited to 'vendor/github.com/aarzilli')
-rw-r--r-- | vendor/github.com/aarzilli/nucular/font/font_gio.go | 5 | ||||
-rw-r--r-- | vendor/github.com/aarzilli/nucular/gio.go | 253 | ||||
-rw-r--r-- | vendor/github.com/aarzilli/nucular/go.mod | 6 | ||||
-rw-r--r-- | vendor/github.com/aarzilli/nucular/go.sum | 14 | ||||
-rw-r--r-- | vendor/github.com/aarzilli/nucular/masterwindow.go | 1 | ||||
-rw-r--r-- | vendor/github.com/aarzilli/nucular/nucular.go | 18 | ||||
-rw-r--r-- | vendor/github.com/aarzilli/nucular/shiny.go | 68 | ||||
-rw-r--r-- | vendor/github.com/aarzilli/nucular/text.go | 6 |
8 files changed, 225 insertions, 146 deletions
diff --git a/vendor/github.com/aarzilli/nucular/font/font_gio.go b/vendor/github.com/aarzilli/nucular/font/font_gio.go index f4816d7..2f27d5b 100644 --- a/vendor/github.com/aarzilli/nucular/font/font_gio.go +++ b/vendor/github.com/aarzilli/nucular/font/font_gio.go @@ -17,7 +17,7 @@ import ( type Face struct { fnt *opentype.Font - shaper *text.FontRegistry + shaper *text.Cache size int fsize fixed.Int26_6 metrics font.Metrics @@ -40,8 +40,7 @@ func NewFace(ttf []byte, size int) (Face, error) { } } - shaper := &text.FontRegistry{} - shaper.Register(text.Font{}, fnt) + shaper := text.NewCache([]text.FontFace{{text.Font{}, fnt}}) face := Face{fnt, shaper, size, fixed.I(size), font.Metrics{}} metricsTxt, _ := face.shaper.Layout(text.Font{}, fixed.I(size), 1e6, strings.NewReader("metrics")) diff --git a/vendor/github.com/aarzilli/nucular/gio.go b/vendor/github.com/aarzilli/nucular/gio.go index 1b6adf3..d8adeaf 100644 --- a/vendor/github.com/aarzilli/nucular/gio.go +++ b/vendor/github.com/aarzilli/nucular/gio.go @@ -13,6 +13,7 @@ import ( "sync" "sync/atomic" "time" + "unicode/utf8" "unsafe" "gioui.org/app" @@ -46,6 +47,7 @@ type masterWindow struct { Title string initialSize image.Point size image.Point + onClose func() w *app.Window ops op.Ops @@ -81,6 +83,11 @@ func (mw *masterWindow) Main() { go func() { mw.w = app.NewWindow(app.Title(mw.Title), app.Size(unit.Px(float32(mw.ctx.scale(mw.initialSize.X))), unit.Px(float32(mw.ctx.scale(mw.initialSize.Y))))) mw.main() + if mw.onClose != nil { + mw.onClose() + } else { + os.Exit(0) + } }() go mw.updater() app.Main() @@ -95,7 +102,7 @@ func (mw *masterWindow) Unlock() { } func (mw *masterWindow) Close() { - os.Exit(0) // Bad... + mw.w.Close() } func (mw *masterWindow) Closed() bool { @@ -104,9 +111,13 @@ func (mw *masterWindow) Closed() bool { return mw.closed } +func (mw *masterWindow) OnClose(onClose func()) { + mw.onClose = onClose +} + func (mw *masterWindow) main() { - for { - e := <-mw.w.Events() + perfString := "" + for e := range mw.w.Events() { switch e := e.(type) { case system.DestroyEvent: mw.uilock.Lock() @@ -121,15 +132,49 @@ func (mw *masterWindow) main() { mw.size = e.Size mw.uilock.Lock() mw.prevCmds = mw.prevCmds[:0] - mw.updateLocked() + mw.updateLocked(perfString) mw.uilock.Unlock() e.Frame(&mw.ops) + + case profile.Event: + perfString = e.Timings + case pointer.Event: + mw.uilock.Lock() + mw.processPointerEvent(e) + mw.uilock.Unlock() + case key.EditEvent: + changed := atomic.LoadInt32(&mw.ctx.changed) + if changed < 2 { + atomic.StoreInt32(&mw.ctx.changed, 2) + } + mw.uilock.Lock() + io.WriteString(&mw.textbuffer, e.Text) + mw.uilock.Unlock() + + case key.Event: + changed := atomic.LoadInt32(&mw.ctx.changed) + if changed < 2 { + atomic.StoreInt32(&mw.ctx.changed, 2) + } + if e.State == key.Press { + mw.uilock.Lock() + switch e.Name { + case key.NameEnter, key.NameReturn: + io.WriteString(&mw.textbuffer, "\n") + } + mw.ctx.Input.Keyboard.Keys = append(mw.ctx.Input.Keyboard.Keys, gio2mobileKey(e)) + mw.uilock.Unlock() + } } } } func (mw *masterWindow) processPointerEvent(e pointer.Event) { + changed := atomic.LoadInt32(&mw.ctx.changed) + if changed < 2 { + atomic.StoreInt32(&mw.ctx.changed, 2) + } switch e.Type { case pointer.Release, pointer.Cancel: for i := range mw.ctx.Input.Mouse.Buttons { @@ -144,11 +189,11 @@ func (mw *masterWindow) processPointerEvent(e pointer.Event) { var button mouse.Button switch { - case e.Buttons.Contain(pointer.ButtonLeft): + case e.Buttons.Contain(pointer.ButtonPrimary): button = mouse.ButtonLeft - case e.Buttons.Contain(pointer.ButtonRight): + case e.Buttons.Contain(pointer.ButtonSecondary): button = mouse.ButtonRight - case e.Buttons.Contain(pointer.ButtonMiddle): + case e.Buttons.Contain(pointer.ButtonTertiary): button = mouse.ButtonMiddle } @@ -169,7 +214,7 @@ func (mw *masterWindow) processPointerEvent(e pointer.Event) { btn.Clicked = true btn.Down = down - case pointer.Move: + case pointer.Move, pointer.Drag, pointer.Scroll: mw.ctx.Input.Mouse.Pos.X = int(e.Position.X) mw.ctx.Input.Mouse.Pos.Y = int(e.Position.Y) mw.ctx.Input.Mouse.Delta = mw.ctx.Input.Mouse.Pos.Sub(mw.ctx.Input.Mouse.Prev) @@ -219,6 +264,19 @@ func init() { runeToCode[key.NamePageUp] = mkey.CodePageUp runeToCode[key.NamePageDown] = mkey.CodePageDown runeToCode[key.NameTab] = mkey.CodeTab + + runeToCode["F1"] = mkey.CodeF1 + runeToCode["F2"] = mkey.CodeF2 + runeToCode["F3"] = mkey.CodeF3 + runeToCode["F4"] = mkey.CodeF4 + runeToCode["F5"] = mkey.CodeF5 + runeToCode["F6"] = mkey.CodeF6 + runeToCode["F7"] = mkey.CodeF7 + runeToCode["F8"] = mkey.CodeF8 + runeToCode["F9"] = mkey.CodeF9 + runeToCode["F10"] = mkey.CodeF10 + runeToCode["F11"] = mkey.CodeF11 + runeToCode["F12"] = mkey.CodeF12 } func gio2mobileKey(e key.Event) mkey.Event { @@ -275,27 +333,7 @@ func (w *masterWindow) updater() { } } -func (mw *masterWindow) updateLocked() { - perfString := "" - q := mw.w.Queue() - for _, e := range q.Events(mw.ctx) { - switch e := e.(type) { - case profile.Event: - perfString = e.Timings - case pointer.Event: - mw.processPointerEvent(e) - case key.EditEvent: - io.WriteString(&mw.textbuffer, e.Text) - - case key.Event: - switch e.Name { - case key.NameEnter, key.NameReturn: - io.WriteString(&mw.textbuffer, "\n") - } - mw.ctx.Input.Keyboard.Keys = append(mw.ctx.Input.Keyboard.Keys, gio2mobileKey(e)) - } - } - +func (mw *masterWindow) updateLocked(perfString string) { mw.ctx.Windows[0].Bounds = rect.Rect{X: 0, Y: 0, W: mw.size.X, H: mw.size.Y} in := &mw.ctx.Input in.Mouse.clip = nk_null_rect @@ -341,11 +379,9 @@ func (mw *masterWindow) updateLocked() { paintRect := f32.Rectangle{f32.Point{float32(pos.X), float32(pos.Y)}, f32.Point{float32(pos.X + bounds.X), float32(pos.Y + bounds.Y)}} - var stack op.StackOp - stack.Push(&mw.ops) - paint.ColorOp{Color: color.RGBA{0xff, 0xff, 0xff, 0xff}}.Add(&mw.ops) - paint.PaintOp{Rect: paintRect}.Add(&mw.ops) - stack.Pop() + stack := op.Save(&mw.ops) + paint.FillShape(&mw.ops, color.NRGBA{0xff, 0xff, 0xff, 0xff}, gioclip.UniformRRect(paintRect, 0).Op(&mw.ops)) + stack.Load() drawText(&mw.ops, txt, font, color.RGBA{0x00, 0x00, 0x00, 0xff}, pos, bounds, paintRect) } @@ -367,10 +403,10 @@ func (ctx *context) Draw(ops *op.Ops, size image.Point, perf bool) int { if perf { profile.Op{ctx}.Add(ops) } - pointer.InputOp{ctx, false}.Add(ops) - key.InputOp{ctx, true}.Add(ops) + pointer.InputOp{ctx, false, pointer.Cancel | pointer.Press | pointer.Release | pointer.Move | pointer.Drag | pointer.Scroll, image.Rect(0, 0, 4096, 4096)}.Add(ops) + key.InputOp{ctx}.Add(ops) - var scissorStack op.StackOp + var scissorStack op.StateOp scissorless := true for i := range ctx.cmds { @@ -378,18 +414,17 @@ func (ctx *context) Draw(ops *op.Ops, size image.Point, perf bool) int { switch icmd.Kind { case command.ScissorCmd: if !scissorless { - scissorStack.Pop() + scissorStack.Load() } - scissorStack.Push(ops) - gioclip.Rect{Rect: n2fRect(icmd.Rect)}.Op(ops).Add(ops) + scissorStack = op.Save(ops) + gioclip.Rect(icmd.Rect.Rectangle()).Add(ops) scissorless = false case command.LineCmd: cmd := icmd.Line - var stack op.StackOp - stack.Push(ops) - paint.ColorOp{Color: cmd.Color}.Add(ops) + stack := op.Save(ops) + paint.ColorOp{Color: toNRGBA(cmd.Color)}.Add(ops) h1 := int(cmd.LineThickness / 2) h2 := int(cmd.LineThickness) - h1 @@ -399,17 +434,15 @@ func (ctx *context) Draw(ops *op.Ops, size image.Point, perf bool) int { if y0 > y1 { y0, y1 = y1, y0 } - paint.PaintOp{Rect: f32.Rectangle{ - f32.Point{float32(cmd.Begin.X - h1), float32(y0)}, - f32.Point{float32(cmd.Begin.X + h2), float32(y1)}}}.Add(ops) + gioclip.Rect{image.Point{cmd.Begin.X - h1, y0}, image.Point{cmd.Begin.X + h2, y1}}.Add(ops) + paint.PaintOp{}.Add(ops) } else if cmd.Begin.Y == cmd.End.Y { x0, x1 := cmd.Begin.X, cmd.End.X if x0 > x1 { x0, x1 = x1, x0 } - paint.PaintOp{Rect: f32.Rectangle{ - f32.Point{float32(x0), float32(cmd.Begin.Y - h1)}, - f32.Point{float32(x1), float32(cmd.Begin.Y + h2)}}}.Add(ops) + gioclip.Rect{image.Point{x0, cmd.Begin.Y - h1}, image.Point{x1, cmd.Begin.Y + h2}}.Add(ops) + paint.PaintOp{}.Add(ops) } else { m := float32(cmd.Begin.Y-cmd.End.Y) / float32(cmd.Begin.X-cmd.End.X) invm := -1 / m @@ -429,33 +462,26 @@ func (ctx *context) Draw(ops *op.Ops, size image.Point, perf bool) int { pd := f32.Point{-2 * xadv, -2 * yadv} p.Line(pd) p.Line(f32.Point{float32(cmd.Begin.X - cmd.End.X), float32(cmd.Begin.Y - cmd.End.Y)}) + p.Close() - p.End().Add(ops) + gioclip.Outline{Path: p.End()}.Op().Add(ops) pb = pb.Add(pa) pc = pc.Add(pb) pd = pd.Add(pc) - minp := f32.Point{ - min4(pa.X, pb.X, pc.X, pd.X), - min4(pa.Y, pb.Y, pc.Y, pd.Y)} - maxp := f32.Point{ - max4(pa.X, pb.X, pc.X, pd.X), - max4(pa.Y, pb.Y, pc.Y, pd.Y)} - - paint.PaintOp{Rect: f32.Rectangle{minp, maxp}}.Add(ops) + paint.PaintOp{}.Add(ops) } - stack.Pop() + stack.Load() case command.RectFilledCmd: cmd := icmd.RectFilled // rounding is true if rounding has been requested AND we can draw it rounding := cmd.Rounding > 0 && int(cmd.Rounding*2) < icmd.W && int(cmd.Rounding*2) < icmd.H - var stack op.StackOp - stack.Push(ops) - paint.ColorOp{Color: cmd.Color}.Add(ops) + stack := op.Save(ops) + paint.ColorOp{Color: toNRGBA(cmd.Color)}.Add(ops) if rounding { const c = 0.55228475 // 4*(sqrt(2)-1)/3 @@ -473,19 +499,20 @@ func (ctx *context) Draw(ops *op.Ops, size image.Point, perf bool) int { b.Cube(f32.Point{X: 0, Y: -r * c}, f32.Point{X: r - r*c, Y: -r}, f32.Point{X: r, Y: -r}) // NW b.Line(f32.Point{X: w - r - r, Y: 0}) b.Cube(f32.Point{X: r * c, Y: 0}, f32.Point{X: r, Y: r - r*c}, f32.Point{X: r, Y: r}) // NE - b.End().Add(ops) + b.Close() + gioclip.Outline{Path: b.End()}.Op().Add(ops) } - paint.PaintOp{Rect: n2fRect(icmd.Rect)}.Add(ops) - stack.Pop() + gioclip.Rect(icmd.Rect.Rectangle()).Add(ops) + paint.PaintOp{}.Add(ops) + stack.Load() case command.TriangleFilledCmd: cmd := icmd.TriangleFilled - var stack op.StackOp - stack.Push(ops) + stack := op.Save(ops) - paint.ColorOp{cmd.Color}.Add(ops) + paint.ColorOp{toNRGBA(cmd.Color)}.Add(ops) var p gioclip.Path p.Begin(ops) @@ -493,25 +520,17 @@ func (ctx *context) Draw(ops *op.Ops, size image.Point, perf bool) int { p.Line(f32.Point{float32(cmd.B.X - cmd.A.X), float32(cmd.B.Y - cmd.A.Y)}) p.Line(f32.Point{float32(cmd.C.X - cmd.B.X), float32(cmd.C.Y - cmd.B.Y)}) p.Line(f32.Point{float32(cmd.A.X - cmd.C.X), float32(cmd.A.Y - cmd.C.Y)}) - p.End().Add(ops) - - pmin := f32.Point{ - min2(min2(float32(cmd.A.X), float32(cmd.B.X)), float32(cmd.C.X)), - min2(min2(float32(cmd.A.Y), float32(cmd.B.Y)), float32(cmd.C.Y))} + p.Close() + gioclip.Outline{Path: p.End()}.Op().Add(ops) - pmax := f32.Point{ - max2(max2(float32(cmd.A.X), float32(cmd.B.X)), float32(cmd.C.X)), - max2(max2(float32(cmd.A.Y), float32(cmd.B.Y)), float32(cmd.C.Y))} + paint.PaintOp{}.Add(ops) - paint.PaintOp{Rect: f32.Rectangle{pmin, pmax}}.Add(ops) - - stack.Pop() + stack.Load() case command.CircleFilledCmd: - var stack op.StackOp - stack.Push(ops) + stack := op.Save(ops) - paint.ColorOp{icmd.CircleFilled.Color}.Add(ops) + paint.ColorOp{toNRGBA(icmd.CircleFilled.Color)}.Add(ops) r := min2(float32(icmd.W), float32(icmd.H)) / 2 @@ -523,19 +542,20 @@ func (ctx *context) Draw(ops *op.Ops, size image.Point, perf bool) int { b.Cube(f32.Point{X: -r * c, Y: 0}, f32.Point{X: -r, Y: -r + r*c}, f32.Point{X: -r, Y: -r}) // SW b.Cube(f32.Point{X: 0, Y: -r * c}, f32.Point{X: r - r*c, Y: -r}, f32.Point{X: r, Y: -r}) // NW b.Cube(f32.Point{X: r * c, Y: 0}, f32.Point{X: r, Y: r - r*c}, f32.Point{X: r, Y: r}) // NE - b.End().Add(ops) + gioclip.Outline{Path: b.End()}.Op().Add(ops) - paint.PaintOp{Rect: n2fRect(icmd.Rect)}.Add(ops) + paint.PaintOp{}.Add(ops) - stack.Pop() + stack.Load() case command.ImageCmd: - var stack op.StackOp - stack.Push(ops) + stack := op.Save(ops) //TODO: this should be retained between frames somehow... paint.NewImageOp(icmd.Image.Img).Add(ops) - paint.PaintOp{n2fRect(icmd.Rect)}.Add(ops) - stack.Pop() + op.Offset(f32.Point{float32(icmd.Rect.X), float32(icmd.Rect.Y)}).Add(ops) + gioclip.Rect{image.Point{0, 0}, image.Point{icmd.Rect.W, icmd.Rect.H}}.Add(ops) + paint.PaintOp{}.Add(ops) + stack.Load() case command.TextCmd: txt := fontFace2fontFace(&icmd.Text.Face).layout(icmd.Text.String, -1) @@ -618,21 +638,26 @@ func textPadding(lines []text.Line) (padding image.Rectangle) { func clipLine(line text.Line, clip image.Rectangle) (text.Line, f32.Point, bool) { off := fixed.Point26_6{X: fixed.I(0), Y: fixed.I(line.Ascent.Ceil())} - for len(line.Layout) > 0 { - adv := line.Layout[0].Advance + for len(line.Layout.Advances) > 0 { + adv := line.Layout.Advances[0] + _, n := utf8.DecodeRuneInString(line.Layout.Text) if (off.X + adv + line.Bounds.Max.X - line.Width).Ceil() >= clip.Min.X { break } off.X += adv - line.Layout = line.Layout[1:] + line.Layout.Text = line.Layout.Text[n:] + line.Layout.Advances = line.Layout.Advances[1:] } endx := off.X - for i, glyph := range line.Layout { + rune := 0 + for n, _ := range line.Layout.Text { if (endx + line.Bounds.Min.X).Floor() > clip.Max.X { - line.Layout = line.Layout[:i] + line.Layout.Advances = line.Layout.Advances[:rune] + line.Layout.Text = line.Layout.Text[:n] break } - endx += glyph.Advance + endx += line.Layout.Advances[rune] + rune++ } offf := f32.Point{X: float32(off.X) / 64, Y: float32(off.Y) / 64} return line, offf, true @@ -652,9 +677,8 @@ func drawText(ops *op.Ops, txt []text.Line, face font.Face, fgcolor color.RGBA, clip := textPadding(txt) clip.Max = clip.Max.Add(bounds) - var stack op.StackOp - stack.Push(ops) - paint.ColorOp{fgcolor}.Add(ops) + stack := op.Save(ops) + paint.ColorOp{toNRGBA(fgcolor)}.Add(ops) fc := fontFace2fontFace(&face) @@ -667,23 +691,23 @@ func drawText(ops *op.Ops, txt []text.Line, face font.Face, fgcolor color.RGBA, off.X += float32(pos.X) off.Y += float32(pos.Y) + float32(i*FontHeight(face)) - var stack op.StackOp - stack.Push(ops) + stack := op.Save(ops) - op.TransformOp{}.Offset(off).Add(ops) + op.Offset(off).Add(ops) fc.shape(txtstr.Layout).Add(ops) - paint.PaintOp{Rect: paintRect.Sub(off)}.Add(ops) + gioclip.UniformRRect(paintRect.Sub(off), 0).Add(ops) + paint.PaintOp{}.Add(ops) - stack.Pop() + stack.Load() } - stack.Pop() + stack.Load() } type fontFace struct { fnt *opentype.Font - shaper *text.FontRegistry + shaper *text.Cache size int fsize fixed.Int26_6 metrics ifont.Metrics @@ -700,7 +724,7 @@ func (face *fontFace) layout(str string, width int) []text.Line { return face.shaper.LayoutString(text.Font{}, fixed.I(face.size), width, str) } -func (face *fontFace) shape(txtstr []text.Glyph) op.CallOp { +func (face *fontFace) shape(txtstr text.Layout) op.CallOp { return face.shaper.Shape(text.Font{}, fixed.I(face.size), txtstr) } @@ -817,11 +841,18 @@ func widgetTextWrap(o *command.Buffer, b rect.Rect, str []rune, t *textWidget, f if line.Y+line.H >= (b.Y + b.H) { break } - runes := make([]rune, len(txtline.Layout)) - for i := range txtline.Layout { - runes[i] = txtline.Layout[i].Rune - } - widgetText(o, line, string(runes), &text, "LC", f) + widgetText(o, line, txtline.Layout.Text, &text, "LC", f) line.Y += FontHeight(f) + 2*t.Padding.Y } } + +func toNRGBA(c color.RGBA) color.NRGBA { + if c.A == 0xff { + return color.NRGBA{c.R, c.G, c.B, c.A} + } + r, g, b, a := c.RGBA() + r = (r * 0xffff) / a + g = (g * 0xffff) / a + b = (b * 0xffff) / a + return color.NRGBA{uint8(r >> 8), uint8(g >> 8), uint8(b >> 8), uint8(a >> 8)} +} diff --git a/vendor/github.com/aarzilli/nucular/go.mod b/vendor/github.com/aarzilli/nucular/go.mod index d8a9134..7f38a4e 100644 --- a/vendor/github.com/aarzilli/nucular/go.mod +++ b/vendor/github.com/aarzilli/nucular/go.mod @@ -1,13 +1,13 @@ module github.com/aarzilli/nucular require ( - gioui.org v0.0.0-20200417085050-0cfc914d8b7d + gioui.org v0.0.0-20210407072325-abd6e8f9cdd4 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 github.com/golang/freetype v0.0.0-20161208064710-d9be45aaf745 github.com/hashicorp/golang-lru v0.0.0-20160813221303-0a025b7e63ad golang.org/x/exp v0.0.0-20191224044220-1fea468a75e9 - golang.org/x/image v0.0.0-20190802002840-cff245a6509b + golang.org/x/image v0.0.0-20200618115811-c13761719519 golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 ) -go 1.10 +go 1.14 diff --git a/vendor/github.com/aarzilli/nucular/go.sum b/vendor/github.com/aarzilli/nucular/go.sum index 4dea8aa..14e367d 100644 --- a/vendor/github.com/aarzilli/nucular/go.sum +++ b/vendor/github.com/aarzilli/nucular/go.sum @@ -12,6 +12,16 @@ gioui.org v0.0.0-20191218180754-3dd7c8121c67 h1:y9md+l1thtMqJu/ulhF1Upv3pnOpGotp gioui.org v0.0.0-20191218180754-3dd7c8121c67/go.mod h1:KqFFi2Dq5gYA3FJ0sDOt8OBXoMsuxMtE8v2f0JExXAY= gioui.org v0.0.0-20200417085050-0cfc914d8b7d h1:uZspKksrY99JQRUrP0XCoClt9Y6SZdxaT4Q7tAXsl4I= gioui.org v0.0.0-20200417085050-0cfc914d8b7d/go.mod h1:AHI9rFr6AEEHCb8EPVtb/p5M+NMJRKH58IOp8O3Je04= +gioui.org v0.0.0-20200824174209-9543b5f8f3ff h1:xiUlvOxsqxGuXx56i+BXa381HjHIh8UUcJYPJD3EemQ= +gioui.org v0.0.0-20200824174209-9543b5f8f3ff/go.mod h1:Y+uS7hHMvku1Q+ooaoq6fYD5B2LGoT8JtFgvmYmRzTw= +gioui.org v0.0.0-20200825104353-4821472ea1c9 h1:wjaosWGBhqWYSffsg55/LYlqlqmTvgo8h6RPRY2cuqs= +gioui.org v0.0.0-20200825104353-4821472ea1c9/go.mod h1:Y+uS7hHMvku1Q+ooaoq6fYD5B2LGoT8JtFgvmYmRzTw= +gioui.org v0.0.0-20210106084211-c030065af7bc h1:0jo2QznfZl35y/Bzqt915yUT1ruaTjmC24iJM/4vA94= +gioui.org v0.0.0-20210106084211-c030065af7bc/go.mod h1:Y+uS7hHMvku1Q+ooaoq6fYD5B2LGoT8JtFgvmYmRzTw= +gioui.org v0.0.0-20210222172543-284659d3eac9 h1:rEhi0IMfjyzZu73tiAaPOtprJd9Z3QxJ0/VeY42dLv8= +gioui.org v0.0.0-20210222172543-284659d3eac9/go.mod h1:Y+uS7hHMvku1Q+ooaoq6fYD5B2LGoT8JtFgvmYmRzTw= +gioui.org v0.0.0-20210407072325-abd6e8f9cdd4 h1:AlnhfKQm5z7MT1Soxj5dObqyhOU0YCGT6+gc7zCCCLg= +gioui.org v0.0.0-20210407072325-abd6e8f9cdd4/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 h1:1BDTz0u9nC3//pOCMdNH+CiXJVYJh5UQNCOBG7jbELc= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1 h1:QbL/5oDUmRBzO9/Z7Seo6zf912W/a6Sr4Eu0G/3Jho0= @@ -37,6 +47,8 @@ golang.org/x/image v0.0.0-20190227222117-0694c2d4d067 h1:KYGJGHOQy8oSi1fDlSpcZF0 golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200618115811-c13761719519 h1:1e2ufUJNM3lCHEY5jIgac/7UTjd6cgJNdatjPdFWf34= +golang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190318164015-6bd122906c08 h1:REhdg1qxVTaAJcvh9BOGNgt2kd+KiUZ148XXlLp08FU= golang.org/x/mobile v0.0.0-20190318164015-6bd122906c08/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= @@ -56,6 +68,8 @@ golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9 h1:1/DFK4b7JH8DmkqhUk48onnSfrPzImPoVxuomtbT2nk= golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210304124612-50617c2ba197 h1:7+SpRyhoo46QjKkYInQXpcfxx3TYFEYkn131lwGE9/0= +golang.org/x/sys v0.0.0-20210304124612-50617c2ba197/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= diff --git a/vendor/github.com/aarzilli/nucular/masterwindow.go b/vendor/github.com/aarzilli/nucular/masterwindow.go index 1ecf1f3..f74bd42 100644 --- a/vendor/github.com/aarzilli/nucular/masterwindow.go +++ b/vendor/github.com/aarzilli/nucular/masterwindow.go @@ -23,6 +23,7 @@ type MasterWindow interface { Changed() Close() Closed() bool + OnClose(func()) ActivateEditor(ed *TextEditor) Style() *nstyle.Style diff --git a/vendor/github.com/aarzilli/nucular/nucular.go b/vendor/github.com/aarzilli/nucular/nucular.go index 20ce6d2..7e4967c 100644 --- a/vendor/github.com/aarzilli/nucular/nucular.go +++ b/vendor/github.com/aarzilli/nucular/nucular.go @@ -49,8 +49,6 @@ type Window struct { parent *Window // helper windows to implement groups groupWnd map[string]*Window - // editor of the active property widget (see PropertyInt, PropertyFloat) - editor *TextEditor // update function updateFn UpdateFn usingSub bool @@ -60,6 +58,7 @@ type Window struct { lastLayoutCnt int adjust map[int]map[int]*adjustCol undockedSz image.Point + editors map[string]*TextEditor } type FittingWidthFn func(width int) @@ -161,6 +160,7 @@ func createTreeNode(initialState bool, parent *treeNode) *treeNode { func createWindow(ctx *context, title string) *Window { rootNode := createTreeNode(false, nil) r := &Window{ctx: ctx, title: title, rootNode: rootNode, curNode: rootNode, groupWnd: map[string]*Window{}, first: true} + r.editors = make(map[string]*TextEditor) r.rowCtor.win = r r.widgets.cur = make(map[rect.Rect]frozenWidget) return r @@ -600,6 +600,9 @@ func panelEnd(ctx *context, window *Window) { scroll_inc = float64(layout.Clip.H) * 0.01 scroll_target = float64(layout.AtY - layout.Clip.Y) scroll_offset = doScrollbarv(window, bounds, layout.Bounds, scroll_offset, scroll_target, scroll_step, scroll_inc, &ctx.Style.Scrollv, in, style.Font) + if layout.Offset.Y != int(scroll_offset) { + ctx.trashFrame = true + } layout.Offset.Y = int(scroll_offset) } if layout.Flags&WindowNoHScrollbar == 0 { @@ -629,6 +632,9 @@ func panelEnd(ctx *context, window *Window) { scroll_step = float64(layout.MaxX) * 0.05 scroll_inc = float64(layout.MaxX) * 0.005 scroll_offset = doScrollbarh(window, bounds, scroll_offset, scroll_target, scroll_step, scroll_inc, &ctx.Style.Scrollh, in, style.Font) + if layout.Offset.X != int(scroll_offset) { + ctx.trashFrame = true + } layout.Offset.X = int(scroll_offset) } } @@ -2494,8 +2500,8 @@ func (win *Window) doProperty(property rect.Rect, name string, text string, filt ws := win.widgets.PrevState(property) oldws := ws - if ws == nstyle.WidgetStateActive && win.editor != nil { - ed = win.editor + if ws == nstyle.WidgetStateActive && win.editors[name] != nil { + ed = win.editors[name] } else { ed = &TextEditor{} ed.init(win) @@ -2527,9 +2533,9 @@ func (win *Window) doProperty(property rect.Rect, name string, text string, filt } if ws == nstyle.WidgetStateActive { ed.Active = true - win.editor = ed + win.editors[name] = ed } else if oldws == nstyle.WidgetStateActive { - win.editor = nil + delete(win.editors, name) } ed.win.widgets.Add(ws, property) drawProperty(ed.win, style, property, lblrect, ws, name) diff --git a/vendor/github.com/aarzilli/nucular/shiny.go b/vendor/github.com/aarzilli/nucular/shiny.go index 2f8461b..3e44a98 100644 --- a/vendor/github.com/aarzilli/nucular/shiny.go +++ b/vendor/github.com/aarzilli/nucular/shiny.go @@ -52,7 +52,11 @@ type masterWindow struct { wndb screen.Buffer bounds image.Rectangle + paintEvent *paint.Event + sizeEvent *size.Event + initialSize image.Point + onClose func() // window is focused Focus bool @@ -86,6 +90,9 @@ func NewMasterWindowSize(flags WindowFlags, title string, sz image.Point, update // Shows window, runs event loop func (mw *masterWindow) Main() { driver.Main(mw.main) + if mw.onClose != nil { + mw.onClose() + } } func (mw *masterWindow) Lock() { @@ -96,6 +103,10 @@ func (mw *masterWindow) Unlock() { mw.uilock.Unlock() } +func (mw *masterWindow) OnClose(onClose func()) { + mw.onClose = onClose +} + func (mw *masterWindow) main(s screen.Screen) { var err error mw.screen = s @@ -124,12 +135,7 @@ func (mw *masterWindow) main(s screen.Screen) { func (w *masterWindow) handleEventLocked(ei interface{}) bool { switch e := ei.(type) { case paint.Event: - // On darwin we must respond to a paint.Event by reuploading the buffer or - // the appplication will freeze. - // On windows when the window goes off screen part of the window contents - // will be discarded and must be redrawn. - w.prevCmds = w.prevCmds[:0] - w.updateLocked() + w.paintEvent = &e case lifecycle.Event: if e.Crosses(lifecycle.StageDead) == lifecycle.CrossOn || e.To == lifecycle.StageDead || w.closing { @@ -158,22 +164,7 @@ func (w *masterWindow) handleEventLocked(ei interface{}) bool { } } case size.Event: - sz := e.Size() - bb := w.wndb.Bounds() - if sz.X <= bb.Dx() && sz.Y <= bb.Dy() { - w.bounds = w.wndb.Bounds() - w.bounds.Max.Y = w.bounds.Min.Y + sz.Y - w.bounds.Max.X = w.bounds.Min.X + sz.X - } else { - if w.wndb != nil { - w.wndb.Release() - } - w.setupBuffer(sz) - } - w.prevCmds = w.prevCmds[:0] - if changed := atomic.LoadInt32(&w.ctx.changed); changed < 2 { - atomic.StoreInt32(&w.ctx.changed, 2) - } + w.sizeEvent = &e case mouse.Event: changed := atomic.LoadInt32(&w.ctx.changed) @@ -235,10 +226,43 @@ func (w *masterWindow) updater() { if w.closing { return } + + forceUpdate := false + + if w.paintEvent != nil { + w.paintEvent = nil + w.prevCmds = w.prevCmds[:0] + forceUpdate = true + } + + if w.sizeEvent != nil { + sz := w.sizeEvent.Size() + w.sizeEvent = nil + if sz.X > 0 && sz.Y > 0 { + bb := w.wndb.Bounds() + if sz.X <= bb.Dx() && sz.Y <= bb.Dy() { + w.bounds = w.wndb.Bounds() + w.bounds.Max.Y = w.bounds.Min.Y + sz.Y + w.bounds.Max.X = w.bounds.Min.X + sz.X + } else { + if w.wndb != nil { + w.wndb.Release() + } + w.setupBuffer(sz) + } + w.prevCmds = w.prevCmds[:0] + if changed := atomic.LoadInt32(&w.ctx.changed); changed < 2 { + atomic.StoreInt32(&w.ctx.changed, 2) + } + } + } + changed := atomic.LoadInt32(&w.ctx.changed) if changed > 0 { atomic.AddInt32(&w.ctx.changed, -1) w.updateLocked() + } else if forceUpdate { + w.updateLocked() } else { down = false for _, btn := range w.ctx.Input.Mouse.Buttons { diff --git a/vendor/github.com/aarzilli/nucular/text.go b/vendor/github.com/aarzilli/nucular/text.go index a51a197..994a79a 100644 --- a/vendor/github.com/aarzilli/nucular/text.go +++ b/vendor/github.com/aarzilli/nucular/text.go @@ -1378,7 +1378,11 @@ func (ed *TextEditor) doEdit(bounds rect.Rect, style *nstyle.Edit, inp *Input, c scroll_step := float64(scroll.H) * 0.1 scroll_inc := float64(scroll.H) * 0.01 scroll_target := float64(d.TextSize.Y + row_height) - ed.Scrollbar.Y = int(doScrollbarv(ed.win, scroll, bounds, scroll_offset, scroll_target, scroll_step, scroll_inc, &style.Scrollbar, inp, font)) + newy := int(doScrollbarv(ed.win, scroll, bounds, scroll_offset, scroll_target, scroll_step, scroll_inc, &style.Scrollbar, inp, font)) + if newy != ed.Scrollbar.Y { + ed.win.ctx.trashFrame = true + } + ed.Scrollbar.Y = newy } return ret |