file dialogs
[vrlugburz] / tools / dunger / src / main.c
index 83d7fd0..ed456f7 100644 (file)
@@ -16,6 +16,18 @@ static void keyup(unsigned char key, int x, int y);
 static void mouse(int bn, int st, int x, int y);
 static void motion(int x, int y);
 
+static void cb_new(utk_event *ev, void *data);
+static void cb_new_ok(utk_event *ev, void *data);
+static void cb_open(utk_event *ev, void *data);
+static void cb_open_ok(utk_event *ev, void *data);
+static void cb_save(utk_event *ev, void *data);
+static void cb_save_ok(utk_event *ev, void *data);
+
+static void cb_cancel(utk_event *ev, void *data);
+
+static int parse_args(int argc, char **argv);
+
+
 static void ucolor(int r, int g, int b, int a);
 static void uclip(int x1, int y1, int x2, int y2);
 static void uimage(int x, int y, const void *pix, int xsz, int ysz);
@@ -25,8 +37,6 @@ static void utext(int x, int y, const char *txt, int sz);
 static int utextspacing(void);
 static int utextwidth(const char *txt, int sz);
 
-static int parse_args(int argc, char **argv);
-
 
 int win_width, win_height;
 int view_width, view_height;
@@ -41,7 +51,9 @@ int splitx;
 
 #define FONTSZ 16
 static struct dtx_font *uifont;
-static utk_widget *uiroot;
+static utk_widget *uiroot, *uiwin_new;
+static utk_widget *uigrab;
+static utk_widget *cbox_newsz;
 
 static struct level *lvl;
 
@@ -81,7 +93,8 @@ int main(int argc, char **argv)
 
 static int init(void)
 {
-       utk_widget *win;
+       int pad;
+       utk_widget *win, *hbox, *vbox;
 
        glEnable(GL_MULTISAMPLE);
 
@@ -109,9 +122,24 @@ static int init(void)
 
        win = utk_vbox(uiroot, 0, UTK_DEF_SPACING);
        utk_set_pos(win, 15, 15);
-       utk_button(win, "hello", 0, 0, 0, 0);
-       utk_button(win, "button 2", 0, 0, 0, 0);
-       utk_button(win, "button 3", 0, 0, 0, 0);
+       utk_button(win, "New", 0, 0, cb_new, 0);
+       utk_button(win, "Open ...", 0, 0, cb_open, 0);
+       utk_button(win, "Save ...", 0, 0, cb_save, 0);
+
+       uiwin_new = utk_window(uiroot, (win_width - 220) / 2, (win_height - 150) / 2,
+                       220, 150, "New level");
+       vbox = utk_vbox(uiwin_new, UTK_DEF_PADDING, UTK_DEF_SPACING);
+       {
+               const char *items[] = {"small (16x16)", "medium (24x24)", "large (32x32)"};
+               cbox_newsz = utk_combobox_items(vbox, items, sizeof items / sizeof *items, 0, 0);
+               utk_select(cbox_newsz, 2);
+       }
+       hbox = utk_hbox(vbox, UTK_DEF_PADDING, UTK_DEF_SPACING);
+       utk_button(hbox, "OK", 0, 0, cb_new_ok, 0);
+       utk_button(hbox, "Cancel", 0, 0, cb_cancel, uiwin_new);
+       pad = utk_get_padding(uiwin_new);
+       utk_set_size(uiwin_new, utk_get_width(vbox) + pad * 2.0f, utk_get_height(vbox) + pad * 2.0f);
+
 
        if(!(lvl = create_level(32, 32))) {
                fprintf(stderr, "failed to create level\n");
@@ -143,22 +171,6 @@ static void display(void)
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
 
-       /* draw UI */
-
-       glMatrixMode(GL_PROJECTION);
-       glLoadIdentity();
-       glOrtho(0, splitx, win_height, 0, -1, 1);
-       glViewport(0, 0, splitx, win_height);
-
-       glBegin(GL_QUADS);
-       glColor3f(0.25, 0.25, 0.25);
-       glVertex2f(0, 0);
-       glVertex2f(splitx, 0);
-       glVertex2f(splitx, win_height);
-       glVertex2f(0, win_height);
-       glEnd();
-       utk_draw(uiroot);
-
        /* draw view */
 
        glMatrixMode(GL_PROJECTION);
@@ -176,6 +188,27 @@ static void display(void)
 
        draw_lview();
 
+       /* draw UI */
+
+       glMatrixMode(GL_PROJECTION);
+       glLoadIdentity();
+       glOrtho(0, win_width, win_height, 0, -1, 1);
+       glViewport(0, 0, win_width, win_height);
+
+       glBegin(GL_QUADS);
+       glColor3f(0.25, 0.25, 0.25);
+       glVertex2f(0, 0);
+       glVertex2f(splitx, 0);
+       glVertex2f(splitx, win_height);
+       glVertex2f(0, win_height);
+       glEnd();
+
+       glEnable(GL_BLEND);
+       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+       utk_draw(uiroot);
+       glDisable(GL_BLEND);
+
+
        glutSwapBuffers();
 }
 
@@ -193,7 +226,24 @@ static void reshape(int x, int y)
 
 static void keyb(unsigned char key, int x, int y)
 {
-       if(key == 27) exit(0);
+       switch(key) {
+       case 27:
+               if(uigrab) {
+                       if(utk_is_dialog(uigrab)) {
+                               utk_destroy_window(uigrab);
+                       } else {
+                               utk_hide(uigrab);
+                       }
+                       uigrab = 0;
+               } else {
+                       exit(0);
+               }
+               return;
+
+       default:
+               break;
+       }
+
        utk_keyboard_event(key, 1);
        glutPostRedisplay();
 }
@@ -221,12 +271,14 @@ static void mouse(int bn, int st, int x, int y)
                        clickx = clicky = -1;
                }
        } else if(bn == 3) {
-               if(press) view_zoom += 0.1;
+               if(press) zoom_lview(0.1);
        } else if(bn == 4) {
-               if(press) view_zoom -= 0.1;
+               if(press) zoom_lview(-0.1);
        }
 
-       lview_mbutton(bidx, press, x, y);
+       if(!uigrab) {
+               lview_mbutton(bidx, press, x, y);
+       }
 
        utk_mbutton_event(bidx, press, x / uiscale, y / uiscale);
        glutPostRedisplay();
@@ -242,17 +294,86 @@ static void motion(int x, int y)
 
        if(clickx >= splitx) {
                if(bnstate[1]) {
-                       view_panx -= dx;
-                       view_pany += dy;
+                       pan_lview(-dx, dy);
                }
        }
 
-       lview_mouse(x, y);
+       if(!uigrab) {
+               lview_mouse(x, y);
+       }
 
        utk_mmotion_event(x / uiscale, y / uiscale);
        glutPostRedisplay();
 }
 
+static void cb_new(utk_event *ev, void *data)
+{
+       utk_show(uiwin_new);
+       uigrab = uiwin_new;
+}
+
+static void cb_new_ok(utk_event *ev, void *data)
+{
+       static int levsz[] = {16, 24, 32};
+       int sz;
+       struct level *newlvl;
+
+       sz = levsz[utk_get_selected(cbox_newsz)];
+
+       if(!(newlvl = create_level(sz, sz))) {
+               utk_message_dialog("failed to create new level", UTK_MSG_TYPE_ERROR,
+                               UTK_MSG_BN_OK, cb_cancel, 0);
+               return;
+       }
+
+       free_level(lvl);
+       destroy_lview();
+
+       lvl = newlvl;
+       init_lview(newlvl);
+
+       utk_hide(uiwin_new);
+       uigrab = 0;
+}
+
+static void cb_open(utk_event *ev, void *data)
+{
+       uigrab = utk_file_dialog(UTK_FILE_DIALOG_OPEN, 0, "Level file (*.lvl) [.lvl]", 0, cb_open_ok, 0);
+}
+
+static void cb_open_ok(utk_event *ev, void *data)
+{
+       utk_widget *dlg = utk_event_widget(ev);
+       printf("selected: %s\n", utk_file_dialog_file(dlg));
+       utk_destroy_window(dlg);
+       if(uigrab == dlg) uigrab = 0;
+}
+
+static void cb_save(utk_event *ev, void *data)
+{
+       uigrab = utk_file_dialog(UTK_FILE_DIALOG_SAVE, 0, "Level file (*.lvl) [.lvl]", 0, cb_save_ok, 0);
+}
+
+static void cb_save_ok(utk_event *ev, void *data)
+{
+       utk_widget *dlg = utk_event_widget(ev);
+       printf("selected: %s\n", utk_file_dialog_file(dlg));
+       utk_destroy_window(dlg);
+       if(uigrab == dlg) uigrab = 0;
+}
+
+static void cb_cancel(utk_event *ev, void *data)
+{
+       if(!data) data = utk_get_window(utk_event_widget(ev));
+
+       if(utk_is_dialog(data)) {
+               utk_destroy_window(data);
+       } else {
+               utk_hide(data);
+       }
+       uigrab = 0;
+}
+
 static int parse_args(int argc, char **argv)
 {
        int i;