]> git.draconx.ca Git - rrace.git/blobdiff - src/motif.c
motif: Avoid constantly recalculating tile size.
[rrace.git] / src / motif.c
index fe030799984fc3442aa4b35917cbdb5039eba160..c4ea62dbbd25b5d5e4a4b7d6ceec50a3d8f4e40d 100644 (file)
 
 #define TIMER_UPDATE_MS 33
 
+#define SPLIT_NUMERATOR    75
+#define SPLIT_DENOMINATOR 100
+
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+
 #define PROGNAME "rrace"
 static const char *progname = PROGNAME;
 static const struct option lopts[] = { LOPTS_INITIALIZER, {0} };
@@ -182,7 +187,6 @@ static void game_input(Widget w, void *data, void *cb_data)
        XmDrawingAreaCallbackStruct *cbs = cb_data;
        XButtonEvent *b = &cbs->event->xbutton;
        struct app_state *state = data;
-       Dimension width, height;
 
        switch (cbs->event->type) {
        case ButtonPress:
@@ -191,12 +195,8 @@ static void game_input(Widget w, void *data, void *cb_data)
                        if (b->state & Button3Mask)
                                break;
 
-                       XtVaGetValues(w, XmNwidth, &width,
-                                        XmNheight, &height,
-                                        (char *)NULL);
-
-                       do_input_move(state, b->x / (width / 5),
-                                            b->y / (height / 5));
+                       do_input_move(state, b->x / state->game_tile_sz,
+                                            b->y / state->game_tile_sz);
                        break;
                case Button3:
                        set_view_goal(state, 1);
@@ -250,10 +250,44 @@ static void proc_about(Widget w, XEvent *e, String *argv, Cardinal *argc)
        ui_show_about(&state, get_shell(w));
 }
 
-static const XtActionsRec menu_actions[] = {
+static void proc_resize(Widget form, XEvent *e, String *argv, Cardinal *argc)
+{
+       Widget game = XtParent(state.game);
+       Widget goal = XtParent(state.goal);
+       Dimension w, h, gamesz, gameborder, goalsz, goalborder;
+       int x, y, gap;
+
+       XtVaGetValues(form, XmNwidth, &w, XmNheight, &h, (char *)NULL);
+       XtVaGetValues(game, XmNshadowThickness, &gameborder, (char *)NULL);
+       XtVaGetValues(goal, XmNshadowThickness, &goalborder,
+                           XmNleftOffset, &gap,
+                           (char *)NULL);
+
+       gamesz = MIN(h, w * SPLIT_NUMERATOR / SPLIT_DENOMINATOR);
+       state.game_tile_sz = (gamesz - 2*gameborder) / 5;
+       gamesz = 5*state.game_tile_sz + 2*gameborder;
+
+       goalsz = MIN(gamesz*3/5, w - gamesz - gap);
+       state.goal_tile_sz = (goalsz - 2*goalborder) / 3;
+       goalsz = 3*state.goal_tile_sz + 2*goalborder;
+
+       x = (w - gamesz - goalsz - gap) / 2;
+       if (x < 2) x = 0;
+
+       y = (h - gamesz) / 2;
+       if (y < 3) y = 0;
+
+       XtVaSetValues(game, XmNleftOffset, x, XmNtopOffset, y, (char *)NULL);
+       XtVaSetValues(game, XmNwidth, gamesz, XmNheight, gamesz, (char *)NULL);
+       XtVaSetValues(goal, XmNwidth, goalsz, XmNheight, goalsz, (char *)NULL);
+}
+
+static const XtActionsRec app_actions[] = {
        { "gameNew", proc_new_game },
        { "gameExit", proc_exit },
-       { "helpAbout", proc_about }
+       { "helpAbout", proc_about },
+
+       { "ResizeGameArea", proc_resize }
 };
 
 static XtAppContext app_initialize(int argc, char **argv)
@@ -266,11 +300,11 @@ static XtAppContext app_initialize(int argc, char **argv)
                progname = argv[0];
 
        shell = early_setup(&app, argc, argv);
-       XtAppAddActions(app, (void *)menu_actions, XtNumber(menu_actions));
+       XtAppAddActions(app, (void *)app_actions, XtNumber(app_actions));
        ui_initialize(&state, shell);
        x11_initialize(&state, shell);
 
-       XtAddCallback(state.game, XmNinputCallback,  game_input, &state);
+       XtAddCallback(state.game, XmNinputCallback, game_input, &state);
 
        /* Begin with the game in winning state */
        game_reset(&state.board);