aboutsummaryrefslogtreecommitdiff
path: root/windows.c
diff options
context:
space:
mode:
authorSimon Tatham <anakin@pobox.com>2004-04-28 12:07:15 +0000
committerSimon Tatham <anakin@pobox.com>2004-04-28 12:07:15 +0000
commit3d8e7585b7a9d215e4b40d9f83f7fa5a0fd79b43 (patch)
treebcbe1187a4bedd34122a5a65366c2dbfe2e8641b /windows.c
parent03e486268314c77a0180c7c2c4fbe2bb74c1a553 (diff)
downloadpuzzles-3d8e7585b7a9d215e4b40d9f83f7fa5a0fd79b43.zip
puzzles-3d8e7585b7a9d215e4b40d9f83f7fa5a0fd79b43.tar.gz
puzzles-3d8e7585b7a9d215e4b40d9f83f7fa5a0fd79b43.tar.bz2
puzzles-3d8e7585b7a9d215e4b40d9f83f7fa5a0fd79b43.tar.xz
Add a menu bar, in both Windows and GTK. In particular, game modules
are now expected to provide a list of `presets' (game_params plus a name) which are selectable from the menu. This means I can play both Octahedron and Cube without recompiling in between :-) While I'm here, also enabled a Cygwin makefile, which Just Worked. [originally from svn r4158]
Diffstat (limited to 'windows.c')
-rw-r--r--windows.c112
1 files changed, 109 insertions, 3 deletions
diff --git a/windows.c b/windows.c
index 1fda71b..618d440 100644
--- a/windows.c
+++ b/windows.c
@@ -11,6 +11,13 @@
#include "puzzles.h"
+#define IDM_NEW 0x0010
+#define IDM_RESTART 0x0020
+#define IDM_UNDO 0x0030
+#define IDM_REDO 0x0040
+#define IDM_QUIT 0x0050
+#define IDM_PRESETS 0x0100
+
struct frontend {
midend_data *me;
HWND hwnd;
@@ -20,6 +27,8 @@ struct frontend {
HBRUSH *brushes;
HPEN *pens;
UINT timer;
+ int npresets;
+ game_params **presets;
};
void fatal(char *fmt, ...)
@@ -178,7 +187,7 @@ static frontend *new_window(HINSTANCE inst)
r.bottom = y;
AdjustWindowRectEx(&r, WS_OVERLAPPEDWINDOW &~
(WS_THICKFRAME | WS_MAXIMIZEBOX | WS_OVERLAPPED),
- FALSE, 0);
+ TRUE, 0);
fe->hwnd = CreateWindowEx(0, "puzzle", "puzzle",
WS_OVERLAPPEDWINDOW &~
@@ -187,6 +196,44 @@ static frontend *new_window(HINSTANCE inst)
r.right - r.left, r.bottom - r.top,
NULL, NULL, inst, NULL);
+ {
+ HMENU bar = CreateMenu();
+ HMENU menu = CreateMenu();
+
+ AppendMenu(bar, MF_ENABLED|MF_POPUP, (UINT)menu, "Game");
+ AppendMenu(menu, MF_ENABLED, IDM_NEW, "New");
+ AppendMenu(menu, MF_ENABLED, IDM_RESTART, "Restart");
+
+ if ((fe->npresets = midend_num_presets(fe->me)) > 0) {
+ HMENU sub = CreateMenu();
+ int i;
+
+ AppendMenu(menu, MF_ENABLED|MF_POPUP, (UINT)sub, "Type");
+
+ fe->presets = snewn(fe->npresets, game_params *);
+
+ for (i = 0; i < fe->npresets; i++) {
+ char *name;
+
+ midend_fetch_preset(fe->me, i, &name, &fe->presets[i]);
+
+ /*
+ * FIXME: we ought to go through and do something
+ * with ampersands here.
+ */
+
+ AppendMenu(sub, MF_ENABLED, IDM_PRESETS + 0x10 * i, name);
+ }
+ }
+
+ AppendMenu(menu, MF_SEPARATOR, 0, 0);
+ AppendMenu(menu, MF_ENABLED, IDM_UNDO, "Undo");
+ AppendMenu(menu, MF_ENABLED, IDM_REDO, "Redo");
+ AppendMenu(menu, MF_SEPARATOR, 0, 0);
+ AppendMenu(menu, MF_ENABLED, IDM_QUIT, "Exit");
+ SetMenu(fe->hwnd, bar);
+ }
+
hdc = GetDC(fe->hwnd);
fe->bitmap = CreateCompatibleBitmap(hdc, x, y);
ReleaseDC(fe->hwnd, hdc);
@@ -210,6 +257,65 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
case WM_CLOSE:
DestroyWindow(hwnd);
return 0;
+ case WM_COMMAND:
+ switch (wParam & ~0xF) { /* low 4 bits reserved to Windows */
+ case IDM_NEW:
+ if (!midend_process_key(fe->me, 0, 0, 'n'))
+ PostQuitMessage(0);
+ break;
+ case IDM_RESTART:
+ if (!midend_process_key(fe->me, 0, 0, 'r'))
+ PostQuitMessage(0);
+ break;
+ case IDM_UNDO:
+ if (!midend_process_key(fe->me, 0, 0, 'u'))
+ PostQuitMessage(0);
+ break;
+ case IDM_REDO:
+ if (!midend_process_key(fe->me, 0, 0, '\x12'))
+ PostQuitMessage(0);
+ break;
+ case IDM_QUIT:
+ if (!midend_process_key(fe->me, 0, 0, 'q'))
+ PostQuitMessage(0);
+ break;
+ default:
+ {
+ int p = ((wParam &~ 0xF) - IDM_PRESETS) / 0x10;
+
+ if (p >= 0 && p < fe->npresets) {
+ RECT r;
+ HDC hdc;
+ int x, y;
+
+ midend_set_params(fe->me, fe->presets[p]);
+ midend_new_game(fe->me, NULL);
+ midend_size(fe->me, &x, &y);
+
+ r.left = r.top = 0;
+ r.right = x;
+ r.bottom = y;
+ AdjustWindowRectEx(&r, WS_OVERLAPPEDWINDOW &~
+ (WS_THICKFRAME | WS_MAXIMIZEBOX |
+ WS_OVERLAPPED),
+ TRUE, 0);
+
+ SetWindowPos(fe->hwnd, NULL, 0, 0,
+ r.right - r.left, r.bottom - r.top,
+ SWP_NOMOVE | SWP_NOZORDER);
+
+ DeleteObject(fe->bitmap);
+
+ hdc = GetDC(fe->hwnd);
+ fe->bitmap = CreateCompatibleBitmap(hdc, x, y);
+ ReleaseDC(fe->hwnd, hdc);
+
+ midend_redraw(fe->me);
+ }
+ }
+ break;
+ }
+ break;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
@@ -246,7 +352,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
}
if (key != -1) {
- if (!midend_process_key(fe->me, -1, -1, key))
+ if (!midend_process_key(fe->me, 0, 0, key))
PostQuitMessage(0);
}
}
@@ -262,7 +368,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
break;
case WM_CHAR:
- if (!midend_process_key(fe->me, -1, -1, (unsigned char)wParam))
+ if (!midend_process_key(fe->me, 0, 0, (unsigned char)wParam))
PostQuitMessage(0);
return 0;
case WM_TIMER: