Some changes to UI elements.
- Added colors to palette and renamed white/black to lightest/darkest. - Extracted drawing code. - Restyled checkbox, spinner and scrollbar.
This commit is contained in:
parent
115f9877c1
commit
239c24533d
@ -2,7 +2,6 @@ package ui
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"image"
|
|
||||||
"image/color"
|
"image/color"
|
||||||
|
|
||||||
"github.com/llgcode/draw2d/draw2dimg"
|
"github.com/llgcode/draw2d/draw2dimg"
|
||||||
@ -13,50 +12,34 @@ import (
|
|||||||
|
|
||||||
type CheckboxValueChangedFn func(bool)
|
type CheckboxValueChangedFn func(bool)
|
||||||
|
|
||||||
func createOnBitmap(fill, stroke color.Color) *allegro5.Bitmap {
|
func drawCheckedBitmap(fill, stroke color.Color) *allegro5.Bitmap {
|
||||||
var sz = float64(checkboxSize)
|
return drawBitmap(checkboxSize, checkboxSize, func(gc *draw2dimg.GraphicContext) {
|
||||||
on := image.NewRGBA(image.Rect(0, 0, checkboxSize, checkboxSize))
|
var size = float64(checkboxSize)
|
||||||
|
var margin = float64(checkboxMargin)
|
||||||
|
|
||||||
gc := draw2dimg.NewGraphicContext(on)
|
|
||||||
gc.SetFillColor(color.Transparent)
|
|
||||||
gc.Clear()
|
|
||||||
gc.SetFillColor(fill)
|
gc.SetFillColor(fill)
|
||||||
draw2dkit.RoundedRectangle(gc, 0, 0, sz, sz, 3, 3)
|
draw2dkit.RoundedRectangle(gc, margin, margin, size-margin, size-margin, margin, margin)
|
||||||
gc.Fill()
|
gc.Fill()
|
||||||
|
|
||||||
gc.SetStrokeColor(stroke)
|
gc.SetStrokeColor(stroke)
|
||||||
gc.SetLineWidth(2)
|
gc.SetLineWidth(1.5)
|
||||||
gc.MoveTo(2.5, 5.5)
|
gc.MoveTo(7, 12)
|
||||||
gc.LineTo(5.5, 8.5)
|
gc.LineTo(10.5, 15.5)
|
||||||
gc.LineTo(10, 3.5)
|
gc.LineTo(17, 9)
|
||||||
gc.Stroke()
|
gc.Stroke()
|
||||||
|
})
|
||||||
bmp, err := allegro5.NewBitmapFromImage(on, false)
|
|
||||||
if nil != err {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return bmp
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func createOffBitmap(fill, stroke color.Color) *allegro5.Bitmap {
|
func drawUncheckedBitmap(fill, stroke color.Color) *allegro5.Bitmap {
|
||||||
var sz = float64(checkboxSize)
|
return drawBitmap(checkboxSize, checkboxSize, func(gc *draw2dimg.GraphicContext) {
|
||||||
off := image.NewRGBA(image.Rect(0, 0, checkboxSize, checkboxSize))
|
var size = float64(checkboxSize)
|
||||||
|
var margin = float64(checkboxMargin)
|
||||||
|
|
||||||
gc := draw2dimg.NewGraphicContext(off)
|
gc.SetLineWidth(2)
|
||||||
gc.SetFillColor(color.Transparent)
|
gc.SetStrokeColor(stroke)
|
||||||
gc.Clear()
|
draw2dkit.RoundedRectangle(gc, margin+1, margin+1, size-margin-1, size-margin-1, margin-1, margin-1)
|
||||||
gc.SetFillColor(stroke)
|
gc.Stroke()
|
||||||
draw2dkit.RoundedRectangle(gc, 0, 0, sz, sz, 4, 4)
|
})
|
||||||
gc.Fill()
|
|
||||||
gc.SetFillColor(fill)
|
|
||||||
draw2dkit.RoundedRectangle(gc, 1, 1, sz-1, sz-1, 3, 3)
|
|
||||||
gc.Fill()
|
|
||||||
|
|
||||||
bmp, err := allegro5.NewBitmapFromImage(off, false)
|
|
||||||
if nil != err {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return bmp
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Checkbox struct {
|
type Checkbox struct {
|
||||||
@ -64,8 +47,8 @@ type Checkbox struct {
|
|||||||
Value bool
|
Value bool
|
||||||
Text string
|
Text string
|
||||||
OnChanged CheckboxValueChangedFn
|
OnChanged CheckboxValueChangedFn
|
||||||
on *allegro5.Bitmap
|
checked *allegro5.Bitmap
|
||||||
off *allegro5.Bitmap
|
unchecked *allegro5.Bitmap
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Checkbox) Created(ctx Context, p Container) error {
|
func (c *Checkbox) Created(ctx Context, p Container) error {
|
||||||
@ -74,9 +57,9 @@ func (c *Checkbox) Created(ctx Context, p Container) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
var plt = ctx.Palette()
|
var plt = ctx.Palette()
|
||||||
c.on = createOnBitmap(plt.Primary(), plt.White())
|
c.checked = drawCheckedBitmap(plt.Primary(), plt.Lightest())
|
||||||
c.off = createOffBitmap(plt.White(), plt.Black())
|
c.unchecked = drawUncheckedBitmap(plt.Lightest(), plt.Darkest())
|
||||||
if nil == c.on || nil == c.off {
|
if nil == c.checked || nil == c.unchecked {
|
||||||
return fmt.Errorf("error creating checkboxes")
|
return fmt.Errorf("error creating checkboxes")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -101,32 +84,28 @@ func (c *Checkbox) DesiredSize(ctx Context) geom.PointF {
|
|||||||
var fonts = ctx.Fonts()
|
var fonts = ctx.Fonts()
|
||||||
var fnt = fonts.Get("default")
|
var fnt = fonts.Get("default")
|
||||||
var w = fnt.TextWidth(c.Text)
|
var w = fnt.TextWidth(c.Text)
|
||||||
return geom.PtF(float64(w+2*leftMargin+checkboxSize), 24)
|
return geom.PtF(float64(w+checkboxSize+leftMargin), checkboxSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Checkbox) box() *allegro5.Bitmap {
|
func (c *Checkbox) box() *allegro5.Bitmap {
|
||||||
if c.Value {
|
if c.Value {
|
||||||
return c.on
|
return c.checked
|
||||||
}
|
}
|
||||||
return c.off
|
return c.unchecked
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Checkbox) Render(ctx Context) {
|
func (c *Checkbox) Render(ctx Context) {
|
||||||
var fonts = ctx.Fonts()
|
var fonts = ctx.Fonts()
|
||||||
|
|
||||||
var min = c.Bounds.Min.To32()
|
var min = c.Bounds.Min.To32()
|
||||||
min = geom.PointF32{X: min.X + leftMargin, Y: min.Y + topMargin}
|
|
||||||
|
|
||||||
var fnt = fonts.Get("default")
|
var fnt = fonts.Get("default")
|
||||||
|
|
||||||
var _, textY, _, textH = fnt.TextDims(c.Text)
|
fnt.Draw(min.X+checkboxSize, min.Y-.67*fnt.Ascent()+.5*checkboxSize, ctx.Palette().Darkest(), allegro5.AlignLeft, c.Text)
|
||||||
fnt.Draw(min.X+leftMargin+checkboxSize, min.Y-textY, ctx.Palette().Black(), allegro5.AlignLeft, c.Text)
|
|
||||||
var checkboxTop = min.Y + textH - checkboxSize
|
|
||||||
if c.Disabled {
|
if c.Disabled {
|
||||||
var disabled = ctx.Palette().Disabled()
|
var disabled = ctx.Palette().Disabled()
|
||||||
c.box().DrawOptions(min.X, checkboxTop, allegro5.DrawOptions{Tint: &disabled})
|
c.box().DrawOptions(min.X, min.Y, allegro5.DrawOptions{Tint: &disabled})
|
||||||
} else {
|
} else {
|
||||||
c.box().Draw(min.X, checkboxTop)
|
c.box().Draw(min.X, min.Y)
|
||||||
}
|
}
|
||||||
|
|
||||||
c.ControlBase.Render(ctx)
|
c.ControlBase.Render(ctx)
|
||||||
|
@ -32,7 +32,7 @@ type debug struct {
|
|||||||
func rainbow() []allegro5.Color {
|
func rainbow() []allegro5.Color {
|
||||||
var colors = make([]allegro5.Color, len(Colors500))
|
var colors = make([]allegro5.Color, len(Colors500))
|
||||||
for i, c := range Colors500 {
|
for i, c := range Colors500 {
|
||||||
colors[i] = NewColorAlpha(c, 0xbf)
|
colors[i] = NewColorAlpha(c, 0x7f)
|
||||||
}
|
}
|
||||||
return colors
|
return colors
|
||||||
}
|
}
|
||||||
|
@ -2,4 +2,6 @@ package ui
|
|||||||
|
|
||||||
const topMargin = 4
|
const topMargin = 4
|
||||||
const leftMargin = 8
|
const leftMargin = 8
|
||||||
const checkboxSize = 12
|
const lineHeight = 16
|
||||||
|
const checkboxMargin = 4
|
||||||
|
const checkboxSize = 24
|
||||||
|
38
ui/draw.go
Normal file
38
ui/draw.go
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
package ui
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image"
|
||||||
|
"image/color"
|
||||||
|
"math"
|
||||||
|
|
||||||
|
"github.com/llgcode/draw2d/draw2dimg"
|
||||||
|
"opslag.de/schobers/galleg/allegro5"
|
||||||
|
)
|
||||||
|
|
||||||
|
func drawBitmap(w, h int, draw func(*draw2dimg.GraphicContext)) *allegro5.Bitmap {
|
||||||
|
dest := image.NewRGBA(image.Rect(0, 0, w, h))
|
||||||
|
gc := draw2dimg.NewGraphicContext(dest)
|
||||||
|
gc.SetFillColor(color.Transparent)
|
||||||
|
gc.Clear()
|
||||||
|
draw(gc)
|
||||||
|
bmp, err := allegro5.NewBitmapFromImage(dest, false)
|
||||||
|
if nil != err {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return bmp
|
||||||
|
}
|
||||||
|
|
||||||
|
func drawCircle(r, w int, startAngle, a float64, c color.Color) *allegro5.Bitmap {
|
||||||
|
var width = 2*r + w
|
||||||
|
return drawBitmap(width, width, func(gc *draw2dimg.GraphicContext) {
|
||||||
|
gc.SetFillColor(c)
|
||||||
|
gc.SetStrokeColor(c)
|
||||||
|
gc.SetLineWidth(float64(w))
|
||||||
|
var rad = float64(r)
|
||||||
|
var cnt = float64(width) * .5
|
||||||
|
var dx1, dy1 = cnt + math.Cos(startAngle)*rad, cnt + math.Sin(startAngle)*rad
|
||||||
|
gc.MoveTo(dx1, dy1)
|
||||||
|
gc.ArcTo(cnt, cnt, rad, rad, startAngle, a)
|
||||||
|
gc.Stroke()
|
||||||
|
})
|
||||||
|
}
|
@ -13,7 +13,7 @@ func (l *Label) Render(ctx Context) {
|
|||||||
var min = l.Bounds.Min.To32()
|
var min = l.Bounds.Min.To32()
|
||||||
|
|
||||||
var fnt = fonts.Get("default")
|
var fnt = fonts.Get("default")
|
||||||
fnt.Draw(min.X+leftMargin, min.Y+topMargin, ctx.Palette().Black(), allegro5.AlignLeft, l.Text)
|
fnt.Draw(min.X+leftMargin, min.Y+lineHeight-fnt.Ascent(), ctx.Palette().Darkest(), allegro5.AlignLeft, l.Text)
|
||||||
|
|
||||||
l.ControlBase.Render(ctx)
|
l.ControlBase.Render(ctx)
|
||||||
}
|
}
|
||||||
|
@ -8,27 +8,42 @@ import (
|
|||||||
|
|
||||||
type Palette interface {
|
type Palette interface {
|
||||||
Primary() allegro5.Color
|
Primary() allegro5.Color
|
||||||
White() allegro5.Color
|
PrimaryTransparent() allegro5.Color
|
||||||
Black() allegro5.Color
|
Lightest() allegro5.Color
|
||||||
|
Darker() allegro5.Color
|
||||||
|
Darkest() allegro5.Color
|
||||||
Disabled() allegro5.Color
|
Disabled() allegro5.Color
|
||||||
}
|
}
|
||||||
|
|
||||||
type palette struct {
|
type palette struct {
|
||||||
primary allegro5.Color
|
primary allegro5.Color
|
||||||
white allegro5.Color
|
primaryT allegro5.Color
|
||||||
black allegro5.Color
|
lightest allegro5.Color
|
||||||
|
darker allegro5.Color
|
||||||
|
darkest allegro5.Color
|
||||||
disabled allegro5.Color
|
disabled allegro5.Color
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *palette) Primary() allegro5.Color {
|
func (p *palette) Primary() allegro5.Color {
|
||||||
return p.primary
|
return p.primary
|
||||||
}
|
}
|
||||||
func (p *palette) White() allegro5.Color {
|
|
||||||
return p.white
|
func (p *palette) PrimaryTransparent() allegro5.Color {
|
||||||
|
return p.primaryT
|
||||||
}
|
}
|
||||||
func (p *palette) Black() allegro5.Color {
|
|
||||||
return p.black
|
func (p *palette) Lightest() allegro5.Color {
|
||||||
|
return p.lightest
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *palette) Darker() allegro5.Color {
|
||||||
|
return p.darker
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *palette) Darkest() allegro5.Color {
|
||||||
|
return p.darkest
|
||||||
|
}
|
||||||
|
|
||||||
func (p *palette) Disabled() allegro5.Color {
|
func (p *palette) Disabled() allegro5.Color {
|
||||||
return p.disabled
|
return p.disabled
|
||||||
}
|
}
|
||||||
@ -42,10 +57,13 @@ func NewColorAlpha(c *color.RGBA, a uint8) allegro5.Color {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func DefaultPalette() Palette {
|
func DefaultPalette() Palette {
|
||||||
|
var primary = Blue500
|
||||||
return &palette{
|
return &palette{
|
||||||
primary: NewColor(Blue500),
|
primary: NewColor(primary),
|
||||||
white: allegro5.NewColor(0xff, 0xff, 0xff),
|
primaryT: NewColorAlpha(primary, 96),
|
||||||
black: allegro5.NewColor(0, 0, 0),
|
lightest: allegro5.NewColor(0xff, 0xff, 0xff),
|
||||||
|
darker: allegro5.NewColorAlpha(0, 0, 0, 188),
|
||||||
|
darkest: allegro5.NewColorAlpha(0, 0, 0, 222),
|
||||||
disabled: allegro5.NewColorAlpha(0x1f, 0x1f, 0x1f, 0x1f),
|
disabled: allegro5.NewColorAlpha(0x1f, 0x1f, 0x1f, 0x1f),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
110
ui/scrollbar.go
110
ui/scrollbar.go
@ -3,13 +3,15 @@ package ui
|
|||||||
import (
|
import (
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
|
"github.com/llgcode/draw2d/draw2dimg"
|
||||||
|
|
||||||
"opslag.de/schobers/galleg/allegro5"
|
"opslag.de/schobers/galleg/allegro5"
|
||||||
"opslag.de/schobers/geom"
|
"opslag.de/schobers/geom"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ Control = &Scrollbar{}
|
var _ Control = &Scrollbar{}
|
||||||
|
|
||||||
const ScrollbarWidth = 26
|
const ScrollbarWidth = 12
|
||||||
const ScrollbarHandleThickness = 4
|
const ScrollbarHandleThickness = 4
|
||||||
const ScrollbarHandlePadding = 1
|
const ScrollbarHandlePadding = 1
|
||||||
|
|
||||||
@ -23,27 +25,57 @@ type Scrollbar struct {
|
|||||||
Orientation Orientation
|
Orientation Orientation
|
||||||
OnChanged ScrollbarValueChangedFn
|
OnChanged ScrollbarValueChangedFn
|
||||||
handle *ControlBase
|
handle *ControlBase
|
||||||
handles []*allegro5.Bitmap
|
normal *allegro5.Bitmap
|
||||||
|
hover *allegro5.Bitmap
|
||||||
|
pressed *allegro5.Bitmap
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Scrollbar) Created(ctx Context, p Container) error {
|
func (s *Scrollbar) Created(ctx Context, p Container) error {
|
||||||
s.ControlBase.Created(ctx, p)
|
s.ControlBase.Created(ctx, p)
|
||||||
s.handles = []*allegro5.Bitmap{
|
var center = float64(ScrollbarWidth) * 1.5
|
||||||
createCirle((ScrollbarWidth/2)-ScrollbarHandleThickness-2*ScrollbarHandlePadding, ScrollbarHandleThickness, 0, math.Pi*2, Blue500),
|
var rad = float64(ScrollbarWidth) * .5
|
||||||
createCirle((ScrollbarWidth/2)-ScrollbarHandleThickness-2*ScrollbarHandlePadding, ScrollbarHandleThickness, 0, math.Pi*2, Blue300),
|
s.normal = drawBitmap(3*ScrollbarWidth, 3*ScrollbarWidth, func(gc *draw2dimg.GraphicContext) {
|
||||||
createCirle((ScrollbarWidth/2)-ScrollbarHandleThickness-2*ScrollbarHandlePadding, ScrollbarHandleThickness, 0, math.Pi*2, Blue700),
|
gc.SetFillColor(ctx.Palette().Primary())
|
||||||
|
gc.MoveTo(center, center)
|
||||||
|
gc.ArcTo(center, center, rad, rad, 0, 2*math.Pi)
|
||||||
|
gc.Fill()
|
||||||
|
})
|
||||||
|
s.hover = drawBitmap(3*ScrollbarWidth, 3*ScrollbarWidth, func(gc *draw2dimg.GraphicContext) {
|
||||||
|
gc.SetFillColor(ctx.Palette().PrimaryTransparent())
|
||||||
|
gc.MoveTo(center, center)
|
||||||
|
gc.ArcTo(center, center, center, center, 0, 2*math.Pi)
|
||||||
|
gc.Fill()
|
||||||
|
gc.SetFillColor(ctx.Palette().Primary())
|
||||||
|
gc.MoveTo(center, center)
|
||||||
|
gc.ArcTo(center, center, rad, rad, 0, 2*math.Pi)
|
||||||
|
gc.Fill()
|
||||||
|
})
|
||||||
|
s.pressed = drawBitmap(3*ScrollbarWidth, 3*ScrollbarWidth, func(gc *draw2dimg.GraphicContext) {
|
||||||
|
gc.SetFillColor(ctx.Palette().PrimaryTransparent())
|
||||||
|
for i := 0; i < 2; i++ {
|
||||||
|
gc.MoveTo(center, center)
|
||||||
|
gc.ArcTo(center, center, center, center, 0, 2*math.Pi)
|
||||||
|
gc.Fill()
|
||||||
}
|
}
|
||||||
|
gc.SetFillColor(ctx.Palette().Primary())
|
||||||
|
gc.MoveTo(center, center)
|
||||||
|
gc.ArcTo(center, center, rad, rad, 0, 2*math.Pi)
|
||||||
|
gc.Fill()
|
||||||
|
})
|
||||||
s.handle = &ControlBase{}
|
s.handle = &ControlBase{}
|
||||||
s.handle.Created(ctx, nil)
|
s.handle.Created(ctx, nil)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Scrollbar) Destroyed(ctx Context) {
|
func (s *Scrollbar) Destroyed(ctx Context) {
|
||||||
if nil != s.handles {
|
var d = func(b *allegro5.Bitmap) {
|
||||||
for _, h := range s.handles {
|
if nil != b {
|
||||||
h.Destroy()
|
b.Destroy()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
d(s.normal)
|
||||||
|
d(s.hover)
|
||||||
|
d(s.pressed)
|
||||||
s.handle.Destroyed(ctx)
|
s.handle.Destroyed(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,12 +84,12 @@ func (s *Scrollbar) barViewRange() (float64, float64) {
|
|||||||
var min, max float64
|
var min, max float64
|
||||||
switch s.Orientation {
|
switch s.Orientation {
|
||||||
case OrientationHorizontal:
|
case OrientationHorizontal:
|
||||||
min = s.Bounds.Min.X + ScrollbarWidth*.5
|
min = s.Bounds.Min.X + ScrollbarWidth
|
||||||
max = s.Bounds.Max.X - ScrollbarWidth*.5
|
max = s.Bounds.Max.X - ScrollbarWidth
|
||||||
small = min > max
|
small = min > max
|
||||||
default:
|
default:
|
||||||
min = s.Bounds.Max.Y - ScrollbarWidth*.5
|
min = s.Bounds.Max.Y - ScrollbarWidth
|
||||||
max = s.Bounds.Min.Y + ScrollbarWidth*.5
|
max = s.Bounds.Min.Y + ScrollbarWidth
|
||||||
small = max > min
|
small = max > min
|
||||||
}
|
}
|
||||||
if small {
|
if small {
|
||||||
@ -143,22 +175,24 @@ func (s *Scrollbar) Handle(ctx Context, ev allegro5.Event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Scrollbar) DesiredSize(Context) geom.PointF {
|
func (s *Scrollbar) DesiredSize(Context) geom.PointF {
|
||||||
|
var width = float64(2 * ScrollbarWidth)
|
||||||
switch s.Orientation {
|
switch s.Orientation {
|
||||||
case OrientationHorizontal:
|
case OrientationHorizontal:
|
||||||
return geom.PtF(math.NaN(), ScrollbarWidth)
|
return geom.PtF(math.NaN(), width)
|
||||||
}
|
}
|
||||||
return geom.PtF(ScrollbarWidth, math.NaN())
|
return geom.PtF(width, math.NaN())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Scrollbar) SetRect(rect geom.RectangleF) {
|
func (s *Scrollbar) SetRect(rect geom.RectangleF) {
|
||||||
|
var width = float64(2 * ScrollbarWidth)
|
||||||
switch s.Orientation {
|
switch s.Orientation {
|
||||||
case OrientationHorizontal:
|
case OrientationHorizontal:
|
||||||
if rect.Dy() > ScrollbarWidth {
|
if rect.Dy() > width {
|
||||||
rect.Min.Y = rect.Max.Y - ScrollbarWidth
|
rect.Min.Y = rect.Max.Y - width
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
if rect.Dx() > ScrollbarWidth {
|
if rect.Dx() > width {
|
||||||
rect.Min.X = rect.Max.X - ScrollbarWidth
|
rect.Min.X = rect.Max.X - width
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s.ControlBase.SetRect(rect)
|
s.ControlBase.SetRect(rect)
|
||||||
@ -166,7 +200,7 @@ func (s *Scrollbar) SetRect(rect geom.RectangleF) {
|
|||||||
var min, max = s.barViewRange()
|
var min, max = s.barViewRange()
|
||||||
var off = float64(s.Value-s.Minimum) / float64(s.Maximum-s.Minimum)
|
var off = float64(s.Value-s.Minimum) / float64(s.Maximum-s.Minimum)
|
||||||
var centerH = min + (max-min)*off
|
var centerH = min + (max-min)*off
|
||||||
var r = 0.5 * float64(s.handles[0].Width())
|
var r = 0.5 * float64(s.normal.Width())
|
||||||
|
|
||||||
var center = s.barViewCenter()
|
var center = s.barViewCenter()
|
||||||
switch s.Orientation {
|
switch s.Orientation {
|
||||||
@ -182,32 +216,28 @@ func (s *Scrollbar) Render(ctx Context) {
|
|||||||
var min64, max64 = s.barViewRange()
|
var min64, max64 = s.barViewRange()
|
||||||
var min, max = float32(min64), float32(max64)
|
var min, max = float32(min64), float32(max64)
|
||||||
|
|
||||||
var minH = s.handle.Bounds.Min.To32()
|
var centerH = s.handle.Bounds.Center().To32()
|
||||||
var stateH = 0
|
|
||||||
if s.handle.IsOver {
|
|
||||||
stateH = 1
|
|
||||||
if s.handle.IsPressed {
|
|
||||||
stateH = 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
s.handles[stateH].Draw(minH.X, minH.Y)
|
|
||||||
var maxH = s.handle.Bounds.Max.To32()
|
|
||||||
|
|
||||||
switch s.Orientation {
|
switch s.Orientation {
|
||||||
case OrientationHorizontal:
|
case OrientationHorizontal:
|
||||||
if min < minH.X-1 { // Top line
|
// Left line
|
||||||
allegro5.DrawLine(min, center, minH.X-1, center, ctx.Palette().Black(), 1)
|
allegro5.DrawLine(min, center, centerH.X, center, ctx.Palette().Primary(), 2)
|
||||||
}
|
allegro5.DrawLine(centerH.X, center, max, center, ctx.Palette().PrimaryTransparent(), 2)
|
||||||
if max > maxH.X+1 { // Bottom line
|
|
||||||
allegro5.DrawLine(maxH.X+1, center, max, center, ctx.Palette().Black(), 1)
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
if max < minH.Y-1 { // Top line
|
allegro5.DrawLine(center, max, center, centerH.Y, ctx.Palette().PrimaryTransparent(), 2)
|
||||||
allegro5.DrawLine(center, max, center, minH.Y-1, ctx.Palette().Black(), 1)
|
allegro5.DrawLine(center, centerH.Y, center, min, ctx.Palette().Primary(), 2)
|
||||||
}
|
}
|
||||||
if min > maxH.Y+1 { // Bottom line
|
|
||||||
allegro5.DrawLine(center, maxH.Y+1, center, min, ctx.Palette().Black(), 1)
|
var minH = s.handle.Bounds.Min.To32()
|
||||||
|
var state = s.normal
|
||||||
|
if s.handle.IsOver {
|
||||||
|
if s.handle.IsPressed {
|
||||||
|
state = s.pressed
|
||||||
|
} else {
|
||||||
|
state = s.hover
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
state.Draw(minH.X, minH.Y)
|
||||||
|
|
||||||
s.ControlBase.Render(ctx)
|
s.ControlBase.Render(ctx)
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
package ui
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"image"
|
|
||||||
"image/color"
|
|
||||||
"math"
|
"math"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/llgcode/draw2d/draw2dimg"
|
"github.com/llgcode/draw2d/draw2dimg"
|
||||||
|
|
||||||
"opslag.de/schobers/galleg/allegro5"
|
"opslag.de/schobers/galleg/allegro5"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -16,53 +15,56 @@ type Spinner struct {
|
|||||||
ControlBase
|
ControlBase
|
||||||
Text string
|
Text string
|
||||||
spin float32
|
spin float32
|
||||||
circs []*allegro5.Bitmap
|
circs *allegro5.Bitmap
|
||||||
}
|
|
||||||
|
|
||||||
func createCirle(r, w int, startAngle, a float64, c color.Color) *allegro5.Bitmap {
|
|
||||||
var width = 2*r + w
|
|
||||||
dest := image.NewRGBA(image.Rect(0, 0, width, width))
|
|
||||||
|
|
||||||
gc := draw2dimg.NewGraphicContext(dest)
|
|
||||||
gc.SetFillColor(color.Transparent)
|
|
||||||
gc.Clear()
|
|
||||||
gc.SetFillColor(c)
|
|
||||||
gc.SetStrokeColor(c)
|
|
||||||
gc.SetLineWidth(float64(w))
|
|
||||||
var rad = float64(r)
|
|
||||||
var cnt = float64(width) * .5
|
|
||||||
var dx1, dy1 = cnt + math.Cos(startAngle)*rad, cnt + math.Sin(startAngle)*rad
|
|
||||||
gc.MoveTo(dx1, dy1)
|
|
||||||
gc.ArcTo(cnt, cnt, rad, rad, startAngle, a)
|
|
||||||
gc.Stroke()
|
|
||||||
|
|
||||||
bmp, err := allegro5.NewBitmapFromImage(dest, false)
|
|
||||||
if nil != err {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return bmp
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Spinner) Created(ctx Context, p Container) error {
|
func (s *Spinner) Created(ctx Context, p Container) error {
|
||||||
s.ControlBase.Created(ctx, p)
|
s.ControlBase.Created(ctx, p)
|
||||||
const numCircs = 32
|
const row = 6
|
||||||
s.circs = make([]*allegro5.Bitmap, numCircs)
|
const numCircs = row * row
|
||||||
var am = math.Pi * 2 / float64(numCircs)
|
const width = 48
|
||||||
for i := range s.circs {
|
const center = width * .5
|
||||||
s.circs[i] = createCirle(8, 3, float64(i)*am, math.Pi, Blue500)
|
const full = 2 * math.Pi
|
||||||
|
s.circs = drawBitmap(row*width, row*width, func(gc *draw2dimg.GraphicContext) {
|
||||||
|
var start, a float64 = 0, .2 * math.Pi
|
||||||
|
var inc = true
|
||||||
|
gc.SetLineWidth(4)
|
||||||
|
gc.SetStrokeColor(ctx.Palette().Primary())
|
||||||
|
for i := 0; i < numCircs; i++ {
|
||||||
|
var left = float64(i%row) * width
|
||||||
|
var top = float64(i/row) * width
|
||||||
|
gc.ArcTo(left+center, top+center, center-8, center-8, start, a)
|
||||||
|
gc.Stroke()
|
||||||
|
if inc {
|
||||||
|
start += full / numCircs
|
||||||
|
a += 1.90 * full / numCircs
|
||||||
|
if a >= full {
|
||||||
|
inc = false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
start += 2.90 * full / numCircs
|
||||||
|
a -= 1.90 * full / numCircs
|
||||||
|
// if a <= .1*math.Pi {
|
||||||
|
// inc = true
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
for i := 0; i < numCircs; i++ {
|
||||||
|
var left = (i % row) * width
|
||||||
|
var top = (i / row) * width
|
||||||
|
s.circs.Sub(left, top, width, width)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Spinner) Destroyed(ctx Context) {
|
func (s *Spinner) Destroyed(ctx Context) {
|
||||||
for _, circ := range s.circs {
|
s.circs.Destroy()
|
||||||
circ.Destroy()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Spinner) Update(ctx Context, dt time.Duration) {
|
func (s *Spinner) Update(ctx Context, dt time.Duration) {
|
||||||
var spin = float64(s.spin)
|
var spin = float64(s.spin)
|
||||||
spin += dt.Seconds()
|
spin += dt.Seconds() * .5
|
||||||
for spin > 1. {
|
for spin > 1. {
|
||||||
spin -= 1.
|
spin -= 1.
|
||||||
}
|
}
|
||||||
@ -85,13 +87,13 @@ func (s *Spinner) Render(ctx Context) {
|
|||||||
const textH float32 = 12
|
const textH float32 = 12
|
||||||
var rectW, rectH float32 = textW + 2*marginH, 3*marginV + textH + 32
|
var rectW, rectH float32 = textW + 2*marginH, 3*marginV + textH + 32
|
||||||
var rectX, rectY = (width - rectW) * .5, (height - rectH) * .5
|
var rectX, rectY = (width - rectW) * .5, (height - rectH) * .5
|
||||||
allegro5.DrawFilledRectangle(rectX, rectY, rectX+rectW, rectY+rectH, ctx.Palette().White())
|
allegro5.DrawFilledRectangle(rectX, rectY, rectX+rectW, rectY+rectH, ctx.Palette().Lightest())
|
||||||
DropShadow(rectX, rectY, rectX+rectW, rectY+rectH)
|
DropShadow(rectX, rectY, rectX+rectW, rectY+rectH)
|
||||||
fnt.Draw(rectX+marginH, rectY+marginV, ctx.Palette().Black(), allegro5.AlignLeft, s.Text)
|
fnt.Draw(rectX+marginH, rectY+marginV, ctx.Palette().Darkest(), allegro5.AlignLeft, s.Text)
|
||||||
|
|
||||||
const numCircs = 32
|
const numCircs = 36
|
||||||
var i = int(math.Floor(float64(s.spin) * numCircs))
|
var i = int(math.Floor(float64(s.spin) * numCircs))
|
||||||
s.circs[i].DrawOptions(width*.5, rectY+2*marginV+2*textH, allegro5.DrawOptions{Center: true})
|
s.circs.Subs()[i].DrawOptions(width*.5, rectY+2*marginV+2*textH, allegro5.DrawOptions{Center: true})
|
||||||
|
|
||||||
s.ControlBase.Render(ctx)
|
s.ControlBase.Render(ctx)
|
||||||
}
|
}
|
||||||
|
@ -29,8 +29,9 @@ func (b *StatusBar) Render(ctx Context) {
|
|||||||
allegro5.DrawFilledRectangle(min.X, min.Y, max.X, max.Y, ctx.Palette().Primary())
|
allegro5.DrawFilledRectangle(min.X, min.Y, max.X, max.Y, ctx.Palette().Primary())
|
||||||
|
|
||||||
var fnt = fonts.Get("default")
|
var fnt = fonts.Get("default")
|
||||||
fnt.Draw(min.X+leftMargin, min.Y+topMargin, ctx.Palette().White(), allegro5.AlignLeft, b.Text)
|
var y = min.Y + float32(.5*b.Bounds.Dy()) - .67*fnt.Ascent()
|
||||||
fnt.Draw(max.X-leftMargin, min.Y+topMargin, ctx.Palette().White(), allegro5.AlignRight, b.RightText)
|
fnt.Draw(min.X+leftMargin, y, ctx.Palette().Lightest(), allegro5.AlignLeft, b.Text)
|
||||||
|
fnt.Draw(max.X-leftMargin, y, ctx.Palette().Lightest(), allegro5.AlignRight, b.RightText)
|
||||||
|
|
||||||
b.ControlBase.Render(ctx)
|
b.ControlBase.Render(ctx)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user