big dialogs: Refactoring. do not pass the term.
[elinks.git] / src / bfu / group.c
blob4d404b9f2bb0b0fff8e0358cd17f8b2e076b67ec
1 /* Widget group implementation. */
3 #ifdef HAVE_CONFIG_H
4 #include "config.h"
5 #endif
7 #include <string.h>
9 #include "elinks.h"
11 #include "bfu/dialog.h"
12 #include "bfu/button.h"
13 #include "bfu/group.h"
14 #include "intl/gettext/libintl.h"
15 #include "terminal/draw.h"
16 #include "terminal/terminal.h"
17 #include "util/color.h"
19 /* Same as in src/bfu/checkbox.c */
20 #define CHECKBOX_LEN 3 /* "[X]" or "(X)" */
22 void
23 dlg_format_group(struct dialog_data *dlg_data,
24 struct widget_data *widget_data,
25 int n, int x, int *y, int w, int *rw, int format_only)
27 struct terminal *term = dlg_data->win->term;
28 int space_between_widgets = 1;
29 int line_width = 0;
30 int xpos;
31 struct color_pair *color = get_bfu_color(term, "dialog.text");
33 assert(n > 0);
34 if_assert_failed return;
36 while (n--) {
37 int widget_width;
38 int width;
39 unsigned char *text = widget_data->widget->text;
40 int label_length;
41 int label_padding;
43 #ifdef CONFIG_UTF8
44 if (term->utf8_cp) {
45 if (text && *text)
46 label_length = utf8_ptr2cells(text, NULL);
47 else
48 label_length = 0;
49 } else
50 #endif /* CONFIG_UTF8 */
51 label_length = (text && *text) ? strlen(text) : 0;
53 label_padding = (label_length > 0);
55 if (widget_data->widget->type == WIDGET_CHECKBOX) {
56 width = CHECKBOX_LEN;
57 } else if (widget_is_textfield(widget_data)) {
58 #ifdef CONFIG_UTF8
59 if (term->utf8_cp) {
60 width = utf8_ptr2cells(widget_data->widget->data,
61 NULL);
62 } else
63 #endif /* CONFIG_UTF8 */
64 width = widget_data->widget->datalen;
65 } else {
66 /* TODO: handle all widget types. */
67 widget_data++;
68 continue;
71 int_bounds(&label_length, 0, w - width - label_padding);
73 widget_width = width + label_padding + label_length;
74 if (line_width + widget_width > w) {
75 line_width = 0;
76 (*y) += 2; /* Next line */
79 xpos = x + line_width;
81 if (!format_only) {
82 if (widget_data->widget->type == WIDGET_CHECKBOX) {
83 /* Draw text at right of checkbox. */
84 if (label_length) {
85 #ifdef CONFIG_UTF8
86 if (term->utf8_cp) {
87 int lb = utf8_cells2bytes(
88 text,
89 label_length,
90 NULL);
91 draw_dlg_text(term, dlg_data, xpos + width
92 + label_padding,
93 *y, text, lb, 0,
94 color);
95 } else
96 #endif /* CONFIG_UTF8 */
98 draw_dlg_text(term, dlg_data, xpos + width
99 + label_padding,
100 *y, text,
101 label_length, 0,
102 color);
106 set_box(&widget_data->box, xpos, *y, width, 1);
108 } else if (widget_is_textfield(widget_data)) {
109 /* Draw label at left of widget. */
110 if (label_length) {
111 #ifdef CONFIG_UTF8
112 if (term->utf8_cp) {
113 int lb = utf8_cells2bytes(
114 text,
115 label_length,
116 NULL);
117 draw_dlg_text(term, dlg_data, xpos, *y,
118 text, lb, 0, color);
119 } else
120 #endif /* CONFIG_UTF8 */
122 draw_dlg_text(term, dlg_data, xpos, *y,
123 text, label_length,
124 0, color);
128 set_box(&widget_data->box,
129 xpos + label_padding + label_length, *y,
130 width, 1);
134 line_width += widget_width;
135 if (rw) int_bounds(rw, line_width, w);
136 line_width += space_between_widgets;
138 widget_data++;
140 (*y)++;
143 void
144 group_layouter(struct dialog_data *dlg_data)
146 struct terminal *term = dlg_data->win->term;
147 int w = dialog_max_width(term);
148 int rw;
149 int y = 0;
150 int n = dlg_data->number_of_widgets - 2;
152 #ifdef CONFIG_UTF8
153 if (term->utf8_cp)
154 rw = int_min(w, utf8_ptr2cells(dlg_data->dlg->title, NULL));
155 else
156 #endif /* CONFIG_UTF8 */
157 rw = int_min(w, strlen(dlg_data->dlg->title));
159 dlg_format_group(dlg_data, dlg_data->widgets_data, n,
160 0, &y, w, &rw, 1);
162 y++;
163 dlg_format_buttons(dlg_data, dlg_data->widgets_data + n, 2, 0, &y, w,
164 &rw, ALIGN_CENTER, 1);
166 w = rw;
168 draw_dialog(dlg_data, w, y);
170 y = dlg_data->box.y + DIALOG_TB + 1;
171 dlg_format_group(dlg_data, dlg_data->widgets_data, n,
172 dlg_data->box.x + DIALOG_LB, &y, w, NULL, 0);
174 y++;
175 dlg_format_buttons(dlg_data, dlg_data->widgets_data + n, 2,
176 dlg_data->box.x + DIALOG_LB, &y, w, &rw, ALIGN_CENTER, 0);