diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-09-11 07:43:57 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-09-11 07:43:57 +0300 |
commit | 1410bbde7779efe3a20f603523547c8b8f55b6a1 (patch) | |
tree | 54e8ab43ea6d3dc35d7993b6909096c6c8429e50 /src | |
parent | 61c23be799956615ceeeda10aaeccc2bb11e9c94 (diff) |
Mobile: Many UI improvements; Upload UI
Diffstat (limited to 'src')
-rw-r--r-- | src/app.c | 7 | ||||
-rw-r--r-- | src/ui/certimportwidget.c | 120 | ||||
-rw-r--r-- | src/ui/documentwidget.c | 9 | ||||
-rw-r--r-- | src/ui/labelwidget.c | 17 | ||||
-rw-r--r-- | src/ui/mobile.c | 134 | ||||
-rw-r--r-- | src/ui/mobile.h | 19 | ||||
-rw-r--r-- | src/ui/root.c | 10 | ||||
-rw-r--r-- | src/ui/uploadwidget.c | 188 | ||||
-rw-r--r-- | src/ui/util.c | 15 | ||||
-rw-r--r-- | src/ui/widget.c | 4 |
10 files changed, 328 insertions, 195 deletions
@@ -2382,7 +2382,8 @@ iBool handleCommand_App(const char *cmd) { | |||
2382 | setUrl_UploadWidget(upload, url); | 2382 | setUrl_UploadWidget(upload, url); |
2383 | setResponseViewer_UploadWidget(upload, document_App()); | 2383 | setResponseViewer_UploadWidget(upload, document_App()); |
2384 | addChild_Widget(get_Root()->widget, iClob(upload)); | 2384 | addChild_Widget(get_Root()->widget, iClob(upload)); |
2385 | finalizeSheet_Mobile(as_Widget(upload)); | 2385 | // finalizeSheet_Mobile(as_Widget(upload)); |
2386 | setupSheetTransition_Mobile(as_Widget(upload), iTrue); | ||
2386 | postRefresh_App(); | 2387 | postRefresh_App(); |
2387 | return iTrue; | 2388 | return iTrue; |
2388 | } | 2389 | } |
@@ -2761,7 +2762,9 @@ iBool handleCommand_App(const char *cmd) { | |||
2761 | iCertImportWidget *imp = new_CertImportWidget(); | 2762 | iCertImportWidget *imp = new_CertImportWidget(); |
2762 | setPageContent_CertImportWidget(imp, sourceContent_DocumentWidget(document_App())); | 2763 | setPageContent_CertImportWidget(imp, sourceContent_DocumentWidget(document_App())); |
2763 | addChild_Widget(get_Root()->widget, iClob(imp)); | 2764 | addChild_Widget(get_Root()->widget, iClob(imp)); |
2764 | finalizeSheet_Mobile(as_Widget(imp)); | 2765 | // finalizeSheet_Mobile(as_Widget(imp)); |
2766 | arrange_Widget(as_Widget(imp)); | ||
2767 | setupSheetTransition_Mobile(as_Widget(imp), iTrue); | ||
2765 | postRefresh_App(); | 2768 | postRefresh_App(); |
2766 | return iTrue; | 2769 | return iTrue; |
2767 | } | 2770 | } |
diff --git a/src/ui/certimportwidget.c b/src/ui/certimportwidget.c index 2e60c71f..65cb6654 100644 --- a/src/ui/certimportwidget.c +++ b/src/ui/certimportwidget.c | |||
@@ -104,61 +104,83 @@ static iBool tryImport_CertImportWidget_(iCertImportWidget *d, const iBlock *dat | |||
104 | 104 | ||
105 | void init_CertImportWidget(iCertImportWidget *d) { | 105 | void init_CertImportWidget(iCertImportWidget *d) { |
106 | iWidget *w = as_Widget(d); | 106 | iWidget *w = as_Widget(d); |
107 | const iMenuItem actions[] = { | ||
108 | #if defined (iPlatformAppleMobile) | ||
109 | { "${dlg.certimport.pickfile}", 0, 0, "certimport.pickfile" }, | ||
110 | { "---" }, | ||
111 | #endif | ||
112 | { "${cancel}" }, | ||
113 | { uiTextAction_ColorEscape "${dlg.certimport.import}", | ||
114 | SDLK_RETURN, KMOD_PRIMARY, | ||
115 | "certimport.accept" } | ||
116 | }; | ||
107 | init_Widget(w); | 117 | init_Widget(w); |
108 | setId_Widget(w, "certimport"); | 118 | setId_Widget(w, "certimport"); |
109 | d->cert = NULL; | 119 | d->cert = NULL; |
110 | /* This should behave similar to sheets. */ | 120 | if (isUsingPanelLayout_Mobile()) { |
111 | useSheetStyle_Widget(w); | 121 | initPanels_Mobile(w, NULL, (iMenuItem[]){ |
112 | addChildFlags_Widget( | 122 | { "title id:heading.certimport" }, |
113 | w, | 123 | { format_CStr("label id:certimport.info text:%s", infoText_) }, |
114 | iClob(new_LabelWidget(uiHeading_ColorEscape "${heading.certimport}", NULL)), | 124 | //{ "padding" }, |
115 | frameless_WidgetFlag); | 125 | { "label id:certimport.crt nowrap:1 frame:1" }, |
116 | d->info = addChildFlags_Widget(w, iClob(new_LabelWidget(infoText_, NULL)), frameless_WidgetFlag); | 126 | { "padding arg:0.25" }, |
117 | addChild_Widget(w, iClob(makePadding_Widget(gap_UI))); | 127 | { "label id:certimport.key nowrap:1 frame:1" }, |
118 | d->crtLabel = new_LabelWidget("", NULL); { | 128 | { "heading text:${dlg.certimport.notes}" }, |
119 | setFont_LabelWidget(d->crtLabel, uiContent_FontId); | 129 | { "input id:certimport.notes hint:hint.certimport.description noheading:1" }, |
120 | addChildFlags_Widget(w, iClob(d->crtLabel), 0); | 130 | { NULL } |
121 | setFrameColor_Widget(as_Widget(d->crtLabel), uiTextCaution_ColorId); | 131 | }, actions, iElemCount(actions)); |
132 | d->info = findChild_Widget(w, "certimport.info"); | ||
133 | d->crtLabel = findChild_Widget(w, "certimport.crt"); | ||
134 | d->keyLabel = findChild_Widget(w, "certimport.key"); | ||
135 | d->notes = findChild_Widget(w, "certimport.notes"); | ||
136 | setFixedSize_Widget(as_Widget(d->crtLabel), init_I2(-1, gap_UI * 12)); | ||
137 | setFixedSize_Widget(as_Widget(d->keyLabel), init_I2(-1, gap_UI * 12)); | ||
122 | } | 138 | } |
123 | d->keyLabel = new_LabelWidget("", NULL); { | 139 | else { |
124 | setFont_LabelWidget(d->keyLabel, uiContent_FontId); | 140 | /* This should behave similar to sheets. */ |
141 | useSheetStyle_Widget(w); | ||
142 | addChildFlags_Widget( | ||
143 | w, | ||
144 | iClob(new_LabelWidget(uiHeading_ColorEscape "${heading.certimport}", NULL)), | ||
145 | frameless_WidgetFlag); | ||
146 | d->info = addChildFlags_Widget(w, iClob(new_LabelWidget(infoText_, NULL)), frameless_WidgetFlag); | ||
125 | addChild_Widget(w, iClob(makePadding_Widget(gap_UI))); | 147 | addChild_Widget(w, iClob(makePadding_Widget(gap_UI))); |
126 | addChildFlags_Widget(w, iClob(d->keyLabel), 0); | 148 | d->crtLabel = new_LabelWidget("", NULL); { |
127 | setFrameColor_Widget(as_Widget(d->keyLabel), uiTextCaution_ColorId); | 149 | setFont_LabelWidget(d->crtLabel, uiContent_FontId); |
128 | } | 150 | addChildFlags_Widget(w, iClob(d->crtLabel), 0); |
129 | addChild_Widget(w, iClob(makePadding_Widget(gap_UI))); | 151 | } |
130 | /* TODO: Use makeTwoColumnWidget_() */ | 152 | d->keyLabel = new_LabelWidget("", NULL); { |
131 | iWidget *page = new_Widget(); { | 153 | setFont_LabelWidget(d->keyLabel, uiContent_FontId); |
132 | setFlags_Widget(page, arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag, iTrue); | 154 | addChild_Widget(w, iClob(makePadding_Widget(gap_UI))); |
133 | iWidget *headings = addChildFlags_Widget( | 155 | addChildFlags_Widget(w, iClob(d->keyLabel), 0); |
134 | page, iClob(new_Widget()), arrangeVertical_WidgetFlag | arrangeSize_WidgetFlag); | 156 | } |
135 | iWidget *values = addChildFlags_Widget( | 157 | addChild_Widget(w, iClob(makePadding_Widget(gap_UI))); |
136 | page, iClob(new_Widget()), arrangeVertical_WidgetFlag | arrangeSize_WidgetFlag); | 158 | /* TODO: Use makeTwoColumnWidget_() */ |
137 | // addChild_Widget(headings, iClob(makeHeading_Widget("${dlg.certimport.notes}"))); | 159 | iWidget *page = new_Widget(); { |
138 | // addChild_Widget(values, iClob(d->notes = new_InputWidget(0))); | 160 | setFlags_Widget(page, arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag, iTrue); |
139 | // setHint_InputWidget(d->notes, "${hint.certimport.description}"); | 161 | iWidget *headings = addChildFlags_Widget( |
140 | addTwoColumnDialogInputField_Widget( | 162 | page, iClob(new_Widget()), arrangeVertical_WidgetFlag | arrangeSize_WidgetFlag); |
141 | headings, | 163 | iWidget *values = addChildFlags_Widget( |
142 | values, | 164 | page, iClob(new_Widget()), arrangeVertical_WidgetFlag | arrangeSize_WidgetFlag); |
143 | "${dlg.certimport.notes}", | 165 | addTwoColumnDialogInputField_Widget( |
144 | "", | 166 | headings, |
145 | iClob(d->notes = newHint_InputWidget(0, "${hint.certimport.description}"))); | 167 | values, |
146 | as_Widget(d->notes)->rect.size.x = gap_UI * 70; | 168 | "${dlg.certimport.notes}", |
169 | "", | ||
170 | iClob(d->notes = newHint_InputWidget(0, "${hint.certimport.description}"))); | ||
171 | as_Widget(d->notes)->rect.size.x = gap_UI * 70; | ||
172 | } | ||
173 | addChild_Widget(w, iClob(page)); | ||
174 | arrange_Widget(w); | ||
175 | setFixedSize_Widget(as_Widget(d->crtLabel), init_I2(width_Widget(w) - 6.5 * gap_UI, gap_UI * 12)); | ||
176 | setFixedSize_Widget(as_Widget(d->keyLabel), init_I2(width_Widget(w) - 6.5 * gap_UI, gap_UI * 12)); | ||
177 | /* Buttons. */ | ||
178 | addChild_Widget(w, iClob(makePadding_Widget(gap_UI))); | ||
179 | iWidget *buttons = makeDialogButtons_Widget(actions, iElemCount(actions)); | ||
180 | addChild_Widget(w, iClob(buttons)); | ||
147 | } | 181 | } |
148 | addChild_Widget(w, iClob(page)); | 182 | setFrameColor_Widget(as_Widget(d->crtLabel), uiTextCaution_ColorId); |
149 | arrange_Widget(w); | 183 | setFrameColor_Widget(as_Widget(d->keyLabel), uiTextCaution_ColorId); |
150 | setFixedSize_Widget(as_Widget(d->crtLabel), init_I2(width_Widget(w) - 6.5 * gap_UI, gap_UI * 12)); | ||
151 | setFixedSize_Widget(as_Widget(d->keyLabel), init_I2(width_Widget(w) - 6.5 * gap_UI, gap_UI * 12)); | ||
152 | /* Buttons. */ | ||
153 | addChild_Widget(w, iClob(makePadding_Widget(gap_UI))); | ||
154 | iWidget *buttons = makeDialogButtons_Widget( | ||
155 | (iMenuItem[]){ { "${cancel}" }, | ||
156 | { uiTextAction_ColorEscape "${dlg.certimport.import}", | ||
157 | SDLK_RETURN, | ||
158 | KMOD_PRIMARY, | ||
159 | "certimport.accept" } }, | ||
160 | 2); | ||
161 | addChild_Widget(w, iClob(buttons)); | ||
162 | if (deviceType_App() != desktop_AppDeviceType) { | 184 | if (deviceType_App() != desktop_AppDeviceType) { |
163 | /* Try auto-pasting. */ | 185 | /* Try auto-pasting. */ |
164 | postCommand_App("certimport.paste"); | 186 | postCommand_App("certimport.paste"); |
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index 83f2ea6a..4b3c2db0 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c | |||
@@ -2852,7 +2852,8 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) | |||
2852 | setUrl_UploadWidget(upload, d->mod.url); | 2852 | setUrl_UploadWidget(upload, d->mod.url); |
2853 | setResponseViewer_UploadWidget(upload, d); | 2853 | setResponseViewer_UploadWidget(upload, d); |
2854 | addChild_Widget(get_Root()->widget, iClob(upload)); | 2854 | addChild_Widget(get_Root()->widget, iClob(upload)); |
2855 | finalizeSheet_Mobile(as_Widget(upload)); | 2855 | // finalizeSheet_Mobile(as_Widget(upload)); |
2856 | setupSheetTransition_Mobile(as_Widget(upload), iTrue); | ||
2856 | postRefresh_App(); | 2857 | postRefresh_App(); |
2857 | } | 2858 | } |
2858 | return iTrue; | 2859 | return iTrue; |
@@ -3679,16 +3680,10 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e | |||
3679 | { "---" }, | 3680 | { "---" }, |
3680 | { book_Icon " ${menu.page.import}", 0, 0, "bookmark.links confirm:1" }, | 3681 | { book_Icon " ${menu.page.import}", 0, 0, "bookmark.links confirm:1" }, |
3681 | { globe_Icon " ${menu.page.translate}", 0, 0, "document.translate" }, | 3682 | { globe_Icon " ${menu.page.translate}", 0, 0, "document.translate" }, |
3682 | #if defined (iPlatformMobile) | ||
3683 | { "---" }, | ||
3684 | { "${menu.page.copyurl}", 0, 0, "document.copylink" } }, | ||
3685 | 14); | ||
3686 | #else | ||
3687 | { upload_Icon " ${menu.page.upload}", 0, 0, "document.upload" }, | 3683 | { upload_Icon " ${menu.page.upload}", 0, 0, "document.upload" }, |
3688 | { "---" }, | 3684 | { "---" }, |
3689 | { "${menu.page.copyurl}", 0, 0, "document.copylink" } }, | 3685 | { "${menu.page.copyurl}", 0, 0, "document.copylink" } }, |
3690 | 15); | 3686 | 15); |
3691 | #endif | ||
3692 | if (isEmpty_Range(&d->selectMark)) { | 3687 | if (isEmpty_Range(&d->selectMark)) { |
3693 | pushBackN_Array( | 3688 | pushBackN_Array( |
3694 | &items, | 3689 | &items, |
diff --git a/src/ui/labelwidget.c b/src/ui/labelwidget.c index 03595d1a..ec324d02 100644 --- a/src/ui/labelwidget.c +++ b/src/ui/labelwidget.c | |||
@@ -244,6 +244,9 @@ static void getColors_LabelWidget_(const iLabelWidget *d, int *bg, int *fg, int | |||
244 | } | 244 | } |
245 | } | 245 | } |
246 | } | 246 | } |
247 | if (d->forceFg >= 0) { | ||
248 | *fg = d->forceFg; | ||
249 | } | ||
247 | if (isPress) { | 250 | if (isPress) { |
248 | *bg = uiBackgroundPressed_ColorId | permanent_ColorId; | 251 | *bg = uiBackgroundPressed_ColorId | permanent_ColorId; |
249 | if (isButton) { | 252 | if (isButton) { |
@@ -257,9 +260,6 @@ static void getColors_LabelWidget_(const iLabelWidget *d, int *bg, int *fg, int | |||
257 | *fg = isDark_ColorTheme(colorTheme_App()) ? white_ColorId : black_ColorId; | 260 | *fg = isDark_ColorTheme(colorTheme_App()) ? white_ColorId : black_ColorId; |
258 | } | 261 | } |
259 | } | 262 | } |
260 | if (d->forceFg >= 0) { | ||
261 | *fg = d->forceFg; | ||
262 | } | ||
263 | } | 263 | } |
264 | 264 | ||
265 | iLocalDef int iconPadding_LabelWidget_(const iLabelWidget *d) { | 265 | iLocalDef int iconPadding_LabelWidget_(const iLabelWidget *d) { |
@@ -318,6 +318,10 @@ static void draw_LabelWidget_(const iLabelWidget *d) { | |||
318 | } | 318 | } |
319 | setClip_Paint(&p, rect); | 319 | setClip_Paint(&p, rect); |
320 | const int iconPad = iconPadding_LabelWidget_(d); | 320 | const int iconPad = iconPadding_LabelWidget_(d); |
321 | const int iconColor = isCaution ? uiTextCaution_ColorId | ||
322 | : flags & (disabled_WidgetFlag | pressed_WidgetFlag) ? fg | ||
323 | : isHover ? uiIconHover_ColorId | ||
324 | : uiIcon_ColorId; | ||
321 | if (d->icon && d->icon != 0x20) { /* no need to draw an empty icon */ | 325 | if (d->icon && d->icon != 0x20) { /* no need to draw an empty icon */ |
322 | iString str; | 326 | iString str; |
323 | initUnicodeN_String(&str, &d->icon, 1); | 327 | initUnicodeN_String(&str, &d->icon, 1); |
@@ -331,10 +335,7 @@ static void draw_LabelWidget_(const iLabelWidget *d) { | |||
331 | -gap_UI / 8)), | 335 | -gap_UI / 8)), |
332 | init_I2(iconPad, lineHeight_Text(d->font)) }, | 336 | init_I2(iconPad, lineHeight_Text(d->font)) }, |
333 | iTrue, | 337 | iTrue, |
334 | isCaution ? uiTextCaution_ColorId | 338 | iconColor, |
335 | : flags & (disabled_WidgetFlag | pressed_WidgetFlag) ? fg | ||
336 | : isHover ? uiIconHover_ColorId | ||
337 | : uiIcon_ColorId, | ||
338 | "%s", | 339 | "%s", |
339 | cstr_String(&str)); | 340 | cstr_String(&str)); |
340 | deinit_String(&str); | 341 | deinit_String(&str); |
@@ -387,7 +388,7 @@ static void draw_LabelWidget_(const iLabelWidget *d) { | |||
387 | drawCentered_Text(d->font, | 388 | drawCentered_Text(d->font, |
388 | (iRect){ addX_I2(topRight_Rect(chRect), -iconPad), | 389 | (iRect){ addX_I2(topRight_Rect(chRect), -iconPad), |
389 | init_I2(chSize, height_Rect(chRect)) }, | 390 | init_I2(chSize, height_Rect(chRect)) }, |
390 | iTrue, uiSeparator_ColorId, rightAngle_Icon); | 391 | iTrue, iconColor /*uiSeparator_ColorId*/, rightAngle_Icon); |
391 | } | 392 | } |
392 | unsetClip_Paint(&p); | 393 | unsetClip_Paint(&p); |
393 | } | 394 | } |
diff --git a/src/ui/mobile.c b/src/ui/mobile.c index daa1fa1a..6ea672e6 100644 --- a/src/ui/mobile.c +++ b/src/ui/mobile.c | |||
@@ -90,15 +90,15 @@ static void unselectAllPanelButtons_(iWidget *topPanel) { | |||
90 | 90 | ||
91 | static iBool mainDetailSplitHandler_(iWidget *mainDetailSplit, const char *cmd) { | 91 | static iBool mainDetailSplitHandler_(iWidget *mainDetailSplit, const char *cmd) { |
92 | if (equal_Command(cmd, "window.resized")) { | 92 | if (equal_Command(cmd, "window.resized")) { |
93 | const iBool isPortrait = (deviceType_App() == phone_AppDeviceType && isPortrait_App()); | 93 | const iBool isPortrait = (deviceType_App() == phone_AppDeviceType && isPortrait_App()); |
94 | const iRect safeRoot = safeRect_Root(mainDetailSplit->root); | 94 | const iRect safeRoot = safeRect_Root(mainDetailSplit->root); |
95 | setPos_Widget(mainDetailSplit, topLeft_Rect(safeRoot)); | ||
96 | setFixedSize_Widget(mainDetailSplit, safeRoot.size); | ||
97 | iWidget * sheet = parent_Widget(mainDetailSplit); | 95 | iWidget * sheet = parent_Widget(mainDetailSplit); |
98 | iWidget * navi = findChild_Widget(sheet, "panel.navi"); | 96 | iWidget * navi = findChild_Widget(sheet, "panel.navi"); |
99 | iWidget * detailStack = findChild_Widget(mainDetailSplit, "detailstack"); | 97 | iWidget * detailStack = findChild_Widget(mainDetailSplit, "detailstack"); |
100 | const size_t numPanels = childCount_Widget(detailStack); | 98 | const size_t numPanels = childCount_Widget(detailStack); |
101 | const iBool isSideBySide = isSideBySideLayout_() && numPanels > 0; | 99 | const iBool isSideBySide = isSideBySideLayout_() && numPanels > 0; |
100 | setPos_Widget(mainDetailSplit, topLeft_Rect(safeRoot)); | ||
101 | setFixedSize_Widget(mainDetailSplit, safeRoot.size); | ||
102 | setFlags_Widget(mainDetailSplit, arrangeHorizontal_WidgetFlag, isSideBySide); | 102 | setFlags_Widget(mainDetailSplit, arrangeHorizontal_WidgetFlag, isSideBySide); |
103 | setFlags_Widget(detailStack, expand_WidgetFlag, isSideBySide); | 103 | setFlags_Widget(detailStack, expand_WidgetFlag, isSideBySide); |
104 | setFlags_Widget(detailStack, hidden_WidgetFlag, numPanels == 0); | 104 | setFlags_Widget(detailStack, hidden_WidgetFlag, numPanels == 0); |
@@ -172,7 +172,16 @@ static iBool topPanelHandler_(iWidget *topPanel, const char *cmd) { | |||
172 | } | 172 | } |
173 | unselectAllPanelButtons_(topPanel); | 173 | unselectAllPanelButtons_(topPanel); |
174 | if (!wasClosed) { | 174 | if (!wasClosed) { |
175 | postCommand_App("prefs.dismiss"); | 175 | /* TODO: Should come up with a more general-purpose approach here. */ |
176 | if (findWidget_App("prefs")) { | ||
177 | postCommand_App("prefs.dismiss"); | ||
178 | } | ||
179 | else if (findWidget_App("upload")) { | ||
180 | postCommand_App("upload.cancel"); | ||
181 | } | ||
182 | else { | ||
183 | postCommand_App("cancel"); | ||
184 | } | ||
176 | } | 185 | } |
177 | return iTrue; | 186 | return iTrue; |
178 | } | 187 | } |
@@ -503,11 +512,19 @@ void makePanelItem_Mobile(iWidget *panel, const iMenuItem *item) { | |||
503 | else if (equal_Command(spec, "label")) { | 512 | else if (equal_Command(spec, "label")) { |
504 | iLabelWidget *lab = new_LabelWidget(label, NULL); | 513 | iLabelWidget *lab = new_LabelWidget(label, NULL); |
505 | widget = as_Widget(lab); | 514 | widget = as_Widget(lab); |
506 | setWrap_LabelWidget(lab, iTrue); | 515 | setId_Widget(widget, id); |
507 | setFlags_Widget(widget, fixedHeight_WidgetFlag | frameless_WidgetFlag, iTrue); | 516 | setWrap_LabelWidget(lab, !argLabel_Command(spec, "nowrap")); |
517 | setFlags_Widget(widget, | ||
518 | fixedHeight_WidgetFlag | | ||
519 | (!argLabel_Command(spec, "frame") ? frameless_WidgetFlag : 0), | ||
520 | iTrue); | ||
508 | } | 521 | } |
509 | else if (equal_Command(spec, "padding")) { | 522 | else if (equal_Command(spec, "padding")) { |
510 | widget = makePadding_Widget(lineHeight_Text(labelFont_()) * 1.5f); | 523 | float height = 1.5f; |
524 | if (hasLabel_Command(spec, "arg")) { | ||
525 | height *= argfLabel_Command(spec, "arg"); | ||
526 | } | ||
527 | widget = makePadding_Widget(lineHeight_Text(labelFont_()) * height); | ||
511 | } | 528 | } |
512 | /* Apply common styling to the heading. */ | 529 | /* Apply common styling to the heading. */ |
513 | if (heading) { | 530 | if (heading) { |
@@ -539,7 +556,7 @@ static const iMenuItem *findDialogCancelAction_(const iMenuItem *items, size_t n | |||
539 | return NULL; | 556 | return NULL; |
540 | } | 557 | } |
541 | for (size_t i = 0; i < n; i++) { | 558 | for (size_t i = 0; i < n; i++) { |
542 | if (!iCmpStr(items[i].label, "${cancel}")) { | 559 | if (!iCmpStr(items[i].label, "${cancel}") || !iCmpStr(items[i].label, "${close}")) { |
543 | return &items[i]; | 560 | return &items[i]; |
544 | } | 561 | } |
545 | } | 562 | } |
@@ -556,13 +573,20 @@ iWidget *makePanelsParent_Mobile(iWidget *parentWidget, | |||
556 | const char *id, | 573 | const char *id, |
557 | const iMenuItem *itemsNullTerminated, | 574 | const iMenuItem *itemsNullTerminated, |
558 | const iMenuItem *actions, size_t numActions) { | 575 | const iMenuItem *actions, size_t numActions) { |
576 | iWidget *panels = new_Widget(); | ||
577 | setId_Widget(panels, id); | ||
578 | initPanels_Mobile(panels, parentWidget, itemsNullTerminated, actions, numActions); | ||
579 | return panels; | ||
580 | } | ||
581 | |||
582 | void initPanels_Mobile(iWidget *panels, iWidget *parentWidget, | ||
583 | const iMenuItem *itemsNullTerminated, | ||
584 | const iMenuItem *actions, size_t numActions) { | ||
559 | /* A multipanel widget has a top panel and one or more detail panels. In a horizontal layout, | 585 | /* A multipanel widget has a top panel and one or more detail panels. In a horizontal layout, |
560 | the detail panels slide in from the right and cover the top panel. In a landscape layout, | 586 | the detail panels slide in from the right and cover the top panel. In a landscape layout, |
561 | the detail panels are always visible on the side. */ | 587 | the detail panels are always visible on the side. */ |
562 | iWidget *sheet = new_Widget(); | 588 | setBackgroundColor_Widget(panels, uiBackground_ColorId); |
563 | setId_Widget(sheet, id); | 589 | setFlags_Widget(panels, |
564 | setBackgroundColor_Widget(sheet, uiBackground_ColorId); | ||
565 | setFlags_Widget(sheet, | ||
566 | resizeToParentWidth_WidgetFlag | resizeToParentHeight_WidgetFlag | | 590 | resizeToParentWidth_WidgetFlag | resizeToParentHeight_WidgetFlag | |
567 | frameless_WidgetFlag | focusRoot_WidgetFlag | commandOnClick_WidgetFlag | | 591 | frameless_WidgetFlag | focusRoot_WidgetFlag | commandOnClick_WidgetFlag | |
568 | overflowScrollable_WidgetFlag | leftEdgeDraggable_WidgetFlag, | 592 | overflowScrollable_WidgetFlag | leftEdgeDraggable_WidgetFlag, |
@@ -572,7 +596,7 @@ iWidget *makePanelsParent_Mobile(iWidget *parentWidget, | |||
572 | setCommandHandler_Widget(mainDetailSplit, mainDetailSplitHandler_); | 596 | setCommandHandler_Widget(mainDetailSplit, mainDetailSplitHandler_); |
573 | setFlags_Widget(mainDetailSplit, resizeHeightOfChildren_WidgetFlag, iFalse); | 597 | setFlags_Widget(mainDetailSplit, resizeHeightOfChildren_WidgetFlag, iFalse); |
574 | setId_Widget(mainDetailSplit, "mdsplit"); | 598 | setId_Widget(mainDetailSplit, "mdsplit"); |
575 | addChild_Widget(sheet, iClob(mainDetailSplit)); | 599 | addChild_Widget(panels, iClob(mainDetailSplit)); |
576 | } | 600 | } |
577 | /* The panel roots. */ | 601 | /* The panel roots. */ |
578 | iWidget *topPanel = new_Widget(); { | 602 | iWidget *topPanel = new_Widget(); { |
@@ -591,7 +615,6 @@ iWidget *makePanelsParent_Mobile(iWidget *parentWidget, | |||
591 | setFlags_Widget(detailStack, collapse_WidgetFlag | resizeWidthOfChildren_WidgetFlag, iTrue); | 615 | setFlags_Widget(detailStack, collapse_WidgetFlag | resizeWidthOfChildren_WidgetFlag, iTrue); |
592 | addChild_Widget(mainDetailSplit, iClob(detailStack)); | 616 | addChild_Widget(mainDetailSplit, iClob(detailStack)); |
593 | } | 617 | } |
594 | addChild_Widget(topPanel, iClob(makePadding_Widget(lineHeight_Text(labelFont_())))); | ||
595 | /* Slide top panel with detail panels. */ { | 618 | /* Slide top panel with detail panels. */ { |
596 | setFlags_Widget(topPanel, refChildrenOffset_WidgetFlag, iTrue); | 619 | setFlags_Widget(topPanel, refChildrenOffset_WidgetFlag, iTrue); |
597 | topPanel->offsetRef = detailStack; | 620 | topPanel->offsetRef = detailStack; |
@@ -612,15 +635,17 @@ iWidget *makePanelsParent_Mobile(iWidget *parentWidget, | |||
612 | checkIcon_LabelWidget(naviBack); | 635 | checkIcon_LabelWidget(naviBack); |
613 | setId_Widget(as_Widget(naviBack), "panel.back"); | 636 | setId_Widget(as_Widget(naviBack), "panel.back"); |
614 | setFont_LabelWidget(naviBack, labelFont_()); | 637 | setFont_LabelWidget(naviBack, labelFont_()); |
615 | addChildFlags_Widget(sheet, iClob(navi), | 638 | addChildFlags_Widget(panels, iClob(navi), |
616 | drawBackgroundToVerticalSafeArea_WidgetFlag | | 639 | drawBackgroundToVerticalSafeArea_WidgetFlag | |
617 | arrangeHeight_WidgetFlag | resizeWidthOfChildren_WidgetFlag | | 640 | arrangeHeight_WidgetFlag | resizeWidthOfChildren_WidgetFlag | |
618 | resizeToParentWidth_WidgetFlag | arrangeVertical_WidgetFlag); | 641 | resizeToParentWidth_WidgetFlag | arrangeVertical_WidgetFlag); |
619 | } | 642 | } |
643 | iBool haveDetailPanels = iFalse; | ||
620 | /* Create panel contents based on provided items. */ | 644 | /* Create panel contents based on provided items. */ |
621 | for (size_t i = 0; itemsNullTerminated[i].label; i++) { | 645 | for (size_t i = 0; itemsNullTerminated[i].label; i++) { |
622 | const iMenuItem *item = &itemsNullTerminated[i]; | 646 | const iMenuItem *item = &itemsNullTerminated[i]; |
623 | if (equal_Command(item->label, "panel")) { | 647 | if (equal_Command(item->label, "panel")) { |
648 | haveDetailPanels = iTrue; | ||
624 | const char *id = cstr_Rangecc(range_Command(item->label, "id")); | 649 | const char *id = cstr_Rangecc(range_Command(item->label, "id")); |
625 | const iString *label = hasLabel_Command(item->label, "text") | 650 | const iString *label = hasLabel_Command(item->label, "text") |
626 | ? collect_String(suffix_Command(item->label, "text")) | 651 | ? collect_String(suffix_Command(item->label, "text")) |
@@ -655,10 +680,12 @@ iWidget *makePanelsParent_Mobile(iWidget *parentWidget, | |||
655 | setFont_LabelWidget(naviBack, labelBoldFont_()); | 680 | setFont_LabelWidget(naviBack, labelBoldFont_()); |
656 | } | 681 | } |
657 | else if (defaultItem && defaultItem != cancelItem) { | 682 | else if (defaultItem && defaultItem != cancelItem) { |
658 | updateTextCStr_LabelWidget(naviBack, cancelItem->label); | 683 | if (!haveDetailPanels) { |
659 | setCommand_LabelWidget(naviBack, collectNewCStr_String(cancelItem->command | 684 | updateTextCStr_LabelWidget(naviBack, cancelItem->label); |
660 | ? cancelItem->command | 685 | setCommand_LabelWidget(naviBack, collectNewCStr_String(cancelItem->command |
661 | : "cancel")); | 686 | ? cancelItem->command |
687 | : "cancel")); | ||
688 | } | ||
662 | iLabelWidget *defaultButton = new_LabelWidget(defaultItem->label, defaultItem->command); | 689 | iLabelWidget *defaultButton = new_LabelWidget(defaultItem->label, defaultItem->command); |
663 | setFont_LabelWidget(defaultButton, labelBoldFont_()); | 690 | setFont_LabelWidget(defaultButton, labelBoldFont_()); |
664 | setFlags_Widget(as_Widget(defaultButton), | 691 | setFlags_Widget(as_Widget(defaultButton), |
@@ -689,16 +716,21 @@ iWidget *makePanelsParent_Mobile(iWidget *parentWidget, | |||
689 | } | 716 | } |
690 | makePanelItem_Mobile( | 717 | makePanelItem_Mobile( |
691 | topPanel, | 718 | topPanel, |
692 | &(iMenuItem){ format_CStr("button text:%s", act->label), 0, 0, act->command }); | 719 | &(iMenuItem){ format_CStr("button text:" uiTextAction_ColorEscape "%s", act->label), |
720 | 0, | ||
721 | 0, | ||
722 | act->command }); | ||
693 | } | 723 | } |
694 | } | 724 | } |
695 | /* Finalize the layout. */ | 725 | /* Finalize the layout. */ |
696 | addChild_Widget(parentWidget, iClob(sheet)); | 726 | if (parentWidget) { |
727 | addChild_Widget(parentWidget, iClob(panels)); | ||
728 | } | ||
697 | mainDetailSplitHandler_(mainDetailSplit, "window.resized"); /* make it resize the split */ | 729 | mainDetailSplitHandler_(mainDetailSplit, "window.resized"); /* make it resize the split */ |
698 | updatePanelSheetMetrics_(sheet); | 730 | updatePanelSheetMetrics_(panels); |
699 | arrange_Widget(sheet); | 731 | arrange_Widget(panels); |
700 | postCommand_App("widget.overflow"); /* with the correct dimensions */ | 732 | postCommand_App("widget.overflow"); /* with the correct dimensions */ |
701 | return sheet; | 733 | printTree_Widget(panels); |
702 | } | 734 | } |
703 | 735 | ||
704 | #if 0 | 736 | #if 0 |
@@ -1130,7 +1162,9 @@ void setupMenuTransition_Mobile(iWidget *sheet, iBool isIncoming) { | |||
1130 | } | 1162 | } |
1131 | } | 1163 | } |
1132 | 1164 | ||
1133 | void setupSheetTransition_Mobile(iWidget *sheet, iBool isIncoming) { | 1165 | void setupSheetTransition_Mobile(iWidget *sheet, int flags) { |
1166 | const iBool isIncoming = (flags & incoming_TransitionFlag) != 0; | ||
1167 | const int dir = flags & dirMask_TransitionFlag; | ||
1134 | if (!isUsingPanelLayout_Mobile()) { | 1168 | if (!isUsingPanelLayout_Mobile()) { |
1135 | if (prefs_App()->uiAnimations) { | 1169 | if (prefs_App()->uiAnimations) { |
1136 | setFlags_Widget(sheet, horizontalOffset_WidgetFlag, iFalse); | 1170 | setFlags_Widget(sheet, horizontalOffset_WidgetFlag, iFalse); |
@@ -1144,17 +1178,51 @@ void setupSheetTransition_Mobile(iWidget *sheet, iBool isIncoming) { | |||
1144 | } | 1178 | } |
1145 | return; | 1179 | return; |
1146 | } | 1180 | } |
1147 | if(isSideBySideLayout_()) { | 1181 | if (isSideBySideLayout_()) { |
1182 | /* TODO: Landscape transitions? */ | ||
1148 | return; | 1183 | return; |
1149 | } | 1184 | } |
1150 | setFlags_Widget(sheet, horizontalOffset_WidgetFlag, iTrue); | 1185 | setFlags_Widget(sheet, |
1186 | horizontalOffset_WidgetFlag, | ||
1187 | dir == right_TransitionDir || dir == left_TransitionDir); | ||
1151 | if (isIncoming) { | 1188 | if (isIncoming) { |
1152 | setVisualOffset_Widget(sheet, size_Root(sheet->root).x, 0, 0); | 1189 | switch (dir) { |
1190 | case right_TransitionDir: | ||
1191 | setVisualOffset_Widget(sheet, size_Root(sheet->root).x, 0, 0); | ||
1192 | break; | ||
1193 | case left_TransitionDir: | ||
1194 | setVisualOffset_Widget(sheet, -size_Root(sheet->root).x, 0, 0); | ||
1195 | break; | ||
1196 | case top_TransitionDir: | ||
1197 | setVisualOffset_Widget( | ||
1198 | sheet, -bottom_Rect(boundsWithoutVisualOffset_Widget(sheet)), 0, 0); | ||
1199 | break; | ||
1200 | case bottom_TransitionDir: | ||
1201 | setVisualOffset_Widget(sheet, height_Widget(sheet), 0, 0); | ||
1202 | break; | ||
1203 | } | ||
1153 | setVisualOffset_Widget(sheet, 0, 200, easeOut_AnimFlag); | 1204 | setVisualOffset_Widget(sheet, 0, 200, easeOut_AnimFlag); |
1154 | } | 1205 | } |
1155 | else { | 1206 | else { |
1156 | const iBool wasDragged = iAbs(value_Anim(&sheet->visualOffset)) > 0; | 1207 | switch (dir) { |
1157 | setVisualOffset_Widget(sheet, size_Root(sheet->root).x, wasDragged ? 100 : 200, | 1208 | case right_TransitionDir: { |
1158 | wasDragged ? 0 : easeIn_AnimFlag); | 1209 | const iBool wasDragged = iAbs(value_Anim(&sheet->visualOffset)) > 0; |
1210 | setVisualOffset_Widget(sheet, size_Root(sheet->root).x, wasDragged ? 100 : 200, | ||
1211 | wasDragged ? 0 : easeIn_AnimFlag); | ||
1212 | break; | ||
1213 | } | ||
1214 | case left_TransitionDir: | ||
1215 | setVisualOffset_Widget(sheet, -size_Root(sheet->root).x, 200, easeIn_AnimFlag); | ||
1216 | break; | ||
1217 | case top_TransitionDir: | ||
1218 | setVisualOffset_Widget(sheet, | ||
1219 | -bottom_Rect(boundsWithoutVisualOffset_Widget(sheet)), | ||
1220 | 200, | ||
1221 | easeIn_AnimFlag); | ||
1222 | break; | ||
1223 | case bottom_TransitionDir: | ||
1224 | setVisualOffset_Widget(sheet, height_Widget(sheet), 200, easeIn_AnimFlag); | ||
1225 | break; | ||
1226 | } | ||
1159 | } | 1227 | } |
1160 | } | 1228 | } |
diff --git a/src/ui/mobile.h b/src/ui/mobile.h index 30679c7c..e1131953 100644 --- a/src/ui/mobile.h +++ b/src/ui/mobile.h | |||
@@ -35,8 +35,23 @@ iWidget * makePanelsParent_Mobile (iWidget *parent, | |||
35 | const char *id, | 35 | const char *id, |
36 | const iMenuItem *itemsNullTerminated, | 36 | const iMenuItem *itemsNullTerminated, |
37 | const iMenuItem *actions, size_t numActions); | 37 | const iMenuItem *actions, size_t numActions); |
38 | void initPanels_Mobile (iWidget *panels, iWidget *parentWidget, | ||
39 | const iMenuItem *itemsNullTerminated, | ||
40 | const iMenuItem *actions, size_t numActions); | ||
41 | |||
42 | enum iTransitionFlags { | ||
43 | incoming_TransitionFlag = iBit(1), | ||
44 | dirMask_TransitionFlag = iBit(2) | iBit(3), | ||
45 | }; | ||
46 | |||
47 | enum iTransitionDir { | ||
48 | right_TransitionDir = 0, | ||
49 | bottom_TransitionDir = 2, | ||
50 | left_TransitionDir = 4, | ||
51 | top_TransitionDir = 6, | ||
52 | }; | ||
38 | 53 | ||
39 | void setupMenuTransition_Mobile (iWidget *menu, iBool isIncoming); | 54 | void setupMenuTransition_Mobile (iWidget *menu, iBool isIncoming); |
40 | void setupSheetTransition_Mobile (iWidget *sheet, iBool isIncoming); | 55 | void setupSheetTransition_Mobile (iWidget *sheet, int flags); |
41 | 56 | ||
42 | void finalizeSheet_Mobile (iWidget *sheet); | 57 | void finalizeSheet_Mobile (iWidget *sheet); |
diff --git a/src/ui/root.c b/src/ui/root.c index eae8e4bb..a792e93d 100644 --- a/src/ui/root.c +++ b/src/ui/root.c | |||
@@ -118,7 +118,7 @@ static const iMenuItem phoneNavMenuItems_[] = { | |||
118 | { "${menu.downloads}", 0, 0, "downloads.open" }, | 118 | { "${menu.downloads}", 0, 0, "downloads.open" }, |
119 | { "${menu.feeds.entrylist}", 0, 0, "!open url:about:feeds" }, | 119 | { "${menu.feeds.entrylist}", 0, 0, "!open url:about:feeds" }, |
120 | { "---" }, | 120 | { "---" }, |
121 | { gear_Icon " Settings...", SDLK_COMMA, KMOD_PRIMARY, "preferences" }, | 121 | { gear_Icon " ${menu.settings}", SDLK_COMMA, KMOD_PRIMARY, "preferences" }, |
122 | }; | 122 | }; |
123 | #endif /* Mobile */ | 123 | #endif /* Mobile */ |
124 | 124 | ||
@@ -1163,20 +1163,12 @@ void createUserInterface_Root(iRoot *d) { | |||
1163 | { star_Icon " ${menu.page.subscribe}", subscribeToPage_KeyModifier, "feeds.subscribe" }, | 1163 | { star_Icon " ${menu.page.subscribe}", subscribeToPage_KeyModifier, "feeds.subscribe" }, |
1164 | { book_Icon " ${menu.page.import}", 0, 0, "bookmark.links confirm:1" }, | 1164 | { book_Icon " ${menu.page.import}", 0, 0, "bookmark.links confirm:1" }, |
1165 | { globe_Icon " ${menu.page.translate}", 0, 0, "document.translate" }, | 1165 | { globe_Icon " ${menu.page.translate}", 0, 0, "document.translate" }, |
1166 | #if defined (iPlatformMobile) | ||
1167 | { "---" }, | ||
1168 | { "${menu.page.copyurl}", 0, 0, "document.copylink" }, | ||
1169 | { "${menu.page.copysource}", 'c', KMOD_PRIMARY, "copy" }, | ||
1170 | { download_Icon " " saveToDownloads_Label, SDLK_s, KMOD_PRIMARY, "document.save" } }, | ||
1171 | 11); | ||
1172 | #else | ||
1173 | { upload_Icon " ${menu.page.upload}", 0, 0, "document.upload" }, | 1166 | { upload_Icon " ${menu.page.upload}", 0, 0, "document.upload" }, |
1174 | { "---" }, | 1167 | { "---" }, |
1175 | { "${menu.page.copyurl}", 0, 0, "document.copylink" }, | 1168 | { "${menu.page.copyurl}", 0, 0, "document.copylink" }, |
1176 | { "${menu.page.copysource}", 'c', KMOD_PRIMARY, "copy" }, | 1169 | { "${menu.page.copysource}", 'c', KMOD_PRIMARY, "copy" }, |
1177 | { download_Icon " " saveToDownloads_Label, SDLK_s, KMOD_PRIMARY, "document.save" } }, | 1170 | { download_Icon " " saveToDownloads_Label, SDLK_s, KMOD_PRIMARY, "document.save" } }, |
1178 | 12); | 1171 | 12); |
1179 | #endif | ||
1180 | setId_Widget(as_Widget(pageMenuButton), "pagemenubutton"); | 1172 | setId_Widget(as_Widget(pageMenuButton), "pagemenubutton"); |
1181 | setFont_LabelWidget(pageMenuButton, uiContentBold_FontId); | 1173 | setFont_LabelWidget(pageMenuButton, uiContentBold_FontId); |
1182 | setAlignVisually_LabelWidget(pageMenuButton, iTrue); | 1174 | setAlignVisually_LabelWidget(pageMenuButton, iTrue); |
diff --git a/src/ui/uploadwidget.c b/src/ui/uploadwidget.c index 4c72c60a..fb8aaf0a 100644 --- a/src/ui/uploadwidget.c +++ b/src/ui/uploadwidget.c | |||
@@ -81,91 +81,122 @@ void init_UploadWidget(iUploadWidget *d) { | |||
81 | iWidget *w = as_Widget(d); | 81 | iWidget *w = as_Widget(d); |
82 | init_Widget(w); | 82 | init_Widget(w); |
83 | setId_Widget(w, "upload"); | 83 | setId_Widget(w, "upload"); |
84 | useSheetStyle_Widget(w); | ||
85 | init_String(&d->originalUrl); | 84 | init_String(&d->originalUrl); |
86 | init_String(&d->url); | 85 | init_String(&d->url); |
87 | d->viewer = NULL; | 86 | d->viewer = NULL; |
88 | d->request = NULL; | 87 | d->request = NULL; |
89 | init_String(&d->filePath); | 88 | init_String(&d->filePath); |
90 | d->fileSize = 0; | 89 | d->fileSize = 0; |
91 | addChildFlags_Widget(w, | 90 | const iMenuItem actions[] = { |
92 | iClob(new_LabelWidget(uiHeading_ColorEscape "${heading.upload}", NULL)), | 91 | { "${upload.port}", 0, 0, "upload.setport" }, |
93 | frameless_WidgetFlag); | 92 | { "---" }, |
94 | d->info = addChildFlags_Widget(w, iClob(new_LabelWidget("", NULL)), | 93 | { "${close}", SDLK_ESCAPE, 0, "upload.cancel" }, |
95 | frameless_WidgetFlag | resizeToParentWidth_WidgetFlag | | 94 | { uiTextAction_ColorEscape "${dlg.upload.send}", SDLK_RETURN, KMOD_PRIMARY, "upload.accept" } |
96 | fixedHeight_WidgetFlag); | 95 | }; |
97 | setWrap_LabelWidget(d->info, iTrue); | 96 | if (isUsingPanelLayout_Mobile()) { |
98 | /* Tabs for input data. */ | 97 | const iMenuItem textItems[] = { |
99 | iWidget *tabs = makeTabs_Widget(w); | 98 | { "title id:heading.upload.text" }, |
100 | /* Make the tabs support vertical expansion based on content. */ { | 99 | { "input id:upload.text noheading:1" }, |
101 | setFlags_Widget(tabs, resizeHeightOfChildren_WidgetFlag, iFalse); | 100 | { NULL } |
102 | setFlags_Widget(tabs, arrangeHeight_WidgetFlag, iTrue); | 101 | }; |
103 | iWidget *tabPages = findChild_Widget(tabs, "tabs.pages"); | 102 | const iMenuItem fileItems[] = { |
104 | setFlags_Widget(tabPages, resizeHeightOfChildren_WidgetFlag, iFalse); | 103 | { "title id:heading.upload.file" }, |
105 | setFlags_Widget(tabPages, arrangeHeight_WidgetFlag, iTrue); | 104 | { "button text:" uiTextAction_ColorEscape "${dlg.upload.pickfile}", 0, 0, "upload.pickfile" }, |
105 | { "heading id:upload.file.name" }, | ||
106 | { "label id:upload.filepathlabel" }, | ||
107 | { "heading id:upload.file.size" }, | ||
108 | { "label id:upload.filesizelabel" }, | ||
109 | { "padding" }, | ||
110 | { "input id:upload.mime" }, | ||
111 | { "label id:upload.counter text:" }, | ||
112 | { NULL } | ||
113 | }; | ||
114 | initPanels_Mobile(w, NULL, (iMenuItem[]){ | ||
115 | { "title id:heading.upload" }, | ||
116 | { "label id:upload.info" }, | ||
117 | // { "padding" }, | ||
118 | { "panel id:dlg.upload.text icon:0x1f5b9", 0, 0, (const void *) textItems }, | ||
119 | { "panel id:dlg.upload.file icon:0x1f4c1", 0, 0, (const void *) fileItems }, | ||
120 | { "padding" }, | ||
121 | { "input id:upload.token hint:hint.upload.token" }, | ||
122 | { NULL } | ||
123 | }, actions, iElemCount(actions)); | ||
124 | d->info = findChild_Widget(w, "upload.info"); | ||
125 | d->input = findChild_Widget(w, "upload.text"); | ||
126 | d->filePathLabel = findChild_Widget(w, "upload.file.name"); | ||
127 | d->fileSizeLabel = findChild_Widget(w, "upload.file.size"); | ||
128 | d->mime = findChild_Widget(w, "upload.mime"); | ||
129 | d->token = findChild_Widget(w, "upload.token"); | ||
130 | d->counter = findChild_Widget(w, "upload.counter"); | ||
106 | } | 131 | } |
107 | iWidget *headings, *values; | 132 | else { |
108 | setBackgroundColor_Widget(findChild_Widget(tabs, "tabs.buttons"), uiBackgroundSidebar_ColorId); | 133 | useSheetStyle_Widget(w); |
109 | setId_Widget(tabs, "upload.tabs"); | 134 | addChildFlags_Widget(w, |
110 | // const int bigGap = lineHeight_Text(uiLabel_FontId) * 3 / 4; | 135 | iClob(new_LabelWidget(uiHeading_ColorEscape "${heading.upload}", NULL)), |
111 | /* Text input. */ { | 136 | frameless_WidgetFlag); |
112 | //appendTwoColumnTabPage_Widget(tabs, "${heading.upload.text}", '1', &headings, &values); | 137 | d->info = addChildFlags_Widget(w, iClob(new_LabelWidget("", NULL)), |
113 | iWidget *page = new_Widget(); | 138 | frameless_WidgetFlag | resizeToParentWidth_WidgetFlag | |
114 | setFlags_Widget(page, arrangeSize_WidgetFlag, iTrue); | 139 | fixedHeight_WidgetFlag); |
115 | d->input = new_InputWidget(0); | 140 | setWrap_LabelWidget(d->info, iTrue); |
116 | setId_Widget(as_Widget(d->input), "upload.text"); | 141 | /* Tabs for input data. */ |
117 | setFont_InputWidget(d->input, monospace_FontId); | 142 | iWidget *tabs = makeTabs_Widget(w); |
118 | setLineLimits_InputWidget(d->input, 7, 20); | 143 | /* Make the tabs support vertical expansion based on content. */ { |
119 | setUseReturnKeyBehavior_InputWidget(d->input, iFalse); /* traditional text editor */ | 144 | setFlags_Widget(tabs, resizeHeightOfChildren_WidgetFlag, iFalse); |
120 | setHint_InputWidget(d->input, "${hint.upload.text}"); | 145 | setFlags_Widget(tabs, arrangeHeight_WidgetFlag, iTrue); |
121 | setFixedSize_Widget(as_Widget(d->input), init_I2(120 * gap_UI, -1)); | 146 | iWidget *tabPages = findChild_Widget(tabs, "tabs.pages"); |
122 | addChild_Widget(page, iClob(d->input)); | 147 | setFlags_Widget(tabPages, resizeHeightOfChildren_WidgetFlag, iFalse); |
123 | appendFramelessTabPage_Widget(tabs, iClob(page), "${heading.upload.text}", '1', 0); | 148 | setFlags_Widget(tabPages, arrangeHeight_WidgetFlag, iTrue); |
124 | } | 149 | } |
125 | /* File content. */ { | 150 | iWidget *headings, *values; |
126 | appendTwoColumnTabPage_Widget(tabs, "${heading.upload.file}", '2', &headings, &values); | 151 | setBackgroundColor_Widget(findChild_Widget(tabs, "tabs.buttons"), uiBackgroundSidebar_ColorId); |
127 | // iWidget *pad = addChild_Widget(headings, iClob(makePadding_Widget(0))); | 152 | setId_Widget(tabs, "upload.tabs"); |
128 | // iWidget *hint = addChild_Widget(values, iClob(new_LabelWidget("${upload.file.drophint}", NULL))); | 153 | /* Text input. */ { |
129 | // pad->sizeRef = hint; | 154 | iWidget *page = new_Widget(); |
130 | addChildFlags_Widget(headings, iClob(new_LabelWidget("${upload.file.name}", NULL)), frameless_WidgetFlag); | 155 | setFlags_Widget(page, arrangeSize_WidgetFlag, iTrue); |
131 | d->filePathLabel = addChildFlags_Widget(values, iClob(new_LabelWidget(uiTextAction_ColorEscape "${upload.file.drophere}", NULL)), frameless_WidgetFlag); | 156 | d->input = new_InputWidget(0); |
132 | addChildFlags_Widget(headings, iClob(new_LabelWidget("${upload.file.size}", NULL)), frameless_WidgetFlag); | 157 | setId_Widget(as_Widget(d->input), "upload.text"); |
133 | d->fileSizeLabel = addChildFlags_Widget(values, iClob(new_LabelWidget("\u2014", NULL)), frameless_WidgetFlag); | 158 | setFixedSize_Widget(as_Widget(d->input), init_I2(120 * gap_UI, -1)); |
134 | d->mime = new_InputWidget(0); | 159 | addChild_Widget(page, iClob(d->input)); |
135 | setFixedSize_Widget(as_Widget(d->mime), init_I2(70 * gap_UI, -1)); | 160 | appendFramelessTabPage_Widget(tabs, iClob(page), "${heading.upload.text}", '1', 0); |
136 | addTwoColumnDialogInputField_Widget(headings, values, "${upload.mime}", "upload.mime", iClob(d->mime)); | 161 | } |
137 | } | 162 | /* File content. */ { |
138 | /* Token. */ { | 163 | appendTwoColumnTabPage_Widget(tabs, "${heading.upload.file}", '2', &headings, &values); |
139 | addChild_Widget(w, iClob(makePadding_Widget(gap_UI))); | 164 | addChildFlags_Widget(headings, iClob(new_LabelWidget("${upload.file.name}", NULL)), frameless_WidgetFlag); |
140 | iWidget *page = makeTwoColumns_Widget(&headings, &values); | 165 | d->filePathLabel = addChildFlags_Widget(values, iClob(new_LabelWidget(uiTextAction_ColorEscape "${upload.file.drophere}", NULL)), frameless_WidgetFlag); |
141 | d->token = addTwoColumnDialogInputField_Widget( | 166 | addChildFlags_Widget(headings, iClob(new_LabelWidget("${upload.file.size}", NULL)), frameless_WidgetFlag); |
142 | headings, values, "${upload.token}", "upload.token", iClob(new_InputWidget(0))); | 167 | d->fileSizeLabel = addChildFlags_Widget(values, iClob(new_LabelWidget("\u2014", NULL)), frameless_WidgetFlag); |
143 | setHint_InputWidget(d->token, "${hint.upload.token}"); | 168 | d->mime = new_InputWidget(0); |
144 | setFixedSize_Widget(as_Widget(d->token), init_I2(50 * gap_UI, -1)); | 169 | setFixedSize_Widget(as_Widget(d->mime), init_I2(70 * gap_UI, -1)); |
145 | addChild_Widget(w, iClob(page)); | 170 | addTwoColumnDialogInputField_Widget(headings, values, "${upload.mime}", "upload.mime", iClob(d->mime)); |
146 | } | 171 | } |
147 | /* Buttons. */ { | 172 | /* Token. */ { |
148 | addChild_Widget(w, iClob(makePadding_Widget(gap_UI))); | 173 | addChild_Widget(w, iClob(makePadding_Widget(gap_UI))); |
149 | iWidget *buttons = | 174 | iWidget *page = makeTwoColumns_Widget(&headings, &values); |
150 | makeDialogButtons_Widget((iMenuItem[]){ { "${upload.port}", 0, 0, "upload.setport" }, | 175 | d->token = addTwoColumnDialogInputField_Widget( |
151 | { "---" }, | 176 | headings, values, "${upload.token}", "upload.token", iClob(new_InputWidget(0))); |
152 | { "${close}", SDLK_ESCAPE, 0, "upload.cancel" }, | 177 | setHint_InputWidget(d->token, "${hint.upload.token}"); |
153 | { uiTextAction_ColorEscape "${dlg.upload.send}", | 178 | setFixedSize_Widget(as_Widget(d->token), init_I2(50 * gap_UI, -1)); |
154 | SDLK_RETURN, | 179 | addChild_Widget(w, iClob(page)); |
155 | KMOD_PRIMARY, | 180 | } |
156 | "upload.accept" } }, | 181 | /* Buttons. */ { |
157 | 4); | 182 | addChild_Widget(w, iClob(makePadding_Widget(gap_UI))); |
158 | setId_Widget(insertChildAfterFlags_Widget(buttons, | 183 | iWidget *buttons = makeDialogButtons_Widget(actions, iElemCount(actions)); |
159 | iClob(d->counter = new_LabelWidget("", NULL)), | 184 | setId_Widget(insertChildAfterFlags_Widget(buttons, |
160 | 0, frameless_WidgetFlag), | 185 | iClob(d->counter = new_LabelWidget("", NULL)), |
161 | "upload.counter"); | 186 | 0, frameless_WidgetFlag), |
162 | addChild_Widget(w, iClob(buttons)); | 187 | "upload.counter"); |
188 | addChild_Widget(w, iClob(buttons)); | ||
189 | } | ||
190 | resizeToLargestPage_Widget(tabs); | ||
191 | arrange_Widget(w); | ||
192 | setFixedSize_Widget(as_Widget(d->token), init_I2(width_Widget(tabs) - left_Rect(parent_Widget(d->token)->rect), -1)); | ||
193 | setFlags_Widget(as_Widget(d->token), expand_WidgetFlag, iTrue); | ||
194 | setFocus_Widget(as_Widget(d->input)); | ||
163 | } | 195 | } |
164 | resizeToLargestPage_Widget(tabs); | 196 | setFont_InputWidget(d->input, monospace_FontId); |
165 | arrange_Widget(w); | 197 | setUseReturnKeyBehavior_InputWidget(d->input, iFalse); /* traditional text editor */ |
166 | setFixedSize_Widget(as_Widget(d->token), init_I2(width_Widget(tabs) - left_Rect(parent_Widget(d->token)->rect), -1)); | 198 | setLineLimits_InputWidget(d->input, 7, 20); |
167 | setFlags_Widget(as_Widget(d->token), expand_WidgetFlag, iTrue); | 199 | setHint_InputWidget(d->input, "${hint.upload.text}"); |
168 | setFocus_Widget(as_Widget(d->input)); | ||
169 | setBackupFileName_InputWidget(d->input, "uploadbackup.txt"); | 200 | setBackupFileName_InputWidget(d->input, "uploadbackup.txt"); |
170 | updateInputMaxHeight_UploadWidget_(d); | 201 | updateInputMaxHeight_UploadWidget_(d); |
171 | } | 202 | } |
@@ -201,6 +232,7 @@ static void setUrlPort_UploadWidget_(iUploadWidget *d, const iString *url, uint1 | |||
201 | appendFormat_String(&d->url, ":%u", overridePort ? overridePort : titanPortForUrl_(url)); | 232 | appendFormat_String(&d->url, ":%u", overridePort ? overridePort : titanPortForUrl_(url)); |
202 | appendRange_String(&d->url, (iRangecc){ parts.path.start, constEnd_String(url) }); | 233 | appendRange_String(&d->url, (iRangecc){ parts.path.start, constEnd_String(url) }); |
203 | setText_LabelWidget(d->info, &d->url); | 234 | setText_LabelWidget(d->info, &d->url); |
235 | arrange_Widget(as_Widget(d)); | ||
204 | } | 236 | } |
205 | 237 | ||
206 | void setUrl_UploadWidget(iUploadWidget *d, const iString *url) { | 238 | void setUrl_UploadWidget(iUploadWidget *d, const iString *url) { |
@@ -233,7 +265,7 @@ static iBool processEvent_UploadWidget_(iUploadWidget *d, const SDL_Event *ev) { | |||
233 | if (isResize_UserEvent(ev)) { | 265 | if (isResize_UserEvent(ev)) { |
234 | updateInputMaxHeight_UploadWidget_(d); | 266 | updateInputMaxHeight_UploadWidget_(d); |
235 | } | 267 | } |
236 | if (isCommand_Widget(w, ev, "upload.cancel")) { | 268 | if (equal_Command(cmd, "upload.cancel")) { |
237 | setupSheetTransition_Mobile(w, iFalse); | 269 | setupSheetTransition_Mobile(w, iFalse); |
238 | destroy_Widget(w); | 270 | destroy_Widget(w); |
239 | return iTrue; | 271 | return iTrue; |
diff --git a/src/ui/util.c b/src/ui/util.c index b875e260..6069e800 100644 --- a/src/ui/util.c +++ b/src/ui/util.c | |||
@@ -1061,6 +1061,7 @@ iWidget *removeTabPage_Widget(iWidget *tabs, size_t index) { | |||
1061 | } | 1061 | } |
1062 | 1062 | ||
1063 | void resizeToLargestPage_Widget(iWidget *tabs) { | 1063 | void resizeToLargestPage_Widget(iWidget *tabs) { |
1064 | if (!tabs) return; | ||
1064 | // puts("RESIZE TO LARGEST PAGE ..."); | 1065 | // puts("RESIZE TO LARGEST PAGE ..."); |
1065 | iWidget *pages = findChild_Widget(tabs, "tabs.pages"); | 1066 | iWidget *pages = findChild_Widget(tabs, "tabs.pages"); |
1066 | iForEach(ObjectList, i, children_Widget(pages)) { | 1067 | iForEach(ObjectList, i, children_Widget(pages)) { |
@@ -1216,7 +1217,7 @@ iBool valueInputHandler_(iWidget *dlg, const char *cmd) { | |||
1216 | postCommandf_App("valueinput.cancelled id:%s", cstr_String(id_Widget(dlg))); | 1217 | postCommandf_App("valueinput.cancelled id:%s", cstr_String(id_Widget(dlg))); |
1217 | setId_Widget(dlg, ""); /* no further commands to emit */ | 1218 | setId_Widget(dlg, ""); /* no further commands to emit */ |
1218 | } | 1219 | } |
1219 | setupSheetTransition_Mobile(dlg, iFalse); | 1220 | setupSheetTransition_Mobile(dlg, top_TransitionDir); |
1220 | destroy_Widget(dlg); | 1221 | destroy_Widget(dlg); |
1221 | return iTrue; | 1222 | return iTrue; |
1222 | } | 1223 | } |
@@ -1225,13 +1226,13 @@ iBool valueInputHandler_(iWidget *dlg, const char *cmd) { | |||
1225 | else if (equal_Command(cmd, "valueinput.cancel")) { | 1226 | else if (equal_Command(cmd, "valueinput.cancel")) { |
1226 | postCommandf_App("valueinput.cancelled id:%s", cstr_String(id_Widget(dlg))); | 1227 | postCommandf_App("valueinput.cancelled id:%s", cstr_String(id_Widget(dlg))); |
1227 | setId_Widget(dlg, ""); /* no further commands to emit */ | 1228 | setId_Widget(dlg, ""); /* no further commands to emit */ |
1228 | setupSheetTransition_Mobile(dlg, iFalse); | 1229 | setupSheetTransition_Mobile(dlg, top_TransitionDir); |
1229 | destroy_Widget(dlg); | 1230 | destroy_Widget(dlg); |
1230 | return iTrue; | 1231 | return iTrue; |
1231 | } | 1232 | } |
1232 | else if (equal_Command(cmd, "valueinput.accept")) { | 1233 | else if (equal_Command(cmd, "valueinput.accept")) { |
1233 | acceptValueInput_(dlg); | 1234 | acceptValueInput_(dlg); |
1234 | setupSheetTransition_Mobile(dlg, iFalse); | 1235 | setupSheetTransition_Mobile(dlg, top_TransitionDir); |
1235 | destroy_Widget(dlg); | 1236 | destroy_Widget(dlg); |
1236 | return iTrue; | 1237 | return iTrue; |
1237 | } | 1238 | } |
@@ -1345,7 +1346,9 @@ iWidget *makeValueInput_Widget(iWidget *parent, const iString *initialValue, con | |||
1345 | acceptKeyMod_ReturnKeyBehavior(prefs_App()->returnKey), | 1346 | acceptKeyMod_ReturnKeyBehavior(prefs_App()->returnKey), |
1346 | "valueinput.accept" } }, | 1347 | "valueinput.accept" } }, |
1347 | 2))); | 1348 | 2))); |
1348 | finalizeSheet_Mobile(dlg); | 1349 | // finalizeSheet_Mobile(dlg); |
1350 | arrange_Widget(dlg); | ||
1351 | setupSheetTransition_Mobile(dlg, incoming_TransitionFlag | top_TransitionDir); | ||
1349 | if (parent) { | 1352 | if (parent) { |
1350 | setFocus_Widget(as_Widget(input)); | 1353 | setFocus_Widget(as_Widget(input)); |
1351 | } | 1354 | } |
@@ -1915,6 +1918,7 @@ iWidget *makePreferences_Widget(void) { | |||
1915 | { NULL } | 1918 | { NULL } |
1916 | }; | 1919 | }; |
1917 | iWidget *dlg = makePanels_Mobile("prefs", (iMenuItem[]){ | 1920 | iWidget *dlg = makePanels_Mobile("prefs", (iMenuItem[]){ |
1921 | { "title id:heading.settings" }, | ||
1918 | { "panel text:" gear_Icon " ${heading.prefs.general}", 0, 0, (const void *) generalPanelItems }, | 1922 | { "panel text:" gear_Icon " ${heading.prefs.general}", 0, 0, (const void *) generalPanelItems }, |
1919 | { "panel icon:0x1f5a7 id:heading.prefs.network", 0, 0, (const void *) networkPanelItems }, | 1923 | { "panel icon:0x1f5a7 id:heading.prefs.network", 0, 0, (const void *) networkPanelItems }, |
1920 | { "panel text:" person_Icon " ${sidebar.identities}", 0, 0, (const void *) identityPanelItems }, | 1924 | { "panel text:" person_Icon " ${sidebar.identities}", 0, 0, (const void *) identityPanelItems }, |
@@ -2405,7 +2409,7 @@ iWidget *makeFeedSettings_Widget(uint32_t bookmarkId) { | |||
2405 | arrange_Widget(dlg); | 2409 | arrange_Widget(dlg); |
2406 | as_Widget(input)->rect.size.x = 100 * gap_UI - headings->rect.size.x; | 2410 | as_Widget(input)->rect.size.x = 100 * gap_UI - headings->rect.size.x; |
2407 | addChild_Widget(get_Root()->widget, iClob(dlg)); | 2411 | addChild_Widget(get_Root()->widget, iClob(dlg)); |
2408 | finalizeSheet_Mobile(dlg); | 2412 | // finalizeSheet_Mobile(dlg); |
2409 | } | 2413 | } |
2410 | /* Initialize. */ { | 2414 | /* Initialize. */ { |
2411 | const iBookmark *bm = bookmarkId ? get_Bookmarks(bookmarks_App(), bookmarkId) : NULL; | 2415 | const iBookmark *bm = bookmarkId ? get_Bookmarks(bookmarks_App(), bookmarkId) : NULL; |
@@ -2419,6 +2423,7 @@ iWidget *makeFeedSettings_Widget(uint32_t bookmarkId) { | |||
2419 | iTrue); | 2423 | iTrue); |
2420 | setCommandHandler_Widget(dlg, handleFeedSettingCommands_); | 2424 | setCommandHandler_Widget(dlg, handleFeedSettingCommands_); |
2421 | } | 2425 | } |
2426 | setupSheetTransition_Mobile(dlg, incoming_TransitionFlag); | ||
2422 | return dlg; | 2427 | return dlg; |
2423 | } | 2428 | } |
2424 | 2429 | ||
diff --git a/src/ui/widget.c b/src/ui/widget.c index 4fd8f066..659a00cc 100644 --- a/src/ui/widget.c +++ b/src/ui/widget.c | |||
@@ -452,7 +452,7 @@ static void arrange_Widget_(iWidget *d) { | |||
452 | else if (d->flags & centerHorizontal_WidgetFlag) { | 452 | else if (d->flags & centerHorizontal_WidgetFlag) { |
453 | centerHorizontal_Widget_(d); | 453 | centerHorizontal_Widget_(d); |
454 | } | 454 | } |
455 | if (d->flags & resizeToParentWidth_WidgetFlag) { | 455 | if (d->flags & resizeToParentWidth_WidgetFlag && d->parent) { |
456 | iRect childBounds = zero_Rect(); | 456 | iRect childBounds = zero_Rect(); |
457 | if (flags_Widget(d->parent) & arrangeWidth_WidgetFlag) { | 457 | if (flags_Widget(d->parent) & arrangeWidth_WidgetFlag) { |
458 | /* Can't go narrower than what the children require, though. */ | 458 | /* Can't go narrower than what the children require, though. */ |
@@ -462,7 +462,7 @@ static void arrange_Widget_(iWidget *d) { | |||
462 | setWidth_Widget_(d, iMaxi(width_Rect(innerRect_Widget_(d->parent)), | 462 | setWidth_Widget_(d, iMaxi(width_Rect(innerRect_Widget_(d->parent)), |
463 | width_Rect(childBounds))); | 463 | width_Rect(childBounds))); |
464 | } | 464 | } |
465 | if (d->flags & resizeToParentHeight_WidgetFlag) { | 465 | if (d->flags & resizeToParentHeight_WidgetFlag && d->parent) { |
466 | TRACE(d, "resize to parent height"); | 466 | TRACE(d, "resize to parent height"); |
467 | setHeight_Widget_(d, height_Rect(innerRect_Widget_(d->parent))); | 467 | setHeight_Widget_(d, height_Rect(innerRect_Widget_(d->parent))); |
468 | } | 468 | } |