=> 1410bbde7779efe3a20f603523547c8b8f55b6a1
[1mdiff --git a/po/en.po b/po/en.po[m [1mindex dd3af388..546a9489 100644[m [1m--- a/po/en.po[m [1m+++ b/po/en.po[m [36m@@ -251,6 +251,10 @@[m [mmsgstr "Show Feed Entries"[m msgid "menu.preferences"[m msgstr "Preferences…"[m [m [32m+[m[32m# used for Preferences on mobile[m [32m+[m[32mmsgid "menu.settings"[m [32m+[m[32mmsgstr "Settings…"[m [32m+[m msgid "menu.help"[m msgstr "Help"[m [m [36m@@ -906,7 +910,7 @@[m [mmsgid "heading.lookup.other"[m msgstr "OTHER"[m [m msgid "menu.page.upload"[m [31m-msgstr "Upload Page with Titan"[m [32m+[m[32mmsgstr "Upload Page with Titan…"[m [m msgid "heading.upload"[m msgstr "UPLOAD WITH TITAN"[m [36m@@ -953,6 +957,18 @@[m [mmsgstr "Set the Titan server port to use for this URL.\nThe port is saved in the[m msgid "dlg.uploadport.set"[m msgstr "Set Port"[m [m [32m+[m[32m# used on mobile[m [32m+[m[32mmsgid "dlg.upload.text"[m [32m+[m[32mmsgstr "Upload Plain Text"[m [32m+[m [32m+[m[32m# used on mobile[m [32m+[m[32mmsgid "dlg.upload.file"[m [32m+[m[32mmsgstr "Upload a File"[m [32m+[m [32m+[m[32m# used on mobile[m [32m+[m[32mmsgid "dlg.upload.pickfile"[m [32m+[m[32mmsgstr "Select File…"[m [32m+[m msgid "heading.translate"[m msgstr "TRANSLATE PAGE"[m [m [36m@@ -1151,6 +1167,10 @@[m [mmsgstr "SPECIAL TAGS"[m msgid "heading.prefs"[m msgstr "PREFERENCES"[m [m [32m+[m[32m# used on mobile[m [32m+[m[32mmsgid "heading.settings"[m [32m+[m[32mmsgstr "SETTINGS"[m [32m+[m msgid "heading.prefs.certs"[m msgstr "CERTIFICATES"[m [m [1mdiff --git a/res/lang/de.bin b/res/lang/de.bin[m [1mindex 9d87657f..ba87d002 100644[m Binary files a/res/lang/de.bin and b/res/lang/de.bin differ [1mdiff --git a/res/lang/en.bin b/res/lang/en.bin[m [1mindex 9fe4cfb3..a7dfb866 100644[m Binary files a/res/lang/en.bin and b/res/lang/en.bin differ [1mdiff --git a/res/lang/es.bin b/res/lang/es.bin[m [1mindex 1effaf3d..7e7398d6 100644[m Binary files a/res/lang/es.bin and b/res/lang/es.bin differ [1mdiff --git a/res/lang/fi.bin b/res/lang/fi.bin[m [1mindex fcaa8cc6..607e52fd 100644[m Binary files a/res/lang/fi.bin and b/res/lang/fi.bin differ [1mdiff --git a/res/lang/fr.bin b/res/lang/fr.bin[m [1mindex 32104f44..955695ed 100644[m Binary files a/res/lang/fr.bin and b/res/lang/fr.bin differ [1mdiff --git a/res/lang/ia.bin b/res/lang/ia.bin[m [1mindex 5b64a182..61a18efc 100644[m Binary files a/res/lang/ia.bin and b/res/lang/ia.bin differ [1mdiff --git a/res/lang/ie.bin b/res/lang/ie.bin[m [1mindex 6d568972..06ea7979 100644[m Binary files a/res/lang/ie.bin and b/res/lang/ie.bin differ [1mdiff --git a/res/lang/pl.bin b/res/lang/pl.bin[m [1mindex 69ad06f8..5fc5e24a 100644[m Binary files a/res/lang/pl.bin and b/res/lang/pl.bin differ [1mdiff --git a/res/lang/ru.bin b/res/lang/ru.bin[m [1mindex 67babbcd..1718f647 100644[m Binary files a/res/lang/ru.bin and b/res/lang/ru.bin differ [1mdiff --git a/res/lang/sr.bin b/res/lang/sr.bin[m [1mindex a7f7639b..60b7b600 100644[m Binary files a/res/lang/sr.bin and b/res/lang/sr.bin differ [1mdiff --git a/res/lang/tok.bin b/res/lang/tok.bin[m [1mindex b7476101..3298f0e8 100644[m Binary files a/res/lang/tok.bin and b/res/lang/tok.bin differ [1mdiff --git a/res/lang/zh_Hans.bin b/res/lang/zh_Hans.bin[m [1mindex 03eb8b43..8c32a0c5 100644[m Binary files a/res/lang/zh_Hans.bin and b/res/lang/zh_Hans.bin differ [1mdiff --git a/res/lang/zh_Hant.bin b/res/lang/zh_Hant.bin[m [1mindex c0378db8..68f7d3bc 100644[m Binary files a/res/lang/zh_Hant.bin and b/res/lang/zh_Hant.bin differ [1mdiff --git a/src/app.c b/src/app.c[m [1mindex a52552c0..e597edbe 100644[m [1m--- a/src/app.c[m [1m+++ b/src/app.c[m [36m@@ -2382,7 +2382,8 @@[m [miBool handleCommand_App(const char *cmd) {[m setUrl_UploadWidget(upload, url);[m setResponseViewer_UploadWidget(upload, document_App());[m addChild_Widget(get_Root()->widget, iClob(upload));[m [31m- finalizeSheet_Mobile(as_Widget(upload));[m [32m+[m[32m// finalizeSheet_Mobile(as_Widget(upload));[m [32m+[m[32m setupSheetTransition_Mobile(as_Widget(upload), iTrue);[m postRefresh_App();[m return iTrue;[m }[m [36m@@ -2761,7 +2762,9 @@[m [miBool handleCommand_App(const char *cmd) {[m iCertImportWidget *imp = new_CertImportWidget();[m setPageContent_CertImportWidget(imp, sourceContent_DocumentWidget(document_App()));[m addChild_Widget(get_Root()->widget, iClob(imp));[m [31m- finalizeSheet_Mobile(as_Widget(imp));[m [32m+[m[32m// finalizeSheet_Mobile(as_Widget(imp));[m [32m+[m[32m arrange_Widget(as_Widget(imp));[m [32m+[m[32m setupSheetTransition_Mobile(as_Widget(imp), iTrue);[m postRefresh_App();[m return iTrue;[m }[m [1mdiff --git a/src/ui/certimportwidget.c b/src/ui/certimportwidget.c[m [1mindex 2e60c71f..65cb6654 100644[m [1m--- a/src/ui/certimportwidget.c[m [1m+++ b/src/ui/certimportwidget.c[m [36m@@ -104,61 +104,83 @@[m [mstatic iBool tryImport_CertImportWidget_(iCertImportWidget *d, const iBlock *dat[m [m void init_CertImportWidget(iCertImportWidget *d) {[m iWidget *w = as_Widget(d);[m [32m+[m[32m const iMenuItem actions[] = {[m [32m+[m[32m#if defined (iPlatformAppleMobile)[m [32m+[m[32m { "${dlg.certimport.pickfile}", 0, 0, "certimport.pickfile" },[m [32m+[m[32m { "---" },[m [32m+[m[32m#endif[m [32m+[m[32m { "${cancel}" },[m [32m+[m[32m { uiTextAction_ColorEscape "${dlg.certimport.import}",[m [32m+[m[32m SDLK_RETURN, KMOD_PRIMARY,[m [32m+[m[32m "certimport.accept" }[m [32m+[m[32m };[m init_Widget(w);[m setId_Widget(w, "certimport");[m d->cert = NULL;[m [31m- /* This should behave similar to sheets. */ [m [31m- useSheetStyle_Widget(w);[m [31m- addChildFlags_Widget([m [31m- w,[m [31m- iClob(new_LabelWidget(uiHeading_ColorEscape "${heading.certimport}", NULL)),[m [31m- frameless_WidgetFlag);[m [31m- d->info = addChildFlags_Widget(w, iClob(new_LabelWidget(infoText_, NULL)), frameless_WidgetFlag);[m [31m- addChild_Widget(w, iClob(makePadding_Widget(gap_UI)));[m [31m- d->crtLabel = new_LabelWidget("", NULL); {[m [31m- setFont_LabelWidget(d->crtLabel, uiContent_FontId);[m [31m- addChildFlags_Widget(w, iClob(d->crtLabel), 0);[m [31m- setFrameColor_Widget(as_Widget(d->crtLabel), uiTextCaution_ColorId);[m [32m+[m[32m if (isUsingPanelLayout_Mobile()) {[m [32m+[m[32m initPanels_Mobile(w, NULL, (iMenuItem[]){[m [32m+[m[32m { "title id:heading.certimport" },[m [32m+[m[32m { format_CStr("label id:certimport.info text:%s", infoText_) },[m [32m+[m[32m //{ "padding" },[m [32m+[m[32m { "label id:certimport.crt nowrap:1 frame:1" },[m [32m+[m[32m { "padding arg:0.25" },[m [32m+[m[32m { "label id:certimport.key nowrap:1 frame:1" },[m [32m+[m[32m { "heading text:${dlg.certimport.notes}" },[m [32m+[m[32m { "input id:certimport.notes hint:hint.certimport.description noheading:1" },[m [32m+[m[32m { NULL }[m [32m+[m[32m }, actions, iElemCount(actions));[m [32m+[m[32m d->info = findChild_Widget(w, "certimport.info");[m [32m+[m[32m d->crtLabel = findChild_Widget(w, "certimport.crt");[m [32m+[m[32m d->keyLabel = findChild_Widget(w, "certimport.key");[m [32m+[m[32m d->notes = findChild_Widget(w, "certimport.notes");[m [32m+[m[32m setFixedSize_Widget(as_Widget(d->crtLabel), init_I2(-1, gap_UI * 12));[m [32m+[m[32m setFixedSize_Widget(as_Widget(d->keyLabel), init_I2(-1, gap_UI * 12));[m }[m [31m- d->keyLabel = new_LabelWidget("", NULL); {[m [31m- setFont_LabelWidget(d->keyLabel, uiContent_FontId);[m [32m+[m[32m else {[m [32m+[m[32m /* This should behave similar to sheets. */[m[41m [m [32m+[m[32m useSheetStyle_Widget(w);[m [32m+[m[32m addChildFlags_Widget([m [32m+[m[32m w,[m [32m+[m[32m iClob(new_LabelWidget(uiHeading_ColorEscape "${heading.certimport}", NULL)),[m [32m+[m[32m frameless_WidgetFlag);[m [32m+[m[32m d->info = addChildFlags_Widget(w, iClob(new_LabelWidget(infoText_, NULL)), frameless_WidgetFlag);[m addChild_Widget(w, iClob(makePadding_Widget(gap_UI)));[m [31m- addChildFlags_Widget(w, iClob(d->keyLabel), 0);[m [31m- setFrameColor_Widget(as_Widget(d->keyLabel), uiTextCaution_ColorId);[m [31m- }[m [31m- addChild_Widget(w, iClob(makePadding_Widget(gap_UI)));[m [31m- /* TODO: Use makeTwoColumnWidget_() */[m [31m- iWidget *page = new_Widget(); {[m [31m- setFlags_Widget(page, arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag, iTrue);[m [31m- iWidget *headings = addChildFlags_Widget([m [31m- page, iClob(new_Widget()), arrangeVertical_WidgetFlag | arrangeSize_WidgetFlag);[m [31m- iWidget *values = addChildFlags_Widget([m [31m- page, iClob(new_Widget()), arrangeVertical_WidgetFlag | arrangeSize_WidgetFlag);[m [31m-// addChild_Widget(headings, iClob(makeHeading_Widget("${dlg.certimport.notes}")));[m [31m-// addChild_Widget(values, iClob(d->notes = new_InputWidget(0)));[m [31m-// setHint_InputWidget(d->notes, "${hint.certimport.description}");[m [31m- addTwoColumnDialogInputField_Widget([m [31m- headings,[m [31m- values,[m [31m- "${dlg.certimport.notes}",[m [31m- "",[m [31m- iClob(d->notes = newHint_InputWidget(0, "${hint.certimport.description}")));[m [31m- as_Widget(d->notes)->rect.size.x = gap_UI * 70;[m [32m+[m[32m d->crtLabel = new_LabelWidget("", NULL); {[m [32m+[m[32m setFont_LabelWidget(d->crtLabel, uiContent_FontId);[m [32m+[m[32m addChildFlags_Widget(w, iClob(d->crtLabel), 0);[m [32m+[m[32m }[m [32m+[m[32m d->keyLabel = new_LabelWidget("", NULL); {[m [32m+[m[32m setFont_LabelWidget(d->keyLabel, uiContent_FontId);[m [32m+[m[32m addChild_Widget(w, iClob(makePadding_Widget(gap_UI)));[m [32m+[m[32m addChildFlags_Widget(w, iClob(d->keyLabel), 0);[m [32m+[m[32m }[m [32m+[m[32m addChild_Widget(w, iClob(makePadding_Widget(gap_UI)));[m [32m+[m[32m /* TODO: Use makeTwoColumnWidget_() */[m [32m+[m[32m iWidget *page = new_Widget(); {[m [32m+[m[32m setFlags_Widget(page, arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag, iTrue);[m [32m+[m[32m iWidget *headings = addChildFlags_Widget([m [32m+[m[32m page, iClob(new_Widget()), arrangeVertical_WidgetFlag | arrangeSize_WidgetFlag);[m [32m+[m[32m iWidget *values = addChildFlags_Widget([m [32m+[m[32m page, iClob(new_Widget()), arrangeVertical_WidgetFlag | arrangeSize_WidgetFlag);[m [32m+[m[32m addTwoColumnDialogInputField_Widget([m [32m+[m[32m headings,[m [32m+[m[32m values,[m [32m+[m[32m "${dlg.certimport.notes}",[m [32m+[m[32m "",[m [32m+[m[32m iClob(d->notes = newHint_InputWidget(0, "${hint.certimport.description}")));[m [32m+[m[32m as_Widget(d->notes)->rect.size.x = gap_UI * 70;[m [32m+[m[32m }[m [32m+[m[32m addChild_Widget(w, iClob(page));[m [32m+[m[32m arrange_Widget(w);[m [32m+[m[32m setFixedSize_Widget(as_Widget(d->crtLabel), init_I2(width_Widget(w) - 6.5 * gap_UI, gap_UI * 12));[m [32m+[m[32m setFixedSize_Widget(as_Widget(d->keyLabel), init_I2(width_Widget(w) - 6.5 * gap_UI, gap_UI * 12));[m [32m+[m[32m /* Buttons. */[m [32m+[m[32m addChild_Widget(w, iClob(makePadding_Widget(gap_UI)));[m [32m+[m[32m iWidget *buttons = makeDialogButtons_Widget(actions, iElemCount(actions));[m [32m+[m[32m addChild_Widget(w, iClob(buttons));[m }[m [31m- addChild_Widget(w, iClob(page));[m [31m- arrange_Widget(w);[m [31m- setFixedSize_Widget(as_Widget(d->crtLabel), init_I2(width_Widget(w) - 6.5 * gap_UI, gap_UI * 12));[m [31m- setFixedSize_Widget(as_Widget(d->keyLabel), init_I2(width_Widget(w) - 6.5 * gap_UI, gap_UI * 12));[m [31m- /* Buttons. */[m [31m- addChild_Widget(w, iClob(makePadding_Widget(gap_UI)));[m [31m- iWidget *buttons = makeDialogButtons_Widget([m [31m- (iMenuItem[]){ { "${cancel}" },[m [31m- { uiTextAction_ColorEscape "${dlg.certimport.import}",[m [31m- SDLK_RETURN,[m [31m- KMOD_PRIMARY,[m [31m- "certimport.accept" } },[m [31m- 2);[m [31m- addChild_Widget(w, iClob(buttons));[m [32m+[m[32m setFrameColor_Widget(as_Widget(d->crtLabel), uiTextCaution_ColorId);[m [32m+[m[32m setFrameColor_Widget(as_Widget(d->keyLabel), uiTextCaution_ColorId);[m if (deviceType_App() != desktop_AppDeviceType) {[m /* Try auto-pasting. */[m postCommand_App("certimport.paste");[m [1mdiff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c[m [1mindex 83f2ea6a..4b3c2db0 100644[m [1m--- a/src/ui/documentwidget.c[m [1m+++ b/src/ui/documentwidget.c[m [36m@@ -2852,7 +2852,8 @@[m [mstatic iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd)[m setUrl_UploadWidget(upload, d->mod.url);[m setResponseViewer_UploadWidget(upload, d);[m addChild_Widget(get_Root()->widget, iClob(upload));[m [31m- finalizeSheet_Mobile(as_Widget(upload));[m [32m+[m[32m// finalizeSheet_Mobile(as_Widget(upload));[m [32m+[m[32m setupSheetTransition_Mobile(as_Widget(upload), iTrue);[m postRefresh_App();[m }[m return iTrue;[m [36m@@ -3679,16 +3680,10 @@[m [mstatic iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e[m { "---" },[m { book_Icon " ${menu.page.import}", 0, 0, "bookmark.links confirm:1" },[m { globe_Icon " ${menu.page.translate}", 0, 0, "document.translate" },[m [31m-#if defined (iPlatformMobile)[m [31m- { "---" },[m [31m- { "${menu.page.copyurl}", 0, 0, "document.copylink" } },[m [31m- 14);[m [31m-#else[m { upload_Icon " ${menu.page.upload}", 0, 0, "document.upload" },[m { "---" },[m { "${menu.page.copyurl}", 0, 0, "document.copylink" } },[m 15);[m [31m-#endif[m if (isEmpty_Range(&d->selectMark)) {[m pushBackN_Array([m &items,[m [1mdiff --git a/src/ui/labelwidget.c b/src/ui/labelwidget.c[m [1mindex 03595d1a..ec324d02 100644[m [1m--- a/src/ui/labelwidget.c[m [1m+++ b/src/ui/labelwidget.c[m [36m@@ -244,6 +244,9 @@[m [mstatic void getColors_LabelWidget_(const iLabelWidget *d, int *bg, int *fg, int[m }[m }[m }[m [32m+[m[32m if (d->forceFg >= 0) {[m [32m+[m[32m *fg = d->forceFg;[m [32m+[m[32m }[m if (isPress) {[m *bg = uiBackgroundPressed_ColorId | permanent_ColorId;[m if (isButton) {[m [36m@@ -257,9 +260,6 @@[m [mstatic void getColors_LabelWidget_(const iLabelWidget *d, int *bg, int *fg, int[m *fg = isDark_ColorTheme(colorTheme_App()) ? white_ColorId : black_ColorId;[m }[m }[m [31m- if (d->forceFg >= 0) {[m [31m- *fg = d->forceFg;[m [31m- }[m }[m [m iLocalDef int iconPadding_LabelWidget_(const iLabelWidget *d) {[m [36m@@ -318,6 +318,10 @@[m [mstatic void draw_LabelWidget_(const iLabelWidget *d) {[m }[m setClip_Paint(&p, rect);[m const int iconPad = iconPadding_LabelWidget_(d);[m [32m+[m[32m const int iconColor = isCaution ? uiTextCaution_ColorId[m [32m+[m[32m : flags & (disabled_WidgetFlag | pressed_WidgetFlag) ? fg[m [32m+[m[32m : isHover ? uiIconHover_ColorId[m [32m+[m[32m : uiIcon_ColorId;[m if (d->icon && d->icon != 0x20) { /* no need to draw an empty icon */[m iString str;[m initUnicodeN_String(&str, &d->icon, 1);[m [36m@@ -331,10 +335,7 @@[m [mstatic void draw_LabelWidget_(const iLabelWidget *d) {[m -gap_UI / 8)),[m init_I2(iconPad, lineHeight_Text(d->font)) },[m iTrue,[m [31m- isCaution ? uiTextCaution_ColorId[m [31m- : flags & (disabled_WidgetFlag | pressed_WidgetFlag) ? fg[m [31m- : isHover ? uiIconHover_ColorId[m [31m- : uiIcon_ColorId,[m [32m+[m[32m iconColor,[m "%s",[m cstr_String(&str));[m deinit_String(&str);[m [36m@@ -387,7 +388,7 @@[m [mstatic void draw_LabelWidget_(const iLabelWidget *d) {[m drawCentered_Text(d->font,[m (iRect){ addX_I2(topRight_Rect(chRect), -iconPad),[m init_I2(chSize, height_Rect(chRect)) },[m [31m- iTrue, uiSeparator_ColorId, rightAngle_Icon);[m [32m+[m[32m iTrue, iconColor /*uiSeparator_ColorId*/, rightAngle_Icon);[m }[m unsetClip_Paint(&p);[m }[m [1mdiff --git a/src/ui/mobile.c b/src/ui/mobile.c[m [1mindex daa1fa1a..6ea672e6 100644[m [1m--- a/src/ui/mobile.c[m [1m+++ b/src/ui/mobile.c[m [36m@@ -90,15 +90,15 @@[m [mstatic void unselectAllPanelButtons_(iWidget *topPanel) {[m [m static iBool mainDetailSplitHandler_(iWidget *mainDetailSplit, const char *cmd) {[m if (equal_Command(cmd, "window.resized")) {[m [31m- const iBool isPortrait = (deviceType_App() == phone_AppDeviceType && isPortrait_App());[m [31m- const iRect safeRoot = safeRect_Root(mainDetailSplit->root);[m [31m- setPos_Widget(mainDetailSplit, topLeft_Rect(safeRoot));[m [31m- setFixedSize_Widget(mainDetailSplit, safeRoot.size);[m [32m+[m[32m const iBool isPortrait = (deviceType_App() == phone_AppDeviceType && isPortrait_App());[m [32m+[m[32m const iRect safeRoot = safeRect_Root(mainDetailSplit->root);[m iWidget * sheet = parent_Widget(mainDetailSplit);[m iWidget * navi = findChild_Widget(sheet, "panel.navi");[m iWidget * detailStack = findChild_Widget(mainDetailSplit, "detailstack");[m const size_t numPanels = childCount_Widget(detailStack);[m const iBool isSideBySide = isSideBySideLayout_() && numPanels > 0;[m [32m+[m[32m setPos_Widget(mainDetailSplit, topLeft_Rect(safeRoot));[m [32m+[m[32m setFixedSize_Widget(mainDetailSplit, safeRoot.size);[m setFlags_Widget(mainDetailSplit, arrangeHorizontal_WidgetFlag, isSideBySide);[m setFlags_Widget(detailStack, expand_WidgetFlag, isSideBySide);[m setFlags_Widget(detailStack, hidden_WidgetFlag, numPanels == 0);[m [36m@@ -172,7 +172,16 @@[m [mstatic iBool topPanelHandler_(iWidget *topPanel, const char *cmd) {[m }[m unselectAllPanelButtons_(topPanel);[m if (!wasClosed) {[m [31m- postCommand_App("prefs.dismiss");[m [32m+[m[32m /* TODO: Should come up with a more general-purpose approach here. */[m [32m+[m[32m if (findWidget_App("prefs")) {[m [32m+[m[32m postCommand_App("prefs.dismiss");[m [32m+[m[32m }[m [32m+[m[32m else if (findWidget_App("upload")) {[m [32m+[m[32m postCommand_App("upload.cancel");[m [32m+[m[32m }[m [32m+[m[32m else {[m [32m+[m[32m postCommand_App("cancel");[m [32m+[m[32m }[m }[m return iTrue;[m }[m [36m@@ -503,11 +512,19 @@[m [mvoid makePanelItem_Mobile(iWidget *panel, const iMenuItem *item) {[m else if (equal_Command(spec, "label")) {[m iLabelWidget *lab = new_LabelWidget(label, NULL);[m widget = as_Widget(lab);[m [31m- setWrap_LabelWidget(lab, iTrue);[m [31m- setFlags_Widget(widget, fixedHeight_WidgetFlag | frameless_WidgetFlag, iTrue);[m [32m+[m[32m setId_Widget(widget, id);[m [32m+[m[32m setWrap_LabelWidget(lab, !argLabel_Command(spec, "nowrap"));[m [32m+[m[32m setFlags_Widget(widget,[m [32m+[m[32m fixedHeight_WidgetFlag |[m [32m+[m[32m (!argLabel_Command(spec, "frame") ? frameless_WidgetFlag : 0),[m [32m+[m[32m iTrue);[m }[m else if (equal_Command(spec, "padding")) {[m [31m- widget = makePadding_Widget(lineHeight_Text(labelFont_()) * 1.5f);[m [32m+[m[32m float height = 1.5f;[m [32m+[m[32m if (hasLabel_Command(spec, "arg")) {[m [32m+[m[32m height *= argfLabel_Command(spec, "arg");[m [32m+[m[32m }[m [32m+[m[32m widget = makePadding_Widget(lineHeight_Text(labelFont_()) * height);[m }[m /* Apply common styling to the heading. */[m if (heading) {[m [36m@@ -539,7 +556,7 @@[m [mstatic const iMenuItem *findDialogCancelAction_(const iMenuItem *items, size_t n[m return NULL;[m }[m for (size_t i = 0; i < n; i++) {[m [31m- if (!iCmpStr(items[i].label, "${cancel}")) {[m [32m+[m[32m if (!iCmpStr(items[i].label, "${cancel}") || !iCmpStr(items[i].label, "${close}")) {[m return &items[i];[m }[m }[m [36m@@ -556,13 +573,20 @@[m [miWidget *makePanelsParent_Mobile(iWidget *parentWidget,[m const char *id,[m const iMenuItem *itemsNullTerminated,[m const iMenuItem *actions, size_t numActions) {[m [32m+[m[32m iWidget *panels = new_Widget();[m [32m+[m[32m setId_Widget(panels, id);[m [32m+[m[32m initPanels_Mobile(panels, parentWidget, itemsNullTerminated, actions, numActions);[m [32m+[m[32m return panels;[m [32m+[m[32m}[m [32m+[m [32m+[m[32mvoid initPanels_Mobile(iWidget *panels, iWidget *parentWidget,[m[41m [m [32m+[m[32m const iMenuItem *itemsNullTerminated,[m [32m+[m[32m const iMenuItem *actions, size_t numActions) {[m /* A multipanel widget has a top panel and one or more detail panels. In a horizontal layout,[m the detail panels slide in from the right and cover the top panel. In a landscape layout,[m the detail panels are always visible on the side. */[m [31m- iWidget *sheet = new_Widget();[m [31m- setId_Widget(sheet, id);[m [31m- setBackgroundColor_Widget(sheet, uiBackground_ColorId);[m [31m- setFlags_Widget(sheet,[m [32m+[m[32m setBackgroundColor_Widget(panels, uiBackground_ColorId);[m [32m+[m[32m setFlags_Widget(panels,[m resizeToParentWidth_WidgetFlag | resizeToParentHeight_WidgetFlag |[m frameless_WidgetFlag | focusRoot_WidgetFlag | commandOnClick_WidgetFlag |[m overflowScrollable_WidgetFlag | leftEdgeDraggable_WidgetFlag,[m [36m@@ -572,7 +596,7 @@[m [miWidget *makePanelsParent_Mobile(iWidget *parentWidget,[m setCommandHandler_Widget(mainDetailSplit, mainDetailSplitHandler_);[m setFlags_Widget(mainDetailSplit, resizeHeightOfChildren_WidgetFlag, iFalse);[m setId_Widget(mainDetailSplit, "mdsplit");[m [31m- addChild_Widget(sheet, iClob(mainDetailSplit));[m [32m+[m[32m addChild_Widget(panels, iClob(mainDetailSplit));[m }[m /* The panel roots. */[m iWidget *topPanel = new_Widget(); {[m [36m@@ -591,7 +615,6 @@[m [miWidget *makePanelsParent_Mobile(iWidget *parentWidget,[m setFlags_Widget(detailStack, collapse_WidgetFlag | resizeWidthOfChildren_WidgetFlag, iTrue);[m addChild_Widget(mainDetailSplit, iClob(detailStack));[m }[m [31m- addChild_Widget(topPanel, iClob(makePadding_Widget(lineHeight_Text(labelFont_()))));[m /* Slide top panel with detail panels. */ {[m setFlags_Widget(topPanel, refChildrenOffset_WidgetFlag, iTrue);[m topPanel->offsetRef = detailStack;[m [36m@@ -612,15 +635,17 @@[m [miWidget *makePanelsParent_Mobile(iWidget *parentWidget,[m checkIcon_LabelWidget(naviBack);[m setId_Widget(as_Widget(naviBack), "panel.back");[m setFont_LabelWidget(naviBack, labelFont_());[m [31m- addChildFlags_Widget(sheet, iClob(navi),[m [32m+[m[32m addChildFlags_Widget(panels, iClob(navi),[m drawBackgroundToVerticalSafeArea_WidgetFlag |[m arrangeHeight_WidgetFlag | resizeWidthOfChildren_WidgetFlag |[m resizeToParentWidth_WidgetFlag | arrangeVertical_WidgetFlag); [m }[m [32m+[m[32m iBool haveDetailPanels = iFalse;[m /* Create panel contents based on provided items. */[m for (size_t i = 0; itemsNullTerminated[i].label; i++) {[m const iMenuItem *item = &itemsNullTerminated[i];[m if (equal_Command(item->label, "panel")) {[m [32m+[m[32m haveDetailPanels = iTrue;[m const char *id = cstr_Rangecc(range_Command(item->label, "id"));[m const iString *label = hasLabel_Command(item->label, "text")[m ? collect_String(suffix_Command(item->label, "text"))[m [36m@@ -655,10 +680,12 @@[m [miWidget *makePanelsParent_Mobile(iWidget *parentWidget,[m setFont_LabelWidget(naviBack, labelBoldFont_()); [m }[m else if (defaultItem && defaultItem != cancelItem) {[m [31m- updateTextCStr_LabelWidget(naviBack, cancelItem->label);[m [31m- setCommand_LabelWidget(naviBack, collectNewCStr_String(cancelItem->command[m [31m- ? cancelItem->command[m [31m- : "cancel"));[m [32m+[m[32m if (!haveDetailPanels) {[m [32m+[m[32m updateTextCStr_LabelWidget(naviBack, cancelItem->label);[m [32m+[m[32m setCommand_LabelWidget(naviBack, collectNewCStr_String(cancelItem->command[m [32m+[m[32m ? cancelItem->command[m [32m+[m[32m : "cancel"));[m [32m+[m[32m }[m iLabelWidget *defaultButton = new_LabelWidget(defaultItem->label, defaultItem->command);[m setFont_LabelWidget(defaultButton, labelBoldFont_());[m setFlags_Widget(as_Widget(defaultButton),[m [36m@@ -689,16 +716,21 @@[m [miWidget *makePanelsParent_Mobile(iWidget *parentWidget,[m }[m makePanelItem_Mobile([m topPanel,[m [31m- &(iMenuItem){ format_CStr("button text:%s", act->label), 0, 0, act->command });[m [32m+[m[32m &(iMenuItem){ format_CStr("button text:" uiTextAction_ColorEscape "%s", act->label),[m [32m+[m[32m 0,[m [32m+[m[32m 0,[m [32m+[m[32m act->command });[m }[m }[m /* Finalize the layout. */[m [31m- addChild_Widget(parentWidget, iClob(sheet));[m [32m+[m[32m if (parentWidget) {[m [32m+[m[32m addChild_Widget(parentWidget, iClob(panels));[m [32m+[m[32m }[m mainDetailSplitHandler_(mainDetailSplit, "window.resized"); /* make it resize the split */[m [31m- updatePanelSheetMetrics_(sheet);[m [31m- arrange_Widget(sheet);[m [32m+[m[32m updatePanelSheetMetrics_(panels);[m [32m+[m[32m arrange_Widget(panels);[m postCommand_App("widget.overflow"); /* with the correct dimensions */ [m [31m- return sheet;[m [32m+[m[32m printTree_Widget(panels);[m }[m [m #if 0[m [36m@@ -1130,7 +1162,9 @@[m [mvoid setupMenuTransition_Mobile(iWidget *sheet, iBool isIncoming) {[m }[m }[m [m [31m-void setupSheetTransition_Mobile(iWidget *sheet, iBool isIncoming) {[m [32m+[m[32mvoid setupSheetTransition_Mobile(iWidget *sheet, int flags) {[m [32m+[m[32m const iBool isIncoming = (flags & incoming_TransitionFlag) != 0;[m [32m+[m[32m const int dir = flags & dirMask_TransitionFlag;[m if (!isUsingPanelLayout_Mobile()) {[m if (prefs_App()->uiAnimations) {[m setFlags_Widget(sheet, horizontalOffset_WidgetFlag, iFalse);[m [36m@@ -1144,17 +1178,51 @@[m [mvoid setupSheetTransition_Mobile(iWidget *sheet, iBool isIncoming) {[m }[m return;[m }[m [31m- if(isSideBySideLayout_()) {[m [32m+[m[32m if (isSideBySideLayout_()) {[m [32m+[m[32m /* TODO: Landscape transitions? */[m return;[m }[m [31m- setFlags_Widget(sheet, horizontalOffset_WidgetFlag, iTrue);[m [32m+[m[32m setFlags_Widget(sheet,[m [32m+[m[32m horizontalOffset_WidgetFlag,[m [32m+[m[32m dir == right_TransitionDir || dir == left_TransitionDir);[m if (isIncoming) {[m [31m- setVisualOffset_Widget(sheet, size_Root(sheet->root).x, 0, 0);[m [32m+[m[32m switch (dir) {[m [32m+[m[32m case right_TransitionDir:[m [32m+[m[32m setVisualOffset_Widget(sheet, size_Root(sheet->root).x, 0, 0);[m [32m+[m[32m break;[m [32m+[m[32m case left_TransitionDir:[m [32m+[m[32m setVisualOffset_Widget(sheet, -size_Root(sheet->root).x, 0, 0);[m [32m+[m[32m break;[m [32m+[m[32m case top_TransitionDir:[m [32m+[m[32m setVisualOffset_Widget([m [32m+[m[32m sheet, -bottom_Rect(boundsWithoutVisualOffset_Widget(sheet)), 0, 0);[m [32m+[m[32m break;[m [32m+[m[32m case bottom_TransitionDir:[m [32m+[m[32m setVisualOffset_Widget(sheet, height_Widget(sheet), 0, 0);[m [32m+[m[32m break;[m [32m+[m[32m }[m setVisualOffset_Widget(sheet, 0, 200, easeOut_AnimFlag);[m [31m- }[m [32m+[m[32m }[m[41m [m else {[m [31m- const iBool wasDragged = iAbs(value_Anim(&sheet->visualOffset)) > 0;[m [31m- setVisualOffset_Widget(sheet, size_Root(sheet->root).x, wasDragged ? 100 : 200,[m [31m- wasDragged ? 0 : easeIn_AnimFlag);[m [32m+[m[32m switch (dir) {[m [32m+[m[32m case right_TransitionDir: {[m [32m+[m[32m const iBool wasDragged = iAbs(value_Anim(&sheet->visualOffset)) > 0;[m [32m+[m[32m setVisualOffset_Widget(sheet, size_Root(sheet->root).x, wasDragged ? 100 : 200,[m [32m+[m[32m wasDragged ? 0 : easeIn_AnimFlag);[m [32m+[m[32m break;[m [32m+[m[32m }[m [32m+[m[32m case left_TransitionDir:[m [32m+[m[32m setVisualOffset_Widget(sheet, -size_Root(sheet->root).x, 200, easeIn_AnimFlag);[m [32m+[m[32m break;[m [32m+[m[32m case top_TransitionDir:[m [32m+[m[32m setVisualOffset_Widget(sheet,[m [32m+[m[32m -bottom_Rect(boundsWithoutVisualOffset_Widget(sheet)),[m [32m+[m[32m 200,[m [32m+[m[32m easeIn_AnimFlag);[m [32m+[m[32m break;[m [32m+[m[32m case bottom_TransitionDir:[m [32m+[m[32m setVisualOffset_Widget(sheet, height_Widget(sheet), 200, easeIn_AnimFlag);[m [32m+[m[32m break;[m [32m+[m[32m }[m }[m }[m [1mdiff --git a/src/ui/mobile.h b/src/ui/mobile.h[m [1mindex 30679c7c..e1131953 100644[m [1m--- a/src/ui/mobile.h[m [1m+++ b/src/ui/mobile.h[m [36m@@ -35,8 +35,23 @@[m [miWidget * makePanelsParent_Mobile (iWidget *parent,[m const char *id, [m const iMenuItem *itemsNullTerminated,[m const iMenuItem *actions, size_t numActions);[m [32m+[m[32mvoid initPanels_Mobile (iWidget *panels, iWidget *parentWidget,[m [32m+[m[32m const iMenuItem *itemsNullTerminated,[m [32m+[m[32m const iMenuItem *actions, size_t numActions);[m [32m+[m [32m+[m[32menum iTransitionFlags {[m [32m+[m[32m incoming_TransitionFlag = iBit(1),[m [32m+[m[32m dirMask_TransitionFlag = iBit(2) | iBit(3),[m [32m+[m[32m};[m [32m+[m [32m+[m[32menum iTransitionDir {[m [32m+[m[32m right_TransitionDir = 0,[m [32m+[m[32m bottom_TransitionDir = 2,[m [32m+[m[32m left_TransitionDir = 4,[m [32m+[m[32m top_TransitionDir = 6,[m [32m+[m[32m};[m [m [31m-void setupMenuTransition_Mobile (iWidget *menu, iBool isIncoming);[m [31m-void setupSheetTransition_Mobile (iWidget *sheet, iBool isIncoming);[m [32m+[m[32mvoid setupMenuTransition_Mobile (iWidget *menu, iBool isIncoming);[m [32m+[m[32mvoid setupSheetTransition_Mobile (iWidget *sheet, int flags);[m [m void finalizeSheet_Mobile (iWidget *sheet);[m [1mdiff --git a/src/ui/root.c b/src/ui/root.c[m [1mindex eae8e4bb..a792e93d 100644[m [1m--- a/src/ui/root.c[m [1m+++ b/src/ui/root.c[m [36m@@ -118,7 +118,7 @@[m [mstatic const iMenuItem phoneNavMenuItems_[] = {[m { "${menu.downloads}", 0, 0, "downloads.open" },[m { "${menu.feeds.entrylist}", 0, 0, "!open url:about:feeds" },[m { "---" },[m [31m- { gear_Icon " Settings...", SDLK_COMMA, KMOD_PRIMARY, "preferences" },[m [32m+[m[32m { gear_Icon " ${menu.settings}", SDLK_COMMA, KMOD_PRIMARY, "preferences" },[m };[m #endif /* Mobile */[m [m [36m@@ -1163,20 +1163,12 @@[m [mvoid createUserInterface_Root(iRoot *d) {[m { star_Icon " ${menu.page.subscribe}", subscribeToPage_KeyModifier, "feeds.subscribe" },[m { book_Icon " ${menu.page.import}", 0, 0, "bookmark.links confirm:1" },[m { globe_Icon " ${menu.page.translate}", 0, 0, "document.translate" },[m [31m-#if defined (iPlatformMobile)[m [31m- { "---" },[m [31m- { "${menu.page.copyurl}", 0, 0, "document.copylink" },[m [31m- { "${menu.page.copysource}", 'c', KMOD_PRIMARY, "copy" },[m [31m- { download_Icon " " saveToDownloads_Label, SDLK_s, KMOD_PRIMARY, "document.save" } },[m [31m- 11);[m [31m-#else[m { upload_Icon " ${menu.page.upload}", 0, 0, "document.upload" },[m { "---" },[m { "${menu.page.copyurl}", 0, 0, "document.copylink" },[m { "${menu.page.copysource}", 'c', KMOD_PRIMARY, "copy" },[m { download_Icon " " saveToDownloads_Label, SDLK_s, KMOD_PRIMARY, "document.save" } },[m 12);[m [31m-#endif[m setId_Widget(as_Widget(pageMenuButton), "pagemenubutton");[m setFont_LabelWidget(pageMenuButton, uiContentBold_FontId);[m setAlignVisually_LabelWidget(pageMenuButton, iTrue);[m [1mdiff --git a/src/ui/uploadwidget.c b/src/ui/uploadwidget.c[m [1mindex 4c72c60a..fb8aaf0a 100644[m [1m--- a/src/ui/uploadwidget.c[m [1m+++ b/src/ui/uploadwidget.c[m [36m@@ -81,91 +81,122 @@[m [mvoid init_UploadWidget(iUploadWidget *d) {[m iWidget *w = as_Widget(d);[m init_Widget(w);[m setId_Widget(w, "upload");[m [31m- useSheetStyle_Widget(w);[m init_String(&d->originalUrl);[m init_String(&d->url);[m d->viewer = NULL;[m d->request = NULL;[m init_String(&d->filePath);[m d->fileSize = 0;[m [31m- addChildFlags_Widget(w,[m [31m- iClob(new_LabelWidget(uiHeading_ColorEscape "${heading.upload}", NULL)),[m [31m- frameless_WidgetFlag);[m [31m- d->info = addChildFlags_Widget(w, iClob(new_LabelWidget("", NULL)),[m [31m- frameless_WidgetFlag | resizeToParentWidth_WidgetFlag |[m [31m- fixedHeight_WidgetFlag);[m [31m- setWrap_LabelWidget(d->info, iTrue);[m [31m- /* Tabs for input data. */[m [31m- iWidget *tabs = makeTabs_Widget(w);[m [31m- /* Make the tabs support vertical expansion based on content. */ {[m [31m- setFlags_Widget(tabs, resizeHeightOfChildren_WidgetFlag, iFalse);[m [31m- setFlags_Widget(tabs, arrangeHeight_WidgetFlag, iTrue);[m [31m- iWidget *tabPages = findChild_Widget(tabs, "tabs.pages");[m [31m- setFlags_Widget(tabPages, resizeHeightOfChildren_WidgetFlag, iFalse);[m [31m- setFlags_Widget(tabPages, arrangeHeight_WidgetFlag, iTrue);[m [32m+[m[32m const iMenuItem actions[] = {[m [32m+[m[32m { "${upload.port}", 0, 0, "upload.setport" },[m [32m+[m[32m { "---" },[m [32m+[m[32m { "${close}", SDLK_ESCAPE, 0, "upload.cancel" },[m [32m+[m[32m { uiTextAction_ColorEscape "${dlg.upload.send}", SDLK_RETURN, KMOD_PRIMARY, "upload.accept" }[m [32m+[m[32m };[m [32m+[m[32m if (isUsingPanelLayout_Mobile()) {[m [32m+[m[32m const iMenuItem textItems[] = {[m [32m+[m[32m { "title id:heading.upload.text" },[m [32m+[m[32m { "input id:upload.text noheading:1" },[m [32m+[m[32m { NULL }[m[41m [m [32m+[m[32m };[m [32m+[m[32m const iMenuItem fileItems[] = {[m [32m+[m[32m { "title id:heading.upload.file" },[m [32m+[m[32m { "button text:" uiTextAction_ColorEscape "${dlg.upload.pickfile}", 0, 0, "upload.pickfile" },[m[41m [m [32m+[m[32m { "heading id:upload.file.name" },[m [32m+[m[32m { "label id:upload.filepathlabel" },[m [32m+[m[32m { "heading id:upload.file.size" },[m [32m+[m[32m { "label id:upload.filesizelabel" },[m [32m+[m[32m { "padding" },[m [32m+[m[32m { "input id:upload.mime" },[m [32m+[m[32m { "label id:upload.counter text:" },[m [32m+[m[32m { NULL }[m[41m [m [32m+[m[32m };[m [32m+[m[32m initPanels_Mobile(w, NULL, (iMenuItem[]){[m [32m+[m[32m { "title id:heading.upload" },[m [32m+[m[32m { "label id:upload.info" },[m [32m+[m[32m// { "padding" },[m [32m+[m[32m { "panel id:dlg.upload.text icon:0x1f5b9", 0, 0, (const void *) textItems },[m [32m+[m[32m { "panel id:dlg.upload.file icon:0x1f4c1", 0, 0, (const void *) fileItems },[m [32m+[m[32m { "padding" },[m [32m+[m[32m { "input id:upload.token hint:hint.upload.token" },[m [32m+[m[32m { NULL }[m [32m+[m[32m }, actions, iElemCount(actions));[m [32m+[m[32m d->info = findChild_Widget(w, "upload.info");[m [32m+[m[32m d->input = findChild_Widget(w, "upload.text");[m [32m+[m[32m d->filePathLabel = findChild_Widget(w, "upload.file.name");[m [32m+[m[32m d->fileSizeLabel = findChild_Widget(w, "upload.file.size");[m [32m+[m[32m d->mime = findChild_Widget(w, "upload.mime");[m [32m+[m[32m d->token = findChild_Widget(w, "upload.token");[m [32m+[m[32m d->counter = findChild_Widget(w, "upload.counter");[m }[m [31m- iWidget *headings, *values;[m [31m- setBackgroundColor_Widget(findChild_Widget(tabs, "tabs.buttons"), uiBackgroundSidebar_ColorId);[m [31m- setId_Widget(tabs, "upload.tabs");[m [31m-// const int bigGap = lineHeight_Text(uiLabel_FontId) * 3 / 4;[m [31m- /* Text input. */ {[m [31m- //appendTwoColumnTabPage_Widget(tabs, "${heading.upload.text}", '1', &headings, &values);[m [31m- iWidget *page = new_Widget();[m [31m- setFlags_Widget(page, arrangeSize_WidgetFlag, iTrue);[m [31m- d->input = new_InputWidget(0);[m [31m- setId_Widget(as_Widget(d->input), "upload.text");[m [31m- setFont_InputWidget(d->input, monospace_FontId);[m [31m- setLineLimits_InputWidget(d->input, 7, 20);[m [31m- setUseReturnKeyBehavior_InputWidget(d->input, iFalse); /* traditional text editor */ [m [31m- setHint_InputWidget(d->input, "${hint.upload.text}");[m [31m- setFixedSize_Widget(as_Widget(d->input), init_I2(120 * gap_UI, -1));[m [31m- addChild_Widget(page, iClob(d->input));[m [31m- appendFramelessTabPage_Widget(tabs, iClob(page), "${heading.upload.text}", '1', 0);[m [31m- }[m [31m- /* File content. */ {[m [31m- appendTwoColumnTabPage_Widget(tabs, "${heading.upload.file}", '2', &headings, &values); [m [31m-// iWidget *pad = addChild_Widget(headings, iClob(makePadding_Widget(0)));[m [31m-// iWidget *hint = addChild_Widget(values, iClob(new_LabelWidget("${upload.file.drophint}", NULL)));[m [31m-// pad->sizeRef = hint;[m [31m- addChildFlags_Widget(headings, iClob(new_LabelWidget("${upload.file.name}", NULL)), frameless_WidgetFlag);[m [31m- d->filePathLabel = addChildFlags_Widget(values, iClob(new_LabelWidget(uiTextAction_ColorEscape "${upload.file.drophere}", NULL)), frameless_WidgetFlag);[m [31m- addChildFlags_Widget(headings, iClob(new_LabelWidget("${upload.file.size}", NULL)), frameless_WidgetFlag);[m [31m- d->fileSizeLabel = addChildFlags_Widget(values, iClob(new_LabelWidget("\u2014", NULL)), frameless_WidgetFlag);[m [31m- d->mime = new_InputWidget(0);[m [31m- setFixedSize_Widget(as_Widget(d->mime), init_I2(70 * gap_UI, -1));[m [31m- addTwoColumnDialogInputField_Widget(headings, values, "${upload.mime}", "upload.mime", iClob(d->mime));[m [31m- }[m [31m- /* Token. */ {[m [31m- addChild_Widget(w, iClob(makePadding_Widget(gap_UI)));[m [31m- iWidget *page = makeTwoColumns_Widget(&headings, &values);[m [31m- d->token = addTwoColumnDialogInputField_Widget([m [31m- headings, values, "${upload.token}", "upload.token", iClob(new_InputWidget(0)));[m [31m- setHint_InputWidget(d->token, "${hint.upload.token}");[m [31m- setFixedSize_Widget(as_Widget(d->token), init_I2(50 * gap_UI, -1));[m [31m- addChild_Widget(w, iClob(page));[m [31m- }[m [31m- /* Buttons. */ {[m [31m- addChild_Widget(w, iClob(makePadding_Widget(gap_UI)));[m [31m- iWidget *buttons =[m [31m- makeDialogButtons_Widget((iMenuItem[]){ { "${upload.port}", 0, 0, "upload.setport" },[m [31m- { "---" },[m [31m- { "${close}", SDLK_ESCAPE, 0, "upload.cancel" },[m [31m- { uiTextAction_ColorEscape "${dlg.upload.send}",[m [31m- SDLK_RETURN,[m [31m- KMOD_PRIMARY,[m [31m- "upload.accept" } },[m [31m- 4);[m [31m- setId_Widget(insertChildAfterFlags_Widget(buttons,[m [31m- iClob(d->counter = new_LabelWidget("", NULL)),[m [31m- 0, frameless_WidgetFlag),[m [31m- "upload.counter");[m [31m- addChild_Widget(w, iClob(buttons));[m [32m+[m[32m else {[m [32m+[m[32m useSheetStyle_Widget(w);[m [32m+[m[32m addChildFlags_Widget(w,[m [32m+[m[32m iClob(new_LabelWidget(uiHeading_ColorEscape "${heading.upload}", NULL)),[m [32m+[m[32m frameless_WidgetFlag);[m [32m+[m[32m d->info = addChildFlags_Widget(w, iClob(new_LabelWidget("", NULL)),[m [32m+[m[32m frameless_WidgetFlag | resizeToParentWidth_WidgetFlag |[m [32m+[m[32m fixedHeight_WidgetFlag);[m [32m+[m[32m setWrap_LabelWidget(d->info, iTrue);[m [32m+[m[32m /* Tabs for input data. */[m [32m+[m[32m iWidget *tabs = makeTabs_Widget(w);[m [32m+[m[32m /* Make the tabs support vertical expansion based on content. */ {[m [32m+[m[32m setFlags_Widget(tabs, resizeHeightOfChildren_WidgetFlag, iFalse);[m [32m+[m[32m setFlags_Widget(tabs, arrangeHeight_WidgetFlag, iTrue);[m [32m+[m[32m iWidget *tabPages = findChild_Widget(tabs, "tabs.pages");[m [32m+[m[32m setFlags_Widget(tabPages, resizeHeightOfChildren_WidgetFlag, iFalse);[m [32m+[m[32m setFlags_Widget(tabPages, arrangeHeight_WidgetFlag, iTrue);[m [32m+[m[32m }[m [32m+[m[32m iWidget *headings, *values;[m [32m+[m[32m setBackgroundColor_Widget(findChild_Widget(tabs, "tabs.buttons"), uiBackgroundSidebar_ColorId);[m [32m+[m[32m setId_Widget(tabs, "upload.tabs");[m [32m+[m[32m /* Text input. */ {[m [32m+[m[32m iWidget *page = new_Widget();[m [32m+[m[32m setFlags_Widget(page, arrangeSize_WidgetFlag, iTrue);[m [32m+[m[32m d->input = new_InputWidget(0);[m [32m+[m[32m setId_Widget(as_Widget(d->input), "upload.text");[m [32m+[m[32m setFixedSize_Widget(as_Widget(d->input), init_I2(120 * gap_UI, -1));[m [32m+[m[32m addChild_Widget(page, iClob(d->input));[m [32m+[m[32m appendFramelessTabPage_Widget(tabs, iClob(page), "${heading.upload.text}", '1', 0);[m [32m+[m[32m }[m [32m+[m[32m /* File content. */ {[m [32m+[m[32m appendTwoColumnTabPage_Widget(tabs, "${heading.upload.file}", '2', &headings, &values);[m[41m [m [32m+[m[32m addChildFlags_Widget(headings, iClob(new_LabelWidget("${upload.file.name}", NULL)), frameless_WidgetFlag);[m [32m+[m[32m d->filePathLabel = addChildFlags_Widget(values, iClob(new_LabelWidget(uiTextAction_ColorEscape "${upload.file.drophere}", NULL)), frameless_WidgetFlag);[m [32m+[m[32m addChildFlags_Widget(headings, iClob(new_LabelWidget("${upload.file.size}", NULL)), frameless_WidgetFlag);[m [32m+[m[32m d->fileSizeLabel = addChildFlags_Widget(values, iClob(new_LabelWidget("\u2014", NULL)), frameless_WidgetFlag);[m [32m+[m[32m d->mime = new_InputWidget(0);[m [32m+[m[32m setFixedSize_Widget(as_Widget(d->mime), init_I2(70 * gap_UI, -1));[m [32m+[m[32m addTwoColumnDialogInputField_Widget(headings, values, "${upload.mime}", "upload.mime", iClob(d->mime));[m [32m+[m[32m }[m [32m+[m[32m /* Token. */ {[m [32m+[m[32m addChild_Widget(w, iClob(makePadding_Widget(gap_UI)));[m [32m+[m[32m iWidget *page = makeTwoColumns_Widget(&headings, &values);[m [32m+[m[32m d->token = addTwoColumnDialogInputField_Widget([m [32m+[m[32m headings, values, "${upload.token}", "upload.token", iClob(new_InputWidget(0)));[m [32m+[m[32m setHint_InputWidget(d->token, "${hint.upload.token}");[m [32m+[m[32m setFixedSize_Widget(as_Widget(d->token), init_I2(50 * gap_UI, -1));[m [32m+[m[32m addChild_Widget(w, iClob(page));[m [32m+[m[32m }[m [32m+[m[32m /* Buttons. */ {[m [32m+[m[32m addChild_Widget(w, iClob(makePadding_Widget(gap_UI)));[m [32m+[m[32m iWidget *buttons = makeDialogButtons_Widget(actions, iElemCount(actions));[m [32m+[m[32m setId_Widget(insertChildAfterFlags_Widget(buttons,[m [32m+[m[32m iClob(d->counter = new_LabelWidget("", NULL)),[m [32m+[m[32m 0, frameless_WidgetFlag),[m [32m+[m[32m "upload.counter");[m [32m+[m[32m addChild_Widget(w, iClob(buttons));[m [32m+[m[32m }[m [32m+[m[32m resizeToLargestPage_Widget(tabs);[m [32m+[m[32m arrange_Widget(w);[m [32m+[m[32m setFixedSize_Widget(as_Widget(d->token), init_I2(width_Widget(tabs) - left_Rect(parent_Widget(d->token)->rect), -1));[m [32m+[m[32m setFlags_Widget(as_Widget(d->token), expand_WidgetFlag, iTrue);[m [32m+[m[32m setFocus_Widget(as_Widget(d->input));[m }[m [31m- resizeToLargestPage_Widget(tabs);[m [31m- arrange_Widget(w);[m [31m- setFixedSize_Widget(as_Widget(d->token), init_I2(width_Widget(tabs) - left_Rect(parent_Widget(d->token)->rect), -1));[m [31m- setFlags_Widget(as_Widget(d->token), expand_WidgetFlag, iTrue);[m [31m- setFocus_Widget(as_Widget(d->input));[m [32m+[m[32m setFont_InputWidget(d->input, monospace_FontId);[m [32m+[m[32m setUseReturnKeyBehavior_InputWidget(d->input, iFalse); /* traditional text editor */[m [32m+[m[32m setLineLimits_InputWidget(d->input, 7, 20);[m [32m+[m[32m setHint_InputWidget(d->input, "${hint.upload.text}");[m setBackupFileName_InputWidget(d->input, "uploadbackup.txt");[m updateInputMaxHeight_UploadWidget_(d);[m }[m [36m@@ -201,6 +232,7 @@[m [mstatic void setUrlPort_UploadWidget_(iUploadWidget *d, const iString *url, uint1[m appendFormat_String(&d->url, ":%u", overridePort ? overridePort : titanPortForUrl_(url));[m appendRange_String(&d->url, (iRangecc){ parts.path.start, constEnd_String(url) });[m setText_LabelWidget(d->info, &d->url);[m [32m+[m[32m arrange_Widget(as_Widget(d));[m }[m [m void setUrl_UploadWidget(iUploadWidget *d, const iString *url) {[m [36m@@ -233,7 +265,7 @@[m [mstatic iBool processEvent_UploadWidget_(iUploadWidget *d, const SDL_Event *ev) {[m if (isResize_UserEvent(ev)) {[m updateInputMaxHeight_UploadWidget_(d);[m }[m [31m- if (isCommand_Widget(w, ev, "upload.cancel")) {[m [32m+[m[32m if (equal_Command(cmd, "upload.cancel")) {[m setupSheetTransition_Mobile(w, iFalse);[m destroy_Widget(w);[m return iTrue;[m [1mdiff --git a/src/ui/util.c b/src/ui/util.c[m [1mindex b875e260..6069e800 100644[m [1m--- a/src/ui/util.c[m [1m+++ b/src/ui/util.c[m [36m@@ -1061,6 +1061,7 @@[m [miWidget *removeTabPage_Widget(iWidget *tabs, size_t index) {[m }[m [m void resizeToLargestPage_Widget(iWidget *tabs) {[m [32m+[m[32m if (!tabs) return;[m // puts("RESIZE TO LARGEST PAGE ...");[m iWidget *pages = findChild_Widget(tabs, "tabs.pages");[m iForEach(ObjectList, i, children_Widget(pages)) {[m [36m@@ -1216,7 +1217,7 @@[m [miBool valueInputHandler_(iWidget *dlg, const char *cmd) {[m postCommandf_App("valueinput.cancelled id:%s", cstr_String(id_Widget(dlg)));[m setId_Widget(dlg, ""); /* no further commands to emit */[m }[m [31m- setupSheetTransition_Mobile(dlg, iFalse);[m [32m+[m[32m setupSheetTransition_Mobile(dlg, top_TransitionDir);[m destroy_Widget(dlg);[m return iTrue;[m }[m [36m@@ -1225,13 +1226,13 @@[m [miBool valueInputHandler_(iWidget *dlg, const char *cmd) {[m else if (equal_Command(cmd, "valueinput.cancel")) {[m postCommandf_App("valueinput.cancelled id:%s", cstr_String(id_Widget(dlg)));[m setId_Widget(dlg, ""); /* no further commands to emit */[m [31m- setupSheetTransition_Mobile(dlg, iFalse);[m [32m+[m[32m setupSheetTransition_Mobile(dlg, top_TransitionDir);[m destroy_Widget(dlg);[m return iTrue;[m }[m else if (equal_Command(cmd, "valueinput.accept")) {[m acceptValueInput_(dlg);[m [31m- setupSheetTransition_Mobile(dlg, iFalse); [m [32m+[m[32m setupSheetTransition_Mobile(dlg, top_TransitionDir);[m[41m [m destroy_Widget(dlg);[m return iTrue;[m }[m [36m@@ -1345,7 +1346,9 @@[m [miWidget *makeValueInput_Widget(iWidget *parent, const iString *initialValue, con[m acceptKeyMod_ReturnKeyBehavior(prefs_App()->returnKey),[m "valueinput.accept" } },[m 2)));[m [31m- finalizeSheet_Mobile(dlg);[m [32m+[m[32m// finalizeSheet_Mobile(dlg);[m [32m+[m[32m arrange_Widget(dlg);[m [32m+[m[32m setupSheetTransition_Mobile(dlg, incoming_TransitionFlag | top_TransitionDir);[m if (parent) {[m setFocus_Widget(as_Widget(input));[m }[m [36m@@ -1915,6 +1918,7 @@[m [miWidget *makePreferences_Widget(void) {[m { NULL }[m };[m iWidget *dlg = makePanels_Mobile("prefs", (iMenuItem[]){[m [32m+[m[32m { "title id:heading.settings" },[m { "panel text:" gear_Icon " ${heading.prefs.general}", 0, 0, (const void *) generalPanelItems },[m { "panel icon:0x1f5a7 id:heading.prefs.network", 0, 0, (const void *) networkPanelItems },[m { "panel text:" person_Icon " ${sidebar.identities}", 0, 0, (const void *) identityPanelItems },[m [36m@@ -2405,7 +2409,7 @@[m [miWidget *makeFeedSettings_Widget(uint32_t bookmarkId) {[m arrange_Widget(dlg);[m as_Widget(input)->rect.size.x = 100 * gap_UI - headings->rect.size.x;[m addChild_Widget(get_Root()->widget, iClob(dlg));[m [31m- finalizeSheet_Mobile(dlg);[m [32m+[m[32m// finalizeSheet_Mobile(dlg);[m }[m /* Initialize. */ {[m const iBookmark *bm = bookmarkId ? get_Bookmarks(bookmarks_App(), bookmarkId) : NULL;[m [36m@@ -2419,6 +2423,7 @@[m [miWidget *makeFeedSettings_Widget(uint32_t bookmarkId) {[m iTrue);[m setCommandHandler_Widget(dlg, handleFeedSettingCommands_);[m }[m [32m+[m[32m setupSheetTransition_Mobile(dlg, incoming_TransitionFlag);[m return dlg;[m }[m [m [1mdiff --git a/src/ui/widget.c b/src/ui/widget.c[m [1mindex 4fd8f066..659a00cc 100644[m [1m--- a/src/ui/widget.c[m [1m+++ b/src/ui/widget.c[m [36m@@ -452,7 +452,7 @@[m [mstatic void arrange_Widget_(iWidget *d) {[m else if (d->flags & centerHorizontal_WidgetFlag) {[m centerHorizontal_Widget_(d);[m }[m [31m- if (d->flags & resizeToParentWidth_WidgetFlag) {[m [32m+[m[32m if (d->flags & resizeToParentWidth_WidgetFlag && d->parent) {[m iRect childBounds = zero_Rect();[m if (flags_Widget(d->parent) & arrangeWidth_WidgetFlag) {[m /* Can't go narrower than what the children require, though. */[m [36m@@ -462,7 +462,7 @@[m [mstatic void arrange_Widget_(iWidget *d) {[m setWidth_Widget_(d, iMaxi(width_Rect(innerRect_Widget_(d->parent)),[m width_Rect(childBounds)));[m }[m [31m- if (d->flags & resizeToParentHeight_WidgetFlag) {[m [32m+[m[32m if (d->flags & resizeToParentHeight_WidgetFlag && d->parent) {[m TRACE(d, "resize to parent height");[m setHeight_Widget_(d, height_Rect(innerRect_Widget_(d->parent)));[m }[m
text/gemini; charset=utf-8
This content has been proxied by September (ba2dc).