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