14 #include "resource/resource.h"
19 #include "widget/dump.h"
20 #include "widget/widgets.h"
22 static void load_resource(struct resource_t
*settings
);
23 static void save_resource(struct resource_t
*resource
);
25 static void init_loop_data(struct gui_t
*gui
);
29 int STDCALL
WinMain(HINSTANCE hInst
, HINSTANCE hPrev
, LPSTR lpCmd
, int nShow
) {
31 int main(int argc
, char *argv
[]) {
33 struct resource_t settings
;
34 struct xuni_t
*xuni
= allocate_xuni();
36 xuni_error_initialize();
37 xuni_error_add_stream(0, stderr
);
38 xuni_error_add_stream("editor.log", 0);
40 load_resource(&settings
);
42 init_xuni(xuni
, &settings
,
43 lookup_resource_string(&settings
, 0, "xuni-resource", "icon", 0));
45 init_loop_data(xuni
->gui
);
47 call_init_funcs(xuni
, xuni
->gui
->widget
, &settings
);
48 main_loop(xuni
, 0, PANEL_EDITOR
);
50 xuni_memory_keep_freed_blocks(1);
52 save_resource(&settings
);
53 free_resource(&settings
);
58 xuni_memory_free_all();
63 static void load_resource(struct resource_t
*settings
) {
64 init_resource(settings
);
66 if(parse_resource(settings
->data
, SETTINGS_FILE
)) {
67 log_message(ERROR_TYPE_FATAL
, 0, __FILE__
, __LINE__
,
68 "Failed to load resource \"%s\"", SETTINGS_FILE
);
72 static void save_resource(struct resource_t
*resource
) {
73 /*write_resource(resource, SETTINGS_FILE ".generated");*/
76 static int editor_init(struct xuni_t
*xuni
, struct panel_data_t
*data
);
77 static int editor_start(struct xuni_t
*xuni
, struct panel_data_t
*data
);
78 static int editor_event(struct xuni_t
*xuni
, struct panel_data_t
*data
);
79 static int editor_click(struct xuni_t
*xuni
, struct panel_data_t
*data
);
80 static int editor_deactivate(struct xuni_t
*xuni
, struct panel_data_t
*data
);
81 static int editor_paint(struct xuni_t
*xuni
, struct panel_data_t
*data
);
82 static int editor_free(struct xuni_t
*xuni
, struct panel_data_t
*data
);
84 static void handle_cancel_action(struct xuni_t
*xuni
,
85 struct editor_data_t
*data
);
86 static void set_editor_mode(struct xuni_t
*xuni
, struct editor_data_t
*data
,
87 enum editor_mode_t mode
);
95 WID_MODE_DELETE_WIDGET
,
103 static void init_loop_data(struct gui_t
*gui
) {
104 struct widget_t
*panel
;
107 init_wid(gui
->widget
, gui
->widget
, PANEL_EDITOR
, "editor");
109 panel
= widget_nameid_access(gui
->widget
, PANEL_EDITOR
);
111 data
= xuni_memory_allocate(sizeof(struct editor_data_t
));
112 set_panel_data(panel
, data
, 0);
113 set_panel_callback(panel
, PANEL_EVENT_INIT
, editor_init
);
114 set_panel_callback(panel
, PANEL_EVENT_START
, editor_start
);
115 set_panel_callback(panel
, PANEL_EVENT_EVENT
, editor_event
);
116 set_panel_callback(panel
, PANEL_EVENT_SEL
, default_panel_sel
);
117 set_panel_callback(panel
, PANEL_EVENT_CLICK
, editor_click
);
118 set_panel_callback(panel
, PANEL_EVENT_DEACTIVATE
, editor_deactivate
);
119 set_panel_callback(panel
, PANEL_EVENT_PAINT
, editor_paint
);
120 set_panel_callback(panel
, PANEL_EVENT_FREE
, editor_free
);
122 /*set_panel_callbacks(widget_nameid_access(gui->widget, PANEL_EDITOR),
123 data, 0, editor_init, editor_start, editor_event,
124 default_panel_sel, editor_click, editor_deactivate,
125 editor_paint, editor_free);*/
128 static const char *get_mode_name(enum editor_mode_t mode
) {
129 static const char *name
[] = {
135 if((size_t)mode
< sizeof(name
)/sizeof(*name
)) {
141 static int editor_init(struct xuni_t
*xuni
, struct panel_data_t
*data
) {
142 struct editor_data_t
*edata
= data
->data
;
143 struct widget_t
*panel
= data
->event
[PANEL_EVENT_INIT
].p
.init
.panel
;
145 init_wid(panel
, panel
, WID_QUIT
, "quit");
146 init_wid(panel
, panel
, WID_MODE_LABEL
, "mode label");
147 init_wid(panel
, panel
, WID_POSITION_LABEL
, "position label");
148 init_wid(panel
, panel
, WID_MODE_TEST
, "resource tab/test");
149 init_wid(panel
, panel
, WID_CANCEL_ACTION
,
150 "resource tab/cancel action");
151 init_wid(panel
, panel
, WID_MODE_DELETE_WIDGET
,
152 "resource tab/delete widget");
153 init_wid(panel
, panel
, WID_MODE_ADD_BUTTON
,
154 "resource tab/add button");
155 init_wid(panel
, panel
, WID_AREA
, "area");
156 init_wid(panel
, panel
, WID_AREA_BOX
, "area/box");
157 init_wid(panel
, panel
, WID_AREA_CURSOR_BOX
, "area/cursor box");
159 add_widget_accelerator(xuni
, panel
, panel
, SDLK_SPACE
, KMOD_NONE
);
160 add_widget_accelerator(xuni
, panel
, widget_nameid_access(panel
,
161 WID_CANCEL_ACTION
), SDLK_ESCAPE
, KMOD_NONE
);
163 edata
->mode
= EDITOR_MODE_TEST
;
168 static int editor_start(struct xuni_t
*xuni
, struct panel_data_t
*data
) {
169 set_caption("xuni editor");
174 static int editor_event(struct xuni_t
*xuni
, struct panel_data_t
*data
) {
175 struct editor_data_t
*edata
= data
->data
;
176 struct widget_t
*cbox
;
178 panel_type_t
*mode
= data
->event
[PANEL_EVENT_EVENT
].p
.event
.mode
;
179 SDL_Event
*event
= data
->event
[PANEL_EVENT_EVENT
].p
.event
.event
;
181 switch(event
->type
) {
186 switch(event
->key
.keysym
.sym
) {
188 dump_widget_tree(xuni
, widget_nameid_follow(xuni
->gui
->widget
,
189 PANEL_EDITOR
, WID_AREA
, (size_t)-1));
192 dump_widget_tree_xml(xuni
, widget_nameid_follow(xuni
->gui
->widget
,
193 PANEL_EDITOR
, WID_AREA
, (size_t)-1), "editor-dump.xml");
200 case SDL_MOUSEMOTION
:
201 if(widget_nameid_follow(xuni
->gui
->widget
,
202 PANEL_EDITOR
, WID_AREA_BOX
, (size_t)-1)->sel
) {
204 char buffer
[BUFSIZ
], **bdata
;
205 struct widget_t
*label
;
206 struct widget_t
*box
= widget_nameid_follow(xuni
->gui
->widget
,
207 PANEL_EDITOR
, WID_AREA
, (size_t)-1);
209 label
= widget_nameid_follow(xuni
->gui
->widget
,
210 PANEL_EDITOR
, WID_POSITION_LABEL
, (size_t)-1);
211 bdata
= (char **)&label
->p
.label
->text
;
213 sprintf(buffer
, "(%.2f,%.2f)",
214 (event
->motion
.x
- box
->pos
->real
.x
)
215 / (xuni
->smode
->width
* (box
->pos
->scale
.w
/ 100.0))
217 (event
->motion
.y
- box
->pos
->real
.y
)
218 / (xuni
->smode
->height
* (box
->pos
->scale
.h
/ 100.0))
221 xuni_memory_free(*bdata
);
222 *bdata
= xuni_memory_duplicate_string(buffer
);
224 widget_event(xuni
, label
, WIDGET_EVENT_RESCALE
);
229 if(edata
->mode
== EDITOR_MODE_ADD_BUTTON
) {
230 cbox
= widget_nameid_follow(xuni
->gui
->widget
,
231 PANEL_EDITOR
, WID_AREA_CURSOR_BOX
, (size_t)-1);
232 if(cbox
->visibility
& WIDGET_VISIBILITY_VISIBLE
) {
233 /* !!! this really needs to be simplified */
234 cbox
->pos
->scale
.w
= (event
->motion
.x
- cbox
->pos
->real
.x
)
235 / ((xuni
->smode
->width
/ 100.0)
236 * (cbox
->base
->pos
->scale
.w
/ 100.0));
237 cbox
->pos
->scale
.h
= (event
->motion
.y
- cbox
->pos
->real
.y
)
238 / ((xuni
->smode
->height
/ 100.0)
239 * (cbox
->base
->pos
->scale
.h
/ 100.0));
240 if(cbox
->pos
->scale
.w
< 0) cbox
->pos
->scale
.w
= 0;
241 if(cbox
->pos
->scale
.h
< 0) cbox
->pos
->scale
.h
= 0;
243 widget_event(xuni
, cbox
->base
, WIDGET_EVENT_RESCALE
);
258 static int set_editor_widget_sel(panel_type_t mode
, int xp
, int yp
, int click
,
259 void *vdata
, struct xuni_t
*xuni
) {
261 struct editor_data_t
*data
= vdata
;
262 struct widget_t
*widget
;
265 case EDITOR_MODE_ADD_BUTTON
:
266 widget
= widget_nameid_follow(xuni
->gui
->widget
,
267 PANEL_EDITOR
, WID_AREA_BOX
, (size_t)-1);
269 clear_widget_sel(xuni
->gui
->widget
);
271 if(pos_in_rect(xp
, yp
, widget
->pos
)) {
281 return set_widget_sel_repaint(&xuni
->gui
->sel
, xp
, yp
, click
,
282 widget_nameid_access(xuni
->gui
->widget
, mode
));
286 static void handle_cancel_action(struct xuni_t
*xuni
,
287 struct editor_data_t
*data
) {
289 if(data
->mode
== EDITOR_MODE_ADD_BUTTON
) {
290 struct widget_t
*panel
= widget_nameid_follow(xuni
->gui
->widget
,
291 PANEL_EDITOR
, WID_AREA_CURSOR_BOX
, (size_t)-1);
293 panel
->visibility
&= ~WIDGET_VISIBILITY_VISIBLE
;
294 panel
->visibility
&= ~WIDGET_VISIBILITY_SELABLE
;
298 static void set_editor_mode(struct xuni_t
*xuni
, struct editor_data_t
*data
,
299 enum editor_mode_t mode
) {
301 struct widget_t
*modelabel
;
304 if(mode
== data
->mode
) return;
308 handle_cancel_action(xuni
, data
);
310 modelabel
= widget_nameid_follow(xuni
->gui
->widget
,
311 PANEL_EDITOR
, WID_MODE_LABEL
, (size_t)-1);
313 xuni_memory_free((void *)modelabel
->p
.label
->text
);
314 text
= get_mode_name(data
->mode
);
315 text
= xuni_memory_duplicate_string(text
);
316 modelabel
->p
.label
->text
= text
;
317 widget_event(xuni
, modelabel
, WIDGET_EVENT_RESCALE
);
320 static void set_all_widget_visibilities(struct widget_t
*widget
,
321 enum widget_visibility_t visibility
) {
325 widget
->visibility
&= ~visibility
;
327 if(widget
->compose
) {
328 for(x
= 0; x
< widget
->compose
->widgets
; x
++) {
329 set_all_widget_visibilities(widget
->compose
->widget
[x
],
335 static int editor_click(struct xuni_t
*xuni
, struct panel_data_t
*data
) {
336 struct editor_data_t
*edata
= data
->data
;
337 panel_type_t
*mode
= data
->event
[PANEL_EVENT_CLICK
].p
.click
.mode
;
338 struct widget_t
*widget
= data
->event
[PANEL_EVENT_CLICK
].p
.click
.widget
;
339 struct widget_t
*cbox
;
348 widget_nameid_follow(xuni
->gui
->widget
, PANEL_EDITOR
, WID_AREA_BOX
,
349 (size_t)-1)->visibility
&= ~WIDGET_VISIBILITY_CLICKABLE
;
351 set_editor_mode(xuni
, edata
, EDITOR_MODE_TEST
);
354 case WID_CANCEL_ACTION
:
355 handle_cancel_action(xuni
, edata
);
359 case WID_MODE_DELETE_WIDGET
:
360 widget_nameid_follow(xuni
->gui
->widget
, PANEL_EDITOR
, WID_AREA_BOX
,
361 (size_t)-1)->visibility
&= ~WIDGET_VISIBILITY_CLICKABLE
;
363 set_editor_mode(xuni
, edata
, EDITOR_MODE_DELETE_WIDGET
);
366 case WID_MODE_ADD_BUTTON
:
367 widget_nameid_follow(xuni
->gui
->widget
, PANEL_EDITOR
, WID_AREA_BOX
,
368 (size_t)-1)->visibility
|= WIDGET_VISIBILITY_CLICKABLE
;
370 /*set_all_widget_visibilities(widget_nameid_follow(xuni->gui->widget,
371 PANEL_EDITOR, WID_AREA_BOX, (size_t)-1),
372 WIDGET_VISIBILITY_SELABLE);*/
374 set_editor_mode(xuni
, edata
, EDITOR_MODE_ADD_BUTTON
);
378 if(edata
->mode
== EDITOR_MODE_ADD_BUTTON
) {
379 cbox
= widget_nameid_access(widget
->base
->base
,
380 WID_AREA_CURSOR_BOX
);
382 if(cbox
->visibility
& WIDGET_VISIBILITY_VISIBLE
) {
383 cbox
->visibility
&= ~WIDGET_VISIBILITY_VISIBLE
;
385 /* Only add the button if its width and height are nonzero. */
386 if(cbox
->pos
->scale
.w
&& cbox
->pos
->scale
.h
) {
387 add_allocate_widget_compose(widget
->base
, "button");
389 init_widget_pos(last_compose_widget(widget
->base
),
390 cbox
->pos
->scale
.x
, cbox
->pos
->scale
.y
,
391 cbox
->pos
->scale
.w
, cbox
->pos
->scale
.h
,
393 init_button(last_compose_widget(widget
->base
), 0);
395 widget_event(xuni
, last_compose_widget(widget
->base
),
396 WIDGET_EVENT_RESCALE
);
400 cbox
->visibility
|= WIDGET_VISIBILITY_VISIBLE
;
402 SDL_GetMouseState(&xp
, &yp
);
403 xp
-= cbox
->base
->pos
->real
.x
;
404 yp
-= cbox
->base
->pos
->real
.y
;
405 cbox
->pos
->scale
.x
= (double)xp
/ cbox
->base
->pos
->real
.w
407 cbox
->pos
->scale
.y
= (double)yp
/ cbox
->base
->pos
->real
.h
409 cbox
->pos
->scale
.w
= 0;
410 cbox
->pos
->scale
.h
= 0;
412 widget_event(xuni
, cbox
, WIDGET_EVENT_RESCALE
);
419 if(widget_is_parent(widget_nameid_follow(xuni
->gui
->widget
,
420 PANEL_EDITOR
, WID_AREA
, (size_t)-1), widget
)) {
422 if(edata
->mode
== EDITOR_MODE_DELETE_WIDGET
) {
423 delete_widget_pointer(xuni
, widget
);
433 static int editor_deactivate(struct xuni_t
*xuni
, struct panel_data_t
*data
) {
437 static int editor_paint(struct xuni_t
*xuni
, struct panel_data_t
*data
) {
438 /*struct widget_t *area = widget_nameid_follow(xuni->gui->widget,
439 PANEL_EDITOR, WID_AREA, (size_t)-1);*/
441 clear_screen(xuni
->smode
->screen
);
443 widget_event(xuni
, widget_nameid_access(xuni
->gui
->widget
, PANEL_EDITOR
),
448 SDL_GetMouseState(&x, &y);
449 lineRGBA(xuni->smode->screen, area->pos->real.x, area->pos->real.y,
450 x, y, 255, 255, 255, 255);
458 static int editor_free(struct xuni_t
*xuni
, struct panel_data_t
*data
) {
462 #ifdef LOADSO_STATIC_VERSION
463 func_point_t
xuni_loadso_load_function(loadso_t object
, const char *func
) {
464 struct string_function_t data
[] = {
468 = string_to_function(data
, sizeof(data
) / sizeof(*data
), func
);
471 log_message(ERROR_TYPE_RESOURCE
, 0, __FILE__
, __LINE__
,
472 "Unknown function: \"%s\"", func
);