| |
1 /* |
| |
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
| |
3 * |
| |
4 * Copyright 2025 Olaf Wintermann. All rights reserved. |
| |
5 * |
| |
6 * Redistribution and use in source and binary forms, with or without |
| |
7 * modification, are permitted provided that the following conditions are met: |
| |
8 * |
| |
9 * 1. Redistributions of source code must retain the above copyright |
| |
10 * notice, this list of conditions and the following disclaimer. |
| |
11 * |
| |
12 * 2. Redistributions in binary form must reproduce the above copyright |
| |
13 * notice, this list of conditions and the following disclaimer in the |
| |
14 * documentation and/or other materials provided with the distribution. |
| |
15 * |
| |
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| |
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| |
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| |
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
| |
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| |
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| |
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| |
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| |
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| |
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| |
26 * POSSIBILITY OF SUCH DAMAGE. |
| |
27 */ |
| |
28 |
| |
29 #include "args.h" |
| |
30 |
| |
31 #include "../ui/common/args.h" |
| |
32 |
| |
33 #define DEFAULT_ARG_FUNCS(var, prefix) \ |
| |
34 static ArgDefaultFuncs var = { \ |
| |
35 .fill = (argfunc_set_bool)prefix##_args_set_fill, \ |
| |
36 .hexpand = (argfunc_set_bool)prefix##_args_set_hexpand, \ |
| |
37 .vexpand = (argfunc_set_bool)prefix##_args_set_vexpand, \ |
| |
38 .hfill = (argfunc_set_bool)prefix##_args_set_hfill, \ |
| |
39 .vfill = (argfunc_set_bool)prefix##_args_set_vfill, \ |
| |
40 .override_defaults = (argfunc_set_bool)prefix##_args_set_override_defaults, \ |
| |
41 .margin = (argfunc_set_int)prefix##_args_set_margin, \ |
| |
42 .margin_left = (argfunc_set_int)prefix##_args_set_margin_left, \ |
| |
43 .margin_right = (argfunc_set_int)prefix##_args_set_margin_right, \ |
| |
44 .margin_top = (argfunc_set_int)prefix##_args_set_margin_top, \ |
| |
45 .margin_bottom = (argfunc_set_int)prefix##_args_set_margin_bottom, \ |
| |
46 .colspan = (argfunc_set_int)prefix##_args_set_colspan, \ |
| |
47 .rowspan = (argfunc_set_int)prefix##_args_set_rowspan, \ |
| |
48 .name = (argfunc_set_str)prefix##_args_set_name, \ |
| |
49 .style_class = (argfunc_set_str)prefix##_args_set_style_class \ |
| |
50 } |
| |
51 |
| |
52 DEFAULT_ARG_FUNCS(container_args, ui_container); |
| |
53 |
| |
54 DEFAULT_ARG_FUNCS(button_args, ui_button); |
| |
55 |
| |
56 |
| |
57 |
| |
58 static void init_common_args(const CxJsonValue *value, void *args, ArgDefaultFuncs *funcs) { |
| |
59 CxJsonValue *val; |
| |
60 |
| |
61 // boolean args |
| |
62 val = cxJsonObjGet(value, "fill"); |
| |
63 if(val && val->type == CX_JSON_LITERAL && val->value.literal == CX_JSON_TRUE) { |
| |
64 funcs->fill(args, TRUE); |
| |
65 } |
| |
66 |
| |
67 val = cxJsonObjGet(value, "hexpand"); |
| |
68 if(val && val->type == CX_JSON_LITERAL && val->value.literal == CX_JSON_TRUE) { |
| |
69 funcs->hexpand(args, TRUE); |
| |
70 } |
| |
71 |
| |
72 val = cxJsonObjGet(value, "vexpand"); |
| |
73 if(val && val->type == CX_JSON_LITERAL && val->value.literal == CX_JSON_TRUE) { |
| |
74 funcs->vexpand(args, TRUE); |
| |
75 } |
| |
76 |
| |
77 val = cxJsonObjGet(value, "hfill"); |
| |
78 if(val && val->type == CX_JSON_LITERAL && val->value.literal == CX_JSON_TRUE) { |
| |
79 funcs->hfill(args, TRUE); |
| |
80 } |
| |
81 |
| |
82 val = cxJsonObjGet(value, "vfill"); |
| |
83 if(val && val->type == CX_JSON_LITERAL && val->value.literal == CX_JSON_TRUE) { |
| |
84 funcs->vfill(args, TRUE); |
| |
85 } |
| |
86 |
| |
87 val = cxJsonObjGet(value, "override_defaults"); |
| |
88 if(val && val->type == CX_JSON_LITERAL && val->value.literal == CX_JSON_TRUE) { |
| |
89 funcs->override_defaults(args, TRUE); |
| |
90 } |
| |
91 |
| |
92 // int args |
| |
93 val = cxJsonObjGet(value, "margin"); |
| |
94 if(val && val->type == CX_JSON_INTEGER) { |
| |
95 funcs->margin(args, (int)val->value.integer); |
| |
96 } |
| |
97 |
| |
98 val = cxJsonObjGet(value, "margin_left"); |
| |
99 if(val && val->type == CX_JSON_INTEGER) { |
| |
100 funcs->margin_left(args, (int)val->value.integer); |
| |
101 } |
| |
102 |
| |
103 val = cxJsonObjGet(value, "margin_right"); |
| |
104 if(val && val->type == CX_JSON_INTEGER) { |
| |
105 funcs->margin_right(args, (int)val->value.integer); |
| |
106 } |
| |
107 |
| |
108 val = cxJsonObjGet(value, "margin_top"); |
| |
109 if(val && val->type == CX_JSON_INTEGER) { |
| |
110 funcs->margin_top(args, (int)val->value.integer); |
| |
111 } |
| |
112 |
| |
113 val = cxJsonObjGet(value, "margin_bottom"); |
| |
114 if(val && val->type == CX_JSON_INTEGER) { |
| |
115 funcs->margin_bottom(args, (int)val->value.integer); |
| |
116 } |
| |
117 |
| |
118 val = cxJsonObjGet(value, "colspan"); |
| |
119 if(val && val->type == CX_JSON_INTEGER) { |
| |
120 funcs->colspan(args, (int)val->value.integer); |
| |
121 } |
| |
122 |
| |
123 val = cxJsonObjGet(value, "rowspan"); |
| |
124 if(val && val->type == CX_JSON_INTEGER) { |
| |
125 funcs->rowspan(args, (int)val->value.integer); |
| |
126 } |
| |
127 |
| |
128 // string args |
| |
129 val = cxJsonObjGet(value, "name"); |
| |
130 if(val && val->type == CX_JSON_STRING) { |
| |
131 funcs->name(args, val->value.string.ptr); |
| |
132 } |
| |
133 |
| |
134 val = cxJsonObjGet(value, "style_class"); |
| |
135 if(val && val->type == CX_JSON_STRING) { |
| |
136 funcs->name(args, val->value.string.ptr); |
| |
137 } |
| |
138 } |
| |
139 |
| |
140 void init_groups(const CxJsonValue *value, void *args, argfunc_set_intarray setarray) { |
| |
141 CxJsonValue *val = cxJsonObjGet(value, "states"); |
| |
142 if(!val || val->type != CX_JSON_ARRAY) { |
| |
143 return; |
| |
144 } |
| |
145 |
| |
146 int len = (int)val->value.array.array_size; |
| |
147 int *states = calloc(len, sizeof(int)); |
| |
148 for(int i=0;i<len;i++) { |
| |
149 CxJsonValue *s = val->value.array.array[i]; |
| |
150 if(s->type == CX_JSON_INTEGER) { |
| |
151 states[i] = (int)s->value.integer; |
| |
152 } |
| |
153 } |
| |
154 |
| |
155 setarray(args, states, len); |
| |
156 } |
| |
157 |
| |
158 UiContainerArgs* json2container_args(const CxJsonValue *value) { |
| |
159 UiContainerArgs *args = ui_container_args_new(); |
| |
160 if(value->type != CX_JSON_OBJECT) { |
| |
161 return args; |
| |
162 } |
| |
163 |
| |
164 init_common_args(value, args, &container_args); |
| |
165 |
| |
166 CxJsonValue *val = cxJsonObjGet(value, "spacing"); |
| |
167 if(val && val->type == CX_JSON_INTEGER) { |
| |
168 args->spacing = (int)val->value.integer; |
| |
169 } |
| |
170 |
| |
171 val = cxJsonObjGet(value, "columnspacing"); |
| |
172 if(val && val->type == CX_JSON_INTEGER) { |
| |
173 args->columnspacing = (int)val->value.integer; |
| |
174 } |
| |
175 |
| |
176 val = cxJsonObjGet(value, "rowspacing"); |
| |
177 if(val && val->type == CX_JSON_INTEGER) { |
| |
178 args->rowspacing = (int)val->value.integer; |
| |
179 } |
| |
180 |
| |
181 val = cxJsonObjGet(value, "def_hfill"); |
| |
182 if(val && val->type == CX_JSON_LITERAL && val->value.literal == CX_JSON_TRUE) { |
| |
183 args->def_hfill = TRUE; |
| |
184 } |
| |
185 |
| |
186 val = cxJsonObjGet(value, "def_vfill"); |
| |
187 if(val && val->type == CX_JSON_LITERAL && val->value.literal == CX_JSON_TRUE) { |
| |
188 args->def_vfill = TRUE; |
| |
189 } |
| |
190 |
| |
191 val = cxJsonObjGet(value, "def_hexpand"); |
| |
192 if(val && val->type == CX_JSON_LITERAL && val->value.literal == CX_JSON_TRUE) { |
| |
193 args->def_hexpand = TRUE; |
| |
194 } |
| |
195 |
| |
196 val = cxJsonObjGet(value, "def_vexpand"); |
| |
197 if(val && val->type == CX_JSON_LITERAL && val->value.literal == CX_JSON_TRUE) { |
| |
198 args->def_vexpand = TRUE; |
| |
199 } |
| |
200 |
| |
201 return args; |
| |
202 } |
| |
203 |
| |
204 UiButtonArgs* json2button_args(const CxJsonValue *value) { |
| |
205 UiButtonArgs *args = ui_button_args_new(); |
| |
206 if(value->type != CX_JSON_OBJECT) { |
| |
207 return args; |
| |
208 } |
| |
209 |
| |
210 init_common_args(value, args, &button_args); |
| |
211 init_groups(value, args, (argfunc_set_intarray)ui_button_args_set_groups); |
| |
212 |
| |
213 CxJsonValue *val = cxJsonObjGet(value, "label"); |
| |
214 if(val && val->type == CX_JSON_STRING) { |
| |
215 ui_button_args_set_label(args, val->value.string.ptr); |
| |
216 } |
| |
217 |
| |
218 val = cxJsonObjGet(value, "icon"); |
| |
219 if(val && val->type == CX_JSON_STRING) { |
| |
220 ui_button_args_set_icon(args, val->value.string.ptr); |
| |
221 } |
| |
222 |
| |
223 val = cxJsonObjGet(value, "tooltip"); |
| |
224 if(val && val->type == CX_JSON_STRING) { |
| |
225 ui_button_args_set_tooltip(args, val->value.string.ptr); |
| |
226 } |
| |
227 |
| |
228 val = cxJsonObjGet(value, "labeltype"); |
| |
229 if(val && val->type == CX_JSON_INTEGER) { |
| |
230 ui_button_args_set_labeltype(args, (int)val->value.integer); |
| |
231 } |
| |
232 |
| |
233 return args; |
| |
234 } |