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 /src/ui/uploadwidget.c | |
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.
Diffstat (limited to 'src/ui/uploadwidget.c')
-rw-r--r-- | src/ui/uploadwidget.c | 148 |
1 files changed, 148 insertions, 0 deletions
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) | ||