diff options
-rw-r--r-- | pugl/detail/implementation.c | 5 | ||||
-rw-r--r-- | pugl/detail/mac.m | 39 | ||||
-rw-r--r-- | pugl/detail/win.c | 13 | ||||
-rw-r--r-- | pugl/detail/x11.c | 15 | ||||
-rw-r--r-- | pugl/pugl.h | 10 | ||||
-rw-r--r-- | test/test_utils.h | 8 |
6 files changed, 74 insertions, 16 deletions
diff --git a/pugl/detail/implementation.c b/pugl/detail/implementation.c index e9e1ae9..5c3da62 100644 --- a/pugl/detail/implementation.c +++ b/pugl/detail/implementation.c @@ -159,6 +159,9 @@ puglNewView(PuglWorld* const world) void puglFreeView(PuglView* view) { + const PuglEvent destroyEvent = {{PUGL_DESTROY, 0}}; + puglDispatchEvent(view, &destroyEvent); + // Remove from world view list PuglWorld* world = view->world; for (size_t i = 0; i < world->numViews; ++i) { @@ -309,6 +312,8 @@ puglDispatchEvent(PuglView* view, const PuglEvent* event) switch (event->type) { case PUGL_NOTHING: break; + case PUGL_CREATE: + case PUGL_DESTROY: case PUGL_CONFIGURE: view->backend->enter(view, NULL); view->eventFunc(view, event); diff --git a/pugl/detail/mac.m b/pugl/detail/mac.m index da1ab35..c083919 100644 --- a/pugl/detail/mac.m +++ b/pugl/detail/mac.m @@ -98,6 +98,21 @@ updateViewRect(PuglView* view) return YES; } +- (void) setIsVisible:(BOOL)flag +{ + if (flag && !puglview->visible) { + const PuglEvent map = {{PUGL_MAP, 0}}; + puglview->eventFunc(puglview, &map); + } else if (!flag && puglview->visible) { + const PuglEvent unmap = {{PUGL_UNMAP, 0}}; + puglview->eventFunc(puglview, &unmap); + } + + puglview->visible = flag; + + [super setIsVisible:flag]; +} + @end @implementation PuglWrapperView @@ -817,15 +832,32 @@ puglCreateWindow(PuglView* view, const char* title) [impl->wrapperView updateTrackingAreas]; + const PuglEvent createEvent = {{PUGL_CREATE, 0}}; + puglDispatchEvent(view, &createEvent); + + const PuglEventConfigure ev = { + PUGL_CONFIGURE, + 0, + view->frame.x, + view->frame.y, + view->frame.width, + view->frame.height, + }; + + puglDispatchEvent(view, (const PuglEvent*)&ev); + return 0; } PuglStatus puglShowWindow(PuglView* view) { - [view->impl->window setIsVisible:YES]; - updateViewRect(view); - view->visible = true; + if (![view->impl->window isVisible]) { + [view->impl->window setIsVisible:YES]; + [view->impl->drawView setNeedsDisplay: YES]; + updateViewRect(view); + } + return PUGL_SUCCESS; } @@ -833,7 +865,6 @@ PuglStatus puglHideWindow(PuglView* view) { [view->impl->window setIsVisible:NO]; - view->visible = false; return PUGL_SUCCESS; } diff --git a/pugl/detail/win.c b/pugl/detail/win.c index b7f03a3..2e0cd96 100644 --- a/pugl/detail/win.c +++ b/pugl/detail/win.c @@ -193,6 +193,9 @@ puglCreateWindow(PuglView* view, const char* title) puglSetFrame(view, view->frame); SetWindowLongPtr(impl->hwnd, GWLP_USERDATA, (LONG_PTR)view); + const PuglEvent createEvent = {{PUGL_CREATE, 0}}; + view->eventFunc(view, &createEvent); + return PUGL_SUCCESS; } @@ -203,7 +206,6 @@ puglShowWindow(PuglView* view) ShowWindow(impl->hwnd, SW_SHOWNORMAL); SetFocus(impl->hwnd); - view->visible = true; return PUGL_SUCCESS; } @@ -213,7 +215,6 @@ puglHideWindow(PuglView* view) PuglInternals* impl = view->impl; ShowWindow(impl->hwnd, SW_HIDE); - view->visible = false; return PUGL_SUCCESS; } @@ -554,9 +555,17 @@ handleMessage(PuglView* view, UINT message, WPARAM wParam, LPARAM lParam) case WM_SHOWWINDOW: if (wParam) { handleConfigure(view, &event); + puglDispatchEvent(view, &event); + event.type = PUGL_NOTHING; + RedrawWindow(view->impl->hwnd, NULL, NULL, RDW_INVALIDATE|RDW_ALLCHILDREN|RDW_INTERNALPAINT); } + + if ((bool)wParam != view->visible) { + view->visible = wParam; + event.any.type = wParam ? PUGL_MAP : PUGL_UNMAP; + } break; case WM_SIZE: handleConfigure(view, &event); diff --git a/pugl/detail/x11.c b/pugl/detail/x11.c index cc77f29..d3e4195 100644 --- a/pugl/detail/x11.c +++ b/pugl/detail/x11.c @@ -254,6 +254,9 @@ puglCreateWindow(PuglView* view, const char* title) fprintf(stderr, "warning: XCreateIC failed\n"); } + const PuglEvent createEvent = {{PUGL_CREATE, 0}}; + puglDispatchEvent(view, &createEvent); + return PUGL_SUCCESS; } @@ -425,17 +428,11 @@ translateEvent(PuglView* view, XEvent xevent) case VisibilityNotify: view->visible = xevent.xvisibility.state != VisibilityFullyObscured; break; - case MapNotify: { - XWindowAttributes attrs = {0}; - XGetWindowAttributes(view->impl->display, view->impl->win, &attrs); - event.type = PUGL_CONFIGURE; - event.configure.x = attrs.x; - event.configure.y = attrs.y; - event.configure.width = attrs.width; - event.configure.height = attrs.height; + case MapNotify: + event.type = PUGL_MAP; break; - } case UnmapNotify: + event.type = PUGL_UNMAP; view->visible = false; break; case ConfigureNotify: diff --git a/pugl/pugl.h b/pugl/pugl.h index d14c086..04f5343 100644 --- a/pugl/pugl.h +++ b/pugl/pugl.h @@ -168,7 +168,11 @@ typedef enum { PUGL_NOTHING, ///< No event PUGL_BUTTON_PRESS, ///< Mouse button pressed, a #PuglEventButton PUGL_BUTTON_RELEASE, ///< Mouse button released, a #PuglEventButton - PUGL_CONFIGURE, ///< View moved and/or resized, a #PuglEventConfigure + PUGL_CREATE, ///< View created, a #PuglEventAny + PUGL_DESTROY, ///< View destroyed, a #PuglEventAny + PUGL_MAP, ///< View made visible, a #PuglEventAny + PUGL_UNMAP, ///< View made invisible, a #PuglEventAny + PUGL_CONFIGURE, ///< View moved/resized, a #PuglEventConfigure PUGL_EXPOSE, ///< View must be drawn, a #PuglEventExpose PUGL_CLOSE, ///< View will be closed, a #PuglEventAny PUGL_KEY_PRESS, ///< Key pressed, a #PuglEventKey @@ -390,6 +394,10 @@ typedef struct { This is a union of all event types. The #type must be checked to determine which fields are safe to access. A pointer to PuglEvent can either be cast to the appropriate type, or the union members used. + + The graphics system may only be accessed when handling certain events. The + graphics context is active for #PUGL_CREATE, #PUGL_DESTROY, #PUGL_CONFIGURE, + and #PUGL_EXPOSE, but only enabled for drawing for #PUGL_EXPOSE. */ typedef union { PuglEventAny any; ///< Valid for all event types diff --git a/test/test_utils.h b/test/test_utils.h index 80d279b..aca3376 100644 --- a/test/test_utils.h +++ b/test/test_utils.h @@ -124,6 +124,14 @@ printEvent(const PuglEvent* event, const char* prefix, const bool verbose) if (verbose) { switch (event->type) { + case PUGL_CREATE: + return fprintf(stderr, "%sCreate\n", prefix); + case PUGL_DESTROY: + return fprintf(stderr, "%sDestroy\n", prefix); + case PUGL_MAP: + return fprintf(stderr, "%sMap\n", prefix); + case PUGL_UNMAP: + return fprintf(stderr, "%sUnmap\n", prefix); case PUGL_CONFIGURE: return PRINT("%sConfigure " PFMT " " PFMT "\n", prefix, |