summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-04-09 11:19:50 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-04-09 11:19:50 +0300
commit1496aeacf167dd647fdd30a6d2687ebcb4b126b1 (patch)
tree3e7166425da72a533eaf888a5aa9eb6462328141 /src
parentce7f402193aef282972660c9cd22875409a86964 (diff)
Mobile: Fixed dialog field misalignments
Diffstat (limited to 'src')
-rw-r--r--src/ui/certimportwidget.c13
-rw-r--r--src/ui/inputwidget.c36
-rw-r--r--src/ui/labelwidget.c45
-rw-r--r--src/ui/util.c310
-rw-r--r--src/ui/util.h5
5 files changed, 239 insertions, 170 deletions
diff --git a/src/ui/certimportwidget.c b/src/ui/certimportwidget.c
index a4245603..dd800dd2 100644
--- a/src/ui/certimportwidget.c
+++ b/src/ui/certimportwidget.c
@@ -135,15 +135,22 @@ void init_CertImportWidget(iCertImportWidget *d) {
135 setFrameColor_Widget(as_Widget(d->keyLabel), uiTextCaution_ColorId); 135 setFrameColor_Widget(as_Widget(d->keyLabel), uiTextCaution_ColorId);
136 } 136 }
137 addChild_Widget(w, iClob(makePadding_Widget(gap_UI))); 137 addChild_Widget(w, iClob(makePadding_Widget(gap_UI)));
138 /* TODO: Use makeTwoColumnWidget_() */
138 iWidget *page = new_Widget(); { 139 iWidget *page = new_Widget(); {
139 setFlags_Widget(page, arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag, iTrue); 140 setFlags_Widget(page, arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag, iTrue);
140 iWidget *headings = addChildFlags_Widget( 141 iWidget *headings = addChildFlags_Widget(
141 page, iClob(new_Widget()), arrangeVertical_WidgetFlag | arrangeSize_WidgetFlag); 142 page, iClob(new_Widget()), arrangeVertical_WidgetFlag | arrangeSize_WidgetFlag);
142 iWidget *values = addChildFlags_Widget( 143 iWidget *values = addChildFlags_Widget(
143 page, iClob(new_Widget()), arrangeVertical_WidgetFlag | arrangeSize_WidgetFlag); 144 page, iClob(new_Widget()), arrangeVertical_WidgetFlag | arrangeSize_WidgetFlag);
144 addChild_Widget(headings, iClob(makeHeading_Widget("${dlg.certimport.notes}"))); 145// addChild_Widget(headings, iClob(makeHeading_Widget("${dlg.certimport.notes}")));
145 addChild_Widget(values, iClob(d->notes = new_InputWidget(0))); 146// addChild_Widget(values, iClob(d->notes = new_InputWidget(0)));
146 setHint_InputWidget(d->notes, "${hint.certimport.description}"); 147// setHint_InputWidget(d->notes, "${hint.certimport.description}");
148 addTwoColumnDialogInputField_Widget(
149 headings,
150 values,
151 "${dlg.certimport.notes}",
152 "",
153 iClob(d->notes = newHint_InputWidget(0, "${hint.certimport.description}")));
147 as_Widget(d->notes)->rect.size.x = gap_UI * 70; 154 as_Widget(d->notes)->rect.size.x = gap_UI * 70;
148 } 155 }
149 addChild_Widget(w, iClob(page)); 156 addChild_Widget(w, iClob(page));
diff --git a/src/ui/inputwidget.c b/src/ui/inputwidget.c
index 74376a18..df5eb0df 100644
--- a/src/ui/inputwidget.c
+++ b/src/ui/inputwidget.c
@@ -119,13 +119,29 @@ static void invalidateBuffered_InputWidget_(iInputWidget *d) {
119 } 119 }
120} 120}
121 121
122static void updateSizeForFixedLength_InputWidget_(iInputWidget *d) {
123 if (d->maxLen) {
124 /* Set a fixed size based on maximum possible width of the text. */
125 iBlock *content = new_Block(d->maxLen);
126 fill_Block(content, 'M');
127 int extraHeight = (flags_Widget(as_Widget(d)) & extraPadding_WidgetFlag ? 2 * gap_UI : 0);
128 setFixedSize_Widget(
129 as_Widget(d),
130 add_I2(measure_Text(d->font, cstr_Block(content)),
131 init_I2(6 * gap_UI + d->leftPadding + d->rightPadding,
132 2 * gap_UI + extraHeight)));
133 delete_Block(content);
134 }
135}
136
122static void updateMetrics_InputWidget_(iInputWidget *d) { 137static void updateMetrics_InputWidget_(iInputWidget *d) {
123 iWidget *w = as_Widget(d); 138 iWidget *w = as_Widget(d);
139 updateSizeForFixedLength_InputWidget_(d);
124 /* Caller must arrange the width, but the height is fixed. */ 140 /* Caller must arrange the width, but the height is fixed. */
125 w->rect.size.y = lineHeight_Text(d->font) * 1.3f; 141 w->rect.size.y = lineHeight_Text(d->font) * 1.3f;
126#if defined (iPlatformMobile) 142 if (flags_Widget(w) & extraPadding_WidgetFlag) {
127 w->rect.size.y += 2 * gap_UI; 143 w->rect.size.y += 2 * gap_UI;
128#endif 144 }
129 invalidateBuffered_InputWidget_(d); 145 invalidateBuffered_InputWidget_(d);
130 if (parent_Widget(w)) { 146 if (parent_Widget(w)) {
131 arrange_Widget(w); 147 arrange_Widget(w);
@@ -136,6 +152,9 @@ void init_InputWidget(iInputWidget *d, size_t maxLen) {
136 iWidget *w = &d->widget; 152 iWidget *w = &d->widget;
137 init_Widget(w); 153 init_Widget(w);
138 setFlags_Widget(w, focusable_WidgetFlag | hover_WidgetFlag | touchDrag_WidgetFlag, iTrue); 154 setFlags_Widget(w, focusable_WidgetFlag | hover_WidgetFlag | touchDrag_WidgetFlag, iTrue);
155#if defined (iPlatformMobile)
156 setFlags_Widget(w, extraPadding_WidgetFlag, iTrue);
157#endif
139 init_Array(&d->text, sizeof(iChar)); 158 init_Array(&d->text, sizeof(iChar));
140 init_Array(&d->oldText, sizeof(iChar)); 159 init_Array(&d->oldText, sizeof(iChar));
141 init_String(&d->hint); 160 init_String(&d->hint);
@@ -244,15 +263,7 @@ iInputWidgetContentPadding contentPadding_InputWidget(const iInputWidget *d) {
244void setMaxLen_InputWidget(iInputWidget *d, size_t maxLen) { 263void setMaxLen_InputWidget(iInputWidget *d, size_t maxLen) {
245 d->maxLen = maxLen; 264 d->maxLen = maxLen;
246 d->mode = (maxLen == 0 ? insert_InputMode : overwrite_InputMode); 265 d->mode = (maxLen == 0 ? insert_InputMode : overwrite_InputMode);
247 if (maxLen) { 266 updateSizeForFixedLength_InputWidget_(d);
248 /* Set a fixed size. */
249 iBlock *content = new_Block(maxLen);
250 fill_Block(content, 'M');
251 setFixedSize_Widget(
252 as_Widget(d),
253 add_I2(measure_Text(d->font, cstr_Block(content)), init_I2(6 * gap_UI, 2 * gap_UI)));
254 delete_Block(content);
255 }
256} 267}
257 268
258void setHint_InputWidget(iInputWidget *d, const char *hintText) { 269void setHint_InputWidget(iInputWidget *d, const char *hintText) {
@@ -269,6 +280,7 @@ void setContentPadding_InputWidget(iInputWidget *d, int left, int right) {
269 if (right >= 0) { 280 if (right >= 0) {
270 d->rightPadding = right; 281 d->rightPadding = right;
271 } 282 }
283 updateSizeForFixedLength_InputWidget_(d);
272 refresh_Widget(d); 284 refresh_Widget(d);
273} 285}
274 286
diff --git a/src/ui/labelwidget.c b/src/ui/labelwidget.c
index 43f88277..16fee26d 100644
--- a/src/ui/labelwidget.c
+++ b/src/ui/labelwidget.c
@@ -29,15 +29,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
29#include "util.h" 29#include "util.h"
30#include "keys.h" 30#include "keys.h"
31 31
32iLocalDef iInt2 padding_(int64_t flags) {
33#if defined (iPlatformAppleMobile)
34 return init_I2(flags & tight_WidgetFlag ? 2 * gap_UI : (4 * gap_UI),
35 (flags & extraPadding_WidgetFlag ? 1.5f : 1) * 3 * gap_UI / 2);
36#else
37 return init_I2(flags & tight_WidgetFlag ? 3 * gap_UI / 2 : (3 * gap_UI), gap_UI);
38#endif
39}
40
41struct Impl_LabelWidget { 32struct Impl_LabelWidget {
42 iWidget widget; 33 iWidget widget;
43 iString srcLabel; 34 iString srcLabel;
@@ -52,6 +43,24 @@ struct Impl_LabelWidget {
52 iClick click; 43 iClick click;
53}; 44};
54 45
46static iInt2 padding_LabelWidget_(const iLabelWidget *d, int corner) {
47 const iWidget *w = constAs_Widget(d);
48 const int64_t flags = flags_Widget(w);
49 const iInt2 widgetPad = (corner == 0 ? init_I2(w->padding[0], w->padding[1])
50 : corner == 1 ? init_I2(w->padding[2], w->padding[1])
51 : corner == 2 ? init_I2(w->padding[2], w->padding[3])
52 : init_I2(w->padding[0], w->padding[3]));
53#if defined (iPlatformAppleMobile)
54 return add_I2(widgetPad,
55 init_I2(flags & tight_WidgetFlag ? 2 * gap_UI : (4 * gap_UI),
56 (flags & extraPadding_WidgetFlag ? 1.5f : 1) * 3 * gap_UI / 2));
57#else
58 return add_I2(widgetPad,
59 init_I2(flags & tight_WidgetFlag ? 3 * gap_UI / 2 : (3 * gap_UI),
60 gap_UI));
61#endif
62}
63
55iDefineObjectConstructionArgs(LabelWidget, 64iDefineObjectConstructionArgs(LabelWidget,
56 (const char *label, const char *cmd), 65 (const char *label, const char *cmd),
57 label, cmd) 66 label, cmd)
@@ -268,7 +277,7 @@ static void draw_LabelWidget_(const iLabelWidget *d) {
268 d->font, 277 d->font,
269 (iRect){ 278 (iRect){
270 /* The icon position is fine-tuned; c.f. high baseline of Source Sans Pro. */ 279 /* The icon position is fine-tuned; c.f. high baseline of Source Sans Pro. */
271 add_I2(add_I2(bounds.pos, padding_(flags)), 280 add_I2(add_I2(bounds.pos, padding_LabelWidget_(d, 0)),
272 init_I2((flags & extraPadding_WidgetFlag ? -2 : -1.20f) * gap_UI + 281 init_I2((flags & extraPadding_WidgetFlag ? -2 : -1.20f) * gap_UI +
273 (deviceType_App() == tablet_AppDeviceType ? -gap_UI : 0), 282 (deviceType_App() == tablet_AppDeviceType ? -gap_UI : 0),
274 -gap_UI / 8)), 283 -gap_UI / 8)),
@@ -288,14 +297,15 @@ static void draw_LabelWidget_(const iLabelWidget *d) {
288 drawWrapRange_Text(d->font, topLeft_Rect(inner), wrap, fg, range_String(&d->label)); 297 drawWrapRange_Text(d->font, topLeft_Rect(inner), wrap, fg, range_String(&d->label));
289 } 298 }
290 else if (flags & alignLeft_WidgetFlag) { 299 else if (flags & alignLeft_WidgetFlag) {
291 draw_Text(d->font, add_I2(bounds.pos, addX_I2(padding_(flags), iconPad)), fg, cstr_String(&d->label)); 300 draw_Text(d->font, add_I2(bounds.pos, addX_I2(padding_LabelWidget_(d, 0), iconPad)),
301 fg, cstr_String(&d->label));
292 if ((flags & drawKey_WidgetFlag) && d->key) { 302 if ((flags & drawKey_WidgetFlag) && d->key) {
293 iString str; 303 iString str;
294 init_String(&str); 304 init_String(&str);
295 keyStr_LabelWidget_(d, &str); 305 keyStr_LabelWidget_(d, &str);
296 drawAlign_Text(uiShortcuts_FontId, 306 drawAlign_Text(uiShortcuts_FontId,
297 add_I2(topRight_Rect(bounds), 307 add_I2(topRight_Rect(bounds),
298 addX_I2(negX_I2(padding_(flags)), 308 addX_I2(negX_I2(padding_LabelWidget_(d, 1)),
299 deviceType_App() == tablet_AppDeviceType ? gap_UI : 0)), 309 deviceType_App() == tablet_AppDeviceType ? gap_UI : 0)),
300 flags & pressed_WidgetFlag ? fg 310 flags & pressed_WidgetFlag ? fg
301 : isCaution ? uiTextCaution_ColorId 311 : isCaution ? uiTextCaution_ColorId
@@ -308,14 +318,16 @@ static void draw_LabelWidget_(const iLabelWidget *d) {
308 else if (flags & alignRight_WidgetFlag) { 318 else if (flags & alignRight_WidgetFlag) {
309 drawAlign_Text( 319 drawAlign_Text(
310 d->font, 320 d->font,
311 add_I2(topRight_Rect(bounds), negX_I2(padding_(flags))), 321 add_I2(topRight_Rect(bounds), negX_I2(padding_LabelWidget_(d, 1))),
312 fg, 322 fg,
313 right_Alignment, 323 right_Alignment,
314 cstr_String(&d->label)); 324 cstr_String(&d->label));
315 } 325 }
316 else { 326 else {
317 drawCentered_Text(d->font, 327 drawCentered_Text(d->font,
318 adjusted_Rect(bounds, init_I2(iconPad, 0), zero_I2()), 328 adjusted_Rect(bounds,
329 add_I2(zero_I2(), init_I2(iconPad, 0)),
330 neg_I2(zero_I2())),
319 d->alignVisual, 331 d->alignVisual,
320 fg, 332 fg,
321 "%s", 333 "%s",
@@ -327,7 +339,7 @@ static void draw_LabelWidget_(const iLabelWidget *d) {
327 drawCentered_Text(d->font, 339 drawCentered_Text(d->font,
328 (iRect){ addX_I2(topRight_Rect(chRect), -iconPad), 340 (iRect){ addX_I2(topRight_Rect(chRect), -iconPad),
329 init_I2(chSize, height_Rect(chRect)) }, 341 init_I2(chSize, height_Rect(chRect)) },
330 iTrue, fg, rightAngle_Icon); 342 iTrue, uiSeparator_ColorId, rightAngle_Icon);
331 } 343 }
332 unsetClip_Paint(&p); 344 unsetClip_Paint(&p);
333} 345}
@@ -347,7 +359,8 @@ static void sizeChanged_LabelWidget_(iLabelWidget *d) {
347iInt2 defaultSize_LabelWidget(const iLabelWidget *d) { 359iInt2 defaultSize_LabelWidget(const iLabelWidget *d) {
348 const iWidget *w = constAs_Widget(d); 360 const iWidget *w = constAs_Widget(d);
349 const int64_t flags = flags_Widget(w); 361 const int64_t flags = flags_Widget(w);
350 iInt2 size = add_I2(measure_Text(d->font, cstr_String(&d->label)), muli_I2(padding_(flags), 2)); 362 iInt2 size = add_I2(measure_Text(d->font, cstr_String(&d->label)),
363 add_I2(padding_LabelWidget_(d, 0), padding_LabelWidget_(d, 2)));
351 if ((flags & drawKey_WidgetFlag) && d->key) { 364 if ((flags & drawKey_WidgetFlag) && d->key) {
352 iString str; 365 iString str;
353 init_String(&str); 366 init_String(&str);
diff --git a/src/ui/util.c b/src/ui/util.c
index 60518fd4..9bfe40c9 100644
--- a/src/ui/util.c
+++ b/src/ui/util.c
@@ -1153,6 +1153,7 @@ static iLabelWidget *makePanelButton_(const char *text, const char *command) {
1153 iTrue); 1153 iTrue);
1154 checkIcon_LabelWidget(btn); 1154 checkIcon_LabelWidget(btn);
1155 setFont_LabelWidget(btn, defaultBig_FontId); 1155 setFont_LabelWidget(btn, defaultBig_FontId);
1156 setTextColor_LabelWidget(btn, uiTextStrong_ColorId);
1156 setBackgroundColor_Widget(as_Widget(btn), uiBackgroundSidebar_ColorId); 1157 setBackgroundColor_Widget(as_Widget(btn), uiBackgroundSidebar_ColorId);
1157 return btn; 1158 return btn;
1158} 1159}
@@ -1177,6 +1178,28 @@ static iWidget *makeValuePadding_(iWidget *value) {
1177 return pad; 1178 return pad;
1178} 1179}
1179 1180
1181static iWidget *makeValuePaddingWithHeading_(iLabelWidget *heading, iWidget *value) {
1182 iWidget *div = new_Widget();
1183 setFlags_Widget(div,
1184 borderBottom_WidgetFlag | arrangeHeight_WidgetFlag |
1185 resizeWidthOfChildren_WidgetFlag |
1186 arrangeHorizontal_WidgetFlag, iTrue);
1187 setBackgroundColor_Widget(div, uiBackgroundSidebar_ColorId);
1188 setPadding_Widget(div, gap_UI, gap_UI, 4 * gap_UI, gap_UI);
1189 addChildFlags_Widget(div, iClob(heading), 0);
1190 //setFixedSize_Widget(as_Widget(heading), init_I2(-1, height_Widget(value)));
1191 setFont_LabelWidget(heading, defaultBig_FontId);
1192 setTextColor_LabelWidget(heading, uiTextStrong_ColorId);
1193 if (isInstance_Object(value, &Class_InputWidget)) {
1194 addChildFlags_Widget(div, iClob(value), expand_WidgetFlag);
1195 }
1196 else {
1197 addChildFlags_Widget(div, iClob(new_Widget()), expand_WidgetFlag);
1198 addChild_Widget(div, iClob(value));
1199 }
1200 return div;
1201}
1202
1180void finalizeSheet_Widget(iWidget *sheet) { 1203void finalizeSheet_Widget(iWidget *sheet) {
1181 /* The sheet contents are completely rearranged and restyled on a phone. 1204 /* The sheet contents are completely rearranged and restyled on a phone.
1182 We'll set up a linear fullscreen arrangement of the widgets. Sheets are already 1205 We'll set up a linear fullscreen arrangement of the widgets. Sheets are already
@@ -1289,7 +1312,6 @@ void finalizeSheet_Widget(iWidget *sheet) {
1289 focusRoot_WidgetFlag | 1312 focusRoot_WidgetFlag |
1290 hidden_WidgetFlag | 1313 hidden_WidgetFlag |
1291 disabled_WidgetFlag | 1314 disabled_WidgetFlag |
1292 //safePadding_WidgetFlag |
1293 arrangeVertical_WidgetFlag | 1315 arrangeVertical_WidgetFlag |
1294 resizeWidthOfChildren_WidgetFlag | 1316 resizeWidthOfChildren_WidgetFlag |
1295 arrangeHeight_WidgetFlag | 1317 arrangeHeight_WidgetFlag |
@@ -1306,7 +1328,10 @@ void finalizeSheet_Widget(iWidget *sheet) {
1306 iWidget *value = child_Widget(values, 0); 1328 iWidget *value = child_Widget(values, 0);
1307 removeChild_Widget(headings, heading); 1329 removeChild_Widget(headings, heading);
1308 removeChild_Widget(values, value); 1330 removeChild_Widget(values, value);
1309 if (isOmittedPref_(id_Widget(value))) { 1331 /* Can we ignore these widgets? */
1332 if (isOmittedPref_(id_Widget(value)) ||
1333 (class_Widget(heading) == &Class_Widget &&
1334 class_Widget(value) == &Class_Widget) /* just padding */) {
1310 iRelease(heading); 1335 iRelease(heading);
1311 iRelease(value); 1336 iRelease(value);
1312 continue; 1337 continue;
@@ -1315,104 +1340,97 @@ void finalizeSheet_Widget(iWidget *sheet) {
1315 iLabelWidget *headingLabel = NULL; 1340 iLabelWidget *headingLabel = NULL;
1316 iLabelWidget *valueLabel = NULL; 1341 iLabelWidget *valueLabel = NULL;
1317 iInputWidget *valueInput = NULL; 1342 iInputWidget *valueInput = NULL;
1343 const iBool isMenuButton = findChild_Widget(value, "menu") != NULL;
1318 if (isInstance_Object(heading, &Class_LabelWidget)) { 1344 if (isInstance_Object(heading, &Class_LabelWidget)) {
1319 headingLabel = (iLabelWidget *) heading; 1345 headingLabel = (iLabelWidget *) heading;
1320 stripTrailingColon_(headingLabel); 1346 stripTrailingColon_(headingLabel);
1321 } 1347 }
1322 if (isInstance_Object(value, &Class_LabelWidget)) { 1348 if (isInstance_Object(value, &Class_LabelWidget)) {
1323 valueLabel = (iLabelWidget *) value; 1349 valueLabel = (iLabelWidget *) value;
1350 setFont_LabelWidget(valueLabel, defaultBig_FontId);
1324 } 1351 }
1325 if (isInstance_Object(value, &Class_InputWidget)) { 1352 if (isInstance_Object(value, &Class_InputWidget)) {
1326 valueInput = (iInputWidget *) value; 1353 valueInput = (iInputWidget *) value;
1354 setFlags_Widget(value, borderBottom_WidgetFlag, iFalse);
1327 element = textInput_PrefsElement; 1355 element = textInput_PrefsElement;
1328 } 1356 }
1329 if (valueLabel) { 1357 if (childCount_Widget(value) >= 2) {
1330 setFont_LabelWidget(valueLabel, defaultBig_FontId); 1358 if (isInstance_Object(child_Widget(value, 0), &Class_InputWidget)) {
1359 element = textInput_PrefsElement;
1360 setPadding_Widget(value, 0, 0, gap_UI, 0);
1361 valueInput = child_Widget(value, 0);
1362 }
1363 }
1364 if (valueInput) {
1365 setFont_InputWidget(valueInput, defaultBig_FontId);
1366 setContentPadding_InputWidget(valueInput, 3 * gap_UI, 0);
1331 } 1367 }
1332 /* Toggles have the button on the right. */ 1368 /* Toggles have the button on the right. */
1333 if (valueLabel && cmp_String(command_LabelWidget(valueLabel), "toggle") == 0) { 1369 if (valueLabel && cmp_String(command_LabelWidget(valueLabel), "toggle") == 0) {
1334 element = toggle_PrefsElement; 1370 element = toggle_PrefsElement;
1335 iWidget *div = new_Widget();
1336 setBackgroundColor_Widget(div, uiBackgroundSidebar_ColorId);
1337 setPadding_Widget(div, gap_UI, gap_UI, 4 * gap_UI, gap_UI);
1338 addChildFlags_Widget(div, iClob(heading), 0);
1339 setFont_LabelWidget((iLabelWidget *) heading, defaultBig_FontId);
1340 addChildFlags_Widget(div, iClob(new_Widget()), expand_WidgetFlag);
1341 addChild_Widget(div, iClob(value));
1342 addPanelChild_(owner, 1371 addPanelChild_(owner,
1343 iClob(div), 1372 iClob(makeValuePaddingWithHeading_(headingLabel, value)),
1344 borderBottom_WidgetFlag | arrangeHeight_WidgetFlag | 1373 0,
1345 resizeWidthOfChildren_WidgetFlag | 1374 element,
1346 arrangeHorizontal_WidgetFlag, 1375 prevElement);
1376 }
1377 else if (valueLabel && isEmpty_String(text_LabelWidget(valueLabel))) {
1378 element = heading_PrefsElement;
1379 iRelease(value);
1380 addPanelChild_(owner, iClob(heading), 0, element, prevElement);
1381 setFont_LabelWidget(headingLabel, uiLabelBold_FontId);
1382 }
1383 else if (isMenuButton) {
1384 element = dropdown_PrefsElement;
1385 setFlags_Widget(value,
1386 alignRight_WidgetFlag | noBackground_WidgetFlag |
1387 frameless_WidgetFlag, iTrue);
1388 setFlags_Widget(value, alignLeft_WidgetFlag, iFalse);
1389 addPanelChild_(owner, iClob(makeValuePaddingWithHeading_(headingLabel, value)), 0,
1347 element, prevElement); 1390 element, prevElement);
1348 } 1391 }
1392 else if (valueInput) {
1393 addPanelChild_(owner, iClob(makeValuePaddingWithHeading_(headingLabel, value)), 0,
1394 element, prevElement);
1395 }
1349 else { 1396 else {
1350 if (valueLabel && isEmpty_String(text_LabelWidget(valueLabel))) { 1397 addChildFlags_Widget(owner, iClob(heading), borderBottom_WidgetFlag);
1351 element = heading_PrefsElement; 1398 if (headingLabel) {
1352 iRelease(value); 1399 setTextColor_LabelWidget(headingLabel, uiSubheading_ColorId);
1353 addPanelChild_(owner, iClob(heading), 0, element, prevElement); 1400 setText_LabelWidget(headingLabel,
1354 setFont_LabelWidget(headingLabel, uiLabelBold_FontId); 1401 collect_String(upper_String(text_LabelWidget(headingLabel))));
1355 } 1402 }
1356 else { 1403 if (childCount_Widget(value) >= 2) {
1357 addChildFlags_Widget(owner, iClob(heading), borderBottom_WidgetFlag); 1404// if (isInstance_Object(child_Widget(value, 0), &Class_InputWidget)) {
1358 if (headingLabel) { 1405// element = textInput_PrefsElement;
1359 setTextColor_LabelWidget(headingLabel, uiSubheading_ColorId); 1406// setPadding_Widget(value, 0, 0, gap_UI, 0);
1360 setText_LabelWidget(headingLabel, 1407// valueInput = child_Widget(value, 0);
1361 collect_String(upper_String(text_LabelWidget(headingLabel)))); 1408// setFlags_Widget(as_Widget(valueInput), fixedWidth_WidgetFlag, iFalse);
1362 } 1409// setFlags_Widget(as_Widget(valueInput), expand_WidgetFlag, iTrue);
1363 const iBool isMenuButton = findChild_Widget(value, "menu") != NULL; 1410// setFlags_Widget(value, resizeWidthOfChildren_WidgetFlag |
1364 if (isMenuButton) { 1411// resizeToParentWidth_WidgetFlag, iTrue);
1365 element = dropdown_PrefsElement; 1412// setFont_LabelWidget(child_Widget(value, 1), defaultBig_FontId);
1366 setFlags_Widget(value, noBackground_WidgetFlag | frameless_WidgetFlag, iTrue); 1413// setTextColor_LabelWidget(child_Widget(value, 1), uiAnnotation_ColorId);
1367 setFlags_Widget(value, alignLeft_WidgetFlag, iFalse); 1414// }
1368 } 1415// else {
1369 if (childCount_Widget(value) >= 2) { 1416 element = radioButton_PrefsElement;
1370 if (isInstance_Object(child_Widget(value, 0), &Class_InputWidget)) { 1417// }
1371 element = textInput_PrefsElement; 1418 }
1372 setPadding_Widget(value, 0, 0, gap_UI, 0); 1419 addPanelChild_(owner, iClob(value), 0, element, prevElement);
1373 valueInput = child_Widget(value, 0); 1420 /* Radio buttons expand to fill the space. */
1374 setFlags_Widget(as_Widget(valueInput), fixedWidth_WidgetFlag, iFalse); 1421 if (element == radioButton_PrefsElement) {
1375 setFlags_Widget(as_Widget(valueInput), expand_WidgetFlag, iTrue); 1422 setBackgroundColor_Widget(value, uiBackgroundSidebar_ColorId);
1376 setFlags_Widget(value, resizeWidthOfChildren_WidgetFlag | 1423 setPadding_Widget(value, 4 * gap_UI, 2 * gap_UI, 4 * gap_UI, 2 * gap_UI);
1377 resizeToParentWidth_WidgetFlag, iTrue); 1424 setFlags_Widget(value,
1378 setFont_LabelWidget(child_Widget(value, 1), defaultBig_FontId); 1425 borderBottom_WidgetFlag |
1379 setTextColor_LabelWidget(child_Widget(value, 1), uiAnnotation_ColorId); 1426 resizeToParentWidth_WidgetFlag |
1380 } 1427 resizeWidthOfChildren_WidgetFlag,
1381 else { 1428 iTrue);
1382 element = radioButton_PrefsElement; 1429 iForEach(ObjectList, sub, children_Widget(value)) {
1383 } 1430 if (isInstance_Object(sub.object, &Class_LabelWidget)) {
1384 } 1431 iLabelWidget *opt = sub.object;
1385 if (valueInput) { 1432 setFont_LabelWidget(opt, defaultMedium_FontId);
1386 setFont_InputWidget(valueInput, defaultBig_FontId); 1433 setFlags_Widget(as_Widget(opt), noBackground_WidgetFlag, iTrue);
1387 setContentPadding_InputWidget(valueInput, 3 * gap_UI, 3 * gap_UI);
1388 }
1389 if (element == textInput_PrefsElement || isMenuButton) {
1390 setFlags_Widget(value, borderBottom_WidgetFlag, iFalse);
1391 //iWidget *pad = new_Widget();
1392 //setBackgroundColor_Widget(pad, uiBackgroundSidebar_ColorId);
1393 //setPadding_Widget(pad, 0, 1 * gap_UI, 0, 1 * gap_UI);
1394 //addChild_Widget(pad, iClob(value));
1395 addPanelChild_(owner, iClob(makeValuePadding_(value)), 0,
1396 element, prevElement);
1397 }
1398 else {
1399 addPanelChild_(owner, iClob(value), 0, element, prevElement);
1400 }
1401 /* Radio buttons expand to fill the space. */
1402 if (element == radioButton_PrefsElement) {
1403 setBackgroundColor_Widget(value, uiBackgroundSidebar_ColorId);
1404 setPadding_Widget(value, 4 * gap_UI, 2 * gap_UI, 4 * gap_UI, 2 * gap_UI);
1405 setFlags_Widget(value,
1406 borderBottom_WidgetFlag |
1407 resizeToParentWidth_WidgetFlag |
1408 resizeWidthOfChildren_WidgetFlag,
1409 iTrue);
1410 iForEach(ObjectList, sub, children_Widget(value)) {
1411 if (isInstance_Object(sub.object, &Class_LabelWidget)) {
1412 iLabelWidget *opt = sub.object;
1413 setFont_LabelWidget(opt, defaultMedium_FontId);
1414 setFlags_Widget(as_Widget(opt), noBackground_WidgetFlag, iTrue);
1415 }
1416 } 1434 }
1417 } 1435 }
1418 } 1436 }
@@ -1530,7 +1548,7 @@ void finalizeSheet_Widget(iWidget *sheet) {
1530 updateSheetPanelMetrics_(sheet); 1548 updateSheetPanelMetrics_(sheet);
1531 arrange_Widget(sheet->parent); 1549 arrange_Widget(sheet->parent);
1532 postCommand_App("widget.overflow"); /* with the correct dimensions */ 1550 postCommand_App("widget.overflow"); /* with the correct dimensions */
1533 printTree_Widget(sheet); 1551// printTree_Widget(sheet);
1534 } 1552 }
1535 else { 1553 else {
1536 arrange_Widget(sheet); 1554 arrange_Widget(sheet);
@@ -1690,7 +1708,6 @@ iWidget *makeValueInput_Widget(iWidget *parent, const iString *initialValue, con
1690 setFocus_Widget(NULL); 1708 setFocus_Widget(NULL);
1691 } 1709 }
1692 iWidget *dlg = makeSheet_Widget(command); 1710 iWidget *dlg = makeSheet_Widget(command);
1693// setFlags_Widget(dlg, horizontalSafeAreaPadding_Widget, iTrue);
1694 setCommandHandler_Widget(dlg, valueInputHandler_); 1711 setCommandHandler_Widget(dlg, valueInputHandler_);
1695 if (parent) { 1712 if (parent) {
1696 addChild_Widget(parent, iClob(dlg)); 1713 addChild_Widget(parent, iClob(dlg));
@@ -1897,7 +1914,9 @@ static int cmp_MenuItem_(const void *e1, const void *e2) {
1897#endif 1914#endif
1898 1915
1899void updatePreferencesLayout_Widget(iWidget *prefs) { 1916void updatePreferencesLayout_Widget(iWidget *prefs) {
1900 if (!prefs) return; 1917 if (!prefs || deviceType_App() == phone_AppDeviceType) {
1918 return;
1919 }
1901 /* Doing manual layout here because the widget arranging logic isn't sophisticated enough. */ 1920 /* Doing manual layout here because the widget arranging logic isn't sophisticated enough. */
1902 /* TODO: Make the arranging more sophisticated to automate this. */ 1921 /* TODO: Make the arranging more sophisticated to automate this. */
1903 static const char *inputIds[] = { 1922 static const char *inputIds[] = {
@@ -1929,6 +1948,29 @@ void updatePreferencesLayout_Widget(iWidget *prefs) {
1929 } 1948 }
1930} 1949}
1931 1950
1951static void addDialogInputWithHeading_(iWidget *headings, iWidget *values, const char *labelText,
1952 const char *inputId, iInputWidget *input) {
1953 iLabelWidget *head = addChild_Widget(headings, iClob(makeHeading_Widget(labelText)));
1954#if defined (iPlatformMobile)
1955 /* On mobile, inputs have 2 gaps of extra padding. */
1956 setFixedSize_Widget(as_Widget(head), init_I2(-1, height_Widget(input)));
1957 setPadding_Widget(as_Widget(head), 0, gap_UI, 0, 0);
1958#endif
1959 setId_Widget(addChild_Widget(values, input), inputId);
1960}
1961
1962iInputWidget *addTwoColumnDialogInputField_Widget(iWidget *headings, iWidget *values,
1963 const char *labelText, const char *inputId,
1964 iInputWidget *input) {
1965 addDialogInputWithHeading_(headings, values, labelText, inputId, input);
1966 return input;
1967}
1968
1969static void addPrefsInputWithHeading_(iWidget *headings, iWidget *values,
1970 const char *id, iInputWidget *input) {
1971 addDialogInputWithHeading_(headings, values, format_CStr("${%s}", id), id, input);
1972}
1973
1932iWidget *makePreferences_Widget(void) { 1974iWidget *makePreferences_Widget(void) {
1933 iWidget *dlg = makeSheet_Widget("prefs"); 1975 iWidget *dlg = makeSheet_Widget("prefs");
1934 addChildFlags_Widget(dlg, 1976 addChildFlags_Widget(dlg,
@@ -1945,8 +1987,7 @@ iWidget *makePreferences_Widget(void) {
1945 addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.downloads}"))); 1987 addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.downloads}")));
1946 setId_Widget(addChild_Widget(values, iClob(new_InputWidget(0))), "prefs.downloads"); 1988 setId_Widget(addChild_Widget(values, iClob(new_InputWidget(0))), "prefs.downloads");
1947#endif 1989#endif
1948 addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.searchurl}"))); 1990 addPrefsInputWithHeading_(headings, values, "prefs.searchurl", iClob(new_InputWidget(0)));
1949 setId_Widget(addChild_Widget(values, iClob(new_InputWidget(0))), "prefs.searchurl");
1950 addChild_Widget(headings, iClob(makePadding_Widget(bigGap))); 1991 addChild_Widget(headings, iClob(makePadding_Widget(bigGap)));
1951 addChild_Widget(values, iClob(makePadding_Widget(bigGap))); 1992 addChild_Widget(values, iClob(makePadding_Widget(bigGap)));
1952 addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.collapsepreonload}"))); 1993 addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.collapsepreonload}")));
@@ -2033,8 +2074,7 @@ iWidget *makePreferences_Widget(void) {
2033 addChild_Widget(values, iClob(makeToggle_Widget("prefs.hidetoolbarscroll"))); 2074 addChild_Widget(values, iClob(makeToggle_Widget("prefs.hidetoolbarscroll")));
2034 } 2075 }
2035 makeTwoColumnHeading_("${heading.prefs.sizing}", headings, values); 2076 makeTwoColumnHeading_("${heading.prefs.sizing}", headings, values);
2036 addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.uiscale}"))); 2077 addPrefsInputWithHeading_(headings, values, "prefs.uiscale", iClob(new_InputWidget(8)));
2037 setId_Widget(addChild_Widget(values, iClob(new_InputWidget(8))), "prefs.uiscale");
2038 addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.retainwindow}"))); 2078 addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.retainwindow}")));
2039 addChild_Widget(values, iClob(makeToggle_Widget("prefs.retainwindow"))); 2079 addChild_Widget(values, iClob(makeToggle_Widget("prefs.retainwindow")));
2040 } 2080 }
@@ -2142,26 +2182,24 @@ iWidget *makePreferences_Widget(void) {
2142 appendTwoColumnPage_(tabs, "${heading.prefs.network}", '5', &headings, &values); 2182 appendTwoColumnPage_(tabs, "${heading.prefs.network}", '5', &headings, &values);
2143 addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.decodeurls}"))); 2183 addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.decodeurls}")));
2144 addChild_Widget(values, iClob(makeToggle_Widget("prefs.decodeurls"))); 2184 addChild_Widget(values, iClob(makeToggle_Widget("prefs.decodeurls")));
2145 addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.cachesize}"))); 2185 /* Cache size. */ {
2146 iWidget *cacheGroup = new_Widget(); {
2147 iInputWidget *cache = new_InputWidget(4); 2186 iInputWidget *cache = new_InputWidget(4);
2148 setSelectAllOnFocus_InputWidget(cache, iTrue); 2187 setSelectAllOnFocus_InputWidget(cache, iTrue);
2149 setId_Widget(addChild_Widget(cacheGroup, iClob(cache)), "prefs.cachesize"); 2188 addPrefsInputWithHeading_(headings, values, "prefs.cachesize", iClob(cache));
2150 addChildFlags_Widget(cacheGroup, iClob(new_LabelWidget("${mb}", NULL)), frameless_WidgetFlag); 2189 iWidget *unit =
2190 addChildFlags_Widget(as_Widget(cache),
2191 iClob(new_LabelWidget("${mb}", NULL)),
2192 frameless_WidgetFlag | moveToParentRightEdge_WidgetFlag |
2193 resizeToParentHeight_WidgetFlag);
2194 setContentPadding_InputWidget(cache, 0, width_Widget(unit) - 4 * gap_UI);
2151 } 2195 }
2152 addChildFlags_Widget(values, iClob(cacheGroup), arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag);
2153 makeTwoColumnHeading_("${heading.prefs.certs}", headings, values); 2196 makeTwoColumnHeading_("${heading.prefs.certs}", headings, values);
2154 addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.ca.file}"))); 2197 addPrefsInputWithHeading_(headings, values, "prefs.ca.file", iClob(new_InputWidget(0)));
2155 setId_Widget(addChild_Widget(values, iClob(new_InputWidget(0))), "prefs.ca.file"); 2198 addPrefsInputWithHeading_(headings, values, "prefs.ca.path", iClob(new_InputWidget(0)));
2156 addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.ca.path}")));
2157 setId_Widget(addChild_Widget(values, iClob(new_InputWidget(0))), "prefs.ca.path");
2158 makeTwoColumnHeading_("${heading.prefs.proxies}", headings, values); 2199 makeTwoColumnHeading_("${heading.prefs.proxies}", headings, values);
2159 addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.proxy.gemini}"))); 2200 addPrefsInputWithHeading_(headings, values, "prefs.proxy.gemini", iClob(new_InputWidget(0)));
2160 setId_Widget(addChild_Widget(values, iClob(new_InputWidget(0))), "prefs.proxy.gemini"); 2201 addPrefsInputWithHeading_(headings, values, "prefs.proxy.gopher", iClob(new_InputWidget(0)));
2161 addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.proxy.gopher}"))); 2202 addPrefsInputWithHeading_(headings, values, "prefs.proxy.http", iClob(new_InputWidget(0)));
2162 setId_Widget(addChild_Widget(values, iClob(new_InputWidget(0))), "prefs.proxy.gopher");
2163 addChild_Widget(headings, iClob(makeHeading_Widget("${prefs.proxy.http}")));
2164 setId_Widget(addChild_Widget(values, iClob(new_InputWidget(0))), "prefs.proxy.http");
2165 } 2203 }
2166 /* Keybindings. */ 2204 /* Keybindings. */
2167 if (deviceType_App() == desktop_AppDeviceType) { 2205 if (deviceType_App() == desktop_AppDeviceType) {
@@ -2189,15 +2227,11 @@ iWidget *makeBookmarkEditor_Widget(void) {
2189 iWidget *headings, *values; 2227 iWidget *headings, *values;
2190 addChild_Widget(dlg, iClob(makeTwoColumnWidget_(&headings, &values))); 2228 addChild_Widget(dlg, iClob(makeTwoColumnWidget_(&headings, &values)));
2191 iInputWidget *inputs[4]; 2229 iInputWidget *inputs[4];
2192 addChild_Widget(headings, iClob(makeHeading_Widget("${dlg.bookmark.title}"))); 2230 addDialogInputWithHeading_(headings, values, "${dlg.bookmark.title}", "bmed.title", iClob(inputs[0] = new_InputWidget(0)));
2193 setId_Widget(addChild_Widget(values, iClob(inputs[0] = new_InputWidget(0))), "bmed.title"); 2231 addDialogInputWithHeading_(headings, values, "${dlg.bookmark.url}", "bmed.url", iClob(inputs[1] = new_InputWidget(0)));
2194 addChild_Widget(headings, iClob(makeHeading_Widget("${dlg.bookmark.url}")));
2195 setId_Widget(addChild_Widget(values, iClob(inputs[1] = new_InputWidget(0))), "bmed.url");
2196 setUrlContent_InputWidget(inputs[1], iTrue); 2232 setUrlContent_InputWidget(inputs[1], iTrue);
2197 addChild_Widget(headings, iClob(makeHeading_Widget("${dlg.bookmark.tags}"))); 2233 addDialogInputWithHeading_(headings, values, "${dlg.bookmark.tags}", "bmed.tags", iClob(inputs[2] = new_InputWidget(0)));
2198 setId_Widget(addChild_Widget(values, iClob(inputs[2] = new_InputWidget(0))), "bmed.tags"); 2234 addDialogInputWithHeading_(headings, values, "${dlg.bookmark.icon}", "bmed.icon", iClob(inputs[3] = new_InputWidget(1)));
2199 addChild_Widget(headings, iClob(makeHeading_Widget("${dlg.bookmark.icon}")));
2200 setId_Widget(addChild_Widget(values, iClob(inputs[3] = new_InputWidget(1))), "bmed.icon");
2201 arrange_Widget(dlg); 2235 arrange_Widget(dlg);
2202 for (int i = 0; i < 3; ++i) { 2236 for (int i = 0; i < 3; ++i) {
2203 as_Widget(inputs[i])->rect.size.x = 100 * gap_UI - headings->rect.size.x; 2237 as_Widget(inputs[i])->rect.size.x = 100 * gap_UI - headings->rect.size.x;
@@ -2322,9 +2356,8 @@ iWidget *makeFeedSettings_Widget(uint32_t bookmarkId) {
2322 "feedcfg.heading"); 2356 "feedcfg.heading");
2323 iWidget *headings, *values; 2357 iWidget *headings, *values;
2324 addChild_Widget(dlg, iClob(makeTwoColumnWidget_(&headings, &values))); 2358 addChild_Widget(dlg, iClob(makeTwoColumnWidget_(&headings, &values)));
2325 addChild_Widget(headings, iClob(makeHeading_Widget("${dlg.feed.title}")));
2326 iInputWidget *input = new_InputWidget(0); 2359 iInputWidget *input = new_InputWidget(0);
2327 setId_Widget(addChild_Widget(values, iClob(input)), "feedcfg.title"); 2360 addDialogInputWithHeading_(headings, values, "${dlg.feed.title}", "feedcfg.title", iClob(input));
2328 addChild_Widget(headings, iClob(makeHeading_Widget("${dlg.feed.entrytype}"))); 2361 addChild_Widget(headings, iClob(makeHeading_Widget("${dlg.feed.entrytype}")));
2329 iWidget *types = new_Widget(); { 2362 iWidget *types = new_Widget(); {
2330 addRadioButton_(types, "feedcfg.type.gemini", "${dlg.feed.type.gemini}", "feedcfg.type arg:0"); 2363 addRadioButton_(types, "feedcfg.type.gemini", "${dlg.feed.type.gemini}", "feedcfg.type arg:0");
@@ -2369,10 +2402,8 @@ iWidget *makeIdentityCreation_Widget(void) {
2369 "ident.heading"); 2402 "ident.heading");
2370 iWidget *page = new_Widget(); 2403 iWidget *page = new_Widget();
2371 addChildFlags_Widget( 2404 addChildFlags_Widget(
2372 dlg, 2405 dlg, iClob(new_LabelWidget("${dlg.newident.rsa.selfsign}", NULL)), frameless_WidgetFlag);
2373 iClob( 2406 /* TODO: Use makeTwoColumnWidget_? */
2374 new_LabelWidget("${dlg.newident.rsa.selfsign}", NULL)),
2375 frameless_WidgetFlag);
2376 addChild_Widget(dlg, iClob(page)); 2407 addChild_Widget(dlg, iClob(page));
2377 setFlags_Widget(page, arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag, iTrue); 2408 setFlags_Widget(page, arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag, iTrue);
2378 iWidget *headings = addChildFlags_Widget( 2409 iWidget *headings = addChildFlags_Widget(
@@ -2380,10 +2411,16 @@ iWidget *makeIdentityCreation_Widget(void) {
2380 iWidget *values = addChildFlags_Widget( 2411 iWidget *values = addChildFlags_Widget(
2381 page, iClob(new_Widget()), arrangeVertical_WidgetFlag | arrangeSize_WidgetFlag); 2412 page, iClob(new_Widget()), arrangeVertical_WidgetFlag | arrangeSize_WidgetFlag);
2382 iInputWidget *inputs[6]; 2413 iInputWidget *inputs[6];
2383 addChild_Widget(headings, iClob(makeHeading_Widget("${dlg.newident.until}"))); 2414 addDialogInputWithHeading_(headings,
2384 setId_Widget(addChild_Widget(values, iClob(newHint_InputWidget(19, "${hint.newident.date}"))), "ident.until"); 2415 values,
2385 addChild_Widget(headings, iClob(makeHeading_Widget("${dlg.newident.commonname}"))); 2416 "${dlg.newident.until}",
2386 setId_Widget(addChild_Widget(values, iClob(inputs[0] = new_InputWidget(0))), "ident.common"); 2417 "ident.until",
2418 iClob(newHint_InputWidget(19, "${hint.newident.date}")));
2419 addDialogInputWithHeading_(headings,
2420 values,
2421 "${dlg.newident.commonname}",
2422 "ident.common",
2423 iClob(inputs[0] = new_InputWidget(0)));
2387 /* Temporary? */ { 2424 /* Temporary? */ {
2388 addChild_Widget(headings, iClob(makeHeading_Widget("${dlg.newident.temp}"))); 2425 addChild_Widget(headings, iClob(makeHeading_Widget("${dlg.newident.temp}")));
2389 iWidget *tmpGroup = new_Widget(); 2426 iWidget *tmpGroup = new_Widget();
@@ -2399,28 +2436,23 @@ iWidget *makeIdentityCreation_Widget(void) {
2399 } 2436 }
2400 addChild_Widget(headings, iClob(makePadding_Widget(gap_UI))); 2437 addChild_Widget(headings, iClob(makePadding_Widget(gap_UI)));
2401 addChild_Widget(values, iClob(makePadding_Widget(gap_UI))); 2438 addChild_Widget(values, iClob(makePadding_Widget(gap_UI)));
2402 addChild_Widget(headings, iClob(makeHeading_Widget("${dlg.newident.email}"))); 2439 addDialogInputWithHeading_(headings, values, "${dlg.newident.email}", "ident.email", iClob(inputs[1] = newHint_InputWidget(0, "${hint.newident.optional}")));
2403 setId_Widget(addChild_Widget(values, iClob(inputs[1] = newHint_InputWidget(0, "${hint.newident.optional}"))), "ident.email"); 2440 addDialogInputWithHeading_(headings, values, "${dlg.newident.userid}", "ident.userid", iClob(inputs[2] = newHint_InputWidget(0, "${hint.newident.optional}")));
2404 addChild_Widget(headings, iClob(makeHeading_Widget("${dlg.newident.userid}"))); 2441 addDialogInputWithHeading_(headings, values, "${dlg.newident.domain}", "ident.domain", iClob(inputs[3] = newHint_InputWidget(0, "${hint.newident.optional}")));
2405 setId_Widget(addChild_Widget(values, iClob(inputs[2] = newHint_InputWidget(0, "${hint.newident.optional}"))), "ident.userid"); 2442 addDialogInputWithHeading_(headings, values, "${dlg.newident.org}", "ident.org", iClob(inputs[4] = newHint_InputWidget(0, "${hint.newident.optional}")));
2406 addChild_Widget(headings, iClob(makeHeading_Widget("${dlg.newident.domain}"))); 2443 addDialogInputWithHeading_(headings, values, "${dlg.newident.country}", "ident.country", iClob(inputs[5] = newHint_InputWidget(0, "${hint.newident.optional}")));
2407 setId_Widget(addChild_Widget(values, iClob(inputs[3] = newHint_InputWidget(0, "${hint.newident.optional}"))), "ident.domain");
2408 addChild_Widget(headings, iClob(makeHeading_Widget("${dlg.newident.org}")));
2409 setId_Widget(addChild_Widget(values, iClob(inputs[4] = newHint_InputWidget(0, "${hint.newident.optional}"))), "ident.org");
2410 addChild_Widget(headings, iClob(makeHeading_Widget("${dlg.newident.country}")));
2411 setId_Widget(addChild_Widget(values, iClob(inputs[5] = newHint_InputWidget(0, "${hint.newident.optional}"))), "ident.country");
2412 arrange_Widget(dlg); 2444 arrange_Widget(dlg);
2413 for (size_t i = 0; i < iElemCount(inputs); ++i) { 2445 for (size_t i = 0; i < iElemCount(inputs); ++i) {
2414 as_Widget(inputs[i])->rect.size.x = 100 * gap_UI - headings->rect.size.x; 2446 as_Widget(inputs[i])->rect.size.x = 100 * gap_UI - headings->rect.size.x;
2415 } 2447 }
2416 addChild_Widget( 2448 addChild_Widget(dlg,
2417 dlg, 2449 iClob(makeDialogButtons_Widget(
2418 iClob(makeDialogButtons_Widget((iMenuItem[]){ { "${cancel}", 0, 0, NULL }, 2450 (iMenuItem[]){ { "${cancel}", 0, 0, NULL },
2419 { uiTextAction_ColorEscape "${dlg.newident.create}", 2451 { uiTextAction_ColorEscape "${dlg.newident.create}",
2420 SDLK_RETURN, 2452 SDLK_RETURN,
2421 KMOD_PRIMARY, 2453 KMOD_PRIMARY,
2422 "ident.accept" } }, 2454 "ident.accept" } },
2423 2))); 2455 2)));
2424 addChild_Widget(get_Window()->root, iClob(dlg)); 2456 addChild_Widget(get_Window()->root, iClob(dlg));
2425 finalizeSheet_Widget(dlg); 2457 finalizeSheet_Widget(dlg);
2426 return dlg; 2458 return dlg;
@@ -2464,7 +2496,7 @@ const char *languageId_String(const iString *menuItemLabel) {
2464int languageIndex_CStr(const char *langId) { 2496int languageIndex_CStr(const char *langId) {
2465 iForIndices(i, languages) { 2497 iForIndices(i, languages) {
2466 if (equal_Rangecc(range_Command(languages[i].command, "id"), langId)) { 2498 if (equal_Rangecc(range_Command(languages[i].command, "id"), langId)) {
2467 return i; 2499 return (int) i;
2468 } 2500 }
2469 } 2501 }
2470 return -1; 2502 return -1;
diff --git a/src/ui/util.h b/src/ui/util.h
index eb8e31c3..42dad6e0 100644
--- a/src/ui/util.h
+++ b/src/ui/util.h
@@ -31,6 +31,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
31iDeclareType(Click) 31iDeclareType(Click)
32iDeclareType(Widget) 32iDeclareType(Widget)
33iDeclareType(LabelWidget) 33iDeclareType(LabelWidget)
34iDeclareType(InputWidget)
34 35
35iBool isCommand_SDLEvent (const SDL_Event *d); 36iBool isCommand_SDLEvent (const SDL_Event *d);
36iBool isCommand_UserEvent (const SDL_Event *, const char *cmd); 37iBool isCommand_UserEvent (const SDL_Event *, const char *cmd);
@@ -220,6 +221,10 @@ iWidget * makeSheet_Widget (const char *id);
220void finalizeSheet_Widget (iWidget *sheet); 221void finalizeSheet_Widget (iWidget *sheet);
221iWidget * makeDialogButtons_Widget(const iMenuItem *actions, size_t numActions); 222iWidget * makeDialogButtons_Widget(const iMenuItem *actions, size_t numActions);
222 223
224iInputWidget *addTwoColumnDialogInputField_Widget(iWidget *headings, iWidget *values,
225 const char *labelText, const char *inputId,
226 iInputWidget *input);
227
223void makeFilePath_Widget (iWidget *parent, const iString *initialPath, const char *title, 228void makeFilePath_Widget (iWidget *parent, const iString *initialPath, const char *title,
224 const char *acceptLabel, const char *command); 229 const char *acceptLabel, const char *command);
225iWidget * makeValueInput_Widget (iWidget *parent, const iString *initialValue, const char *title, 230iWidget * makeValueInput_Widget (iWidget *parent, const iString *initialValue, const char *title,