diff --git a/allg5/event.go b/allg5/event.go index caaea3f..f4505c4 100644 --- a/allg5/event.go +++ b/allg5/event.go @@ -1,6 +1,15 @@ package allg5 -// #include +/* +#include + +#define USER_EVENT_TYPE ALLEGRO_GET_EVENT_TYPE('u', 's', 'e', 'r') + +void init_user_event(ALLEGRO_EVENT* e) +{ + e->user.type = USER_EVENT_TYPE; +} +*/ import "C" import ( @@ -117,6 +126,14 @@ type MouseMoveEvent struct { Pressure float32 } +type UserEvent struct { + EventBase +} + +type UserEventSource struct { + source *C.ALLEGRO_EVENT_SOURCE +} + func NewEventQueue() (*EventQueue, error) { q := C.al_create_event_queue() if q == nil { @@ -141,6 +158,10 @@ func (eq *EventQueue) RegisterKeyboard() { eq.register(C.al_get_keyboard_event_source()) } +func (eq *EventQueue) RegisterUserEvents(source *UserEventSource) { + eq.register(source.source) +} + func (eq *EventQueue) mapEvent(e *C.ALLEGRO_EVENT) Event { any := (*C.ALLEGRO_ANY_EVENT)(unsafe.Pointer(e)) eb := EventBase{float64(any.timestamp)} @@ -172,6 +193,8 @@ func (eq *EventQueue) mapEvent(e *C.ALLEGRO_EVENT) Event { case C.ALLEGRO_EVENT_KEY_CHAR: key := (*C.ALLEGRO_KEYBOARD_EVENT)(unsafe.Pointer(e)) return &KeyCharEvent{KeyEvent{eb, Key(key.keycode), nil}, rune(key.unichar), KeyMod(key.modifiers), bool(key.repeat)} + case C.USER_EVENT_TYPE: + return &UserEvent{eb} } return nil } @@ -193,3 +216,21 @@ func (eq *EventQueue) GetWait() Event { func (eq *EventQueue) Destroy() { C.al_destroy_event_queue(eq.queue) } + +func NewUserEventSource() *UserEventSource { + s := (*C.ALLEGRO_EVENT_SOURCE)(C.malloc(C.sizeof_ALLEGRO_EVENT_SOURCE)) + source := &UserEventSource{s} + C.al_init_user_event_source(s) + return source +} + +func (s *UserEventSource) Destroy() { + C.al_destroy_user_event_source(s.source) + C.free(unsafe.Pointer(s.source)) +} + +func (s *UserEventSource) EmitEvent() bool { + e := (*C.ALLEGRO_EVENT)(C.malloc(C.sizeof_ALLEGRO_EVENT)) + C.init_user_event(e) + return bool(C.al_emit_user_event(s.source, e, nil)) +} diff --git a/ui/allg5ui/renderer.go b/ui/allg5ui/renderer.go index ec48ca6..72aa33e 100644 --- a/ui/allg5ui/renderer.go +++ b/ui/allg5ui/renderer.go @@ -28,11 +28,13 @@ func NewRenderer(w, h int, opts allg5.NewDisplayOptions) (*Renderer, error) { return nil, err } + user := allg5.NewUserEventSource() eq.RegisterKeyboard() eq.RegisterMouse() eq.RegisterDisplay(disp) + eq.RegisterUserEvents(user) - return &Renderer{disp, eq, map[string]*font{}}, nil + return &Renderer{disp, eq, map[string]*font{}, user}, nil } // Renderer implements ui.Renderer using Allegro 5. @@ -40,6 +42,7 @@ type Renderer struct { disp *allg5.Display eq *allg5.EventQueue ft map[string]*font + user *allg5.UserEventSource } // Renderer implementation (events) @@ -60,14 +63,21 @@ func (r *Renderer) PushEvents(t ui.EventTarget, wait bool) { t.Handle(&ui.MouseButtonUpEvent{MouseEvent: mouseEvent(e.MouseEvent), Button: ui.MouseButton(e.Button)}) case *allg5.MouseMoveEvent: t.Handle(&ui.MouseMoveEvent{MouseEvent: mouseEvent(e.MouseEvent), MouseWheel: float32(e.DeltaZ)}) + case *allg5.UserEvent: + // used to unblock the wait for events. } ev = r.eq.Get() } } +func (r *Renderer) Refresh() { + r.user.EmitEvent() +} + // Renderer implementation (lifetime) func (r *Renderer) Destroy() error { + r.user.Destroy() r.eq.Destroy() r.disp.Destroy() return nil @@ -168,6 +178,11 @@ func (r *Renderer) Size() geom.PointF32 { return geom.PtF32(float32(r.disp.Width()), float32(r.disp.Height())) } +func (r *Renderer) SetIcon(im ui.Image) { + bmp := r.mustGetBitmap(im) + r.disp.SetIcon(bmp) +} + func (r *Renderer) SetWindowTitle(t string) { r.disp.SetWindowTitle(t) } diff --git a/ui/renderer.go b/ui/renderer.go index b2f9138..b90a654 100644 --- a/ui/renderer.go +++ b/ui/renderer.go @@ -10,6 +10,7 @@ import ( type Renderer interface { // Events PushEvents(t EventTarget, wait bool) + Refresh() // Lifetime Destroy() error