Added Rect method to Control interface.
Fixed ContentScrollbar. Added horizontal alignment to label. Removed some dimensional constants. Added several controls: - Margin; - Button; - Columns; - Scroll; - Wrapper (reusable layout control) that wraps around existing control.
This commit is contained in:
parent
eb0b660ab6
commit
9d4b097352
54
ui/button.go
Normal file
54
ui/button.go
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
package ui
|
||||||
|
|
||||||
|
import (
|
||||||
|
"opslag.de/schobers/galleg/allegro5"
|
||||||
|
"opslag.de/schobers/geom"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Button struct {
|
||||||
|
ControlBase
|
||||||
|
Text string
|
||||||
|
HorizontalAlignment allegro5.HorizontalAlignment
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewButton(text string, click MouseClickFn) *Button {
|
||||||
|
return &Button{ControlBase: ControlBase{OnClick: click}, Text: text}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewButtonAlign(text string, click MouseClickFn, align allegro5.HorizontalAlignment) *Button {
|
||||||
|
return &Button{ControlBase: ControlBase{OnClick: click}, Text: text, HorizontalAlignment: align}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Button) DesiredSize(ctx Context) geom.PointF {
|
||||||
|
var fonts = ctx.Fonts()
|
||||||
|
var fnt = fonts.Get("default")
|
||||||
|
var w = fnt.TextWidth(b.Text)
|
||||||
|
var fntH = fnt.Height()
|
||||||
|
return geom.PtF(float64(w+fntH), float64(2*fntH))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Button) Render(ctx Context) {
|
||||||
|
var fonts = ctx.Fonts()
|
||||||
|
|
||||||
|
var min = b.Bounds.Min.To32()
|
||||||
|
var max = b.Bounds.Max.To32()
|
||||||
|
|
||||||
|
var fnt = fonts.Get("default")
|
||||||
|
var fntH = fnt.Height()
|
||||||
|
|
||||||
|
var back = ctx.Palette().Primary()
|
||||||
|
if b.IsOver && !b.IsPressed {
|
||||||
|
back = ctx.Palette().PrimaryHighlight()
|
||||||
|
}
|
||||||
|
allegro5.DrawFilledRectangle(min.X, min.Y, max.X, max.Y, back)
|
||||||
|
switch b.HorizontalAlignment {
|
||||||
|
case allegro5.AlignLeft:
|
||||||
|
fnt.Draw(min.X+.5*fntH, min.Y+.5*fntH, ctx.Palette().Lightest(), allegro5.AlignLeft, b.Text)
|
||||||
|
case allegro5.AlignCenter:
|
||||||
|
fnt.Draw(.5*(min.X+max.X), min.Y+.5*fntH, ctx.Palette().Lightest(), allegro5.AlignCenter, b.Text)
|
||||||
|
case allegro5.AlignRight:
|
||||||
|
fnt.Draw(min.X-.5*fntH, min.Y+.5*fntH, ctx.Palette().Lightest(), allegro5.AlignRight, b.Text)
|
||||||
|
}
|
||||||
|
|
||||||
|
b.ControlBase.Render(ctx)
|
||||||
|
}
|
@ -84,7 +84,7 @@ 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+checkboxSize+leftMargin), checkboxSize)
|
return geom.PtF(float64(w+checkboxSize), checkboxSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Checkbox) box() *allegro5.Bitmap {
|
func (c *Checkbox) box() *allegro5.Bitmap {
|
||||||
|
114
ui/columns.go
Normal file
114
ui/columns.go
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
package ui
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math"
|
||||||
|
|
||||||
|
"opslag.de/schobers/geom"
|
||||||
|
)
|
||||||
|
|
||||||
|
type columns struct {
|
||||||
|
ContainerBase
|
||||||
|
cols []*column
|
||||||
|
col int
|
||||||
|
}
|
||||||
|
|
||||||
|
type column struct {
|
||||||
|
p DockPanel
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *column) Append(ctrl Control) {
|
||||||
|
c.p.Append(DockTop, ctrl)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *column) AppendCreate(ctx Context, ctrl Control) {
|
||||||
|
c.p.AppendCreate(ctx, DockTop, ctrl)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Columns interface {
|
||||||
|
Container
|
||||||
|
Columns() []Column
|
||||||
|
Append(Control)
|
||||||
|
AppendCreate(Context, Control)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Column interface {
|
||||||
|
Append(Control)
|
||||||
|
AppendCreate(Context, Control)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewColumns(cols int, ctrls ...Control) Columns {
|
||||||
|
var c = &columns{}
|
||||||
|
for i := 0; i < cols; i++ {
|
||||||
|
c.addColumn()
|
||||||
|
}
|
||||||
|
for _, ctrl := range ctrls {
|
||||||
|
c.Append(ctrl)
|
||||||
|
}
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *columns) addColumn() {
|
||||||
|
var p = NewDockPanel(c)
|
||||||
|
c.ContainerBase.Append(p)
|
||||||
|
c.cols = append(c.cols, &column{p})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *columns) next() {
|
||||||
|
c.col = (c.col + 1) % len(c.cols)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *columns) Columns() []Column {
|
||||||
|
var cols = make([]Column, len(c.cols))
|
||||||
|
for i, col := range c.cols {
|
||||||
|
cols[i] = col
|
||||||
|
}
|
||||||
|
return cols
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *columns) Append(ctrl Control) {
|
||||||
|
c.cols[c.col].Append(ctrl)
|
||||||
|
c.next()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *columns) AppendCreate(ctx Context, ctrl Control) {
|
||||||
|
c.cols[c.col].AppendCreate(ctx, ctrl)
|
||||||
|
c.next()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *columns) DesiredSize(ctx Context) geom.PointF {
|
||||||
|
var w float64
|
||||||
|
var h float64
|
||||||
|
for _, col := range c.cols {
|
||||||
|
var sz = col.p.DesiredSize(ctx)
|
||||||
|
if !math.IsNaN(w) {
|
||||||
|
if math.IsNaN(sz.X) {
|
||||||
|
w = sz.X
|
||||||
|
} else {
|
||||||
|
w += sz.X
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !math.IsNaN(h) {
|
||||||
|
if math.IsNaN(sz.Y) {
|
||||||
|
h = sz.Y
|
||||||
|
} else {
|
||||||
|
h = math.Max(h, sz.Y)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return geom.PtF(w, h)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *columns) Arrange(ctx Context, rect geom.RectangleF) {
|
||||||
|
c.ContainerBase.SetRect(rect)
|
||||||
|
var w, h = rect.Dx(), rect.Dy()
|
||||||
|
var cols = float64(len(c.cols))
|
||||||
|
for i, col := range c.cols {
|
||||||
|
var ii = float64(i)
|
||||||
|
var colH = col.p.DesiredSize(ctx).Y
|
||||||
|
if colH > h {
|
||||||
|
colH = h
|
||||||
|
}
|
||||||
|
var colR = geom.RectF(rect.Min.X+ii*w/cols, rect.Min.Y, rect.Min.X+(ii+1)*w/cols, rect.Min.Y+colH)
|
||||||
|
Arrange(ctx, col.p, colR)
|
||||||
|
}
|
||||||
|
}
|
@ -18,6 +18,8 @@ type ContentScrollbar struct {
|
|||||||
Orientation Orientation
|
Orientation Orientation
|
||||||
OnChanged ContentScrollbarValueChangedFn
|
OnChanged ContentScrollbarValueChangedFn
|
||||||
handle *contentScrollbarHandle
|
handle *contentScrollbarHandle
|
||||||
|
barLength float64
|
||||||
|
scrollDistance float64
|
||||||
}
|
}
|
||||||
|
|
||||||
type contentScrollbarHandle struct {
|
type contentScrollbarHandle struct {
|
||||||
@ -47,17 +49,21 @@ func (s *ContentScrollbar) Destroyed(ctx Context) {
|
|||||||
s.handle.Destroyed(ctx)
|
s.handle.Destroyed(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ContentScrollbar) barViewRange() (float64, float64) {
|
func (s *ContentScrollbar) length() (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
|
min = s.Bounds.Min.X
|
||||||
max = s.Bounds.Max.X
|
max = s.Bounds.Max.X
|
||||||
default:
|
default:
|
||||||
min = s.Bounds.Max.Y
|
min = s.Bounds.Min.Y
|
||||||
max = s.Bounds.Min.Y
|
max = s.Bounds.Max.Y
|
||||||
}
|
}
|
||||||
var length = (max - min)
|
return max - min, min
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ContentScrollbar) updateBarLength() {
|
||||||
|
var length, _ = s.length()
|
||||||
var bar = length
|
var bar = length
|
||||||
if s.Length > length {
|
if s.Length > length {
|
||||||
bar = length * length / s.Length
|
bar = length * length / s.Length
|
||||||
@ -69,7 +75,12 @@ func (s *ContentScrollbar) barViewRange() (float64, float64) {
|
|||||||
bar = 20
|
bar = 20
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return min + .5*bar, max - .5*bar
|
s.barLength = bar
|
||||||
|
var d = s.Length - length
|
||||||
|
if d < 0 {
|
||||||
|
d = 0
|
||||||
|
}
|
||||||
|
s.scrollDistance = d
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ContentScrollbar) barViewCenter() float64 {
|
func (s *ContentScrollbar) barViewCenter() float64 {
|
||||||
@ -82,23 +93,21 @@ func (s *ContentScrollbar) barViewCenter() float64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *ContentScrollbar) toValue(x, y float64) float64 {
|
func (s *ContentScrollbar) toValue(x, y float64) float64 {
|
||||||
var n = y
|
var pos = y
|
||||||
if OrientationHorizontal == s.Orientation {
|
if OrientationHorizontal == s.Orientation {
|
||||||
n = x
|
pos = x
|
||||||
}
|
}
|
||||||
var min, max = s.barViewRange()
|
var length, min = s.length()
|
||||||
if min == max {
|
if length == 0 {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
var delta = s.Length - (max - min)
|
var offset = (pos - .5*s.barLength - min) / (length - s.barLength)
|
||||||
var off = (n - min) / (max - min)
|
if offset < 0 {
|
||||||
var v = off * (s.Length - (max - min))
|
return 0
|
||||||
if v < 0 {
|
} else if offset > 1 {
|
||||||
v = 0
|
return s.scrollDistance
|
||||||
} else if v > delta {
|
|
||||||
v = delta
|
|
||||||
}
|
}
|
||||||
return v
|
return s.scrollDistance * offset
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ContentScrollbar) change(v float64) {
|
func (s *ContentScrollbar) change(v float64) {
|
||||||
@ -117,13 +126,16 @@ func (s *ContentScrollbar) snapTo(x, y int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *ContentScrollbar) increment(d int) {
|
func (s *ContentScrollbar) increment(d int) {
|
||||||
// var val = s.Value + d
|
if s.Orientation == OrientationVertical {
|
||||||
// if val < s.Minimum {
|
d *= -1
|
||||||
// val = s.Minimum
|
}
|
||||||
// } else if val > s.Maximum {
|
var val = s.Value + float64(d)*ScrollbarWidth
|
||||||
// val = s.Maximum
|
if val < 0 {
|
||||||
// }
|
val = 0
|
||||||
// s.change(val)
|
} else if val > s.scrollDistance {
|
||||||
|
val = s.scrollDistance
|
||||||
|
}
|
||||||
|
s.change(val)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ContentScrollbar) Handle(ctx Context, ev allegro5.Event) {
|
func (s *ContentScrollbar) Handle(ctx Context, ev allegro5.Event) {
|
||||||
@ -168,19 +180,21 @@ func (s *ContentScrollbar) SetRect(rect geom.RectangleF) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
s.ControlBase.SetRect(rect)
|
s.ControlBase.SetRect(rect)
|
||||||
|
s.updateBarLength()
|
||||||
|
|
||||||
// var min, max = s.barViewRange()
|
var offset float64
|
||||||
// var off = float64(s.Value-s.Minimum) / float64(s.Maximum-s.Minimum)
|
if 0 < s.scrollDistance {
|
||||||
// var centerH = min + (max-min)*off
|
offset = s.Value / s.scrollDistance
|
||||||
// var r = 0.5 * float64(s.handles[0].Width())
|
}
|
||||||
|
var length, min = s.length()
|
||||||
// var center = s.barViewCenter()
|
var begin = min + (length-s.barLength)*offset
|
||||||
// switch s.Orientation {
|
var end = begin + s.barLength
|
||||||
// case OrientationHorizontal:
|
switch s.Orientation {
|
||||||
// s.handle.SetRect(geom.RectF(centerH-r, center-r, centerH+r, center+r))
|
case OrientationHorizontal:
|
||||||
// default:
|
s.handle.SetRect(geom.RectF(begin, rect.Min.Y, end, rect.Max.Y))
|
||||||
// s.handle.SetRect(geom.RectF(center-r, centerH-r, center+r, centerH+r))
|
default:
|
||||||
// }
|
s.handle.SetRect(geom.RectF(rect.Min.X, begin, rect.Max.X, end))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ContentScrollbar) Render(ctx Context) {
|
func (s *ContentScrollbar) Render(ctx Context) {
|
||||||
|
@ -14,6 +14,7 @@ type Control interface {
|
|||||||
Update(Context, time.Duration)
|
Update(Context, time.Duration)
|
||||||
Handle(Context, allegro5.Event)
|
Handle(Context, allegro5.Event)
|
||||||
DesiredSize(Context) geom.PointF
|
DesiredSize(Context) geom.PointF
|
||||||
|
Rect() geom.RectangleF
|
||||||
SetRect(geom.RectangleF)
|
SetRect(geom.RectangleF)
|
||||||
Render(Context)
|
Render(Context)
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
package ui
|
package ui
|
||||||
|
|
||||||
const topMargin = 4
|
|
||||||
const leftMargin = 8
|
const leftMargin = 8
|
||||||
const lineHeight = 16
|
|
||||||
const checkboxMargin = 4
|
const checkboxMargin = 4
|
||||||
const checkboxSize = 24
|
const checkboxSize = 24
|
||||||
|
@ -30,6 +30,14 @@ func NewDockPanel(parent Container) DockPanel {
|
|||||||
return &dockPanel{ContainerBase: ContainerBase{parent: parent}}
|
return &dockPanel{ContainerBase: ContainerBase{parent: parent}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewDockPanelContent(parent Container, d Dock, controls ...Control) DockPanel {
|
||||||
|
var p = NewDockPanel(parent)
|
||||||
|
for _, c := range controls {
|
||||||
|
p.Append(d, c)
|
||||||
|
}
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
func (p *dockPanel) Append(d Dock, children ...Control) error {
|
func (p *dockPanel) Append(d Dock, children ...Control) error {
|
||||||
for _, child := range children {
|
for _, child := range children {
|
||||||
p.ContainerBase.Append(child)
|
p.ContainerBase.Append(child)
|
||||||
|
15
ui/label.go
15
ui/label.go
@ -1,10 +1,21 @@
|
|||||||
package ui
|
package ui
|
||||||
|
|
||||||
import "opslag.de/schobers/galleg/allegro5"
|
import (
|
||||||
|
"opslag.de/schobers/galleg/allegro5"
|
||||||
|
"opslag.de/schobers/geom"
|
||||||
|
)
|
||||||
|
|
||||||
type Label struct {
|
type Label struct {
|
||||||
ControlBase
|
ControlBase
|
||||||
Text string
|
Text string
|
||||||
|
HorizontalAlignment allegro5.HorizontalAlignment
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Label) DesiredSize(ctx Context) geom.PointF {
|
||||||
|
var fonts = ctx.Fonts()
|
||||||
|
var fnt = fonts.Get("default")
|
||||||
|
var _, _, w, h = fnt.TextDimensions(l.Text)
|
||||||
|
return geom.PtF(float64(w), float64(h))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Label) Render(ctx Context) {
|
func (l *Label) Render(ctx Context) {
|
||||||
@ -13,7 +24,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+lineHeight-fnt.Ascent(), ctx.Palette().Darkest(), allegro5.AlignLeft, l.Text)
|
fnt.Draw(min.X, min.Y+fnt.Height()-fnt.Ascent(), ctx.Palette().Darkest(), l.HorizontalAlignment, l.Text)
|
||||||
|
|
||||||
l.ControlBase.Render(ctx)
|
l.ControlBase.Render(ctx)
|
||||||
}
|
}
|
||||||
|
50
ui/margin.go
Normal file
50
ui/margin.go
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
package ui
|
||||||
|
|
||||||
|
import "opslag.de/schobers/geom"
|
||||||
|
|
||||||
|
type margin struct {
|
||||||
|
Wrapper
|
||||||
|
Left, Top, Right, Bottom float64
|
||||||
|
}
|
||||||
|
|
||||||
|
func Margin(c Control, m float64) Control {
|
||||||
|
return &margin{Wrap(c), m, m, m, m}
|
||||||
|
}
|
||||||
|
|
||||||
|
func LeftMargin(c Control, m float64) Control {
|
||||||
|
return &margin{Wrap(c), m, 0, 0, 0}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TopMargin(c Control, m float64) Control {
|
||||||
|
return &margin{Wrap(c), 0, m, 0, 0}
|
||||||
|
}
|
||||||
|
|
||||||
|
func HorizontalMargin(c Control, m float64) Control {
|
||||||
|
return &margin{Wrap(c), m, 0, m, 0}
|
||||||
|
}
|
||||||
|
|
||||||
|
func VerticalMargin(c Control, m float64) Control {
|
||||||
|
return &margin{Wrap(c), 0, m, 0, m}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *margin) DesiredSize(ctx Context) geom.PointF {
|
||||||
|
var sz = m.Wrapper.DesiredSize(ctx)
|
||||||
|
return geom.PtF(sz.X+m.Left+m.Right, sz.Y+m.Top+m.Bottom)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *margin) Arrange(ctx Context, rect geom.RectangleF) {
|
||||||
|
m.Wrapper.SetRect(rect)
|
||||||
|
rect.Min.X += m.Left
|
||||||
|
rect.Min.Y += m.Top
|
||||||
|
rect.Max.X -= m.Right
|
||||||
|
rect.Max.Y -= m.Bottom
|
||||||
|
if rect.Min.X > rect.Max.X {
|
||||||
|
var x = .5 * (rect.Min.X + rect.Max.X)
|
||||||
|
rect.Min.X, rect.Max.X = x, x
|
||||||
|
}
|
||||||
|
if rect.Min.Y > rect.Max.Y {
|
||||||
|
var y = .5 * (rect.Min.Y + rect.Max.Y)
|
||||||
|
rect.Min.Y, rect.Max.Y = y, y
|
||||||
|
}
|
||||||
|
Arrange(ctx, m.Wrapped, rect)
|
||||||
|
}
|
77
ui/scroll.go
Normal file
77
ui/scroll.go
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
package ui
|
||||||
|
|
||||||
|
import (
|
||||||
|
"opslag.de/schobers/galleg/allegro5"
|
||||||
|
"opslag.de/schobers/geom"
|
||||||
|
)
|
||||||
|
|
||||||
|
type scroll struct {
|
||||||
|
Wrapper
|
||||||
|
Content Control
|
||||||
|
Bar *ContentScrollbar
|
||||||
|
}
|
||||||
|
|
||||||
|
func Scroll(c Control, o Orientation) Control {
|
||||||
|
var dock = NewDockPanel(nil)
|
||||||
|
var bar = &ContentScrollbar{Orientation: o}
|
||||||
|
switch o {
|
||||||
|
case OrientationHorizontal:
|
||||||
|
dock.Append(DockBottom, TopMargin(bar, ScrollbarWidth))
|
||||||
|
dock.Append(DockBottom, c)
|
||||||
|
case OrientationVertical:
|
||||||
|
dock.Append(DockRight, LeftMargin(bar, ScrollbarWidth))
|
||||||
|
dock.Append(DockRight, c)
|
||||||
|
}
|
||||||
|
var s = &scroll{Wrap(dock), c, bar}
|
||||||
|
bar.OnChanged = func(v float64) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *scroll) Handle(ctx Context, ev allegro5.Event) {
|
||||||
|
s.Wrapper.Handle(ctx, ev)
|
||||||
|
switch e := ev.(type) {
|
||||||
|
case *allegro5.MouseMoveEvent:
|
||||||
|
if 0 != e.DeltaZ && !s.Bar.IsOver && geom.PtF(float64(e.X), float64(e.Y)).In(s.Bounds) {
|
||||||
|
var d = e.DeltaZ
|
||||||
|
if allegro5.IsAnyKeyDown(allegro5.KeyLShift, allegro5.KeyRShift) {
|
||||||
|
d *= 10
|
||||||
|
}
|
||||||
|
s.Bar.increment(d)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *scroll) Render(ctx Context) {
|
||||||
|
var bounds = s.Content.Rect()
|
||||||
|
var w, h = bounds.Dx(), bounds.Dy()
|
||||||
|
var bmp, err = allegro5.NewVideoBitmap(int(w), int(h))
|
||||||
|
if nil != err {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer bmp.Destroy()
|
||||||
|
bmp.SetAsTarget()
|
||||||
|
switch s.Bar.Orientation {
|
||||||
|
case OrientationHorizontal:
|
||||||
|
Arrange(ctx, s.Content, geom.RectF(-s.Bar.Value, 0, w, h))
|
||||||
|
case OrientationVertical:
|
||||||
|
Arrange(ctx, s.Content, geom.RectF(0, -s.Bar.Value, w, h))
|
||||||
|
}
|
||||||
|
s.Content.Render(ctx)
|
||||||
|
ctx.Display().SetAsTarget()
|
||||||
|
var min = s.Bounds.Min.To32()
|
||||||
|
bmp.Draw(min.X, min.Y)
|
||||||
|
s.Bar.Render(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *scroll) Arrange(ctx Context, rect geom.RectangleF) {
|
||||||
|
var sz = s.Content.DesiredSize(ctx)
|
||||||
|
switch s.Bar.Orientation {
|
||||||
|
case OrientationHorizontal:
|
||||||
|
s.Bar.Length = sz.X
|
||||||
|
case OrientationVertical:
|
||||||
|
s.Bar.Length = sz.Y
|
||||||
|
}
|
||||||
|
s.Wrapper.Arrange(ctx, rect)
|
||||||
|
}
|
@ -18,6 +18,7 @@ type State interface {
|
|||||||
|
|
||||||
type StateBase struct {
|
type StateBase struct {
|
||||||
Control Control
|
Control Control
|
||||||
|
ChangeTo State
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StateBase) Enter(ctx Context) error {
|
func (s *StateBase) Enter(ctx Context) error {
|
||||||
@ -42,7 +43,7 @@ func (s *StateBase) Update(ctx Context, dt time.Duration) (State, error) {
|
|||||||
if nil != s.Control {
|
if nil != s.Control {
|
||||||
s.Control.Update(ctx, dt)
|
s.Control.Update(ctx, dt)
|
||||||
}
|
}
|
||||||
return nil, nil
|
return s.ChangeTo, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StateBase) Handle(ctx Context, ev allegro5.Event) error {
|
func (s *StateBase) Handle(ctx Context, ev allegro5.Event) error {
|
||||||
|
58
ui/wrapper.go
Normal file
58
ui/wrapper.go
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
package ui
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"opslag.de/schobers/galleg/allegro5"
|
||||||
|
"opslag.de/schobers/geom"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Wrapper struct {
|
||||||
|
Wrapped Control
|
||||||
|
Bounds geom.RectangleF
|
||||||
|
}
|
||||||
|
|
||||||
|
func Wrap(c Control) Wrapper {
|
||||||
|
return Wrapper{Wrapped: c}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Wrapper) Created(ctx Context, p Container) error {
|
||||||
|
return w.Wrapped.Created(ctx, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Wrapper) Destroyed(ctx Context) {
|
||||||
|
w.Wrapped.Destroyed(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Wrapper) Update(ctx Context, d time.Duration) {
|
||||||
|
w.Wrapped.Update(ctx, d)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Wrapper) Handle(ctx Context, ev allegro5.Event) {
|
||||||
|
w.Wrapped.Handle(ctx, ev)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Wrapper) DesiredSize(ctx Context) geom.PointF {
|
||||||
|
return w.Wrapped.DesiredSize(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Wrapper) Rect() geom.RectangleF {
|
||||||
|
return w.Bounds
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Wrapper) SetRect(rect geom.RectangleF) {
|
||||||
|
w.Bounds = rect
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Wrapper) Render(ctx Context) {
|
||||||
|
w.Wrapped.Render(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Wrapper) Children() []Control {
|
||||||
|
return []Control{w.Wrapped}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Wrapper) Arrange(ctx Context, rect geom.RectangleF) {
|
||||||
|
w.Bounds = rect
|
||||||
|
Arrange(ctx, w.Wrapped, rect)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user