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
) {
106 init_wid(gui
->widget
, gui
->widget
, PANEL_EDITOR
, "editor");
108 data
= xuni_memory_allocate(sizeof(struct editor_data_t
));
109 set_panel_callbacks(widget_nameid_access(gui
->widget
, PANEL_EDITOR
),
110 data
, 0, editor_init
, editor_start
, editor_event
,
111 default_panel_sel
, editor_click
, editor_deactivate
,
112 editor_paint
, editor_free
);
115 static const char *get_mode_name(enum editor_mode_t mode
) {
116 static const char *name
[] = {
122 if((size_t)mode
< sizeof(name
)/sizeof(*name
)) {
128 static int editor_init(struct xuni_t
*xuni
, struct panel_data_t
*data
) {
129 struct editor_data_t
*edata
= data
->data
;
130 struct widget_t
*panel
= data
->event
[PANEL_EVENT_INIT
].p
.init
.panel
;
132 init_wid(panel
, panel
, WID_QUIT
, "quit");
133 init_wid(panel
, panel
, WID_MODE_LABEL
, "mode label");
134 init_wid(panel
, panel
, WID_POSITION_LABEL
, "position label");
135 init_wid(panel
, panel
, WID_MODE_TEST
, "resource tab/test");
136 init_wid(panel
, panel
, WID_CANCEL_ACTION
,
137 "resource tab/cancel action");
138 init_wid(panel
, panel
, WID_MODE_DELETE_WIDGET
,
139 "resource tab/delete widget");
140 init_wid(panel
, panel
, WID_MODE_ADD_BUTTON
,
141 "resource tab/add button");
142 init_wid(panel
, panel
, WID_AREA
, "area");
143 init_wid(panel
, panel
, WID_AREA_BOX
, "area/box");
144 init_wid(panel
, panel
, WID_AREA_CURSOR_BOX
, "area/cursor box");
146 add_widget_accelerator(xuni
, panel
, panel
, SDLK_SPACE
, KMOD_NONE
);
147 add_widget_accelerator(xuni
, panel
, widget_nameid_access(panel
,
148 WID_CANCEL_ACTION
), SDLK_ESCAPE
, KMOD_NONE
);
150 edata
->mode
= EDITOR_MODE_TEST
;
155 static int editor_start(struct xuni_t
*xuni
, struct panel_data_t
*data
) {
156 set_caption("xuni editor");
161 static int editor_event(struct xuni_t
*xuni
, struct panel_data_t
*data
) {
162 /*static int editor_event(void *vdata, struct xuni_t *xuni, panel_type_t *mode,
163 SDL_Event *event) {*/
165 struct editor_data_t
*edata
= data
->data
;
166 struct widget_t
*cbox
;
168 panel_type_t
*mode
= data
->event
[PANEL_EVENT_EVENT
].p
.event
.mode
;
169 SDL_Event
*event
= data
->event
[PANEL_EVENT_EVENT
].p
.event
.event
;
171 switch(event
->type
) {
176 switch(event
->key
.keysym
.sym
) {
178 dump_widget_tree(xuni
, widget_nameid_follow(xuni
->gui
->widget
,
179 PANEL_EDITOR
, WID_AREA
, (size_t)-1));
182 dump_widget_tree_xml(xuni
, widget_nameid_follow(xuni
->gui
->widget
,
183 PANEL_EDITOR
, WID_AREA
, (size_t)-1), "editor-dump.xml");
190 case SDL_MOUSEMOTION
:
191 if(widget_nameid_follow(xuni
->gui
->widget
,
192 PANEL_EDITOR
, WID_AREA_BOX
, (size_t)-1)->sel
) {
194 char buffer
[BUFSIZ
], **bdata
;
195 struct widget_t
*label
;
196 struct widget_t
*box
= widget_nameid_follow(xuni
->gui
->widget
,
197 PANEL_EDITOR
, WID_AREA
, (size_t)-1);
199 label
= widget_nameid_follow(xuni
->gui
->widget
,
200 PANEL_EDITOR
, WID_POSITION_LABEL
, (size_t)-1);
201 bdata
= (char **)&label
->p
.label
->text
;
203 sprintf(buffer
, "(%.2f,%.2f)",
204 (event
->motion
.x
- box
->pos
->real
.x
)
205 / (xuni
->smode
->width
* (box
->pos
->scale
.w
/ 100.0))
207 (event
->motion
.y
- box
->pos
->real
.y
)
208 / (xuni
->smode
->height
* (box
->pos
->scale
.h
/ 100.0))
211 xuni_memory_free(*bdata
);
212 *bdata
= xuni_memory_duplicate_string(buffer
);
214 widget_event(xuni
, label
, WIDGET_EVENT_RESCALE
);
219 if(edata
->mode
== EDITOR_MODE_ADD_BUTTON
) {
220 cbox
= widget_nameid_follow(xuni
->gui
->widget
,
221 PANEL_EDITOR
, WID_AREA_CURSOR_BOX
, (size_t)-1);
222 if(cbox
->visibility
& WIDGET_VISIBILITY_VISIBLE
) {
223 /* !!! this really needs to be simplified */
224 cbox
->pos
->scale
.w
= (event
->motion
.x
- cbox
->pos
->real
.x
)
225 / ((xuni
->smode
->width
/ 100.0)
226 * (cbox
->base
->pos
->scale
.w
/ 100.0));
227 cbox
->pos
->scale
.h
= (event
->motion
.y
- cbox
->pos
->real
.y
)
228 / ((xuni
->smode
->height
/ 100.0)
229 * (cbox
->base
->pos
->scale
.h
/ 100.0));
230 if(cbox
->pos
->scale
.w
< 0) cbox
->pos
->scale
.w
= 0;
231 if(cbox
->pos
->scale
.h
< 0) cbox
->pos
->scale
.h
= 0;
233 widget_event(xuni
, cbox
->base
, WIDGET_EVENT_RESCALE
);
248 static int set_editor_widget_sel(panel_type_t mode
, int xp
, int yp
, int click
,
249 void *vdata
, struct xuni_t
*xuni
) {
251 struct editor_data_t
*data
= vdata
;
252 struct widget_t
*widget
;
255 case EDITOR_MODE_ADD_BUTTON
:
256 widget
= widget_nameid_follow(xuni
->gui
->widget
,
257 PANEL_EDITOR
, WID_AREA_BOX
, (size_t)-1);
259 clear_widget_sel(xuni
->gui
->widget
);
261 if(pos_in_rect(xp
, yp
, widget
->pos
)) {
271 return set_widget_sel_repaint(&xuni
->gui
->sel
, xp
, yp
, click
,
272 widget_nameid_access(xuni
->gui
->widget
, mode
));
276 static void handle_cancel_action(struct xuni_t
*xuni
,
277 struct editor_data_t
*data
) {
279 if(data
->mode
== EDITOR_MODE_ADD_BUTTON
) {
280 struct widget_t
*panel
= widget_nameid_follow(xuni
->gui
->widget
,
281 PANEL_EDITOR
, WID_AREA_CURSOR_BOX
, (size_t)-1);
283 panel
->visibility
&= ~WIDGET_VISIBILITY_VISIBLE
;
284 panel
->visibility
&= ~WIDGET_VISIBILITY_SELABLE
;
288 static void set_editor_mode(struct xuni_t
*xuni
, struct editor_data_t
*data
,
289 enum editor_mode_t mode
) {
291 struct widget_t
*modelabel
;
294 if(mode
== data
->mode
) return;
298 handle_cancel_action(xuni
, data
);
300 modelabel
= widget_nameid_follow(xuni
->gui
->widget
,
301 PANEL_EDITOR
, WID_MODE_LABEL
, (size_t)-1);
303 xuni_memory_free((void *)modelabel
->p
.label
->text
);
304 text
= get_mode_name(data
->mode
);
305 text
= xuni_memory_duplicate_string(text
);
306 modelabel
->p
.label
->text
= text
;
307 widget_event(xuni
, modelabel
, WIDGET_EVENT_RESCALE
);
310 static void set_all_widget_visibilities(struct widget_t
*widget
,
311 enum widget_visibility_t visibility
) {
315 widget
->visibility
&= ~visibility
;
317 if(widget
->compose
) {
318 for(x
= 0; x
< widget
->compose
->widgets
; x
++) {
319 set_all_widget_visibilities(widget
->compose
->widget
[x
],
325 static int editor_click(struct xuni_t
*xuni
, struct panel_data_t
*data
) {
326 struct editor_data_t
*edata
= data
->data
;
327 panel_type_t
*mode
= data
->event
[PANEL_EVENT_CLICK
].p
.click
.mode
;
328 struct widget_t
*widget
= data
->event
[PANEL_EVENT_CLICK
].p
.click
.widget
;
329 struct widget_t
*cbox
;
338 widget_nameid_follow(xuni
->gui
->widget
, PANEL_EDITOR
, WID_AREA_BOX
,
339 (size_t)-1)->visibility
&= ~WIDGET_VISIBILITY_CLICKABLE
;
341 set_editor_mode(xuni
, edata
, EDITOR_MODE_TEST
);
344 case WID_CANCEL_ACTION
:
345 handle_cancel_action(xuni
, edata
);
349 case WID_MODE_DELETE_WIDGET
:
350 widget_nameid_follow(xuni
->gui
->widget
, PANEL_EDITOR
, WID_AREA_BOX
,
351 (size_t)-1)->visibility
&= ~WIDGET_VISIBILITY_CLICKABLE
;
353 set_editor_mode(xuni
, edata
, EDITOR_MODE_DELETE_WIDGET
);
356 case WID_MODE_ADD_BUTTON
:
357 widget_nameid_follow(xuni
->gui
->widget
, PANEL_EDITOR
, WID_AREA_BOX
,
358 (size_t)-1)->visibility
|= WIDGET_VISIBILITY_CLICKABLE
;
360 /*set_all_widget_visibilities(widget_nameid_follow(xuni->gui->widget,
361 PANEL_EDITOR, WID_AREA_BOX, (size_t)-1),
362 WIDGET_VISIBILITY_SELABLE);*/
364 set_editor_mode(xuni
, edata
, EDITOR_MODE_ADD_BUTTON
);
368 if(edata
->mode
== EDITOR_MODE_ADD_BUTTON
) {
369 cbox
= widget_nameid_access(widget
->base
->base
,
370 WID_AREA_CURSOR_BOX
);
372 if(cbox
->visibility
& WIDGET_VISIBILITY_VISIBLE
) {
373 cbox
->visibility
&= ~WIDGET_VISIBILITY_VISIBLE
;
375 /* Only add the button if its width and height are nonzero. */
376 if(cbox
->pos
->scale
.w
&& cbox
->pos
->scale
.h
) {
377 add_allocate_widget_compose(widget
->base
, "button");
379 init_widget_pos(last_compose_widget(widget
->base
),
380 cbox
->pos
->scale
.x
, cbox
->pos
->scale
.y
,
381 cbox
->pos
->scale
.w
, cbox
->pos
->scale
.h
,
383 init_button(last_compose_widget(widget
->base
), 0);
385 widget_event(xuni
, last_compose_widget(widget
->base
),
386 WIDGET_EVENT_RESCALE
);
390 cbox
->visibility
|= WIDGET_VISIBILITY_VISIBLE
;
392 SDL_GetMouseState(&xp
, &yp
);
393 xp
-= cbox
->base
->pos
->real
.x
;
394 yp
-= cbox
->base
->pos
->real
.y
;
395 cbox
->pos
->scale
.x
= (double)xp
/ cbox
->base
->pos
->real
.w
397 cbox
->pos
->scale
.y
= (double)yp
/ cbox
->base
->pos
->real
.h
399 cbox
->pos
->scale
.w
= 0;
400 cbox
->pos
->scale
.h
= 0;
402 widget_event(xuni
, cbox
, WIDGET_EVENT_RESCALE
);
409 if(widget_is_parent(widget_nameid_follow(xuni
->gui
->widget
,
410 PANEL_EDITOR
, WID_AREA
, (size_t)-1), widget
)) {
412 if(edata
->mode
== EDITOR_MODE_DELETE_WIDGET
) {
413 delete_widget_pointer(xuni
, widget
);
423 static int editor_deactivate(struct xuni_t
*xuni
, struct panel_data_t
*data
) {
427 static int editor_paint(struct xuni_t
*xuni
, struct panel_data_t
*data
) {
428 /*struct widget_t *area = widget_nameid_follow(xuni->gui->widget,
429 PANEL_EDITOR, WID_AREA, (size_t)-1);*/
431 clear_screen(xuni
->smode
->screen
);
433 widget_event(xuni
, widget_nameid_access(xuni
->gui
->widget
, PANEL_EDITOR
),
438 SDL_GetMouseState(&x, &y);
439 lineRGBA(xuni->smode->screen, area->pos->real.x, area->pos->real.y,
440 x, y, 255, 255, 255, 255);
448 static int editor_free(struct xuni_t
*xuni
, struct panel_data_t
*data
) {
452 #ifdef LOADSO_STATIC_VERSION
453 func_point_t
xuni_loadso_load_function(loadso_t object
, const char *func
) {
454 struct string_function_t data
[] = {
458 = string_to_function(data
, sizeof(data
) / sizeof(*data
), func
);
461 log_message(ERROR_TYPE_RESOURCE
, 0, __FILE__
, __LINE__
,
462 "Unknown function: \"%s\"", func
);