Added a status bar.

[originally from svn r4174]
This commit is contained in:
Simon Tatham
2004-04-29 19:23:08 +00:00
parent fa7ef572c7
commit a8c8237bd0
10 changed files with 180 additions and 12 deletions

2
Recipe
View File

@ -12,7 +12,7 @@
!makefile vc Makefile.vc !makefile vc Makefile.vc
!makefile cygwin Makefile.cyg !makefile cygwin Makefile.cyg
WINDOWS = windows user32.lib gdi32.lib WINDOWS = windows user32.lib gdi32.lib comctl32.lib
COMMON = midend misc malloc COMMON = midend misc malloc
NET = net random tree234 NET = net random tree234

22
cube.c
View File

@ -788,7 +788,7 @@ game_state *new_game(game_params *params, char *seed)
state->previous = state->current; state->previous = state->current;
state->angle = 0.0; state->angle = 0.0;
state->completed = FALSE; state->completed = 0;
state->movecount = 0; state->movecount = 0;
return state; return state;
@ -1068,7 +1068,7 @@ game_state *make_move(game_state *from, int x, int y, int button)
if (ret->facecolours[i]) if (ret->facecolours[i])
j++; j++;
if (j == ret->solid->nfaces) if (j == ret->solid->nfaces)
ret->completed = TRUE; ret->completed = ret->movecount;
} }
sfree(poly); 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), draw_update(fe, 0, 0, (int)((bb.r-bb.l+2.0F) * GRID_SCALE),
(int)((bb.d-bb.u+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) 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; return 0.0F;
} }
int game_wants_statusbar(void)
{
return TRUE;
}

View File

@ -42,6 +42,7 @@ struct game_state {
int *tiles; int *tiles;
int gap_pos; int gap_pos;
int completed; int completed;
int movecount;
}; };
game_params *default_params(void) game_params *default_params(void)
@ -224,7 +225,7 @@ game_state *new_game(game_params *params, char *seed)
assert(!*p); assert(!*p);
assert(state->tiles[state->gap_pos] == 0); assert(state->tiles[state->gap_pos] == 0);
state->completed = FALSE; state->completed = state->movecount = 0;
return state; return state;
} }
@ -240,6 +241,7 @@ game_state *dup_game(game_state *state)
memcpy(ret->tiles, state->tiles, state->w * state->h * sizeof(int)); memcpy(ret->tiles, state->tiles, state->w * state->h * sizeof(int));
ret->gap_pos = state->gap_pos; ret->gap_pos = state->gap_pos;
ret->completed = state->completed; ret->completed = state->completed;
ret->movecount = state->movecount;
return ret; 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) { for (p = from->gap_pos; p != ret->gap_pos; p += up) {
assert(p >= 0 && p < from->n); assert(p >= 0 && p < from->n);
ret->tiles[p] = from->tiles[p + up]; ret->tiles[p] = from->tiles[p + up];
ret->movecount++;
} }
/* /*
* See if the game has been completed. * See if the game has been completed.
*/ */
if (!ret->completed) { if (!ret->completed) {
ret->completed = TRUE; ret->completed = ret->movecount;
for (p = 0; p < ret->n; p++) for (p = 0; p < ret->n; p++)
if (ret->tiles[p] != (p < ret->n-1 ? p+1 : 0)) if (ret->tiles[p] != (p < ret->n-1 ? p+1 : 0))
ret->completed = FALSE; ret->completed = 0;
} }
return ret; return ret;
@ -544,6 +547,19 @@ void game_redraw(frontend *fe, game_drawstate *ds, game_state *oldstate,
} }
} }
ds->bgcolour = bgcolour; 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) 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 else
return 0.0F; return 0.0F;
} }
int game_wants_statusbar(void)
{
return TRUE;
}

39
gtk.c
View File

@ -3,6 +3,7 @@
*/ */
#include <stdio.h> #include <stdio.h>
#include <assert.h>
#include <stdlib.h> #include <stdlib.h>
#include <time.h> #include <time.h>
#include <stdarg.h> #include <stdarg.h>
@ -50,6 +51,8 @@ struct font {
struct frontend { struct frontend {
GtkWidget *window; GtkWidget *window;
GtkWidget *area; GtkWidget *area;
GtkWidget *statusbar;
guint statusctx;
GdkPixmap *pixmap; GdkPixmap *pixmap;
GdkColor *colours; GdkColor *colours;
int ncolours; int ncolours;
@ -71,6 +74,14 @@ void frontend_default_colour(frontend *fe, float *output)
output[2] = col.blue / 65535.0; 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) void start_draw(frontend *fe)
{ {
fe->gc = gdk_gc_new(fe->area->window); fe->gc = gdk_gc_new(fe->area->window);
@ -299,6 +310,21 @@ static gint expose_area(GtkWidget *widget, GdkEventExpose *event,
return TRUE; 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, static gint configure_area(GtkWidget *widget,
GdkEventConfigure *event, gpointer data) 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(); fe->area = gtk_drawing_area_new();
midend_size(fe->me, &x, &y); midend_size(fe->me, &x, &y);
gtk_drawing_area_size(GTK_DRAWING_AREA(fe->area), 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_FUNC(button_event), fe);
gtk_signal_connect(GTK_OBJECT(fe->area), "expose_event", gtk_signal_connect(GTK_OBJECT(fe->area), "expose_event",
GTK_SIGNAL_FUNC(expose_area), fe); 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_connect(GTK_OBJECT(fe->area), "configure_event",
GTK_SIGNAL_FUNC(configure_area), fe); GTK_SIGNAL_FUNC(configure_area), fe);

View File

@ -294,3 +294,8 @@ void midend_fetch_preset(midend_data *me, int n,
*name = me->preset_names[n]; *name = me->preset_names[n];
*params = me->presets[n]; *params = me->presets[n];
} }
int midend_wants_statusbar(midend_data *me)
{
return game_wants_statusbar();
}

23
net.c
View File

@ -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); sfree(active);
} }
@ -1231,3 +1249,8 @@ float game_flash_length(game_state *oldstate, game_state *newstate)
return 0.0F; return 0.0F;
} }
int game_wants_statusbar(void)
{
return TRUE;
}

View File

@ -144,3 +144,8 @@ float game_flash_length(game_state *oldstate, game_state *newstate)
{ {
return 0.0F; return 0.0F;
} }
int game_wants_statusbar(void)
{
return FALSE;
}

View File

@ -65,6 +65,7 @@ void draw_update(frontend *fe, int x, int y, int w, int h);
void end_draw(frontend *fe); void end_draw(frontend *fe);
void deactivate_timer(frontend *fe); void deactivate_timer(frontend *fe);
void activate_timer(frontend *fe); void activate_timer(frontend *fe);
void status_bar(frontend *fe, char *text);
/* /*
* midend.c * midend.c
@ -82,6 +83,7 @@ void midend_timer(midend_data *me, float tplus);
int midend_num_presets(midend_data *me); int midend_num_presets(midend_data *me);
void midend_fetch_preset(midend_data *me, int n, void midend_fetch_preset(midend_data *me, int n,
char **name, game_params **params); char **name, game_params **params);
int midend_wants_statusbar(midend_data *me);
/* /*
* malloc.c * 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); game_state *newstate, float anim_time, float flash_time);
float game_anim_length(game_state *oldstate, game_state *newstate); float game_anim_length(game_state *oldstate, game_state *newstate);
float game_flash_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 */ #endif /* PUZZLES_PUZZLES_H */

View File

@ -43,6 +43,7 @@ struct game_state {
int w, h, n; int w, h, n;
int *tiles; int *tiles;
int completed; int completed;
int movecount;
}; };
game_params *default_params(void) game_params *default_params(void)
@ -231,7 +232,7 @@ game_state *new_game(game_params *params, char *seed)
} }
assert(!*p); assert(!*p);
state->completed = FALSE; state->completed = state->movecount = 0;
return state; return state;
} }
@ -246,6 +247,7 @@ game_state *dup_game(game_state *state)
ret->tiles = snewn(state->w * state->h, int); ret->tiles = snewn(state->w * state->h, int);
memcpy(ret->tiles, state->tiles, state->w * state->h * sizeof(int)); memcpy(ret->tiles, state->tiles, state->w * state->h * sizeof(int));
ret->completed = state->completed; ret->completed = state->completed;
ret->movecount = state->movecount;
return ret; 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)]; ret->tiles[C(ret, cx, cy)] = from->tiles[C(from, tx, ty)];
} while (--n > 0); } while (--n > 0);
ret->movecount++;
/* /*
* See if the game has been completed. * See if the game has been completed.
*/ */
if (!ret->completed) { if (!ret->completed) {
ret->completed = TRUE; ret->completed = ret->movecount;
for (n = 0; n < ret->n; n++) for (n = 0; n < ret->n; n++)
if (ret->tiles[n] != n+1) if (ret->tiles[n] != n+1)
ret->completed = FALSE; ret->completed = FALSE;
@ -588,6 +592,19 @@ void game_redraw(frontend *fe, game_drawstate *ds, game_state *oldstate,
unclip(fe); unclip(fe);
ds->bgcolour = bgcolour; 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) 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 else
return 0.0F; return 0.0F;
} }
int game_wants_statusbar(void)
{
return TRUE;
}

View File

@ -3,6 +3,7 @@
*/ */
#include <windows.h> #include <windows.h>
#include <commctrl.h>
#include <stdio.h> #include <stdio.h>
#include <assert.h> #include <assert.h>
@ -72,7 +73,7 @@ struct font {
struct frontend { struct frontend {
midend_data *me; midend_data *me;
HWND hwnd; HWND hwnd, statusbar;
HBITMAP bitmap, prevbm; HBITMAP bitmap, prevbm;
HDC hdc_bm; HDC hdc_bm;
COLORREF *colours; COLORREF *colours;
@ -100,6 +101,11 @@ void fatal(char *fmt, ...)
exit(1); exit(1);
} }
void status_bar(frontend *fe, char *text)
{
SetWindowText(fe->statusbar, text);
}
void frontend_default_colour(frontend *fe, float *output) void frontend_default_colour(frontend *fe, float *output)
{ {
DWORD c = GetSysColor(COLOR_MENU); /* ick */ DWORD c = GetSysColor(COLOR_MENU); /* ick */
@ -291,7 +297,7 @@ static frontend *new_window(HINSTANCE inst)
{ {
frontend *fe; frontend *fe;
int x, y; int x, y;
RECT r; RECT r, sr;
HDC hdc; HDC hdc;
fe = snew(frontend); fe = snew(frontend);
@ -374,6 +380,21 @@ static frontend *new_window(HINSTANCE inst)
SetMenu(fe->hwnd, bar); 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); hdc = GetDC(fe->hwnd);
fe->bitmap = CreateCompatibleBitmap(hdc, x, y); fe->bitmap = CreateCompatibleBitmap(hdc, x, y);
ReleaseDC(fe->hwnd, hdc); ReleaseDC(fe->hwnd, hdc);
@ -424,7 +445,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
int p = ((wParam &~ 0xF) - IDM_PRESETS) / 0x10; int p = ((wParam &~ 0xF) - IDM_PRESETS) / 0x10;
if (p >= 0 && p < fe->npresets) { if (p >= 0 && p < fe->npresets) {
RECT r; RECT r, sr;
HDC hdc; HDC hdc;
int x, y; int x, y;
@ -440,9 +461,18 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
WS_OVERLAPPED), WS_OVERLAPPED),
TRUE, 0); 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, 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); SWP_NOMOVE | SWP_NOZORDER);
if (fe->statusbar != NULL)
SetWindowPos(fe->statusbar, NULL, 0, y, x,
sr.bottom - sr.top, SWP_NOZORDER);
DeleteObject(fe->bitmap); DeleteObject(fe->bitmap);
@ -572,6 +602,8 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
srand(time(NULL)); srand(time(NULL));
InitCommonControls();
if (!prev) { if (!prev) {
WNDCLASS wndclass; WNDCLASS wndclass;