diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-07-17 09:00:40 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-07-17 09:00:40 +0300 |
commit | 3528bb86ab14c275c41adc7cfa29a5f5eb167ff2 (patch) | |
tree | 4b93b0f2bb9718408d4b855d1f8b8ed17a3e690f | |
parent | 7e536572b602cba180ad4e85bd9c071479f6fa22 (diff) |
Working on a UI for uploading text/data
`UploadWidget` allows entering long-form text or dropping a file for uploading.
InputWidget isn't yet well suited for really long documents... Some optimizations will be needed.
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/app.c | 10 | ||||
-rw-r--r-- | src/gmrequest.c | 3 | ||||
-rw-r--r-- | src/ui/certimportwidget.c | 17 | ||||
-rw-r--r-- | src/ui/uploadwidget.c | 148 | ||||
-rw-r--r-- | src/ui/uploadwidget.h | 33 | ||||
-rw-r--r-- | src/ui/util.c | 46 | ||||
-rw-r--r-- | src/ui/util.h | 4 |
8 files changed, 226 insertions, 37 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 7a4a2f06..5b5fa9cd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt | |||
@@ -200,6 +200,8 @@ set (SOURCES | |||
200 | src/ui/touch.h | 200 | src/ui/touch.h |
201 | src/ui/translation.c | 201 | src/ui/translation.c |
202 | src/ui/translation.h | 202 | src/ui/translation.h |
203 | src/ui/uploadwidget.c | ||
204 | src/ui/uploadwidget.h | ||
203 | src/ui/util.c | 205 | src/ui/util.c |
204 | src/ui/util.h | 206 | src/ui/util.h |
205 | src/ui/visbuf.c | 207 | src/ui/visbuf.c |
@@ -41,6 +41,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | |||
41 | #include "ui/labelwidget.h" | 41 | #include "ui/labelwidget.h" |
42 | #include "ui/root.h" | 42 | #include "ui/root.h" |
43 | #include "ui/sidebarwidget.h" | 43 | #include "ui/sidebarwidget.h" |
44 | #include "ui/uploadwidget.h" | ||
44 | #include "ui/text.h" | 45 | #include "ui/text.h" |
45 | #include "ui/util.h" | 46 | #include "ui/util.h" |
46 | #include "ui/window.h" | 47 | #include "ui/window.h" |
@@ -2324,6 +2325,15 @@ iBool handleCommand_App(const char *cmd) { | |||
2324 | const iBool fromSidebar = argLabel_Command(cmd, "fromsidebar") != 0; | 2325 | const iBool fromSidebar = argLabel_Command(cmd, "fromsidebar") != 0; |
2325 | iUrl parts; | 2326 | iUrl parts; |
2326 | init_Url(&parts, url); | 2327 | init_Url(&parts, url); |
2328 | if (equalCase_Rangecc(parts.scheme, "titan")) { | ||
2329 | iUploadWidget *upload = new_UploadWidget(); | ||
2330 | setUrl_UploadWidget(upload, url); | ||
2331 | setResponseViewer_UploadWidget(upload, document_App()); | ||
2332 | addChild_Widget(get_Root()->widget, iClob(upload)); | ||
2333 | finalizeSheet_Mobile(as_Widget(upload)); | ||
2334 | postRefresh_App(); | ||
2335 | return iTrue; | ||
2336 | } | ||
2327 | if (argLabel_Command(cmd, "default") || equalCase_Rangecc(parts.scheme, "mailto") || | 2337 | if (argLabel_Command(cmd, "default") || equalCase_Rangecc(parts.scheme, "mailto") || |
2328 | ((noProxy || isEmpty_String(&d->prefs.httpProxy)) && | 2338 | ((noProxy || isEmpty_String(&d->prefs.httpProxy)) && |
2329 | (equalCase_Rangecc(parts.scheme, "http") || | 2339 | (equalCase_Rangecc(parts.scheme, "http") || |
diff --git a/src/gmrequest.c b/src/gmrequest.c index 1d84ef47..2471f311 100644 --- a/src/gmrequest.c +++ b/src/gmrequest.c | |||
@@ -909,7 +909,8 @@ void submit_GmRequest(iGmRequest *d) { | |||
909 | size_Block(&d->titan->data)); | 909 | size_Block(&d->titan->data)); |
910 | if (!isEmpty_String(&d->titan->token)) { | 910 | if (!isEmpty_String(&d->titan->token)) { |
911 | appendCStr_Block(&content, ";token="); | 911 | appendCStr_Block(&content, ";token="); |
912 | append_Block(&content, utf8_String(&d->titan->token)); | 912 | append_Block(&content, |
913 | utf8_String(collect_String(urlEncode_String(&d->titan->token)))); | ||
913 | } | 914 | } |
914 | appendCStr_Block(&content, "\r\n"); | 915 | appendCStr_Block(&content, "\r\n"); |
915 | append_Block(&content, &d->titan->data); | 916 | append_Block(&content, &d->titan->data); |
diff --git a/src/ui/certimportwidget.c b/src/ui/certimportwidget.c index 6e818137..a8346e19 100644 --- a/src/ui/certimportwidget.c +++ b/src/ui/certimportwidget.c | |||
@@ -107,17 +107,8 @@ void init_CertImportWidget(iCertImportWidget *d) { | |||
107 | init_Widget(w); | 107 | init_Widget(w); |
108 | setId_Widget(w, "certimport"); | 108 | setId_Widget(w, "certimport"); |
109 | d->cert = NULL; | 109 | d->cert = NULL; |
110 | /* This should behave similar to sheets. */ { | 110 | /* This should behave similar to sheets. */ |
111 | setPadding1_Widget(w, 3 * gap_UI); | 111 | useSheetStyle_Widget(w); |
112 | setFrameColor_Widget(w, uiSeparator_ColorId); | ||
113 | setBackgroundColor_Widget(w, uiBackground_ColorId); | ||
114 | setFlags_Widget(w, | ||
115 | mouseModal_WidgetFlag | keepOnTop_WidgetFlag | arrangeVertical_WidgetFlag | | ||
116 | arrangeSize_WidgetFlag | centerHorizontal_WidgetFlag | | ||
117 | parentCannotResize_WidgetFlag | | ||
118 | overflowScrollable_WidgetFlag, | ||
119 | iTrue); | ||
120 | } | ||
121 | addChildFlags_Widget( | 112 | addChildFlags_Widget( |
122 | w, | 113 | w, |
123 | iClob(new_LabelWidget(uiHeading_ColorEscape "${heading.certimport}", NULL)), | 114 | iClob(new_LabelWidget(uiHeading_ColorEscape "${heading.certimport}", NULL)), |
@@ -168,7 +159,6 @@ void init_CertImportWidget(iCertImportWidget *d) { | |||
168 | "certimport.accept" } }, | 159 | "certimport.accept" } }, |
169 | 2); | 160 | 2); |
170 | addChild_Widget(w, iClob(buttons)); | 161 | addChild_Widget(w, iClob(buttons)); |
171 | // arrange_Widget(w); | ||
172 | if (deviceType_App() != desktop_AppDeviceType) { | 162 | if (deviceType_App() != desktop_AppDeviceType) { |
173 | /* Try auto-pasting. */ | 163 | /* Try auto-pasting. */ |
174 | postCommand_App("certimport.paste"); | 164 | postCommand_App("certimport.paste"); |
@@ -263,8 +253,7 @@ static iBool processEvent_CertImportWidget_(iCertImportWidget *d, const SDL_Even | |||
263 | } | 253 | } |
264 | 254 | ||
265 | static void draw_CertImportWidget_(const iCertImportWidget *d) { | 255 | static void draw_CertImportWidget_(const iCertImportWidget *d) { |
266 | const iWidget *w = constAs_Widget(d); | 256 | draw_Widget(constAs_Widget(d)); |
267 | draw_Widget(w); | ||
268 | } | 257 | } |
269 | 258 | ||
270 | iBeginDefineSubclass(CertImportWidget, Widget) | 259 | iBeginDefineSubclass(CertImportWidget, Widget) |
diff --git a/src/ui/uploadwidget.c b/src/ui/uploadwidget.c new file mode 100644 index 00000000..036571a5 --- /dev/null +++ b/src/ui/uploadwidget.c | |||
@@ -0,0 +1,148 @@ | |||
1 | /* Copyright 2021 Jaakko Keränen <jaakko.keranen@iki.fi> | ||
2 | |||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions are met: | ||
5 | |||
6 | 1. Redistributions of source code must retain the above copyright notice, this | ||
7 | list of conditions and the following disclaimer. | ||
8 | 2. Redistributions in binary form must reproduce the above copyright notice, | ||
9 | this list of conditions and the following disclaimer in the documentation | ||
10 | and/or other materials provided with the distribution. | ||
11 | |||
12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | ||
13 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
14 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
15 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR | ||
16 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
17 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
18 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
19 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
20 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
21 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | ||
22 | |||
23 | #include "uploadwidget.h" | ||
24 | #include "labelwidget.h" | ||
25 | #include "inputwidget.h" | ||
26 | #include "documentwidget.h" | ||
27 | #include "color.h" | ||
28 | #include "gmrequest.h" | ||
29 | #include "app.h" | ||
30 | |||
31 | iDefineObjectConstruction(UploadWidget) | ||
32 | |||
33 | struct Impl_UploadWidget { | ||
34 | iWidget widget; | ||
35 | iString url; | ||
36 | iDocumentWidget *viewer; | ||
37 | iGmRequest * request; | ||
38 | iLabelWidget * info; | ||
39 | iInputWidget * mime; | ||
40 | iInputWidget * token; | ||
41 | iInputWidget * input; | ||
42 | }; | ||
43 | |||
44 | void init_UploadWidget(iUploadWidget *d) { | ||
45 | iWidget *w = as_Widget(d); | ||
46 | init_Widget(w); | ||
47 | setId_Widget(w, "upload"); | ||
48 | useSheetStyle_Widget(w); | ||
49 | init_String(&d->url); | ||
50 | d->viewer = NULL; | ||
51 | d->request = NULL; | ||
52 | addChildFlags_Widget(w, | ||
53 | iClob(new_LabelWidget(uiHeading_ColorEscape "${heading.upload}", NULL)), | ||
54 | frameless_WidgetFlag); | ||
55 | d->info = addChildFlags_Widget(w, iClob(new_LabelWidget("", NULL)), frameless_WidgetFlag); | ||
56 | /* Tabs for input data. */ | ||
57 | iWidget *tabs = makeTabs_Widget(w); | ||
58 | iWidget *headings, *values; | ||
59 | setBackgroundColor_Widget(findChild_Widget(tabs, "tabs.buttons"), uiBackgroundSidebar_ColorId); | ||
60 | setId_Widget(tabs, "upload.tabs"); | ||
61 | // const int bigGap = lineHeight_Text(uiLabel_FontId) * 3 / 4; | ||
62 | /* Text input. */ { | ||
63 | //appendTwoColumnTabPage_Widget(tabs, "${heading.upload.text}", '1', &headings, &values); | ||
64 | iWidget *page = new_Widget(); | ||
65 | setFlags_Widget(page, arrangeSize_WidgetFlag, iTrue); | ||
66 | d->input = new_InputWidget(0); | ||
67 | setEnterInsertsLF_InputWidget(d->input, iTrue); | ||
68 | setFixedSize_Widget(as_Widget(d->input), init_I2(120 * gap_UI, -1)); | ||
69 | addChild_Widget(page, iClob(d->input)); | ||
70 | appendTabPage_Widget(tabs, iClob(page), "${heading.upload.text}", '1', 0); | ||
71 | } | ||
72 | /* File content. */ { | ||
73 | appendTwoColumnTabPage_Widget(tabs, "${heading.upload.file}", '2', &headings, &values); | ||
74 | // iWidget *pad = addChild_Widget(headings, iClob(makePadding_Widget(0))); | ||
75 | // iWidget *hint = addChild_Widget(values, iClob(new_LabelWidget("${upload.file.drophint}", NULL))); | ||
76 | // pad->sizeRef = hint; | ||
77 | addChild_Widget(headings, iClob(new_LabelWidget("${upload.file.name}", NULL))); | ||
78 | addChild_Widget(values, iClob(new_LabelWidget("filename.ext", NULL))); | ||
79 | addChild_Widget(headings, iClob(new_LabelWidget("${upload.file.size}", NULL))); | ||
80 | addChild_Widget(values, iClob(new_LabelWidget("0 KB", NULL))); | ||
81 | d->mime = new_InputWidget(0); | ||
82 | setFixedSize_Widget(as_Widget(d->mime), init_I2(50 * gap_UI, -1)); | ||
83 | addTwoColumnDialogInputField_Widget(headings, values, "${upload.mime}", "upload.mime", iClob(d->mime)); | ||
84 | } | ||
85 | /* Token. */ { | ||
86 | addChild_Widget(w, iClob(makePadding_Widget(gap_UI))); | ||
87 | iWidget *page = makeTwoColumns_Widget(&headings, &values); | ||
88 | d->token = addTwoColumnDialogInputField_Widget( | ||
89 | headings, values, "${upload.token}", "upload.token", iClob(new_InputWidget(0))); | ||
90 | setHint_InputWidget(d->token, "${hint.upload.token}"); | ||
91 | setFixedSize_Widget(as_Widget(d->token), init_I2(50 * gap_UI, -1)); | ||
92 | addChild_Widget(w, iClob(page)); | ||
93 | } | ||
94 | /* Buttons. */ { | ||
95 | addChild_Widget(w, iClob(makePadding_Widget(gap_UI))); | ||
96 | iWidget *buttons = | ||
97 | makeDialogButtons_Widget((iMenuItem[]){ { "${cancel}", SDLK_ESCAPE, 0, "upload.cancel" }, | ||
98 | { uiTextAction_ColorEscape "${dlg.upload.send}", | ||
99 | SDLK_RETURN, | ||
100 | KMOD_PRIMARY, | ||
101 | "upload.accept" } }, | ||
102 | 2); | ||
103 | addChild_Widget(w, iClob(buttons)); | ||
104 | } | ||
105 | resizeToLargestPage_Widget(tabs); | ||
106 | setFocus_Widget(as_Widget(d->token)); | ||
107 | } | ||
108 | |||
109 | void deinit_UploadWidget(iUploadWidget *d) { | ||
110 | deinit_String(&d->url); | ||
111 | iRelease(d->request); | ||
112 | } | ||
113 | |||
114 | void setUrl_UploadWidget(iUploadWidget *d, const iString *url) { | ||
115 | set_String(&d->url, url); | ||
116 | setText_LabelWidget(d->info, &d->url); | ||
117 | } | ||
118 | |||
119 | void setResponseViewer_UploadWidget(iUploadWidget *d, iDocumentWidget *doc) { | ||
120 | d->viewer = doc; | ||
121 | } | ||
122 | |||
123 | static iBool processEvent_UploadWidget_(iUploadWidget *d, const SDL_Event *ev) { | ||
124 | iWidget *w = as_Widget(d); | ||
125 | if (isCommand_Widget(w, ev, "upload.cancel")) { | ||
126 | /* TODO: If text has been entered, ask for confirmation. */ | ||
127 | setupSheetTransition_Mobile(w, iFalse); | ||
128 | destroy_Widget(w); | ||
129 | return iTrue; | ||
130 | } | ||
131 | if (isCommand_Widget(w, ev, "upload.accept")) { | ||
132 | /* Make a GmRequest and send the data. */ | ||
133 | /* The dialog will remain open until the request finishes, showing upload progress. */ | ||
134 | } | ||
135 | if (ev->type == SDL_DROPFILE) { | ||
136 | /* Switch to File tab. */ | ||
137 | } | ||
138 | return processEvent_Widget(w, ev); | ||
139 | } | ||
140 | |||
141 | static void draw_UploadWidget_(const iUploadWidget *d) { | ||
142 | draw_Widget(constAs_Widget(d)); | ||
143 | } | ||
144 | |||
145 | iBeginDefineSubclass(UploadWidget, Widget) | ||
146 | .processEvent = (iAny *) processEvent_UploadWidget_, | ||
147 | .draw = (iAny *) draw_UploadWidget_, | ||
148 | iEndDefineSubclass(UploadWidget) | ||
diff --git a/src/ui/uploadwidget.h b/src/ui/uploadwidget.h new file mode 100644 index 00000000..5a7de45e --- /dev/null +++ b/src/ui/uploadwidget.h | |||
@@ -0,0 +1,33 @@ | |||
1 | /* Copyright 2021 Jaakko Keränen <jaakko.keranen@iki.fi> | ||
2 | |||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions are met: | ||
5 | |||
6 | 1. Redistributions of source code must retain the above copyright notice, this | ||
7 | list of conditions and the following disclaimer. | ||
8 | 2. Redistributions in binary form must reproduce the above copyright notice, | ||
9 | this list of conditions and the following disclaimer in the documentation | ||
10 | and/or other materials provided with the distribution. | ||
11 | |||
12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | ||
13 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
14 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
15 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR | ||
16 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
17 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
18 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
19 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
20 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
21 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | ||
22 | |||
23 | #pragma once | ||
24 | |||
25 | #include "widget.h" | ||
26 | |||
27 | iDeclareWidgetClass(UploadWidget) | ||
28 | iDeclareObjectConstruction(UploadWidget) | ||
29 | |||
30 | iDeclareType(DocumentWidget) | ||
31 | |||
32 | void setUrl_UploadWidget (iUploadWidget *, const iString *url); | ||
33 | void setResponseViewer_UploadWidget (iUploadWidget *, iDocumentWidget *doc); | ||
diff --git a/src/ui/util.c b/src/ui/util.c index 220e3a50..6bc358de 100644 --- a/src/ui/util.c +++ b/src/ui/util.c | |||
@@ -1118,20 +1118,22 @@ size_t tabCount_Widget(const iWidget *tabs) { | |||
1118 | 1118 | ||
1119 | /*-----------------------------------------------------------------------------------------------*/ | 1119 | /*-----------------------------------------------------------------------------------------------*/ |
1120 | 1120 | ||
1121 | |||
1122 | iWidget *makeSheet_Widget(const char *id) { | 1121 | iWidget *makeSheet_Widget(const char *id) { |
1123 | iWidget *sheet = new_Widget(); | 1122 | iWidget *sheet = new_Widget(); |
1124 | setId_Widget(sheet, id); | 1123 | setId_Widget(sheet, id); |
1125 | setPadding1_Widget(sheet, 3 * gap_UI); | 1124 | useSheetStyle_Widget(sheet); |
1126 | setFrameColor_Widget(sheet, uiSeparator_ColorId); | 1125 | return sheet; |
1127 | setBackgroundColor_Widget(sheet, uiBackground_ColorId); | 1126 | } |
1128 | setFlags_Widget(sheet, | 1127 | |
1129 | parentCannotResize_WidgetFlag | | 1128 | void useSheetStyle_Widget(iWidget *d) { |
1130 | focusRoot_WidgetFlag | mouseModal_WidgetFlag | keepOnTop_WidgetFlag | | 1129 | setPadding1_Widget(d, 3 * gap_UI); |
1131 | arrangeVertical_WidgetFlag | arrangeSize_WidgetFlag | | 1130 | setFrameColor_Widget(d, uiSeparator_ColorId); |
1131 | setBackgroundColor_Widget(d, uiBackground_ColorId); | ||
1132 | setFlags_Widget(d, | ||
1133 | parentCannotResize_WidgetFlag | focusRoot_WidgetFlag | mouseModal_WidgetFlag | | ||
1134 | keepOnTop_WidgetFlag | arrangeVertical_WidgetFlag | arrangeSize_WidgetFlag | | ||
1132 | centerHorizontal_WidgetFlag | overflowScrollable_WidgetFlag, | 1135 | centerHorizontal_WidgetFlag | overflowScrollable_WidgetFlag, |
1133 | iTrue); | 1136 | iTrue); |
1134 | return sheet; | ||
1135 | } | 1137 | } |
1136 | 1138 | ||
1137 | static void acceptValueInput_(iWidget *dlg) { | 1139 | static void acceptValueInput_(iWidget *dlg) { |
@@ -1435,7 +1437,7 @@ static void appendFramelessTabPage_(iWidget *tabs, iWidget *page, const char *ti | |||
1435 | iTrue); | 1437 | iTrue); |
1436 | } | 1438 | } |
1437 | 1439 | ||
1438 | static iWidget *makeTwoColumnWidget_(iWidget **headings, iWidget **values) { | 1440 | iWidget *makeTwoColumns_Widget(iWidget **headings, iWidget **values) { |
1439 | iWidget *page = new_Widget(); | 1441 | iWidget *page = new_Widget(); |
1440 | setFlags_Widget(page, arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag, iTrue); | 1442 | setFlags_Widget(page, arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag, iTrue); |
1441 | *headings = addChildFlags_Widget( | 1443 | *headings = addChildFlags_Widget( |
@@ -1445,8 +1447,8 @@ static iWidget *makeTwoColumnWidget_(iWidget **headings, iWidget **values) { | |||
1445 | return page; | 1447 | return page; |
1446 | } | 1448 | } |
1447 | 1449 | ||
1448 | static iWidget *appendTwoColumnPage_(iWidget *tabs, const char *title, int shortcut, iWidget **headings, | 1450 | iWidget *appendTwoColumnTabPage_Widget(iWidget *tabs, const char *title, int shortcut, iWidget **headings, |
1449 | iWidget **values) { | 1451 | iWidget **values) { |
1450 | /* TODO: Use `makeTwoColumnWidget_()`, see above. */ | 1452 | /* TODO: Use `makeTwoColumnWidget_()`, see above. */ |
1451 | iWidget *page = new_Widget(); | 1453 | iWidget *page = new_Widget(); |
1452 | setFlags_Widget(page, arrangeVertical_WidgetFlag | arrangeSize_WidgetFlag, iTrue); | 1454 | setFlags_Widget(page, arrangeVertical_WidgetFlag | arrangeSize_WidgetFlag, iTrue); |
@@ -1600,7 +1602,7 @@ iWidget *makePreferences_Widget(void) { | |||
1600 | iWidget *headings, *values; | 1602 | iWidget *headings, *values; |
1601 | const int bigGap = lineHeight_Text(uiLabel_FontId) * 3 / 4; | 1603 | const int bigGap = lineHeight_Text(uiLabel_FontId) * 3 / 4; |
1602 | /* General preferences. */ { | 1604 | /* General preferences. */ { |
1603 | appendTwoColumnPage_(tabs, "${heading.prefs.general}", '1', &headings, &values); | 1605 | appendTwoColumnTabPage_Widget(tabs, "${heading.prefs.general}", '1', &headings, &values); |
1604 | #if defined (LAGRANGE_ENABLE_DOWNLOAD_EDIT) | 1606 | #if defined (LAGRANGE_ENABLE_DOWNLOAD_EDIT) |
1605 | addPrefsInputWithHeading_(headings, values, "prefs.downloads", iClob(new_InputWidget(0))); | 1607 | addPrefsInputWithHeading_(headings, values, "prefs.downloads", iClob(new_InputWidget(0))); |
1606 | #endif | 1608 | #endif |
@@ -1668,7 +1670,7 @@ iWidget *makePreferences_Widget(void) { | |||
1668 | } | 1670 | } |
1669 | } | 1671 | } |
1670 | /* User Interface. */ { | 1672 | /* User Interface. */ { |
1671 | appendTwoColumnPage_(tabs, "${heading.prefs.interface}", '2', &headings, &values); | 1673 | appendTwoColumnTabPage_Widget(tabs, "${heading.prefs.interface}", '2', &headings, &values); |
1672 | #if defined (LAGRANGE_ENABLE_CUSTOM_FRAME) | 1674 | #if defined (LAGRANGE_ENABLE_CUSTOM_FRAME) |
1673 | addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.customframe}"))); | 1675 | addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.customframe}"))); |
1674 | addChild_Widget(values, iClob(makeToggle_Widget("prefs.customframe"))); | 1676 | addChild_Widget(values, iClob(makeToggle_Widget("prefs.customframe"))); |
@@ -1711,7 +1713,7 @@ iWidget *makePreferences_Widget(void) { | |||
1711 | } | 1713 | } |
1712 | } | 1714 | } |
1713 | /* Colors. */ { | 1715 | /* Colors. */ { |
1714 | appendTwoColumnPage_(tabs, "${heading.prefs.colors}", '3', &headings, &values); | 1716 | appendTwoColumnTabPage_Widget(tabs, "${heading.prefs.colors}", '3', &headings, &values); |
1715 | makeTwoColumnHeading_("${heading.prefs.uitheme}", headings, values); | 1717 | makeTwoColumnHeading_("${heading.prefs.uitheme}", headings, values); |
1716 | #if defined (iPlatformApple) || defined (iPlatformMSys) | 1718 | #if defined (iPlatformApple) || defined (iPlatformMSys) |
1717 | addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.ostheme}"))); | 1719 | addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.ostheme}"))); |
@@ -1766,7 +1768,7 @@ iWidget *makePreferences_Widget(void) { | |||
1766 | addChildFlags_Widget(values, iClob(sats), arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag); | 1768 | addChildFlags_Widget(values, iClob(sats), arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag); |
1767 | } | 1769 | } |
1768 | /* Fonts. */ { | 1770 | /* Fonts. */ { |
1769 | setId_Widget(appendTwoColumnPage_(tabs, "${heading.prefs.fonts}", '4', &headings, &values), "prefs.page.fonts"); | 1771 | setId_Widget(appendTwoColumnTabPage_Widget(tabs, "${heading.prefs.fonts}", '4', &headings, &values), "prefs.page.fonts"); |
1770 | /* Fonts. */ { | 1772 | /* Fonts. */ { |
1771 | addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.headingfont}"))); | 1773 | addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.headingfont}"))); |
1772 | addFontButtons_(values, "headingfont"); | 1774 | addFontButtons_(values, "headingfont"); |
@@ -1815,7 +1817,7 @@ iWidget *makePreferences_Widget(void) { | |||
1815 | } | 1817 | } |
1816 | } | 1818 | } |
1817 | /* Style. */ { | 1819 | /* Style. */ { |
1818 | setId_Widget(appendTwoColumnPage_(tabs, "${heading.prefs.style}", '5', &headings, &values), "prefs.page.style"); | 1820 | setId_Widget(appendTwoColumnTabPage_Widget(tabs, "${heading.prefs.style}", '5', &headings, &values), "prefs.page.style"); |
1819 | // makeTwoColumnHeading_("${heading.prefs.paragraph}", headings, values); | 1821 | // makeTwoColumnHeading_("${heading.prefs.paragraph}", headings, values); |
1820 | addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.linewidth}"))); | 1822 | addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.linewidth}"))); |
1821 | iWidget *widths = new_Widget(); | 1823 | iWidget *widths = new_Widget(); |
@@ -1850,7 +1852,7 @@ iWidget *makePreferences_Widget(void) { | |||
1850 | addChild_Widget(values, iClob(makeToggle_Widget("prefs.centershort"))); | 1852 | addChild_Widget(values, iClob(makeToggle_Widget("prefs.centershort"))); |
1851 | } | 1853 | } |
1852 | /* Network. */ { | 1854 | /* Network. */ { |
1853 | appendTwoColumnPage_(tabs, "${heading.prefs.network}", '6', &headings, &values); | 1855 | appendTwoColumnTabPage_Widget(tabs, "${heading.prefs.network}", '6', &headings, &values); |
1854 | addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.decodeurls}"))); | 1856 | addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.decodeurls}"))); |
1855 | addChild_Widget(values, iClob(makeToggle_Widget("prefs.decodeurls"))); | 1857 | addChild_Widget(values, iClob(makeToggle_Widget("prefs.decodeurls"))); |
1856 | /* Cache size. */ { | 1858 | /* Cache size. */ { |
@@ -1908,7 +1910,7 @@ iWidget *makeBookmarkEditor_Widget(void) { | |||
1908 | frameless_WidgetFlag), | 1910 | frameless_WidgetFlag), |
1909 | "bmed.heading"); | 1911 | "bmed.heading"); |
1910 | iWidget *headings, *values; | 1912 | iWidget *headings, *values; |
1911 | addChild_Widget(dlg, iClob(makeTwoColumnWidget_(&headings, &values))); | 1913 | addChild_Widget(dlg, iClob(makeTwoColumns_Widget(&headings, &values))); |
1912 | iInputWidget *inputs[4]; | 1914 | iInputWidget *inputs[4]; |
1913 | addDialogInputWithHeading_(headings, values, "${dlg.bookmark.title}", "bmed.title", iClob(inputs[0] = new_InputWidget(0))); | 1915 | addDialogInputWithHeading_(headings, values, "${dlg.bookmark.title}", "bmed.title", iClob(inputs[0] = new_InputWidget(0))); |
1914 | addDialogInputWithHeading_(headings, values, "${dlg.bookmark.url}", "bmed.url", iClob(inputs[1] = new_InputWidget(0))); | 1916 | addDialogInputWithHeading_(headings, values, "${dlg.bookmark.url}", "bmed.url", iClob(inputs[1] = new_InputWidget(0))); |
@@ -1917,7 +1919,7 @@ iWidget *makeBookmarkEditor_Widget(void) { | |||
1917 | addDialogInputWithHeading_(headings, values, "${dlg.bookmark.icon}", "bmed.icon", iClob(inputs[3] = new_InputWidget(1))); | 1919 | addDialogInputWithHeading_(headings, values, "${dlg.bookmark.icon}", "bmed.icon", iClob(inputs[3] = new_InputWidget(1))); |
1918 | /* Buttons for special tags. */ | 1920 | /* Buttons for special tags. */ |
1919 | addChild_Widget(dlg, iClob(makePadding_Widget(gap_UI))); | 1921 | addChild_Widget(dlg, iClob(makePadding_Widget(gap_UI))); |
1920 | addChild_Widget(dlg, iClob(makeTwoColumnWidget_(&headings, &values))); | 1922 | addChild_Widget(dlg, iClob(makeTwoColumns_Widget(&headings, &values))); |
1921 | makeTwoColumnHeading_("SPECIAL TAGS", headings, values); | 1923 | makeTwoColumnHeading_("SPECIAL TAGS", headings, values); |
1922 | addChild_Widget(headings, iClob(makeHeading_Widget("${bookmark.tag.home}"))); | 1924 | addChild_Widget(headings, iClob(makeHeading_Widget("${bookmark.tag.home}"))); |
1923 | addChild_Widget(values, iClob(makeToggle_Widget("bmed.tag.home"))); | 1925 | addChild_Widget(values, iClob(makeToggle_Widget("bmed.tag.home"))); |
@@ -2048,7 +2050,7 @@ iWidget *makeFeedSettings_Widget(uint32_t bookmarkId) { | |||
2048 | frameless_WidgetFlag), | 2050 | frameless_WidgetFlag), |
2049 | "feedcfg.heading"); | 2051 | "feedcfg.heading"); |
2050 | iWidget *headings, *values; | 2052 | iWidget *headings, *values; |
2051 | addChild_Widget(dlg, iClob(makeTwoColumnWidget_(&headings, &values))); | 2053 | addChild_Widget(dlg, iClob(makeTwoColumns_Widget(&headings, &values))); |
2052 | iInputWidget *input = new_InputWidget(0); | 2054 | iInputWidget *input = new_InputWidget(0); |
2053 | addDialogInputWithHeading_(headings, values, "${dlg.feed.title}", "feedcfg.title", iClob(input)); | 2055 | addDialogInputWithHeading_(headings, values, "${dlg.feed.title}", "feedcfg.title", iClob(input)); |
2054 | addChild_Widget(headings, iClob(makeHeading_Widget("${dlg.feed.entrytype}"))); | 2056 | addChild_Widget(headings, iClob(makeHeading_Widget("${dlg.feed.entrytype}"))); |
@@ -2223,7 +2225,7 @@ iWidget *makeTranslation_Widget(iWidget *parent) { | |||
2223 | addChild_Widget(dlg, iClob(makePadding_Widget(lineHeight_Text(uiLabel_FontId)))); | 2225 | addChild_Widget(dlg, iClob(makePadding_Widget(lineHeight_Text(uiLabel_FontId)))); |
2224 | iWidget *headings, *values; | 2226 | iWidget *headings, *values; |
2225 | iWidget *page; | 2227 | iWidget *page; |
2226 | addChild_Widget(dlg, iClob(page = makeTwoColumnWidget_(&headings, &values))); | 2228 | addChild_Widget(dlg, iClob(page = makeTwoColumns_Widget(&headings, &values))); |
2227 | setId_Widget(page, "xlt.langs"); | 2229 | setId_Widget(page, "xlt.langs"); |
2228 | iLabelWidget *fromLang, *toLang; | 2230 | iLabelWidget *fromLang, *toLang; |
2229 | /* Source language. */ { | 2231 | /* Source language. */ { |
diff --git a/src/ui/util.h b/src/ui/util.h index 43aeb172..5b02a4b3 100644 --- a/src/ui/util.h +++ b/src/ui/util.h | |||
@@ -242,6 +242,8 @@ iLabelWidget * makeMenuButton_LabelWidget (const char *label, const iMenuItem | |||
242 | 242 | ||
243 | iWidget * makeTabs_Widget (iWidget *parent); | 243 | iWidget * makeTabs_Widget (iWidget *parent); |
244 | void appendTabPage_Widget (iWidget *tabs, iWidget *page, const char *label, int key, int kmods); | 244 | void appendTabPage_Widget (iWidget *tabs, iWidget *page, const char *label, int key, int kmods); |
245 | iWidget * appendTwoColumnTabPage_Widget(iWidget *tabs, const char *title, int shortcut, iWidget **headings, | ||
246 | iWidget **values); | ||
245 | void prependTabPage_Widget (iWidget *tabs, iWidget *page, const char *label, int key, int kmods); | 247 | void prependTabPage_Widget (iWidget *tabs, iWidget *page, const char *label, int key, int kmods); |
246 | iWidget * removeTabPage_Widget (iWidget *tabs, size_t index); /* returns the page */ | 248 | iWidget * removeTabPage_Widget (iWidget *tabs, size_t index); /* returns the page */ |
247 | void resizeToLargestPage_Widget (iWidget *tabs); | 249 | void resizeToLargestPage_Widget (iWidget *tabs); |
@@ -258,7 +260,9 @@ size_t tabCount_Widget (const iWidget *tabs); | |||
258 | /*-----------------------------------------------------------------------------------------------*/ | 260 | /*-----------------------------------------------------------------------------------------------*/ |
259 | 261 | ||
260 | iWidget * makeSheet_Widget (const char *id); | 262 | iWidget * makeSheet_Widget (const char *id); |
263 | void useSheetStyle_Widget (iWidget *); | ||
261 | iWidget * makeDialogButtons_Widget (const iMenuItem *actions, size_t numActions); | 264 | iWidget * makeDialogButtons_Widget (const iMenuItem *actions, size_t numActions); |
265 | iWidget * makeTwoColumns_Widget (iWidget **headings, iWidget **values); | ||
262 | 266 | ||
263 | iInputWidget *addTwoColumnDialogInputField_Widget(iWidget *headings, iWidget *values, | 267 | iInputWidget *addTwoColumnDialogInputField_Widget(iWidget *headings, iWidget *values, |
264 | const char *labelText, const char *inputId, | 268 | const char *labelText, const char *inputId, |