summaryrefslogtreecommitdiff
path: root/src/ui
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/touch.c40
-rw-r--r--src/ui/util.c46
-rw-r--r--src/ui/widget.c8
-rw-r--r--src/ui/widget.h1
4 files changed, 66 insertions, 29 deletions
diff --git a/src/ui/touch.c b/src/ui/touch.c
index 14e5fe48..a55d370d 100644
--- a/src/ui/touch.c
+++ b/src/ui/touch.c
@@ -54,6 +54,7 @@ enum iTouchAxis {
54struct Impl_Touch { 54struct Impl_Touch {
55 SDL_FingerID id; 55 SDL_FingerID id;
56 iWidget *affinity; /* widget on which the touch started */ 56 iWidget *affinity; /* widget on which the touch started */
57 iWidget *edgeDragging;
57 iBool hasMoved; 58 iBool hasMoved;
58 iBool isTapAndHold; 59 iBool isTapAndHold;
59 enum iTouchEdge edge; 60 enum iTouchEdge edge;
@@ -277,6 +278,15 @@ static iWidget *findOverflowScrollable_Widget_(iWidget *d) {
277 return NULL; 278 return NULL;
278} 279}
279 280
281static iWidget *findSlidePanel_Widget_(iWidget *d) {
282 for (iWidget *w = d; w; w = parent_Widget(w)) {
283 if (isVisible_Widget(w) && flags_Widget(w) & horizontalOffset_WidgetFlag) {
284 return w;
285 }
286 }
287 return NULL;
288}
289
280iBool processEvent_Touch(const SDL_Event *ev) { 290iBool processEvent_Touch(const SDL_Event *ev) {
281 /* We only handle finger events here. */ 291 /* We only handle finger events here. */
282 if (ev->type != SDL_FINGERDOWN && ev->type != SDL_FINGERMOTION && ev->type != SDL_FINGERUP) { 292 if (ev->type != SDL_FINGERDOWN && ev->type != SDL_FINGERMOTION && ev->type != SDL_FINGERUP) {
@@ -297,6 +307,7 @@ iBool processEvent_Touch(const SDL_Event *ev) {
297 const float x = x_F3(pos); 307 const float x = x_F3(pos);
298 enum iTouchEdge edge = none_TouchEdge; 308 enum iTouchEdge edge = none_TouchEdge;
299 const int edgeWidth = 30 * window->pixelRatio; 309 const int edgeWidth = 30 * window->pixelRatio;
310 iWidget *dragging = NULL;
300 if (x < edgeWidth) { 311 if (x < edgeWidth) {
301 edge = left_TouchEdge; 312 edge = left_TouchEdge;
302 } 313 }
@@ -304,9 +315,18 @@ iBool processEvent_Touch(const SDL_Event *ev) {
304 edge = right_TouchEdge; 315 edge = right_TouchEdge;
305 } 316 }
306 iWidget *aff = hitChild_Widget(window->root, init_I2(iRound(x), iRound(y_F3(pos)))); 317 iWidget *aff = hitChild_Widget(window->root, init_I2(iRound(x), iRound(y_F3(pos))));
318 if (edge == left_TouchEdge) {
319 dragging = findSlidePanel_Widget_(aff);
320 if (dragging) {
321 setFlags_Widget(dragging, dragged_WidgetFlag, iTrue);
322 }
323 }
307 /* TODO: We must retain a reference to the affinity widget, or otherwise it might 324 /* TODO: We must retain a reference to the affinity widget, or otherwise it might
308 be destroyed during the gesture. */ 325 be destroyed during the gesture. */
309 printf("aff:%p (%s)\n", aff, aff ? class_Widget(aff)->name : "-"); 326 printf("aff:[%p] %s:'%s'\n", aff, aff ? class_Widget(aff)->name : "-",
327 cstr_String(id_Widget(aff)));
328 printf("drg:[%p] %s:'%s'\n", dragging, dragging ? class_Widget(dragging)->name : "-",
329 cstr_String(id_Widget(dragging)));
310 if (flags_Widget(aff) & touchDrag_WidgetFlag) { 330 if (flags_Widget(aff) & touchDrag_WidgetFlag) {
311 dispatchEvent_Widget(window->root, (SDL_Event *) &(SDL_MouseButtonEvent){ 331 dispatchEvent_Widget(window->root, (SDL_Event *) &(SDL_MouseButtonEvent){
312 .type = SDL_MOUSEBUTTONDOWN, 332 .type = SDL_MOUSEBUTTONDOWN,
@@ -323,6 +343,7 @@ iBool processEvent_Touch(const SDL_Event *ev) {
323 iTouch newTouch = { 343 iTouch newTouch = {
324 .id = fing->fingerId, 344 .id = fing->fingerId,
325 .affinity = aff, 345 .affinity = aff,
346 .edgeDragging = dragging,
326 .hasMoved = (flags_Widget(aff) & touchDrag_WidgetFlag) != 0, 347 .hasMoved = (flags_Widget(aff) & touchDrag_WidgetFlag) != 0,
327 .edge = edge, 348 .edge = edge,
328 .startTime = nowTime, 349 .startTime = nowTime,
@@ -390,8 +411,18 @@ iBool processEvent_Touch(const SDL_Event *ev) {
390 } 411 }
391 } 412 }
392 /* Edge swipe aborted? */ 413 /* Edge swipe aborted? */
393 if (touch->edge == left_TouchEdge && fing->dx < 0) { 414 if (touch->edge == left_TouchEdge) {
394 touch->edge = none_TouchEdge; 415 if (fing->dx < 0) {
416 touch->edge = none_TouchEdge;
417 if (touch->edgeDragging) {
418 setFlags_Widget(touch->edgeDragging, dragged_WidgetFlag, iFalse);
419 setVisualOffset_Widget(touch->edgeDragging, 0, 200, easeOut_AnimFlag);
420 touch->edgeDragging = NULL;
421 }
422 }
423 else if (touch->edgeDragging) {
424 setVisualOffset_Widget(touch->edgeDragging, x_F3(pos) - x_F3(touch->startPos), 10, 0);
425 }
395 } 426 }
396 if (touch->edge == right_TouchEdge && fing->dx > 0) { 427 if (touch->edge == right_TouchEdge && fing->dx > 0) {
397 touch->edge = none_TouchEdge; 428 touch->edge = none_TouchEdge;
@@ -430,6 +461,9 @@ iBool processEvent_Touch(const SDL_Event *ev) {
430 if (touch->id != fing->fingerId) { 461 if (touch->id != fing->fingerId) {
431 continue; 462 continue;
432 } 463 }
464 if (touch->edgeDragging) {
465 setFlags_Widget(touch->edgeDragging, dragged_WidgetFlag, iFalse);
466 }
433 if (touch->isTapAndHold) { 467 if (touch->isTapAndHold) {
434 if (!isStationary_Touch_(touch)) { 468 if (!isStationary_Touch_(touch)) {
435 dispatchClick_Touch_(touch, SDL_BUTTON_LEFT); 469 dispatchClick_Touch_(touch, SDL_BUTTON_LEFT);
diff --git a/src/ui/util.c b/src/ui/util.c
index 0d34658e..826a965c 100644
--- a/src/ui/util.c
+++ b/src/ui/util.c
@@ -607,11 +607,12 @@ void closeMenu_Widget(iWidget *d) {
607 postRefresh_App(); 607 postRefresh_App();
608 postCommand_Widget(d, "menu.closed"); 608 postCommand_Widget(d, "menu.closed");
609 if (isPortrait_App() && deviceType_App() == phone_AppDeviceType) { 609 if (isPortrait_App() && deviceType_App() == phone_AppDeviceType) {
610 const iBool wasDragged = iAbs(value_Anim(&d->visualOffset) - 0) > 1;
610 setVisualOffset_Widget(d, 611 setVisualOffset_Widget(d,
611 flags_Widget(d) & horizontalOffset_WidgetFlag ? 612 flags_Widget(d) & horizontalOffset_WidgetFlag ?
612 width_Widget(d) : height_Widget(d), 613 width_Widget(d) : height_Widget(d),
613 200, 614 wasDragged ? 100 : 200,
614 easeIn_AnimFlag | softer_AnimFlag); 615 wasDragged ? 0 : easeIn_AnimFlag | softer_AnimFlag);
615 } 616 }
616} 617}
617 618
@@ -904,7 +905,7 @@ static iBool slidePanelHandler_(iWidget *d, const char *cmd) {
904 iWidget *button = pointer_Command(cmd); 905 iWidget *button = pointer_Command(cmd);
905 iWidget *panel = userData_Object(button); 906 iWidget *panel = userData_Object(button);
906 openMenu_Widget(panel, zero_I2()); 907 openMenu_Widget(panel, zero_I2());
907 updateTextCStr_LabelWidget(findWidget_App("panel.back"), "Settings"); 908// updateTextCStr_LabelWidget(findWidget_App("panel.back"), "");
908 return iTrue; 909 return iTrue;
909 } 910 }
910 if (equal_Command(cmd, "mouse.clicked") && arg_Command(cmd) && 911 if (equal_Command(cmd, "mouse.clicked") && arg_Command(cmd) &&
@@ -912,25 +913,6 @@ static iBool slidePanelHandler_(iWidget *d, const char *cmd) {
912 postCommand_App("panel.close"); 913 postCommand_App("panel.close");
913 return iTrue; 914 return iTrue;
914 } 915 }
915 if (equal_Command(cmd, "window.resized")) {
916 iWidget *sheet = parent_Widget(d);
917#if defined (iPlatformAppleMobile)
918 float left, top, right, bottom;
919 safeAreaInsets_iOS(&left, &top, &right, &bottom);
920 /* TODO: incorrect */
921 if (isLandscape_App()) {
922 setPadding_Widget(sheet, left, 0, right, 0);
923 }
924 else {
925 setPadding1_Widget(sheet, 0);
926 }
927#endif
928 }
929 if (equal_Command(cmd, "panel.showhelp")) {
930 postCommand_App("prefs.dismiss");
931 postCommand_App("open url:about:help");
932 return iTrue;
933 }
934 if (equal_Command(cmd, "panel.close")) { 916 if (equal_Command(cmd, "panel.close")) {
935 iBool wasClosed = iFalse; 917 iBool wasClosed = iFalse;
936 iForEach(ObjectList, i, children_Widget(parent_Widget(d))) { 918 iForEach(ObjectList, i, children_Widget(parent_Widget(d))) {
@@ -947,7 +929,25 @@ static iBool slidePanelHandler_(iWidget *d, const char *cmd) {
947 } 929 }
948 return iTrue; 930 return iTrue;
949 } 931 }
950 return iFalse; 932 if (equal_Command(cmd, "panel.showhelp")) {
933 postCommand_App("prefs.dismiss");
934 postCommand_App("open url:about:help");
935 return iTrue;
936 }
937 if (equal_Command(cmd, "window.resized")) {
938 iWidget *sheet = parent_Widget(d);
939#if defined (iPlatformAppleMobile)
940 float left, top, right, bottom;
941 safeAreaInsets_iOS(&left, &top, &right, &bottom);
942 /* TODO: incorrect */
943 if (isLandscape_App()) {
944 setPadding_Widget(sheet, left, 0, right, 0);
945 }
946 else {
947 setPadding1_Widget(sheet, 0);
948 }
949#endif
950 } return iFalse;
951} 951}
952 952
953static iBool isTwoColumnPage_(iWidget *d) { 953static iBool isTwoColumnPage_(iWidget *d) {
diff --git a/src/ui/widget.c b/src/ui/widget.c
index 4dd545b5..c7a23c54 100644
--- a/src/ui/widget.c
+++ b/src/ui/widget.c
@@ -152,7 +152,7 @@ void setId_Widget(iWidget *d, const char *id) {
152} 152}
153 153
154const iString *id_Widget(const iWidget *d) { 154const iString *id_Widget(const iWidget *d) {
155 return &d->id; 155 return d ? &d->id : collectNew_String();
156} 156}
157 157
158int64_t flags_Widget(const iWidget *d) { 158int64_t flags_Widget(const iWidget *d) {
@@ -511,7 +511,7 @@ void arrange_Widget(iWidget *d) {
511} 511}
512 512
513static void applyVisualOffset_Widget_(const iWidget *d, iInt2 *pos) { 513static void applyVisualOffset_Widget_(const iWidget *d, iInt2 *pos) {
514 if (d->flags & visualOffset_WidgetFlag) { 514 if (d->flags & (visualOffset_WidgetFlag | dragged_WidgetFlag)) {
515 const int off = iRound(value_Anim(&d->visualOffset)); 515 const int off = iRound(value_Anim(&d->visualOffset));
516 if (d->flags & horizontalOffset_WidgetFlag) { 516 if (d->flags & horizontalOffset_WidgetFlag) {
517 pos->x += off; 517 pos->x += off;
@@ -544,7 +544,9 @@ iInt2 localCoord_Widget(const iWidget *d, iInt2 coord) {
544} 544}
545 545
546iBool contains_Widget(const iWidget *d, iInt2 coord) { 546iBool contains_Widget(const iWidget *d, iInt2 coord) {
547 const iRect bounds = { zero_I2(), d->rect.size }; 547 const iRect bounds = { zero_I2(), addY_I2(d->rect.size,
548 d->flags & drawBackgroundToBottom_WidgetFlag ?
549 rootSize_Window(get_Window()).y : 0) };
548 return contains_Rect(bounds, localCoord_Widget(d, coord)); 550 return contains_Rect(bounds, localCoord_Widget(d, coord));
549} 551}
550 552
diff --git a/src/ui/widget.h b/src/ui/widget.h
index 3edcb3f4..94a2d4a1 100644
--- a/src/ui/widget.h
+++ b/src/ui/widget.h
@@ -106,6 +106,7 @@ enum iWidgetFlag {
106#define horizontalOffset_WidgetFlag iBit64(51) /* default is vertical offset */ 106#define horizontalOffset_WidgetFlag iBit64(51) /* default is vertical offset */
107#define chevron_WidgetFlag iBit64(52) 107#define chevron_WidgetFlag iBit64(52)
108#define drawBackgroundToBottom_WidgetFlag iBit64(53) 108#define drawBackgroundToBottom_WidgetFlag iBit64(53)
109#define dragged_WidgetFlag iBit64(54)
109 110
110enum iWidgetAddPos { 111enum iWidgetAddPos {
111 back_WidgetAddPos, 112 back_WidgetAddPos,