1 #include <string.h>
2 #include <X11/Xlib.h>
3 #include <X11/Xutil.h>
4 #include "handwave.h"
5 #include "spelllist.h"
6 #include "xspell.h"
7
8 #define BBOX_X (32)
9 #define BBOX_Y (576)
10 #define BBOX_W (2)
11 #define BBOX_H (1)
12
13 #define BUTTON_W (150)
14 #define BUTTON_H (32)
15 #define BUTTON_CORNER (3)
16 #define BUTTON_SPACE (4)
17
18 void draw_button();
19
DrawStringCentered(py,str,xpos,ypos)20 void DrawStringCentered(py, str, xpos, ypos)
21 struct player *py;
22 char *str;
23 int xpos, ypos;
24 {
25 static XCharStruct overall;
26 int direction, ascent, descent;
27 int len = strlen(str);
28
29 XTextExtents(py->font, str, len, &direction, &ascent, &descent, &overall);
30 XDrawImageString(py->dpy, py->win, py->blackgc, xpos-(overall.width)/2, ypos, str, len);
31
32 }
33
34 /* list NUMSPELLS-1 spells (skip SP__STAB) */
draw_spelllist(py)35 void draw_spelllist(py)
36 struct player *py;
37 {
38 int ix, jx, snum, gx, val, pos;
39 int tablehgt;
40 struct spelldef *spel;
41 char *cx;
42
43 #define SL_COLUMNS (2)
44 int posx = py->spelllist_rect.x+16;
45 int posy = py->spelllist_rect.y+32;
46
47 draw_frame(py, &py->spelllist_rect);
48
49 if (py->spelllist_way==1)
50 cx = "Spell List (left button: sorted by gesture)";
51 else if (py->spelllist_way==2)
52 cx = "Spell List (middle button: alphabetical sort)";
53 else
54 cx = "Spell List (right button: reversed sort by gesture)";
55
56 DrawStringCentered(py, cx, py->spelllist_rect.x+py->spelllist_rect.w/2,
57 py->spelllist_rect.y+4+py->lineheight);
58
59 tablehgt = (NUMSPELLS-1+SL_COLUMNS-1) / SL_COLUMNS;
60 for (ix=0; ix<SL_COLUMNS; ix++)
61 for (jx=0; jx<tablehgt; jx++) {
62 if (py->spelllist_way==1)
63 snum = ix*tablehgt+jx;
64 else if (py->spelllist_way==2)
65 snum = alphabet_sort_list[ix*tablehgt+jx];
66 else
67 snum = reverse_sort_list[ix*tablehgt+jx];
68 if (snum >= NUMSPELLS-1)
69 break;
70 spel = &(spelllist[snum]);
71 for (gx=0; gx<spel->length; gx++) {
72 val = spel->gests[gx];
73 pos = ((py->spelllist_way==3) ? (gx+(8-spel->length))*(GEST_SMALL+1)-8 :
74 gx*(GEST_SMALL+1));
75 /*spel->length-gx-1 for reversed gestures*/
76 XCopyPlane(py->dpy, py->spelllistbm [(val&Gesture_DOUBLE)?1:0]
77 [(val&(~Gesture_DOUBLE))-1], py->win, py->blackgc,
78 0, 0, GEST_SMALL, GEST_SMALL, posx+ix*300+pos,
79 posy+jx*18, 1);
80 }
81 if (py->spelllist_way!=3)
82 for (gx = spel->length; gx<8; gx++) {
83 pos = gx*(GEST_SMALL+1);
84 XCopyPlane(py->dpy, py->spelllistbm[0][6], py->win, py->blackgc,
85 0, 0, GEST_SMALL, GEST_SMALL, posx+ix*300+pos,
86 posy+jx*18, 1);
87 }
88 XDrawImageString(py->dpy, py->win, py->blackgc, posx+ix*300+8*(GEST_SMALL+1),
89 posy+jx*18+((GEST_SMALL+py->lineheight)/2)-2, spel->name,
90 strlen(spel->name));
91 }
92 }
93
light_button(py,bnum)94 static void light_button(py, bnum)
95 struct player *py;
96 int bnum;
97 {
98 int hitx, hity;
99
100 if (py->button_lit != (-1)) {
101 hitx = py->button_lit % BBOX_W;
102 hity = py->button_lit / BBOX_W;
103 XDrawRectangle(py->dpy, py->win, py->whitegc, BBOX_X+hitx*BUTTON_W-1,
104 BBOX_Y+hity*BUTTON_H-1, BUTTON_W-BUTTON_SPACE+2,
105 BUTTON_H-BUTTON_SPACE+2);
106 }
107
108 py->button_lit = bnum;
109 if (py->button_lit != (-1)) {
110 hitx = py->button_lit % BBOX_W;
111 hity = py->button_lit / BBOX_W;
112 XDrawRectangle(py->dpy, py->win, py->blackgc, BBOX_X+hitx*BUTTON_W-1,
113 BBOX_Y+hity*BUTTON_H-1, BUTTON_W-BUTTON_SPACE+2,
114 BUTTON_H-BUTTON_SPACE+2);
115 }
116 }
117
redraw_buttons(py)118 void redraw_buttons(py)
119 struct player *py;
120 {
121 int bnum;
122
123 for (bnum=0; bnum<BBOX_W*BBOX_H; bnum++) {
124 draw_button(py, bnum, 0);
125 }
126 light_button(py, py->button_lit);
127 }
128
draw_button(py,bnum,mode)129 void draw_button(py, bnum, mode)
130 struct player *py;
131 int bnum;
132 int mode; /* 0 for all, 1 for clear interior and relabel */
133 {
134 int ix, jx;
135 char *cx;
136
137 static XPoint plist[9] = {
138 {0+BUTTON_CORNER, 0},
139 {BUTTON_W-BUTTON_SPACE-2*BUTTON_CORNER, 0},
140 {BUTTON_CORNER, BUTTON_CORNER},
141 {0, BUTTON_H-BUTTON_SPACE-2*BUTTON_CORNER},
142 {-BUTTON_CORNER, BUTTON_CORNER},
143 {-(BUTTON_W-BUTTON_SPACE-2*BUTTON_CORNER), 0},
144 {-BUTTON_CORNER, -BUTTON_CORNER},
145 {0, -(BUTTON_H-BUTTON_SPACE-2*BUTTON_CORNER)},
146 {BUTTON_CORNER, -BUTTON_CORNER},
147 };
148
149 ix = bnum % BBOX_W;
150 jx = bnum / BBOX_W;
151
152 if (mode==0) {
153 plist[0].x = BBOX_X + ix*BUTTON_W + BUTTON_CORNER;
154 plist[0].y = BBOX_Y + jx*BUTTON_H;
155 XDrawLines(py->dpy, py->win, py->blackgc, plist, 9, CoordModePrevious);
156 }
157
158 if (mode==1) {
159 /* clear interior */
160 XClearArea(py->dpy, py->win, BBOX_X + ix*BUTTON_W + BUTTON_CORNER,
161 BBOX_Y + jx*BUTTON_H + BUTTON_CORNER,
162 BUTTON_W-BUTTON_SPACE-2*BUTTON_CORNER,
163 BUTTON_H-BUTTON_SPACE-2*BUTTON_CORNER, 0);
164 }
165
166 switch (bnum) {
167 case 0:
168 if (!py->turn_active)
169 cx = "please wait....";
170 else if (turnstate == State_Top) {
171 if (!py->turn_done)
172 cx = "End Move";
173 else
174 cx = "Move ENDED.";
175 }
176 else if (turnstate == State_End) {
177 if (!py->turn_done)
178 cx = "Quit";
179 else
180 cx = "Wait....";
181 }
182 else {
183 if (!py->turn_done)
184 cx = "End Answers";
185 else
186 cx = "Answers ENDED.";
187 }
188 DrawStringCentered(py, cx, BBOX_X+ix*BUTTON_W+BUTTON_W/2,
189 BBOX_Y+jx*BUTTON_H+py->lineheight+1);
190 break;
191 case 1:
192 DrawStringCentered(py, "Spell List", BBOX_X+ix*BUTTON_W+BUTTON_W/2,
193 BBOX_Y+jx*BUTTON_H+py->lineheight+1);
194 break;
195 default:
196 break;
197 }
198
199 }
200
in_bbox_box(py,xpos,ypos)201 int in_bbox_box(py, xpos, ypos)
202 struct player *py;
203 int xpos, ypos;
204 {
205 return (xpos >= BBOX_X
206 && xpos < BBOX_X + BBOX_W*BUTTON_W
207 && ypos >= BBOX_Y
208 && ypos < BBOX_Y + BBOX_H*BUTTON_H);
209 }
210
button_hit(py,xpos,ypos,button)211 int button_hit(py, xpos, ypos, button)
212 struct player *py;
213 int xpos, ypos;
214 int button;
215 {
216 int hitx, hity, bnum;
217 int ix;
218
219 hitx = (xpos-BBOX_X) / BUTTON_W;
220 hity = (ypos-BBOX_Y) / BUTTON_H;
221
222 if (hitx<0 || hity<0 || hitx>=BBOX_W || hity>=BBOX_H)
223 return ms_None;
224
225 bnum = hitx + hity*BBOX_W;
226
227 switch (bnum) {
228 case 0:
229 if (!py->turn_active)
230 return ms_None;
231 light_button(py, bnum);
232 return ms_DoneBtn;
233 break;
234 case 1:
235 py->spelllist_rect.w = 620;
236 py->spelllist_rect.h = 420;
237 py->spelllist_rect.x = 10;
238 py->spelllist_rect.y = 10;
239 py->spelllist_way = button;
240 backing_store(py, &py->spelllist_rect);
241 draw_spelllist(py);
242 return ms_SpellBtn;
243 break;
244 default:
245 printf("ERROR: unknown button thing!\n");
246 break;
247 }
248 }
249
button_motion(py,xpos,ypos,button)250 int button_motion(py, xpos, ypos, button)
251 struct player *py;
252 int xpos, ypos;
253 int button;
254 {
255 int hitx, hity, bnum;
256
257 switch (py->mousestate) {
258 case ms_DoneBtn:
259 hitx = (xpos-BBOX_X+BUTTON_W) / BUTTON_W - 1;
260 hity = (ypos-BBOX_Y+BUTTON_H) / BUTTON_H - 1;
261 if (hitx==0 && hity==0) {
262 if (py->button_lit!=0)
263 light_button(py, 0);
264 }
265 else {
266 if (py->button_lit!=(-1))
267 light_button(py, (-1));
268 }
269 break;
270 case ms_SpellBtn:
271 default:
272 break;
273 }
274 }
275
button_release(py,xpos,ypos,button)276 int button_release(py, xpos, ypos, button)
277 struct player *py;
278 int xpos, ypos;
279 int button;
280 {
281 int ix, isok;
282
283 switch (py->mousestate) {
284 case ms_DoneBtn:
285 isok = 1;
286 if (turnstate==State_EQueries || turnstate==State_Queries) {
287 for (ix=0; ix<py->siquery.nlines; ix++)
288 if (!py->answers[ix].done) {
289 isok = 0;
290 strcpy(py->answers[ix].ans_str, "<answer?>");
291 /* ### set value to scroll to? */
292 }
293 }
294 if (py->button_lit==0) {
295 if (isok) {
296 py->turn_done = !(py->turn_done);
297 redraw_done_markers(py);
298 }
299 else
300 redraw_queries_only(py, 0);
301 light_button(py, (-1));
302 }
303 draw_button(py, 0, 1);
304 break;
305 case ms_SpellBtn:
306 backing_restore(py);
307 break;
308 default:
309 break;
310 }
311 }
312