diff --git a/allg5/display.go b/allg5/display.go index e3b60c6..cb1ac90 100644 --- a/allg5/display.go +++ b/allg5/display.go @@ -78,6 +78,10 @@ func (d *Display) SetIcon(i *Bitmap) { C.al_set_display_icon(d.display, i.bitmap) } +func (d *Display) SetMouseCursor(c MouseCursor) { + C.al_set_system_mouse_cursor(d.display, C.ALLEGRO_SYSTEM_MOUSE_CURSOR(c)) +} + func (d *Display) SetMousePosition(x, y int) { C.al_set_mouse_xy(d.display, C.int(x), C.int(y)) } diff --git a/allg5/mouse.go b/allg5/mouse.go index 8ad9f6d..2e917f8 100644 --- a/allg5/mouse.go +++ b/allg5/mouse.go @@ -11,6 +11,31 @@ const ( MouseButtonMiddle = 3 ) +type MouseCursor uint + +const ( + MouseCursorNone MouseCursor = 0 + MouseCursorDefault = 1 + MouseCursorArrow = 2 + MouseCursorBusy = 3 + MouseCursorQuestion = 4 + MouseCursorEdit = 5 + MouseCursorMove = 6 + MouseCursorResizeN = 7 + MouseCursorResizeW = 8 + MouseCursorResizeS = 9 + MouseCursorResizeE = 10 + MouseCursorResizeNW = 11 + MouseCursorResizeSW = 12 + MouseCursorResizeSE = 13 + MouseCursorResizeNE = 14 + MouseCursorProgress = 15 + MouseCursorPrecision = 16 + MouseCursorLink = 17 + MouseCursorAltSelect = 18 + MouseCursorUnavailable = 19 +) + func IsMouseButtonDown(b MouseButton) bool { var state C.ALLEGRO_MOUSE_STATE C.al_get_mouse_state(&state) diff --git a/ui/allg5ui/renderer.go b/ui/allg5ui/renderer.go index 72aa33e..dbc657b 100644 --- a/ui/allg5ui/renderer.go +++ b/ui/allg5ui/renderer.go @@ -34,15 +34,17 @@ func NewRenderer(w, h int, opts allg5.NewDisplayOptions) (*Renderer, error) { eq.RegisterDisplay(disp) eq.RegisterUserEvents(user) - return &Renderer{disp, eq, map[string]*font{}, user}, nil + return &Renderer{disp, eq, map[string]*font{}, user, ui.MouseCursorDefault, ui.MouseCursorDefault}, nil } // Renderer implements ui.Renderer using Allegro 5. type Renderer struct { - disp *allg5.Display - eq *allg5.EventQueue - ft map[string]*font - user *allg5.UserEventSource + disp *allg5.Display + eq *allg5.EventQueue + ft map[string]*font + user *allg5.UserEventSource + cursor ui.MouseCursor + newCursor ui.MouseCursor } // Renderer implementation (events) @@ -50,6 +52,7 @@ type Renderer struct { func (r *Renderer) PushEvents(t ui.EventTarget, wait bool) { r.disp.Flip() + r.newCursor = ui.MouseCursorDefault var ev = eventWait(r.eq, wait) for nil != ev { switch e := ev.(type) { @@ -68,6 +71,22 @@ func (r *Renderer) PushEvents(t ui.EventTarget, wait bool) { } ev = r.eq.Get() } + + if r.newCursor != r.cursor { + r.cursor = r.newCursor + switch r.cursor { + case ui.MouseCursorNone: + r.disp.SetMouseCursor(allg5.MouseCursorNone) + case ui.MouseCursorDefault: + r.disp.SetMouseCursor(allg5.MouseCursorDefault) + case ui.MouseCursorNotAllowed: + r.disp.SetMouseCursor(allg5.MouseCursorUnavailable) + case ui.MouseCursorPointer: + r.disp.SetMouseCursor(allg5.MouseCursorLink) + case ui.MouseCursorText: + r.disp.SetMouseCursor(allg5.MouseCursorEdit) + } + } } func (r *Renderer) Refresh() { @@ -183,6 +202,10 @@ func (r *Renderer) SetIcon(im ui.Image) { r.disp.SetIcon(bmp) } +func (r *Renderer) SetMouseCursor(c ui.MouseCursor) { + r.newCursor = c +} + func (r *Renderer) SetWindowTitle(t string) { r.disp.SetWindowTitle(t) } diff --git a/ui/button.go b/ui/button.go index 8f956e9..9a109f2 100644 --- a/ui/button.go +++ b/ui/button.go @@ -25,6 +25,13 @@ func (b *Button) DesiredSize(ctx Context) geom.PointF32 { return geom.PtF32(width+pad*2, height+pad*2) } +func (b *Button) Handle(ctx Context, e Event) { + b.ControlBase.Handle(ctx, e) + if b.over { + ctx.Renderer().SetMouseCursor(MouseCursorPointer) + } +} + func (b *Button) Render(ctx Context) { var fore = b.FontColor var style = ctx.Style() diff --git a/ui/mouse.go b/ui/mouse.go new file mode 100644 index 0000000..eca84a5 --- /dev/null +++ b/ui/mouse.go @@ -0,0 +1,11 @@ +package ui + +type MouseCursor int + +const ( + MouseCursorNone MouseCursor = iota + MouseCursorDefault + MouseCursorNotAllowed + MouseCursorPointer + MouseCursorText +) diff --git a/ui/renderer.go b/ui/renderer.go index b90a654..08009b5 100644 --- a/ui/renderer.go +++ b/ui/renderer.go @@ -27,6 +27,7 @@ type Renderer interface { Rectangle(r geom.RectangleF32, c color.Color, thickness float32) RenderTo(Image) RenderToDisplay() + SetMouseCursor(c MouseCursor) Size() geom.PointF32 Target() Image Text(p geom.PointF32, font string, color color.Color, text string)