summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2020-07-25 14:23:46 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2020-07-25 14:23:46 +0300
commit40421af6e6571b58b97b3e3372641de3b3ba60d8 (patch)
treec319e2feccb677d17a0f1222ca760e9188c4cabd /src
parente8233ba5c6f6933d6d20e114192934e1145a750e (diff)
Fixed event processing for menus and dialogs
Diffstat (limited to 'src')
-rw-r--r--src/app.c26
-rw-r--r--src/app.h7
-rw-r--r--src/ui/util.c27
-rw-r--r--src/ui/util.h8
4 files changed, 52 insertions, 16 deletions
diff --git a/src/app.c b/src/app.c
index e0037f0c..6bf62dc7 100644
--- a/src/app.c
+++ b/src/app.c
@@ -241,10 +241,11 @@ const iString *execPath_App(void) {
241 return executablePath_CommandLine(&app_.args); 241 return executablePath_CommandLine(&app_.args);
242} 242}
243 243
244void processEvents_App(void) { 244void processEvents_App(enum iAppEventMode eventMode) {
245 iApp *d = &app_; 245 iApp *d = &app_;
246 SDL_Event ev; 246 SDL_Event ev;
247 while (SDL_WaitEvent(&ev)) { 247 while ((eventMode == waitForNewEvents_AppEventMode && SDL_WaitEvent(&ev)) ||
248 (eventMode == postedEventsOnly_AppEventMode && SDL_PollEvent(&ev))) {
248 switch (ev.type) { 249 switch (ev.type) {
249 case SDL_QUIT: 250 case SDL_QUIT:
250 // if (isModified_Song(d->song)) { 251 // if (isModified_Song(d->song)) {
@@ -303,7 +304,7 @@ static int run_App_(iApp *d) {
303 SDL_EventState(SDL_DROPFILE, SDL_ENABLE); /* open files via drag'n'drop */ 304 SDL_EventState(SDL_DROPFILE, SDL_ENABLE); /* open files via drag'n'drop */
304 while (d->running) { 305 while (d->running) {
305 runTickers_App_(d); 306 runTickers_App_(d);
306 processEvents_App(); /* may wait here for a while */ 307 processEvents_App(waitForNewEvents_AppEventMode);
307 refresh_App(); 308 refresh_App();
308 } 309 }
309 return 0; 310 return 0;
@@ -429,14 +430,17 @@ iBool handleCommand_App(const char *cmd) {
429 d->historyPos = 0; 430 d->historyPos = 0;
430 } 431 }
431 /* Insert new item. */ 432 /* Insert new item. */
432 iHistoryItem item; 433 const iHistoryItem *lastItem = historyItem_App_(d, 0);
433 init_HistoryItem(&item); 434 if (!lastItem || cmpString_String(&lastItem->url, url) != 0) {
434 set_String(&item.url, url); 435 iHistoryItem item;
435 pushBack_Array(&d->history, &item); 436 init_HistoryItem(&item);
436 /* Don't make it too long. */ 437 set_String(&item.url, url);
437 if (size_Array(&d->history) > historyMax_App_) { 438 pushBack_Array(&d->history, &item);
438 deinit_HistoryItem(front_Array(&d->history)); 439 /* Don't make it too long. */
439 remove_Array(&d->history, 0); 440 if (size_Array(&d->history) > historyMax_App_) {
441 deinit_HistoryItem(front_Array(&d->history));
442 remove_Array(&d->history, 0);
443 }
440 } 444 }
441 } 445 }
442 } 446 }
diff --git a/src/app.h b/src/app.h
index f4a2e18d..af0b6134 100644
--- a/src/app.h
+++ b/src/app.h
@@ -6,6 +6,11 @@
6 6
7iDeclareType(Window) 7iDeclareType(Window)
8 8
9enum iAppEventMode {
10 waitForNewEvents_AppEventMode,
11 postedEventsOnly_AppEventMode,
12};
13
9enum iUserEventCode { 14enum iUserEventCode {
10 command_UserEventCode = 1, 15 command_UserEventCode = 1,
11 refresh_UserEventCode = 2, 16 refresh_UserEventCode = 2,
@@ -14,7 +19,7 @@ enum iUserEventCode {
14const iString *execPath_App (void); 19const iString *execPath_App (void);
15 20
16int run_App (int argc, char **argv); 21int run_App (int argc, char **argv);
17void processEvents_App (void); 22void processEvents_App (enum iAppEventMode mode);
18void refresh_App (void); 23void refresh_App (void);
19 24
20iAny * findWidget_App (const char *id); 25iAny * findWidget_App (const char *id);
diff --git a/src/ui/util.c b/src/ui/util.c
index 9487e004..8fc7f9e3 100644
--- a/src/ui/util.c
+++ b/src/ui/util.c
@@ -165,6 +165,7 @@ static iBool menuHandler_(iWidget *menu, const char *cmd) {
165 165
166iWidget *makeMenu_Widget(iWidget *parent, const iMenuItem *items, size_t n) { 166iWidget *makeMenu_Widget(iWidget *parent, const iMenuItem *items, size_t n) {
167 iWidget *menu = new_Widget(); 167 iWidget *menu = new_Widget();
168 setFrameColor_Widget(menu, black_ColorId);
168 setBackgroundColor_Widget(menu, gray25_ColorId); 169 setBackgroundColor_Widget(menu, gray25_ColorId);
169 setFlags_Widget(menu, 170 setFlags_Widget(menu,
170 keepOnTop_WidgetFlag | hidden_WidgetFlag | arrangeVertical_WidgetFlag | 171 keepOnTop_WidgetFlag | hidden_WidgetFlag | arrangeVertical_WidgetFlag |
@@ -194,7 +195,7 @@ iWidget *makeMenu_Widget(iWidget *parent, const iMenuItem *items, size_t n) {
194 195
195void openMenu_Widget(iWidget *d, iInt2 coord) { 196void openMenu_Widget(iWidget *d, iInt2 coord) {
196 /* Menu closes when commands are emitted, so handle any pending ones beforehand. */ 197 /* Menu closes when commands are emitted, so handle any pending ones beforehand. */
197 processEvents_App(); 198 processEvents_App(postedEventsOnly_AppEventMode);
198 setFlags_Widget(d, hidden_WidgetFlag, iFalse); 199 setFlags_Widget(d, hidden_WidgetFlag, iFalse);
199 arrange_Widget(d); 200 arrange_Widget(d);
200 d->rect.pos = coord; 201 d->rect.pos = coord;
@@ -213,10 +214,27 @@ void openMenu_Widget(iWidget *d, iInt2 coord) {
213 if (left_Rect(d->rect) < 0) { 214 if (left_Rect(d->rect) < 0) {
214 d->rect.pos.x = 0; 215 d->rect.pos.x = 0;
215 } 216 }
217 refresh_App();
216} 218}
217 219
218void closeMenu_Widget(iWidget *d) { 220void closeMenu_Widget(iWidget *d) {
219 setFlags_Widget(d, hidden_WidgetFlag, iTrue); 221 setFlags_Widget(d, hidden_WidgetFlag, iTrue);
222 refresh_App();
223}
224
225int checkContextMenu_Widget(iWidget *menu, const SDL_Event *ev) {
226 if (ev->type == SDL_MOUSEBUTTONDOWN && ev->button.button == SDL_BUTTON_RIGHT) {
227 if (isVisible_Widget(menu)) {
228 closeMenu_Widget(menu);
229 return 0x1;
230 }
231 const iInt2 mousePos = init_I2(ev->button.x, ev->button.y);
232 if (contains_Widget(menu->parent, mousePos)) {
233 openMenu_Widget(menu, localCoord_Widget(menu->parent, mousePos));
234 }
235 return 0x2;
236 }
237 return 0;
220} 238}
221 239
222iLabelWidget *makeMenuButton_LabelWidget(const char *label, const iMenuItem *items, size_t n) { 240iLabelWidget *makeMenuButton_LabelWidget(const char *label, const iMenuItem *items, size_t n) {
@@ -406,6 +424,7 @@ iBool filePathHandler_(iWidget *dlg, const char *cmd) {
406iWidget *makeSheet_Widget(const char *id) { 424iWidget *makeSheet_Widget(const char *id) {
407 iWidget *sheet = new_Widget(); 425 iWidget *sheet = new_Widget();
408 setId_Widget(sheet, id); 426 setId_Widget(sheet, id);
427 setFrameColor_Widget(sheet, black_ColorId);
409 setBackgroundColor_Widget(sheet, gray25_ColorId); 428 setBackgroundColor_Widget(sheet, gray25_ColorId);
410 setFlags_Widget(sheet, 429 setFlags_Widget(sheet,
411 keepOnTop_WidgetFlag | arrangeVertical_WidgetFlag | 430 keepOnTop_WidgetFlag | arrangeVertical_WidgetFlag |
@@ -429,7 +448,7 @@ void makeFilePath_Widget(iWidget * parent,
429 const char * acceptLabel, 448 const char * acceptLabel,
430 const char * command) { 449 const char * command) {
431 setFocus_Widget(NULL); 450 setFocus_Widget(NULL);
432 processEvents_App(); 451 processEvents_App(postedEventsOnly_AppEventMode);
433 iWidget *dlg = makeSheet_Widget(command); 452 iWidget *dlg = makeSheet_Widget(command);
434 setCommandHandler_Widget(dlg, filePathHandler_); 453 setCommandHandler_Widget(dlg, filePathHandler_);
435 addChild_Widget(parent, iClob(dlg)); 454 addChild_Widget(parent, iClob(dlg));
@@ -487,7 +506,7 @@ iBool valueInputHandler_(iWidget *dlg, const char *cmd) {
487iWidget *makeValueInput_Widget(iWidget *parent, const iString *initialValue, const char *title, 506iWidget *makeValueInput_Widget(iWidget *parent, const iString *initialValue, const char *title,
488 const char *prompt, const char *command) { 507 const char *prompt, const char *command) {
489 setFocus_Widget(NULL); 508 setFocus_Widget(NULL);
490 processEvents_App(); 509 processEvents_App(postedEventsOnly_AppEventMode);
491 iWidget *dlg = makeSheet_Widget(command); 510 iWidget *dlg = makeSheet_Widget(command);
492 setCommandHandler_Widget(dlg, valueInputHandler_); 511 setCommandHandler_Widget(dlg, valueInputHandler_);
493 addChild_Widget(parent, iClob(dlg)); 512 addChild_Widget(parent, iClob(dlg));
@@ -530,7 +549,7 @@ iWidget *makeQuestion_Widget(const char *title,
530 const char *labels[], 549 const char *labels[],
531 const char *commands[], 550 const char *commands[],
532 size_t count) { 551 size_t count) {
533 processEvents_App(); 552 processEvents_App(postedEventsOnly_AppEventMode);
534 iWidget *dlg = makeSheet_Widget(""); 553 iWidget *dlg = makeSheet_Widget("");
535 setCommandHandler_Widget(dlg, messageHandler_); 554 setCommandHandler_Widget(dlg, messageHandler_);
536 addChild_Widget(dlg, iClob(new_LabelWidget(title, 0, 0, NULL))); 555 addChild_Widget(dlg, iClob(new_LabelWidget(title, 0, 0, NULL)));
diff --git a/src/ui/util.h b/src/ui/util.h
index 04683a2f..3181ea3f 100644
--- a/src/ui/util.h
+++ b/src/ui/util.h
@@ -82,6 +82,14 @@ iWidget * makeMenu_Widget (iWidget *parent, const iMenuItem *items, size_t
82void openMenu_Widget (iWidget *, iInt2 coord); 82void openMenu_Widget (iWidget *, iInt2 coord);
83void closeMenu_Widget (iWidget *); 83void closeMenu_Widget (iWidget *);
84 84
85int checkContextMenu_Widget (iWidget *, const SDL_Event *ev); /* see macro below */
86
87#define processContextMenuEvent_Widget(menu, sdlEvent) \
88 for (const int result = checkContextMenu_Widget((menu), (sdlEvent));;) { \
89 if (result) return result >> 1; \
90 break; \
91 }
92
85iLabelWidget * makeMenuButton_LabelWidget (const char *label, const iMenuItem *items, size_t n); 93iLabelWidget * makeMenuButton_LabelWidget (const char *label, const iMenuItem *items, size_t n);
86 94
87/*-----------------------------------------------------------------------------------------------*/ 95/*-----------------------------------------------------------------------------------------------*/