// Process the first event in queue, sending to the appropriate handler // This is the new object-oriented system // Uses the old system for now, but this may change void event_process(void) { d_event event; window *wind = window_get_front(); timer_update(); event_poll(); // send input events first // Doing this prevents problems when a draw event can create a newmenu, // such as some network menus when they report a problem if (window_get_front() != wind) return; event.type = EVENT_WINDOW_DRAW; // then draw all visible windows wind = window_get_first(); while (wind != NULL) { window *prev = window_get_prev(wind); if (window_is_visible(wind)) window_send_event(wind, &event); if (!window_exists(wind)) { if (!prev) // well there isn't a previous window ... break; // ... just bail out - we've done everything for this frame we can. wind = window_get_next(prev); // the current window seemed to be closed. so take the next one from the previous which should be able to point to the one after the current closed } else wind = window_get_next(wind); } gr_flip(); }
// The dialog handler borrows heavily from the newmenu_handler static int ui_dialog_handler(window *wind, d_event *event, UI_DIALOG *dlg) { int rval = 0; if (event->type == EVENT_WINDOW_CLOSED || event->type == EVENT_WINDOW_ACTIVATED || event->type == EVENT_WINDOW_DEACTIVATED) return 0; if (dlg->callback) if ((*dlg->callback)(dlg, event, dlg->userdata)) return 1; // event handled if (!window_exists(wind)) return 1; switch (event->type) { case EVENT_MOUSE_BUTTON_DOWN: case EVENT_MOUSE_BUTTON_UP: case EVENT_MOUSE_MOVED: /*return*/ ui_dialog_do_gadgets(dlg, event); if (!window_exists(wind)) return 1; rval = mouse_in_window(dlg->wind); break; case EVENT_KEY_COMMAND: case EVENT_KEY_RELEASE: rval = ui_dialog_do_gadgets(dlg, event); break; case EVENT_IDLE: timer_delay2(50); rval = ui_dialog_do_gadgets(dlg, event); break; case EVENT_WINDOW_DRAW: { d_event event2 = { EVENT_UI_DIALOG_DRAW }; ui_dialog_draw(dlg); rval = ui_dialog_do_gadgets(dlg, event); window_send_event(wind, &event2); break; } case EVENT_WINDOW_CLOSE: ui_gadget_delete_all(dlg); selected_gadget = NULL; d_free( dlg ); break; default: break; } return rval; }
// The dialog handler borrows heavily from the newmenu_handler static window_event_result ui_dialog_handler(window *wind,const d_event &event, UI_DIALOG *dlg) { window_event_result rval{window_event_result::ignored}; if (event.type == EVENT_WINDOW_ACTIVATED || event.type == EVENT_WINDOW_DEACTIVATED) return window_event_result::ignored; if (dlg->d_callback) if ((rval = (*dlg->d_callback)(dlg, event, dlg->d_userdata)) != window_event_result::ignored) return rval; // event handled switch (event.type) { case EVENT_IDLE: timer_delay2(50); /*-fallthrough*/ case EVENT_MOUSE_BUTTON_DOWN: case EVENT_MOUSE_BUTTON_UP: case EVENT_MOUSE_MOVED: case EVENT_KEY_COMMAND: case EVENT_KEY_RELEASE: return ui_dialog_do_gadgets(dlg, event); case EVENT_WINDOW_DRAW: { ui_dialog_draw(dlg); rval = ui_dialog_do_gadgets(dlg, event); if (rval != window_event_result::close) { d_event event2 = { EVENT_UI_DIALOG_DRAW }; window_send_event(*wind, event2); } return rval; } case EVENT_WINDOW_CLOSE: if (rval != window_event_result::deleted) // check if handler already deleted dialog (e.g. if UI_DIALOG was subclassed) delete dlg; return window_event_result::ignored; // free the window in any case (until UI_DIALOG is subclass of window) default: return window_event_result::ignored; } }
void event_send(d_event *event) { window *wind; int handled = 0; for (wind = window_get_front(); wind != NULL && !handled; wind = window_get_prev(wind)) if (window_is_visible(wind)) { handled = window_send_event(wind, event); if (!window_exists(wind)) // break away if necessary: window_send_event() could have closed wind by now break; if (window_is_modal(wind)) break; } if (!handled) call_default_handler(event); }