summaryrefslogtreecommitdiff
path: root/src/ui/sidebarwidget.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/sidebarwidget.c')
-rw-r--r--src/ui/sidebarwidget.c271
1 files changed, 215 insertions, 56 deletions
diff --git a/src/ui/sidebarwidget.c b/src/ui/sidebarwidget.c
index 13fc33b1..401c5d25 100644
--- a/src/ui/sidebarwidget.c
+++ b/src/ui/sidebarwidget.c
@@ -39,6 +39,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
39#include "paint.h" 39#include "paint.h"
40#include "root.h" 40#include "root.h"
41#include "scrollwidget.h" 41#include "scrollwidget.h"
42#include "touch.h"
42#include "util.h" 43#include "util.h"
43#include "visited.h" 44#include "visited.h"
44 45
@@ -99,13 +100,15 @@ struct Impl_SidebarWidget {
99 iListWidget * list; 100 iListWidget * list;
100 iCertListWidget * certList; 101 iCertListWidget * certList;
101 iWidget * actions; /* below the list, area for buttons */ 102 iWidget * actions; /* below the list, area for buttons */
103 int midHeight; /* on portrait phone, the height for the middle state */
104 iBool isBeingDraggedVertically; /* on portrait phone, sidebar can be dragged up/down */
102 int modeScroll[max_SidebarMode]; 105 int modeScroll[max_SidebarMode];
103 iLabelWidget * modeButtons[max_SidebarMode]; 106 iLabelWidget * modeButtons[max_SidebarMode];
104 int maxButtonLabelWidth; 107 int maxButtonLabelWidth;
105 float widthAsGaps; 108 float widthAsGaps;
106 int buttonFont; 109 int buttonFont;
107 int itemFonts[2]; 110 int itemFonts[2];
108 size_t numUnreadEntries; 111 size_t numUnreadEntries;
109 iWidget * resizer; 112 iWidget * resizer;
110 iWidget * menu; /* context menu for an item */ 113 iWidget * menu; /* context menu for an item */
111 iWidget * modeMenu; /* context menu for the sidebar mode (no item) */ 114 iWidget * modeMenu; /* context menu for the sidebar mode (no item) */
@@ -194,9 +197,9 @@ static iLabelWidget *addActionButton_SidebarWidget_(iSidebarWidget *d, const cha
194 //(deviceType_App() != desktop_AppDeviceType ? 197 //(deviceType_App() != desktop_AppDeviceType ?
195 // extraPadding_WidgetFlag : 0) | 198 // extraPadding_WidgetFlag : 0) |
196 flags); 199 flags);
197 setFont_LabelWidget(btn, deviceType_App() == phone_AppDeviceType && d->side == right_SidebarSide 200 setFont_LabelWidget(btn, /*deviceType_App() == phone_AppDeviceType && d->side == right_SidebarSide
198 ? uiLabelBig_FontId 201 ? uiLabelBig_FontId : */
199 : d->buttonFont); 202 d->buttonFont);
200 checkIcon_LabelWidget(btn); 203 checkIcon_LabelWidget(btn);
201 return btn; 204 return btn;
202} 205}
@@ -211,7 +214,12 @@ static iBool isBookmarkFolded_SidebarWidget_(const iSidebarWidget *d, const iBoo
211 return iFalse; 214 return iFalse;
212} 215}
213 216
217static iBool isSlidingSheet_SidebarWidget_(const iSidebarWidget *d) {
218 return isPortraitPhone_App();// && scrollPos_ListWidget(d->list) <= 0;
219}
220
214static void updateItemsWithFlags_SidebarWidget_(iSidebarWidget *d, iBool keepActions) { 221static void updateItemsWithFlags_SidebarWidget_(iSidebarWidget *d, iBool keepActions) {
222 const iBool isMobile = (deviceType_App() != desktop_AppDeviceType);
215 clear_ListWidget(d->list); 223 clear_ListWidget(d->list);
216 releaseChildren_Widget(d->blank); 224 releaseChildren_Widget(d->blank);
217 if (!keepActions) { 225 if (!keepActions) {
@@ -299,9 +307,10 @@ static void updateItemsWithFlags_SidebarWidget_(iSidebarWidget *d, iBool keepAct
299 } 307 }
300 /* Actions. */ 308 /* Actions. */
301 if (!keepActions) { 309 if (!keepActions) {
302 addActionButton_SidebarWidget_( 310 addActionButton_SidebarWidget_(d,
303 d, check_Icon " ${sidebar.action.feeds.markallread}", "feeds.markallread", expand_WidgetFlag | 311 check_Icon " ${sidebar.action.feeds.markallread}",
304 tight_WidgetFlag); 312 "feeds.markallread",
313 expand_WidgetFlag | tight_WidgetFlag);
305 updateSize_LabelWidget(addChildFlags_Widget(d->actions, 314 updateSize_LabelWidget(addChildFlags_Widget(d->actions,
306 iClob(new_LabelWidget("${sidebar.action.show}", NULL)), 315 iClob(new_LabelWidget("${sidebar.action.show}", NULL)),
307 frameless_WidgetFlag | tight_WidgetFlag)); 316 frameless_WidgetFlag | tight_WidgetFlag));
@@ -617,6 +626,10 @@ void setClosedFolders_SidebarWidget(iSidebarWidget *d, const iIntSet *closedFold
617 } 626 }
618} 627}
619 628
629void setMidHeight_SidebarWidget(iSidebarWidget *d, int midHeight) {
630 d->midHeight = midHeight;
631}
632
620enum iSidebarMode mode_SidebarWidget(const iSidebarWidget *d) { 633enum iSidebarMode mode_SidebarWidget(const iSidebarWidget *d) {
621 return d ? d->mode : 0; 634 return d ? d->mode : 0;
622} 635}
@@ -686,6 +699,8 @@ void init_SidebarWidget(iSidebarWidget *d, enum iSidebarSide side) {
686 d->side = side; 699 d->side = side;
687 d->mode = -1; 700 d->mode = -1;
688 d->feedsMode = all_FeedsMode; 701 d->feedsMode = all_FeedsMode;
702 d->midHeight = 0;
703 d->isBeingDraggedVertically = iFalse;
689 d->numUnreadEntries = 0; 704 d->numUnreadEntries = 0;
690 d->buttonFont = uiLabel_FontId; /* wiil be changed later */ 705 d->buttonFont = uiLabel_FontId; /* wiil be changed later */
691 d->itemFonts[0] = uiContent_FontId; 706 d->itemFonts[0] = uiContent_FontId;
@@ -703,15 +718,24 @@ void init_SidebarWidget(iSidebarWidget *d, enum iSidebarSide side) {
703 iWidget *vdiv = makeVDiv_Widget(); 718 iWidget *vdiv = makeVDiv_Widget();
704 addChildFlags_Widget(w, vdiv, resizeToParentWidth_WidgetFlag | resizeToParentHeight_WidgetFlag); 719 addChildFlags_Widget(w, vdiv, resizeToParentWidth_WidgetFlag | resizeToParentHeight_WidgetFlag);
705 iZap(d->modeButtons); 720 iZap(d->modeButtons);
706 d->resizer = NULL; 721 d->resizer = NULL;
707 d->list = NULL; 722 d->list = NULL;
708 d->certList = NULL; 723 d->certList = NULL;
709 d->actions = NULL; 724 d->actions = NULL;
710 d->closedFolders = new_IntSet(); 725 d->closedFolders = new_IntSet();
711 /* On a phone, the right sidebar is not used. */ 726 /* On a phone, the right sidebar is not used. */
712 const iBool isPhone = deviceType_App() == phone_AppDeviceType; 727 const iBool isPhone = (deviceType_App() == phone_AppDeviceType);
713 //if (!isPhone || d->side == left_SidebarSide) { 728 if (isPhone) {
714 iWidget *buttons = new_Widget(); 729 iLabelWidget *closeButton =
730 addChildFlags_Widget(vdiv,
731 iClob(new_LabelWidget("${sidebar.close}", "sidebar.toggle")),
732 collapse_WidgetFlag | alignRight_WidgetFlag |
733 extraPadding_WidgetFlag | frameless_WidgetFlag);
734 as_Widget(closeButton)->flags2 |= slidingSheetDraggable_WidgetFlag2; /* phone */
735 setId_Widget(as_Widget(closeButton), "sidebar.close");
736 setFont_LabelWidget(closeButton, uiLabelBigBold_FontId);
737 }
738 iWidget *buttons = new_Widget();
715 setId_Widget(buttons, "buttons"); 739 setId_Widget(buttons, "buttons");
716 setDrawBufferEnabled_Widget(buttons, iTrue); 740 setDrawBufferEnabled_Widget(buttons, iTrue);
717 for (int i = 0; i < max_SidebarMode; i++) { 741 for (int i = 0; i < max_SidebarMode; i++) {
@@ -725,28 +749,14 @@ void init_SidebarWidget(iSidebarWidget *d, enum iSidebarSide side) {
725 tightModeLabels_[i], 749 tightModeLabels_[i],
726 format_CStr("%s.mode arg:%d", cstr_String(id_Widget(w)), i))), 750 format_CStr("%s.mode arg:%d", cstr_String(id_Widget(w)), i))),
727 frameless_WidgetFlag | noBackground_WidgetFlag); 751 frameless_WidgetFlag | noBackground_WidgetFlag);
752 as_Widget(d->modeButtons[i])->flags2 |= slidingSheetDraggable_WidgetFlag2; /* phone */
728 } 753 }
729 setButtonFont_SidebarWidget(d, isPhone ? uiLabelBig_FontId : uiLabel_FontId); 754 setButtonFont_SidebarWidget(d, isPhone ? uiLabelBig_FontId : uiLabel_FontId);
730 addChildFlags_Widget(vdiv, 755 addChildFlags_Widget(vdiv,
731 iClob(buttons), 756 iClob(buttons),
732 arrangeHorizontal_WidgetFlag | 757 arrangeHorizontal_WidgetFlag | resizeWidthOfChildren_WidgetFlag |
733 resizeWidthOfChildren_WidgetFlag | 758 arrangeHeight_WidgetFlag | resizeToParentWidth_WidgetFlag);
734 arrangeHeight_WidgetFlag | resizeToParentWidth_WidgetFlag); // |
735// drawBackgroundToHorizontalSafeArea_WidgetFlag);
736 setBackgroundColor_Widget(buttons, uiBackgroundSidebar_ColorId); 759 setBackgroundColor_Widget(buttons, uiBackgroundSidebar_ColorId);
737// }
738#if 0
739 else {
740 iLabelWidget *heading = new_LabelWidget(person_Icon " ${sidebar.identities}", NULL);
741 checkIcon_LabelWidget(heading);
742 setBackgroundColor_Widget(as_Widget(heading), uiBackgroundSidebar_ColorId);
743 setTextColor_LabelWidget(heading, uiTextSelected_ColorId);
744 setFont_LabelWidget(addChildFlags_Widget(vdiv, iClob(heading), borderTop_WidgetFlag |
745 alignLeft_WidgetFlag | frameless_WidgetFlag |
746 drawBackgroundToHorizontalSafeArea_WidgetFlag),
747 uiLabelLargeBold_FontId);
748 }
749#endif
750 iWidget *content = new_Widget(); 760 iWidget *content = new_Widget();
751 setFlags_Widget(content, resizeChildren_WidgetFlag, iTrue); 761 setFlags_Widget(content, resizeChildren_WidgetFlag, iTrue);
752 iWidget *listAndActions = makeVDiv_Widget(); 762 iWidget *listAndActions = makeVDiv_Widget();
@@ -756,15 +766,17 @@ void init_SidebarWidget(iSidebarWidget *d, enum iSidebarSide side) {
756 d->list = new_ListWidget(); 766 d->list = new_ListWidget();
757 setPadding_Widget(as_Widget(d->list), 0, gap_UI, 0, gap_UI); 767 setPadding_Widget(as_Widget(d->list), 0, gap_UI, 0, gap_UI);
758 addChild_Widget(listArea, iClob(d->list)); 768 addChild_Widget(listArea, iClob(d->list));
759 d->certList = new_CertListWidget(); 769 if (!isPhone) {
760 setPadding_Widget(as_Widget(d->certList), 0, gap_UI, 0, gap_UI); 770 d->certList = new_CertListWidget();
761 addChild_Widget(listArea, iClob(d->certList)); 771 setPadding_Widget(as_Widget(d->certList), 0, gap_UI, 0, gap_UI);
772 addChild_Widget(listArea, iClob(d->certList));
773 }
762 addChildFlags_Widget(listAndActions, 774 addChildFlags_Widget(listAndActions,
763 iClob(listArea), 775 iClob(listArea),
764 expand_WidgetFlag); // | drawBackgroundToHorizontalSafeArea_WidgetFlag); 776 expand_WidgetFlag); // | drawBackgroundToHorizontalSafeArea_WidgetFlag);
765 setId_Widget(addChildPosFlags_Widget(listAndActions, 777 setId_Widget(addChildPosFlags_Widget(listAndActions,
766 iClob(d->actions = new_Widget()), 778 iClob(d->actions = new_Widget()),
767 isPhone ? front_WidgetAddPos : back_WidgetAddPos, 779 /*isPhone ? front_WidgetAddPos :*/ back_WidgetAddPos,
768 arrangeHorizontal_WidgetFlag | arrangeHeight_WidgetFlag | 780 arrangeHorizontal_WidgetFlag | arrangeHeight_WidgetFlag |
769 resizeWidthOfChildren_WidgetFlag), // | 781 resizeWidthOfChildren_WidgetFlag), // |
770// drawBackgroundToHorizontalSafeArea_WidgetFlag), 782// drawBackgroundToHorizontalSafeArea_WidgetFlag),
@@ -891,7 +903,7 @@ static void checkModeButtonLayout_SidebarWidget_(iSidebarWidget *d) {
891// updateMetrics_SidebarWidget_(d); 903// updateMetrics_SidebarWidget_(d);
892 updateItemHeight_SidebarWidget_(d); 904 updateItemHeight_SidebarWidget_(d);
893 } 905 }
894 setButtonFont_SidebarWidget(d, isPortrait_App() ? uiLabelBig_FontId : uiLabel_FontId); 906 setButtonFont_SidebarWidget(d, isPortrait_App() ? uiLabelMedium_FontId : uiLabel_FontId);
895 } 907 }
896 const iBool isTight = 908 const iBool isTight =
897 (width_Rect(bounds_Widget(as_Widget(d->modeButtons[0]))) < d->maxButtonLabelWidth); 909 (width_Rect(bounds_Widget(as_Widget(d->modeButtons[0]))) < d->maxButtonLabelWidth);
@@ -982,6 +994,52 @@ iBool handleBookmarkEditorCommands_SidebarWidget_(iWidget *editor, const char *c
982 return iFalse; 994 return iFalse;
983} 995}
984 996
997static void animateSlidingSheetHeight_SidebarWidget_(iAny *sidebar) {
998 iWidget *d = sidebar;
999 const int oldSize = d->rect.size.y;
1000 const int newSize = bottom_Rect(safeRect_Root(d->root)) - top_Rect(bounds_Widget(d));
1001 if (oldSize != newSize) {
1002 d->rect.size.y = newSize;
1003 arrange_Widget(d);
1004 }
1005// printf("[%p] %u: %d animating %d\n", d, window_Widget(d)->frameTime,
1006// (flags_Widget(sidebar) & visualOffset_WidgetFlag) != 0,
1007// newSize);
1008 if (!isFinished_Anim(&d->visualOffset)) {
1009 addTicker_App(animateSlidingSheetHeight_SidebarWidget_, sidebar);
1010 }
1011}
1012
1013enum iSlidingSheetPos {
1014 top_SlidingSheetPos,
1015 middle_SlidingSheetPos,
1016 bottom_SlidingSheetPos,
1017};
1018
1019static void setSlidingSheetPos_SidebarWidget_(iSidebarWidget *d, enum iSlidingSheetPos slide) {
1020 iWidget *w = as_Widget(d);
1021 const int pos = w->rect.pos.y;
1022 const iRect safeRect = safeRect_Root(w->root);
1023 if (slide == top_SlidingSheetPos) {
1024 w->rect.pos.y = top_Rect(safeRect);
1025 w->rect.size.y = height_Rect(safeRect);
1026 setVisualOffset_Widget(w, pos - w->rect.pos.y, 0, 0);
1027 setVisualOffset_Widget(w, 0, 200, easeOut_AnimFlag | softer_AnimFlag);
1028 setScrollMode_ListWidget(d->list, disabledAtTopUpwards_ScrollMode);
1029 }
1030 else if (slide == bottom_SlidingSheetPos) {
1031 postCommand_Widget(w, "sidebar.toggle");
1032 }
1033 else {
1034 w->rect.size.y = d->midHeight;
1035 w->rect.pos.y = height_Rect(safeRect) - w->rect.size.y;
1036 setVisualOffset_Widget(w, pos - w->rect.pos.y, 0, 0);
1037 setVisualOffset_Widget(w, 0, 200, easeOut_AnimFlag | softer_AnimFlag);
1038 setScrollMode_ListWidget(d->list, disabledAtTopBothDirections_ScrollMode);
1039 }
1040 animateSlidingSheetHeight_SidebarWidget_(d);
1041}
1042
985static iBool handleSidebarCommand_SidebarWidget_(iSidebarWidget *d, const char *cmd) { 1043static iBool handleSidebarCommand_SidebarWidget_(iSidebarWidget *d, const char *cmd) {
986 iWidget *w = as_Widget(d); 1044 iWidget *w = as_Widget(d);
987 if (equal_Command(cmd, "width")) { 1045 if (equal_Command(cmd, "width")) {
@@ -1011,35 +1069,58 @@ static iBool handleSidebarCommand_SidebarWidget_(iSidebarWidget *d, const char *
1011 argLabel_Command(cmd, "noanim") == 0 && 1069 argLabel_Command(cmd, "noanim") == 0 &&
1012 (d->side == left_SidebarSide || deviceType_App() != phone_AppDeviceType); 1070 (d->side == left_SidebarSide || deviceType_App() != phone_AppDeviceType);
1013 int visX = 0; 1071 int visX = 0;
1072 int visY = 0;
1014 if (isVisible_Widget(w)) { 1073 if (isVisible_Widget(w)) {
1015 visX = left_Rect(bounds_Widget(w)) - left_Rect(w->root->widget->rect); 1074 visX = left_Rect(bounds_Widget(w)) - left_Rect(w->root->widget->rect);
1075 visY = top_Rect(bounds_Widget(w)) - top_Rect(w->root->widget->rect);
1016 } 1076 }
1017 setFlags_Widget(w, hidden_WidgetFlag, isVisible_Widget(w)); 1077 const iBool isHiding = isVisible_Widget(w);
1078 setFlags_Widget(w, hidden_WidgetFlag, isHiding);
1018 /* Safe area inset for mobile. */ 1079 /* Safe area inset for mobile. */
1019 const int safePad = (d->side == left_SidebarSide ? left_Rect(safeRect_Root(w->root)) : 0); 1080 const int safePad = (d->side == left_SidebarSide ? left_Rect(safeRect_Root(w->root)) : 0);
1020 if (isVisible_Widget(w)) { 1081 const int animFlags = easeOut_AnimFlag | softer_AnimFlag;
1021 setFlags_Widget(w, keepOnTop_WidgetFlag, iFalse); 1082 if (!isPortraitPhone_App()) {
1022 w->rect.size.x = d->widthAsGaps * gap_UI; 1083 if (!isHiding) {
1023 invalidate_ListWidget(d->list); 1084 setFlags_Widget(w, keepOnTop_WidgetFlag, iFalse);
1024 if (isAnimated) { 1085 w->rect.size.x = d->widthAsGaps * gap_UI;
1086 invalidate_ListWidget(d->list);
1087 if (isAnimated) {
1088 setFlags_Widget(w, horizontalOffset_WidgetFlag, iTrue);
1089 setVisualOffset_Widget(
1090 w, (d->side == left_SidebarSide ? -1 : 1) * (w->rect.size.x + safePad), 0, 0);
1091 setVisualOffset_Widget(w, 0, 300, animFlags);
1092 }
1093 }
1094 else if (isAnimated) {
1025 setFlags_Widget(w, horizontalOffset_WidgetFlag, iTrue); 1095 setFlags_Widget(w, horizontalOffset_WidgetFlag, iTrue);
1026 setVisualOffset_Widget( 1096 if (d->side == right_SidebarSide) {
1027 w, (d->side == left_SidebarSide ? -1 : 1) * (w->rect.size.x + safePad), 0, 0); 1097 setVisualOffset_Widget(w, visX, 0, 0);
1028 setVisualOffset_Widget(w, 0, 300, easeOut_AnimFlag | softer_AnimFlag); 1098 setVisualOffset_Widget(
1099 w, visX + w->rect.size.x + safePad, 300, animFlags);
1100 }
1101 else {
1102 setFlags_Widget(w, keepOnTop_WidgetFlag, iTrue);
1103 setVisualOffset_Widget(
1104 w, -w->rect.size.x - safePad, 300, animFlags);
1105 }
1029 } 1106 }
1107 setScrollMode_ListWidget(d->list, normal_ScrollMode);
1030 } 1108 }
1031 else if (isAnimated) { 1109 else {
1032 setFlags_Widget(w, horizontalOffset_WidgetFlag, iTrue); 1110 /* Portrait phone sidebar works differently: it slides up from the bottom. */
1033 if (d->side == right_SidebarSide) { 1111 setFlags_Widget(w, horizontalOffset_WidgetFlag, iFalse);
1034 setVisualOffset_Widget(w, visX, 0, 0); 1112 if (!isHiding) {
1035 setVisualOffset_Widget( 1113 invalidate_ListWidget(d->list);
1036 w, visX + w->rect.size.x + safePad, 300, easeOut_AnimFlag | softer_AnimFlag); 1114 w->rect.pos.y = height_Rect(safeRect_Root(w->root)) - d->midHeight;
1115 setVisualOffset_Widget(w, bottom_Rect(rect_Root(w->root)) - w->rect.pos.y, 0, 0);
1116 setVisualOffset_Widget(w, 0, 300, animFlags);
1117 animateSlidingSheetHeight_SidebarWidget_(d);
1118 setScrollMode_ListWidget(d->list, disabledAtTopBothDirections_ScrollMode);
1037 } 1119 }
1038 else { 1120 else {
1039 setFlags_Widget(w, keepOnTop_WidgetFlag, iTrue); 1121 setVisualOffset_Widget(w, bottom_Rect(rect_Root(w->root)) - w->rect.pos.y, 300, animFlags);
1040 setVisualOffset_Widget(
1041 w, -w->rect.size.x - safePad, 300, easeOut_AnimFlag | softer_AnimFlag);
1042 } 1122 }
1123 showToolbar_Root(w->root, isHiding);
1043 } 1124 }
1044 updateToolbarColors_Root(w->root); 1125 updateToolbarColors_Root(w->root);
1045 arrange_Widget(w->parent); 1126 arrange_Widget(w->parent);
@@ -1097,13 +1178,32 @@ static size_t numBookmarks_(const iPtrArray *bmList) {
1097 return num; 1178 return num;
1098} 1179}
1099 1180
1181static iRangei SlidingSheetMiddleRegion_SidebarWidget_(const iSidebarWidget *d) {
1182 const iWidget *w = constAs_Widget(d);
1183 const iRect safeRect = safeRect_Root(w->root);
1184 const int midY = bottom_Rect(safeRect) - d->midHeight;
1185 const int topHalf = (top_Rect(safeRect) + midY) / 2;
1186 const int bottomHalf = (bottom_Rect(safeRect) + midY * 2) / 3;
1187 return (iRangei){ topHalf, bottomHalf };
1188}
1189
1190static void gotoNearestSlidingSheetPos_SidebarWidget_(iSidebarWidget *d) {
1191 const iRangei midRegion = SlidingSheetMiddleRegion_SidebarWidget_(d);
1192 const int pos = top_Rect(d->widget.rect);
1193 setSlidingSheetPos_SidebarWidget_(d, pos < midRegion.start
1194 ? top_SlidingSheetPos
1195 : pos > midRegion.end ? bottom_SlidingSheetPos
1196 : middle_SlidingSheetPos);
1197}
1198
1100static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev) { 1199static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev) {
1101 iWidget *w = as_Widget(d); 1200 iWidget *w = as_Widget(d);
1102 /* Handle commands. */ 1201 /* Handle commands. */
1103 if (isResize_UserEvent(ev)) { 1202 if (isResize_UserEvent(ev)) {
1104 checkModeButtonLayout_SidebarWidget_(d); 1203 checkModeButtonLayout_SidebarWidget_(d);
1105 if (deviceType_App() == phone_AppDeviceType && d->side == left_SidebarSide) { 1204 if (deviceType_App() == phone_AppDeviceType) { // && d->side == left_SidebarSide) {
1106 setFlags_Widget(w, rightEdgeDraggable_WidgetFlag, isPortrait_App()); 1205// setFlags_Widget(w, rightEdgeDraggable_WidgetFlag, isPortrait_App());
1206 setFlags_Widget(findChild_Widget(w, "sidebar.close"), hidden_WidgetFlag, isLandscape_App());
1107 /* In landscape, visibility of the toolbar is controlled separately. */ 1207 /* In landscape, visibility of the toolbar is controlled separately. */
1108 if (isVisible_Widget(w)) { 1208 if (isVisible_Widget(w)) {
1109 postCommand_Widget(w, "sidebar.toggle"); 1209 postCommand_Widget(w, "sidebar.toggle");
@@ -1117,6 +1217,10 @@ static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev)
1117 setFlags_Widget(as_Widget(d->list), 1217 setFlags_Widget(as_Widget(d->list),
1118 drawBackgroundToHorizontalSafeArea_WidgetFlag, 1218 drawBackgroundToHorizontalSafeArea_WidgetFlag,
1119 isLandscape_App()); 1219 isLandscape_App());
1220 setFlags_Widget(w,
1221 drawBackgroundToBottom_WidgetFlag,
1222 isPortrait_App());
1223 setBackgroundColor_Widget(w, isPortrait_App() ? uiBackgroundSidebar_ColorId : none_ColorId);
1120 return iFalse; 1224 return iFalse;
1121 } 1225 }
1122 } 1226 }
@@ -1572,6 +1676,61 @@ static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev)
1572 return iTrue; 1676 return iTrue;
1573 } 1677 }
1574 } 1678 }
1679 if (isSlidingSheet_SidebarWidget_(d)) {
1680 if (ev->type == SDL_MOUSEWHEEL) {
1681 enum iWidgetTouchMode touchMode = widgetMode_Touch(w);
1682 if (touchMode == momentum_WidgetTouchMode) {
1683 /* We don't do momentum. */
1684 float swipe = stopWidgetMomentum_Touch(w);
1685// printf("swipe: %f\n", swipe);
1686 const iRangei midRegion = SlidingSheetMiddleRegion_SidebarWidget_(d);
1687 const int pos = top_Rect(w->rect);
1688 if (swipe < 500) {
1689 gotoNearestSlidingSheetPos_SidebarWidget_(d);
1690 }
1691 else if (swipe > 6500 && ev->wheel.y > 0) {
1692 /* Fast swipe down will dismiss. */
1693 setSlidingSheetPos_SidebarWidget_(d, bottom_SlidingSheetPos);
1694 }
1695 else if (ev->wheel.y < 0) {
1696 setSlidingSheetPos_SidebarWidget_(d, top_SlidingSheetPos);
1697 }
1698 else if (pos < (midRegion.start + midRegion.end) / 2) {
1699 setSlidingSheetPos_SidebarWidget_(d, middle_SlidingSheetPos);
1700 }
1701 else {
1702 setSlidingSheetPos_SidebarWidget_(d, bottom_SlidingSheetPos);
1703 }
1704 }
1705 else if (touchMode == touch_WidgetTouchMode) {
1706 /* Move with the finger. */
1707 adjustEdges_Rect(&w->rect, ev->wheel.y, 0, 0, 0);
1708 /* Upon reaching the top, scrolling is switched back to the list. */
1709 const iRect rootRect = safeRect_Root(w->root);
1710 const int top = top_Rect(rootRect);
1711 if (w->rect.pos.y < top) {
1712 setScrollMode_ListWidget(d->list, disabledAtTopUpwards_ScrollMode);
1713 setScrollPos_ListWidget(d->list, top - w->rect.pos.y);
1714 transferAffinity_Touch(w, as_Widget(d->list));
1715 w->rect.pos.y = top;
1716 w->rect.size.y = height_Rect(rootRect);
1717 }
1718 else {
1719 setScrollMode_ListWidget(d->list, disabledAtTopBothDirections_ScrollMode);
1720 }
1721 arrange_Widget(w);
1722 refresh_Widget(w);
1723 }
1724 else {
1725 return iFalse;
1726 }
1727 return iTrue;
1728 }
1729 if (ev->type == SDL_USEREVENT && ev->user.code == widgetTouchEnds_UserEventCode) {
1730 gotoNearestSlidingSheetPos_SidebarWidget_(d);
1731 return iTrue;
1732 }
1733 }
1575 if (ev->type == SDL_MOUSEBUTTONDOWN && 1734 if (ev->type == SDL_MOUSEBUTTONDOWN &&
1576 contains_Widget(as_Widget(d->list), init_I2(ev->button.x, ev->button.y))) { 1735 contains_Widget(as_Widget(d->list), init_I2(ev->button.x, ev->button.y))) {
1577 if (hoverItem_ListWidget(d->list) || isVisible_Widget(d->menu)) { 1736 if (hoverItem_ListWidget(d->list) || isVisible_Widget(d->menu)) {