summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/defs.h5
-rw-r--r--src/ui/inputwidget.c28
-rw-r--r--src/ui/util.c15
-rw-r--r--src/ui/util.h1
-rw-r--r--src/ui/widget.c9
-rw-r--r--src/ui/widget.h1
-rw-r--r--src/ui/window.c21
7 files changed, 70 insertions, 10 deletions
diff --git a/src/defs.h b/src/defs.h
index c54dc44c..530b6902 100644
--- a/src/defs.h
+++ b/src/defs.h
@@ -74,3 +74,8 @@ enum iFileVersion {
74#define rightAngle_Icon "\U0001fba5" 74#define rightAngle_Icon "\U0001fba5"
75#define planet_Icon "\U0001fa90" 75#define planet_Icon "\U0001fa90"
76#define info_Icon "\u2139" 76#define info_Icon "\u2139"
77#define leftHalf_Icon "\u25e7"
78#define rightHalf_Icon "\u25e8"
79#define scissor_Icon "\u2700"
80#define clipCopy_Icon "\u2398"
81#define clipboard_Icon "\U0001f4cb"
diff --git a/src/ui/inputwidget.c b/src/ui/inputwidget.c
index eac195b9..f4302887 100644
--- a/src/ui/inputwidget.c
+++ b/src/ui/inputwidget.c
@@ -314,9 +314,13 @@ void selectAll_InputWidget(iInputWidget *d) {
314 refresh_Widget(as_Widget(d)); 314 refresh_Widget(as_Widget(d));
315} 315}
316 316
317iLocalDef iBool isEditing_InputWidget_(const iInputWidget *d) {
318 return (flags_Widget(constAs_Widget(d)) & selected_WidgetFlag) != 0;
319}
320
317void begin_InputWidget(iInputWidget *d) { 321void begin_InputWidget(iInputWidget *d) {
318 iWidget *w = as_Widget(d); 322 iWidget *w = as_Widget(d);
319 if (flags_Widget(w) & selected_WidgetFlag) { 323 if (isEditing_InputWidget_(d)) {
320 /* Already active. */ 324 /* Already active. */
321 return; 325 return;
322 } 326 }
@@ -346,7 +350,7 @@ void begin_InputWidget(iInputWidget *d) {
346 350
347void end_InputWidget(iInputWidget *d, iBool accept) { 351void end_InputWidget(iInputWidget *d, iBool accept) {
348 iWidget *w = as_Widget(d); 352 iWidget *w = as_Widget(d);
349 if (~flags_Widget(w) & selected_WidgetFlag) { 353 if (!isEditing_InputWidget_(d)) {
350 /* Was not active. */ 354 /* Was not active. */
351 return; 355 return;
352 } 356 }
@@ -614,6 +618,15 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) {
614 end_InputWidget(d, iTrue); 618 end_InputWidget(d, iTrue);
615 return iFalse; 619 return iFalse;
616 } 620 }
621 else if ((isCommand_UserEvent(ev, "copy") || isCommand_UserEvent(ev, "input.copy")) &&
622 isEditing_InputWidget_(d)) {
623 copy_InputWidget_(d, argLabel_Command(command_UserEvent(ev), "cut"));
624 return iTrue;
625 }
626 else if (isCommand_UserEvent(ev, "input.paste") && isEditing_InputWidget_(d)) {
627 paste_InputWidget_(d);
628 return iTrue;
629 }
617 else if (isCommand_UserEvent(ev, "theme.changed")) { 630 else if (isCommand_UserEvent(ev, "theme.changed")) {
618 if (d->buffered) { 631 if (d->buffered) {
619 updateBuffered_InputWidget_(d); 632 updateBuffered_InputWidget_(d);
@@ -675,6 +688,17 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) {
675 case finished_ClickResult: 688 case finished_ClickResult:
676 return iTrue; 689 return iTrue;
677 } 690 }
691 if (ev->type == SDL_MOUSEBUTTONDOWN && ev->button.button == SDL_BUTTON_RIGHT &&
692 contains_Widget(w, init_I2(ev->button.x, ev->button.y))) {
693 iWidget *clipMenu = findWidget_App("clipmenu");
694 if (isVisible_Widget(clipMenu)) {
695 closeMenu_Widget(clipMenu);
696 }
697 else {
698 openMenuFlags_Widget(clipMenu, mouseCoord_Window(get_Window()), iFalse);
699 }
700 return iTrue;
701 }
678 if (ev->type == SDL_KEYUP && isFocused_Widget(w)) { 702 if (ev->type == SDL_KEYUP && isFocused_Widget(w)) {
679 return iTrue; 703 return iTrue;
680 } 704 }
diff --git a/src/ui/util.c b/src/ui/util.c
index 04dbe190..adb3c4b4 100644
--- a/src/ui/util.c
+++ b/src/ui/util.c
@@ -517,14 +517,21 @@ iWidget *makeMenu_Widget(iWidget *parent, const iMenuItem *items, size_t n) {
517} 517}
518 518
519void openMenu_Widget(iWidget *d, iInt2 coord) { 519void openMenu_Widget(iWidget *d, iInt2 coord) {
520 openMenuFlags_Widget(d, coord, iTrue);
521}
522
523void openMenuFlags_Widget(iWidget *d, iInt2 coord, iBool postCommands) {
520 const iInt2 rootSize = rootSize_Window(get_Window()); 524 const iInt2 rootSize = rootSize_Window(get_Window());
521 const iBool isPortraitPhone = (deviceType_App() == phone_AppDeviceType && isPortrait_App()); 525 const iBool isPortraitPhone = (deviceType_App() == phone_AppDeviceType && isPortrait_App());
522 const iBool isSlidePanel = (flags_Widget(d) & horizontalOffset_WidgetFlag) != 0; 526 const iBool isSlidePanel = (flags_Widget(d) & horizontalOffset_WidgetFlag) != 0;
527 if (postCommands) {
528 postCommand_App("cancel"); /* dismiss any other menus */
529 }
523 /* Menu closes when commands are emitted, so handle any pending ones beforehand. */ 530 /* Menu closes when commands are emitted, so handle any pending ones beforehand. */
524 postCommand_App("cancel"); /* dismiss any other menus */
525 processEvents_App(postedEventsOnly_AppEventMode); 531 processEvents_App(postedEventsOnly_AppEventMode);
526 setFlags_Widget(d, hidden_WidgetFlag | disabled_WidgetFlag, iFalse); 532 setFlags_Widget(d, hidden_WidgetFlag | disabled_WidgetFlag, iFalse);
527 setFlags_Widget(d, commandOnMouseMiss_WidgetFlag, iTrue); 533 setFlags_Widget(d, commandOnMouseMiss_WidgetFlag, iTrue);
534 raise_Widget(d);
528 setFlags_Widget(findChild_Widget(d, "menu.cancel"), disabled_WidgetFlag, iFalse); 535 setFlags_Widget(findChild_Widget(d, "menu.cancel"), disabled_WidgetFlag, iFalse);
529 if (isPortraitPhone) { 536 if (isPortraitPhone) {
530 setFlags_Widget(d, arrangeWidth_WidgetFlag | resizeChildrenToWidestChild_WidgetFlag, iFalse); 537 setFlags_Widget(d, arrangeWidth_WidgetFlag | resizeChildrenToWidestChild_WidgetFlag, iFalse);
@@ -576,7 +583,7 @@ void openMenu_Widget(iWidget *d, iInt2 coord) {
576 float l, t, r, b; 583 float l, t, r, b;
577 safeAreaInsets_iOS(&l, &t, &r, &b); 584 safeAreaInsets_iOS(&l, &t, &r, &b);
578 topExcess += t; 585 topExcess += t;
579 bottomExcess += b; 586 bottomExcess += iMax(b, get_Window()->keyboardHeight);
580 leftExcess += l; 587 leftExcess += l;
581 rightExcess += r; 588 rightExcess += r;
582 } 589 }
@@ -594,7 +601,9 @@ void openMenu_Widget(iWidget *d, iInt2 coord) {
594 d->rect.pos.x += leftExcess; 601 d->rect.pos.x += leftExcess;
595 } 602 }
596 postRefresh_App(); 603 postRefresh_App();
597 postCommand_Widget(d, "menu.opened"); 604 if (postCommands) {
605 postCommand_Widget(d, "menu.opened");
606 }
598 if (isPortraitPhone) { 607 if (isPortraitPhone) {
599 setVisualOffset_Widget(d, isSlidePanel ? width_Widget(d) : height_Widget(d), 0, 0); 608 setVisualOffset_Widget(d, isSlidePanel ? width_Widget(d) : height_Widget(d), 0, 0);
600 setVisualOffset_Widget(d, 0, 330, easeOut_AnimFlag | softer_AnimFlag); 609 setVisualOffset_Widget(d, 0, 330, easeOut_AnimFlag | softer_AnimFlag);
diff --git a/src/ui/util.h b/src/ui/util.h
index 7a66ebb3..e2461b9d 100644
--- a/src/ui/util.h
+++ b/src/ui/util.h
@@ -172,6 +172,7 @@ struct Impl_MenuItem {
172 172
173iWidget * makeMenu_Widget (iWidget *parent, const iMenuItem *items, size_t n); /* returns no ref */ 173iWidget * makeMenu_Widget (iWidget *parent, const iMenuItem *items, size_t n); /* returns no ref */
174void openMenu_Widget (iWidget *, iInt2 coord); 174void openMenu_Widget (iWidget *, iInt2 coord);
175void openMenuFlags_Widget(iWidget *d, iInt2 coord, iBool postCommands);
175void closeMenu_Widget (iWidget *); 176void closeMenu_Widget (iWidget *);
176 177
177iLabelWidget * findMenuItem_Widget (iWidget *menu, const char *command); 178iLabelWidget * findMenuItem_Widget (iWidget *menu, const char *command);
diff --git a/src/ui/widget.c b/src/ui/widget.c
index 4d319808..4fad3c86 100644
--- a/src/ui/widget.c
+++ b/src/ui/widget.c
@@ -1207,6 +1207,15 @@ static void printTree_Widget_(const iWidget *d, int indent) {
1207 } 1207 }
1208} 1208}
1209 1209
1210void raise_Widget(iWidget *d) {
1211 iPtrArray *onTop = onTop_RootData_();
1212 if (d->flags & keepOnTop_WidgetFlag) {
1213 iAssert(indexOf_PtrArray(onTop, d) != iInvalidPos);
1214 removeOne_PtrArray(onTop, d);
1215 pushBack_PtrArray(onTop, d);
1216 }
1217}
1218
1210iBool hasVisibleChildOnTop_Widget(const iWidget *parent) { 1219iBool hasVisibleChildOnTop_Widget(const iWidget *parent) {
1211 iConstForEach(ObjectList, i, parent->children) { 1220 iConstForEach(ObjectList, i, parent->children) {
1212 const iWidget *child = i.object; 1221 const iWidget *child = i.object;
diff --git a/src/ui/widget.h b/src/ui/widget.h
index 37c8efdc..a00bb3b7 100644
--- a/src/ui/widget.h
+++ b/src/ui/widget.h
@@ -243,6 +243,7 @@ iWidget * hover_Widget (void);
243void unhover_Widget (void); 243void unhover_Widget (void);
244void setMouseGrab_Widget (iWidget *); 244void setMouseGrab_Widget (iWidget *);
245iWidget * mouseGrab_Widget (void); 245iWidget * mouseGrab_Widget (void);
246void raise_Widget (iWidget *);
246iBool hasVisibleChildOnTop_Widget 247iBool hasVisibleChildOnTop_Widget
247 (const iWidget *parent); 248 (const iWidget *parent);
248void printTree_Widget (const iWidget *); 249void printTree_Widget (const iWidget *);
diff --git a/src/ui/window.c b/src/ui/window.c
index 16f217a3..5b65f173 100644
--- a/src/ui/window.c
+++ b/src/ui/window.c
@@ -262,7 +262,10 @@ static const iMenuItem fileMenuItems_[] = {
262}; 262};
263 263
264static const iMenuItem editMenuItems_[] = { 264static const iMenuItem editMenuItems_[] = {
265 { "Cut", SDLK_x, KMOD_PRIMARY, "input.copy cut:1" },
265 { "Copy", SDLK_c, KMOD_PRIMARY, "copy" }, 266 { "Copy", SDLK_c, KMOD_PRIMARY, "copy" },
267 { "Paste", SDLK_v, KMOD_PRIMARY, "input.paste" },
268 { "---", 0, 0, NULL },
266 { "Copy Link to Page", SDLK_c, KMOD_PRIMARY | KMOD_SHIFT, "document.copylink" }, 269 { "Copy Link to Page", SDLK_c, KMOD_PRIMARY | KMOD_SHIFT, "document.copylink" },
267 { "---", 0, 0, NULL }, 270 { "---", 0, 0, NULL },
268 { "Find", SDLK_f, KMOD_PRIMARY, "focus.set id:find.input" }, 271 { "Find", SDLK_f, KMOD_PRIMARY, "focus.set id:find.input" },
@@ -581,7 +584,6 @@ static iBool handleNavBarCommands_(iWidget *navBar, const char *cmd) {
581 iWidget *urlBar = findChild_Widget(navBar, "url"); 584 iWidget *urlBar = findChild_Widget(navBar, "url");
582 urlBar->rect.size.x = iMini(navBarAvailableSpace_(navBar), 167 * gap_UI); 585 urlBar->rect.size.x = iMini(navBarAvailableSpace_(navBar), 167 * gap_UI);
583 arrange_Widget(navBar); 586 arrange_Widget(navBar);
584 printTree_Widget(urlBar);
585 } 587 }
586 refresh_Widget(navBar); 588 refresh_Widget(navBar);
587 postCommand_Widget(navBar, "layout.changed id:navbar"); 589 postCommand_Widget(navBar, "layout.changed id:navbar");
@@ -1134,7 +1136,7 @@ static void setupUserInterface_Window(iWindow *d) {
1134 } 1136 }
1135#endif 1137#endif
1136 updatePadding_Window_(d); 1138 updatePadding_Window_(d);
1137 /* Context menus. */ { 1139 /* Global context menus. */ {
1138 iWidget *tabsMenu = makeMenu_Widget(d->root, 1140 iWidget *tabsMenu = makeMenu_Widget(d->root,
1139 (iMenuItem[]){ 1141 (iMenuItem[]){
1140 { close_Icon " Close Tab", 0, 0, "tabs.close" }, 1142 { close_Icon " Close Tab", 0, 0, "tabs.close" },
@@ -1145,13 +1147,22 @@ static void setupUserInterface_Window(iWindow *d) {
1145 { barRightArrow_Icon " Close Tabs To Right", 0, 0, "tabs.close toright:1" }, 1147 { barRightArrow_Icon " Close Tabs To Right", 0, 0, "tabs.close toright:1" },
1146 }, 1148 },
1147 6); 1149 6);
1148 setId_Widget(tabsMenu, "doctabs.menu");
1149 iWidget *barMenu = makeMenu_Widget(d->root, 1150 iWidget *barMenu = makeMenu_Widget(d->root,
1150 (iMenuItem[]) { 1151 (iMenuItem[]) {
1151 { "Toggle Left Sidebar", 0, 0, "sidebar.toggle" }, 1152 { leftHalf_Icon " Toggle Left Sidebar", 0, 0, "sidebar.toggle" },
1152 { "Toggle Right Sidebar", 0, 0, "sidebar2.toggle" }, 1153 { rightHalf_Icon " Toggle Right Sidebar", 0, 0, "sidebar2.toggle" },
1153 }, 2); 1154 }, 2);
1155 iWidget *clipMenu = makeMenu_Widget(d->root,
1156 (iMenuItem[]){
1157 { scissor_Icon " Cut", 0, 0, "input.copy cut:1" },
1158 { clipCopy_Icon " Copy", 0, 0, "input.copy" },
1159 { "---", 0, 0, NULL },
1160 { clipboard_Icon " Paste", 0, 0, "input.paste" },
1161 },
1162 4);
1163 setId_Widget(tabsMenu, "doctabs.menu");
1154 setId_Widget(barMenu, "barmenu"); 1164 setId_Widget(barMenu, "barmenu");
1165 setId_Widget(clipMenu, "clipmenu");
1155 } 1166 }
1156 /* Global keyboard shortcuts. */ { 1167 /* Global keyboard shortcuts. */ {
1157 addAction_Widget(d->root, 'l', KMOD_PRIMARY, "navigate.focus"); 1168 addAction_Widget(d->root, 'l', KMOD_PRIMARY, "navigate.focus");