From fd1a1a2b902d34e75a47515a564020b0815ddea6 Mon Sep 17 00:00:00 2001 From: simon Date: Thu, 29 Apr 2004 19:23:08 +0000 Subject: [PATCH] Added a status bar. git-svn-id: svn://svn.tartarus.org/sgt/puzzles@4174 cda61777-01e9-0310-a592-d414129be87e --- Recipe | 2 +- cube.c | 22 ++++++++++++++++++++-- fifteen.c | 27 ++++++++++++++++++++++++--- gtk.c | 39 +++++++++++++++++++++++++++++++++++++++ midend.c | 5 +++++ net.c | 23 +++++++++++++++++++++++ nullgame.c | 5 +++++ puzzles.h | 3 +++ sixteen.c | 26 ++++++++++++++++++++++++-- windows.c | 40 ++++++++++++++++++++++++++++++++++++---- 10 files changed, 180 insertions(+), 12 deletions(-) diff --git a/Recipe b/Recipe index 19ca3a5..a2a5bfc 100644 --- a/Recipe +++ b/Recipe @@ -12,7 +12,7 @@ !makefile vc Makefile.vc !makefile cygwin Makefile.cyg -WINDOWS = windows user32.lib gdi32.lib +WINDOWS = windows user32.lib gdi32.lib comctl32.lib COMMON = midend misc malloc NET = net random tree234 diff --git a/cube.c b/cube.c index 6fef4d1..5940c8b 100644 --- a/cube.c +++ b/cube.c @@ -788,7 +788,7 @@ game_state *new_game(game_params *params, char *seed) state->previous = state->current; state->angle = 0.0; - state->completed = FALSE; + state->completed = 0; state->movecount = 0; return state; @@ -1068,7 +1068,7 @@ game_state *make_move(game_state *from, int x, int y, int button) if (ret->facecolours[i]) j++; if (j == ret->solid->nfaces) - ret->completed = TRUE; + ret->completed = ret->movecount; } sfree(poly); @@ -1329,6 +1329,19 @@ void game_redraw(frontend *fe, game_drawstate *ds, game_state *oldstate, draw_update(fe, 0, 0, (int)((bb.r-bb.l+2.0F) * GRID_SCALE), (int)((bb.d-bb.u+2.0F) * GRID_SCALE)); + + /* + * Update the status bar. + */ + { + char statusbuf[256]; + + sprintf(statusbuf, "%sMoves: %d", + (state->completed ? "COMPLETED! " : ""), + (state->completed ? state->completed : state->movecount)); + + status_bar(fe, statusbuf); + } } float game_anim_length(game_state *oldstate, game_state *newstate) @@ -1340,3 +1353,8 @@ float game_flash_length(game_state *oldstate, game_state *newstate) { return 0.0F; } + +int game_wants_statusbar(void) +{ + return TRUE; +} diff --git a/fifteen.c b/fifteen.c index 9357d65..b3285e7 100644 --- a/fifteen.c +++ b/fifteen.c @@ -42,6 +42,7 @@ struct game_state { int *tiles; int gap_pos; int completed; + int movecount; }; game_params *default_params(void) @@ -224,7 +225,7 @@ game_state *new_game(game_params *params, char *seed) assert(!*p); assert(state->tiles[state->gap_pos] == 0); - state->completed = FALSE; + state->completed = state->movecount = 0; return state; } @@ -240,6 +241,7 @@ game_state *dup_game(game_state *state) memcpy(ret->tiles, state->tiles, state->w * state->h * sizeof(int)); ret->gap_pos = state->gap_pos; ret->completed = state->completed; + ret->movecount = state->movecount; return ret; } @@ -297,16 +299,17 @@ game_state *make_move(game_state *from, int x, int y, int button) for (p = from->gap_pos; p != ret->gap_pos; p += up) { assert(p >= 0 && p < from->n); ret->tiles[p] = from->tiles[p + up]; + ret->movecount++; } /* * See if the game has been completed. */ if (!ret->completed) { - ret->completed = TRUE; + ret->completed = ret->movecount; for (p = 0; p < ret->n; p++) if (ret->tiles[p] != (p < ret->n-1 ? p+1 : 0)) - ret->completed = FALSE; + ret->completed = 0; } return ret; @@ -544,6 +547,19 @@ void game_redraw(frontend *fe, game_drawstate *ds, game_state *oldstate, } } ds->bgcolour = bgcolour; + + /* + * Update the status bar. + */ + { + char statusbuf[256]; + + sprintf(statusbuf, "%sMoves: %d", + (state->completed ? "COMPLETED! " : ""), + (state->completed ? state->completed : state->movecount)); + + status_bar(fe, statusbuf); + } } float game_anim_length(game_state *oldstate, game_state *newstate) @@ -558,3 +574,8 @@ float game_flash_length(game_state *oldstate, game_state *newstate) else return 0.0F; } + +int game_wants_statusbar(void) +{ + return TRUE; +} diff --git a/gtk.c b/gtk.c index 778868a..9ffc96a 100644 --- a/gtk.c +++ b/gtk.c @@ -3,6 +3,7 @@ */ #include +#include #include #include #include @@ -50,6 +51,8 @@ struct font { struct frontend { GtkWidget *window; GtkWidget *area; + GtkWidget *statusbar; + guint statusctx; GdkPixmap *pixmap; GdkColor *colours; int ncolours; @@ -71,6 +74,14 @@ void frontend_default_colour(frontend *fe, float *output) output[2] = col.blue / 65535.0; } +void status_bar(frontend *fe, char *text) +{ + assert(fe->statusbar); + + gtk_statusbar_pop(GTK_STATUSBAR(fe->statusbar), fe->statusctx); + gtk_statusbar_push(GTK_STATUSBAR(fe->statusbar), fe->statusctx, text); +} + void start_draw(frontend *fe) { fe->gc = gdk_gc_new(fe->area->window); @@ -299,6 +310,21 @@ static gint expose_area(GtkWidget *widget, GdkEventExpose *event, return TRUE; } +static gint map_window(GtkWidget *widget, GdkEvent *event, + gpointer data) +{ + frontend *fe = (frontend *)data; + + /* + * Apparently we need to do this because otherwise the status + * bar will fail to update immediately. Annoying, but there we + * go. + */ + gtk_widget_queue_draw(fe->window); + + return TRUE; +} + static gint configure_area(GtkWidget *widget, GdkEventConfigure *event, gpointer data) { @@ -483,6 +509,17 @@ static frontend *new_window(void) } } + if (midend_wants_statusbar(fe->me)) { + fe->statusbar = gtk_statusbar_new(); + gtk_box_pack_end(vbox, fe->statusbar, FALSE, FALSE, 0); + gtk_widget_show(fe->statusbar); + fe->statusctx = gtk_statusbar_get_context_id + (GTK_STATUSBAR(fe->statusbar), "game"); + gtk_statusbar_push(GTK_STATUSBAR(fe->statusbar), fe->statusctx, + ""); + } else + fe->statusbar = NULL; + fe->area = gtk_drawing_area_new(); midend_size(fe->me, &x, &y); gtk_drawing_area_size(GTK_DRAWING_AREA(fe->area), x, y); @@ -505,6 +542,8 @@ static frontend *new_window(void) GTK_SIGNAL_FUNC(button_event), fe); gtk_signal_connect(GTK_OBJECT(fe->area), "expose_event", GTK_SIGNAL_FUNC(expose_area), fe); + gtk_signal_connect(GTK_OBJECT(fe->window), "map_event", + GTK_SIGNAL_FUNC(map_window), fe); gtk_signal_connect(GTK_OBJECT(fe->area), "configure_event", GTK_SIGNAL_FUNC(configure_area), fe); diff --git a/midend.c b/midend.c index 3b1a0e4..79e6d7d 100644 --- a/midend.c +++ b/midend.c @@ -294,3 +294,8 @@ void midend_fetch_preset(midend_data *me, int n, *name = me->preset_names[n]; *params = me->presets[n]; } + +int midend_wants_statusbar(midend_data *me) +{ + return game_wants_statusbar(); +} diff --git a/net.c b/net.c index 268fbca..c345ecb 100644 --- a/net.c +++ b/net.c @@ -1189,6 +1189,24 @@ void game_redraw(frontend *fe, game_drawstate *ds, game_state *oldstate, } } + /* + * Update the status bar. + */ + { + char statusbuf[256]; + int i, n, a; + + n = state->width * state->height; + for (i = a = 0; i < n; i++) + if (active[i]) + a++; + + sprintf(statusbuf, "%sActive: %d/%d", + (state->completed ? "COMPLETED! " : ""), a, n); + + status_bar(fe, statusbuf); + } + sfree(active); } @@ -1231,3 +1249,8 @@ float game_flash_length(game_state *oldstate, game_state *newstate) return 0.0F; } + +int game_wants_statusbar(void) +{ + return TRUE; +} diff --git a/nullgame.c b/nullgame.c index 5ce6f07..3d278ad 100644 --- a/nullgame.c +++ b/nullgame.c @@ -144,3 +144,8 @@ float game_flash_length(game_state *oldstate, game_state *newstate) { return 0.0F; } + +int game_wants_statusbar(void) +{ + return FALSE; +} diff --git a/puzzles.h b/puzzles.h index cb276e2..0c5dec4 100644 --- a/puzzles.h +++ b/puzzles.h @@ -65,6 +65,7 @@ void draw_update(frontend *fe, int x, int y, int w, int h); void end_draw(frontend *fe); void deactivate_timer(frontend *fe); void activate_timer(frontend *fe); +void status_bar(frontend *fe, char *text); /* * midend.c @@ -82,6 +83,7 @@ void midend_timer(midend_data *me, float tplus); int midend_num_presets(midend_data *me); void midend_fetch_preset(midend_data *me, int n, char **name, game_params **params); +int midend_wants_statusbar(midend_data *me); /* * malloc.c @@ -130,5 +132,6 @@ void game_redraw(frontend *fe, game_drawstate *ds, game_state *oldstate, game_state *newstate, float anim_time, float flash_time); float game_anim_length(game_state *oldstate, game_state *newstate); float game_flash_length(game_state *oldstate, game_state *newstate); +int game_wants_statusbar(void); #endif /* PUZZLES_PUZZLES_H */ diff --git a/sixteen.c b/sixteen.c index bc21964..89eef4f 100644 --- a/sixteen.c +++ b/sixteen.c @@ -43,6 +43,7 @@ struct game_state { int w, h, n; int *tiles; int completed; + int movecount; }; game_params *default_params(void) @@ -231,7 +232,7 @@ game_state *new_game(game_params *params, char *seed) } assert(!*p); - state->completed = FALSE; + state->completed = state->movecount = 0; return state; } @@ -246,6 +247,7 @@ game_state *dup_game(game_state *state) ret->tiles = snewn(state->w * state->h, int); memcpy(ret->tiles, state->tiles, state->w * state->h * sizeof(int)); ret->completed = state->completed; + ret->movecount = state->movecount; return ret; } @@ -287,11 +289,13 @@ game_state *make_move(game_state *from, int x, int y, int button) ret->tiles[C(ret, cx, cy)] = from->tiles[C(from, tx, ty)]; } while (--n > 0); + ret->movecount++; + /* * See if the game has been completed. */ if (!ret->completed) { - ret->completed = TRUE; + ret->completed = ret->movecount; for (n = 0; n < ret->n; n++) if (ret->tiles[n] != n+1) ret->completed = FALSE; @@ -588,6 +592,19 @@ void game_redraw(frontend *fe, game_drawstate *ds, game_state *oldstate, unclip(fe); ds->bgcolour = bgcolour; + + /* + * Update the status bar. + */ + { + char statusbuf[256]; + + sprintf(statusbuf, "%sMoves: %d", + (state->completed ? "COMPLETED! " : ""), + (state->completed ? state->completed : state->movecount)); + + status_bar(fe, statusbuf); + } } float game_anim_length(game_state *oldstate, game_state *newstate) @@ -602,3 +619,8 @@ float game_flash_length(game_state *oldstate, game_state *newstate) else return 0.0F; } + +int game_wants_statusbar(void) +{ + return TRUE; +} diff --git a/windows.c b/windows.c index ea5d7a2..507203e 100644 --- a/windows.c +++ b/windows.c @@ -3,6 +3,7 @@ */ #include +#include #include #include @@ -72,7 +73,7 @@ struct font { struct frontend { midend_data *me; - HWND hwnd; + HWND hwnd, statusbar; HBITMAP bitmap, prevbm; HDC hdc_bm; COLORREF *colours; @@ -100,6 +101,11 @@ void fatal(char *fmt, ...) exit(1); } +void status_bar(frontend *fe, char *text) +{ + SetWindowText(fe->statusbar, text); +} + void frontend_default_colour(frontend *fe, float *output) { DWORD c = GetSysColor(COLOR_MENU); /* ick */ @@ -291,7 +297,7 @@ static frontend *new_window(HINSTANCE inst) { frontend *fe; int x, y; - RECT r; + RECT r, sr; HDC hdc; fe = snew(frontend); @@ -374,6 +380,21 @@ static frontend *new_window(HINSTANCE inst) SetMenu(fe->hwnd, bar); } + if (midend_wants_statusbar(fe->me)) { + fe->statusbar = CreateWindowEx(0, STATUSCLASSNAME, "ooh", + WS_CHILD | WS_VISIBLE, + 0, 0, 0, 0, /* status bar does these */ + fe->hwnd, NULL, inst, NULL); + GetWindowRect(fe->statusbar, &sr); + SetWindowPos(fe->hwnd, NULL, 0, 0, + r.right - r.left, r.bottom - r.top + sr.bottom - sr.top, + SWP_NOMOVE | SWP_NOZORDER); + SetWindowPos(fe->statusbar, NULL, 0, y, x, sr.bottom - sr.top, + SWP_NOZORDER); + } else { + fe->statusbar = NULL; + } + hdc = GetDC(fe->hwnd); fe->bitmap = CreateCompatibleBitmap(hdc, x, y); ReleaseDC(fe->hwnd, hdc); @@ -424,7 +445,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, int p = ((wParam &~ 0xF) - IDM_PRESETS) / 0x10; if (p >= 0 && p < fe->npresets) { - RECT r; + RECT r, sr; HDC hdc; int x, y; @@ -440,9 +461,18 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WS_OVERLAPPED), TRUE, 0); + if (fe->statusbar != NULL) { + GetWindowRect(fe->statusbar, &sr); + } else { + sr.left = sr.right = sr.top = sr.bottom = 0; + } SetWindowPos(fe->hwnd, NULL, 0, 0, - r.right - r.left, r.bottom - r.top, + r.right - r.left, + r.bottom - r.top + sr.bottom - sr.top, SWP_NOMOVE | SWP_NOZORDER); + if (fe->statusbar != NULL) + SetWindowPos(fe->statusbar, NULL, 0, y, x, + sr.bottom - sr.top, SWP_NOZORDER); DeleteObject(fe->bitmap); @@ -572,6 +602,8 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) srand(time(NULL)); + InitCommonControls(); + if (!prev) { WNDCLASS wndclass; -- 2.11.0