1 /************************************************************************
3 * voxelands - 3d voxel world sandbox game
4 * Copyright (C) Lisa 'darkrose' Milne 2016 <lisa@ltmnet.com>
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>
18 ************************************************************************/
26 /* TODO: ui scaling based off scale and autoscale settings */
39 int ui_scale_setter(char* value
)
45 v
= strtof(value
,NULL
);
53 int ui_autoscale_setter(char* value
)
55 ui_data
.autoscale
= parse_bool(value
);
60 /* find an empty container, or create a new one */
61 widget_t
*ui_widget_container()
63 widget_t
*w
= ui_data
.containers
;
66 if (!w
->style
.visible
&& !w
->child
&& !w
->x
)
71 w = ui_widget_create(UI_WIDGET_CONTAINER,NULL);
76 /* initialise the ui */
79 char* fontname
= "font.ttf";
80 if (config_get_bool("ui.font.unifont"))
81 fontname
= "unifont.ttf";
82 return font_load(fontname
,"default");
98 w
= ui_data
.containers
;
100 /* TODO: uncomment this
101 if (w->style.visible)
102 ui_widget_draw(w); */
106 wc
= ui_data
.containers
;
108 if (wc
->style
.visible
) {
111 if (w
->hover
&& w
->parent
&& w
->parent
->hover
&& w
->htext
.length
) {
112 events_get_mouse(pos
);
113 textbuffer_get_dimensions(&w
->htext
,size
);
117 if (mouse
[1] > w
->style
.ttfont_size
) {
118 pos
[1] -= w
->style
.ttfont_size
;
119 if (mouse
[0] > (wm_data
.size
.width
-size
[0]))
120 pos
[0] -= size
[0]+10;
122 pos
[0] -= size
[0]+10;
130 if (w->style.has_ttbg)
131 draw2d_rect(&w->style.ttbg,bx,by,bw,bh);
133 if (w->style.has_ttborder) {
134 draw2d_line(&w->style.ttborder,bx,by,bx+bw,by);
135 draw2d_line(&w->style.ttborder,bx,by,bx,by+bh );
136 draw2d_line(&w->style.ttborder,bx+bw,by,bx+bw,by+bh);
137 draw2d_line(&w->style.ttborder,bx,by+bh,bx+bw,by+bh);
143 render2d_textbuffer(&w
->htext
);
152 /* event handler for the msgbox */
153 static int ui_msg_event(widget_t
*w
)
155 msgbox_data_t
*wd
= &w
->parent
->data
->msg
;
156 if (w
->id
== wd
->btn1
->id
) {
159 }else if (w
->id
== wd
->btn2
->id
) {
163 return EVENT_UNHANDLED
;
166 ui_widget_free(w->parent);
168 return EVENT_HANDLED
;
171 /* create a popup message box */
172 void ui_msg(uint8_t type
, char* txt
, int (*func
)(), ...)
177 if (!(type
== UIMSG_OC
|| type
== UIMSG_OK
|| type
== UIMSG_YN
) || !txt
) {
178 vlprintf(CN_WARN
, "Invalid message type: %d",type
);
182 con
= ui_widget_container();
186 con
->style
.x
= UI_ALIGN_CENTRE
;
187 con
->style
.y
= UI_ALIGN_MIDDLE
;
189 con
->style
.visible
= 1;
190 con
->data
= malloc(sizeof(widget_data_t
));
191 con
->data
->msg
.container
= con
;
192 con
->data
->msg
.btn1_func
= func
;
193 con
->data
->msg
.btn2_func
= NULL
;
195 con->data->msg.txt = ui_widget_create(UI_WIDGET_LABEL,con);
196 */ con
->data
->msg
.txt
->style
.w
= 300;
197 con
->data
->msg
.txt
->style
.x
= 0;
198 con
->data
->msg
.txt
->style
.text_align
= UI_ALIGN_CENTRE
;
199 con
->data
->msg
.txt
->style
.y
= 20;
201 ui_widget_value(con->data->msg.txt,txt);
203 /* con->data->msg.btn1 = ui_widget_create(UI_WIDGET_BUTTON,con);
204 */ con
->data
->msg
.btn1
->events
->mclick
= &ui_msg_event
;
206 /* con->data->msg.btn2 = ui_widget_create(UI_WIDGET_BUTTON,con);
207 */ con
->data
->msg
.btn2
->events
->mclick
= &ui_msg_event
;
209 con
->data
->msg
.btn1
->style
.x
= 290-con
->data
->msg
.btn1
->style
.w
;
210 con
->data
->msg
.btn1
->style
.y
= 65;
211 con
->data
->msg
.btn2
->style
.x
= con
->data
->msg
.btn1
->style
.x
-10-con
->data
->msg
.btn2
->style
.w
;
212 con
->data
->msg
.btn2
->style
.y
= 65;
214 if (type
== UIMSG_OC
) {
216 *(void**)(&con
->data
->msg
.btn2_func
) = va_arg(ap
,int (*));
218 /* ui_widget_value(con->data->msg.btn1,"OK");
219 ui_widget_value(con->data->msg.btn2,"Cancel");
220 */ }else if (type
== UIMSG_OK
) {
221 con
->data
->msg
.btn2
->style
.visible
= 0;
222 /* ui_widget_value(con->data->msg.btn1,"OK");
223 */ }else if (type
== UIMSG_YN
) {
225 *(void**)(&con
->data
->msg
.btn2_func
) = va_arg(ap
,int (*));
227 /* ui_widget_value(con->data->msg.btn1,"Yes");
228 ui_widget_value(con->data->msg.btn2,"No");
232 /* event handler for the optbox */
233 static int ui_opt_event(widget_t
*w
)
235 optbox_data_t
*wd
= &w
->parent
->data
->opb
;
236 optbox_btn_t
*btn
= wd
->buttons
;
239 if (btn
->btn
->id
== w
->id
)
245 return EVENT_UNHANDLED
;
250 ui_widget_free(w->parent);
252 return EVENT_HANDLED
;
255 /* create an option select popup box */
256 void ui_opt(char* txt
, ...)
268 t
= (char*)va_arg(ap
,char*);
271 *(void**)(&f
) = va_arg(ap
,int (*));
275 con
= ui_widget_container();
276 con
->data
= malloc(sizeof(widget_data_t
));
278 con
->style
.x
= UI_ALIGN_CENTRE
;
279 con
->style
.y
= UI_ALIGN_MIDDLE
;
280 con
->style
.visible
= 1;
282 con
->data
->opb
.container
= con
;
283 /* con->data->opb.txt = ui_widget_create(UI_WIDGET_LABEL,con);
284 con->data->opb.txt->style.x = 100-((print_length(1,SML_FONT,txt))/2);
285 */ if (con
->data
->opb
.txt
->style
.x
< 0)
286 con
->data
->opb
.txt
->style
.x
= 0;
287 con
->data
->msg
.txt
->style
.y
= 20;
288 /* ui_widget_value(con->data->opb.txt,txt);
290 con
->data
->opb
.buttons
= malloc(sizeof(optbox_btn_t
));
291 con
->data
->opb
.buttons
->func
= f
;
292 /* con->data->opb.buttons->btn = ui_widget_create(UI_WIDGET_BUTTON,con);
293 */ con
->data
->opb
.buttons
->btn
->style
.x
= 63;
294 con
->data
->opb
.buttons
->btn
->style
.y
= 65;
295 con
->data
->opb
.buttons
->btn
->events
->mclick
= &ui_opt_event
;
296 /* ui_widget_value(con->data->opb.buttons->btn,t);
297 */ b
= con
->data
->opb
.buttons
;
299 con
->data
->opb
.buttons
->next
= NULL
;
301 while ((t
= (char*)va_arg(ap
,char*)) != NULL
&& (*(void**)(&f
) = va_arg(ap
,int (*))) != NULL
) {
302 b
->next
= malloc(sizeof(optbox_btn_t
));
304 /* b->next->btn = ui_widget_create(UI_WIDGET_BUTTON,con);
305 */ b
->next
->btn
->style
.x
= 63;
306 b
->next
->btn
->style
.y
= y
;
307 b
->next
->btn
->events
->mclick
= &ui_opt_event
;
308 /* ui_widget_value(b->next->btn,t);