Squashed commit of 'x11-hostlib' branch
[tangerine.git] / workbench / demos / register.c
blob3284a32f7e1ee2e72301edf0e9d682671fdb6cf4
1 #include <intuition/intuition.h>
2 #include <graphics/gfx.h>
3 #include <graphics/text.h>
4 #include <proto/exec.h>
5 #include <proto/intuition.h>
6 #include <proto/graphics.h>
8 #include <stdio.h>
9 #include <string.h>
10 #include <stdlib.h>
12 /****************************************************************************************/
14 #define REGISTER_EXTRA_HEIGHT 4
15 #define REGISTERITEM_EXTRA_WIDTH 8
16 #define REGISTER_SPACE_LEFT 8
17 #define REGISTER_SPACE_RIGHT 8
19 struct Register
21 struct RegisterItem *items;
22 struct DrawInfo *dri;
23 WORD numitems;
24 WORD active;
25 WORD left;
26 WORD top;
27 WORD width;
28 WORD height;
29 WORD fontw;
30 WORD fonth;
31 WORD fontb;
32 WORD slopew;
35 struct RegisterItem
37 STRPTR text;
38 WORD textlen;
39 WORD x1, y1, x2, y2, w, h;
40 WORD tx, ty;
43 /****************************************************************************************/
45 struct IntuitionBase *IntuitionBase;
46 struct GfxBase *GfxBase;
48 struct Screen *scr;
49 struct DrawInfo *dri;
50 struct Window *win;
52 /****************************************************************************************/
54 struct RegisterItem myregisteritems[] =
56 {"Timezone"},
57 {"Country"},
58 {"Language"},
59 {"Something"},
60 {"AROS"},
61 {NULL}
63 struct Register myregister;
65 /****************************************************************************************/
67 static void cleanup(char *msg)
69 if (msg) printf("register: %s\n", msg);
71 if (win) CloseWindow(win);
73 if (dri) FreeScreenDrawInfo(scr, dri);
74 if (scr) UnlockPubScreen(NULL, scr);
76 if (GfxBase) CloseLibrary((struct Library *)GfxBase);
77 if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
79 exit (0);
82 /****************************************************************************************/
84 static void openlibs(void)
86 if (!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 39)))
88 cleanup("Can't open intuition.library V39!");
91 if (!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 39)))
93 cleanup("Can't open graphics.library V39!");
97 /****************************************************************************************/
99 static void getvisual(void)
101 scr = LockPubScreen(NULL);
102 if (!scr) cleanup("Can't lock pub screen!");
104 dri = GetScreenDrawInfo(scr);
105 if (!dri) cleanup("Can't get drawinfo!");
109 /****************************************************************************************/
111 static void initregister(struct Register *reg, struct RegisterItem *items)
113 reg->items = items;
114 reg->numitems = 0;
116 while(items->text)
118 reg->numitems++;
119 items++;
123 /****************************************************************************************/
125 static void layoutregister(struct Register *reg, struct Screen *scr,
126 struct DrawInfo *dri, BOOL samewidth)
128 struct RastPort temprp;
129 WORD i, x, biggest_w = 0;
131 InitRastPort(&temprp);
132 SetFont(&temprp, dri->dri_Font);
133 reg->dri = dri;
134 reg->fonth = dri->dri_Font->tf_YSize;
135 reg->fontb = dri->dri_Font->tf_Baseline;
137 reg->height = ((reg->fonth + REGISTER_EXTRA_HEIGHT) + 3) & ~3; /* Multiple of 4 */
138 reg->height += 4;
140 reg->slopew = (reg->height - 4) / 2;
142 for(i = 0; i < reg->numitems; i++)
144 reg->items[i].textlen = strlen(reg->items[i].text);
145 reg->items[i].w = TextLength(&temprp, reg->items[i].text, reg->items[i].textlen);
146 reg->items[i].w += REGISTERITEM_EXTRA_WIDTH + reg->slopew * 2;
148 if (reg->items[i].w > biggest_w) biggest_w = reg->items[i].w;
151 if (samewidth)
153 for(i = 0; i < reg->numitems; i++)
155 reg->items[i].w = biggest_w;
159 x = REGISTER_SPACE_LEFT;
160 for(i = 0; i < reg->numitems; i++)
162 reg->items[i].x1 = x;
163 reg->items[i].y1 = 0;
164 reg->items[i].x2 = x + reg->items[i].w - 1;
165 reg->items[i].y2 = reg->height - 1;
166 reg->items[i].h = reg->items[i].y2 - reg->items[i].y1 + 1;
167 reg->items[i].tx = reg->items[i].w / 2 - TextLength(&temprp, reg->items[i].text, reg->items[i].textlen) / 2;
168 reg->items[i].ty = reg->fontb + reg->items[i].h / 2 - reg->fonth / 2;
170 x += reg->items[i].w - reg->slopew;
173 reg->width = x + reg->slopew + REGISTER_SPACE_RIGHT;
175 DeinitRastPort(&temprp);
178 /****************************************************************************************/
180 static void setregisterpos(struct Register *reg, WORD left, WORD top)
182 reg->left = left;
183 reg->top = top;
186 /****************************************************************************************/
188 static void renderregisteritem(struct RastPort *rp, struct Register *reg, WORD item)
190 struct RegisterItem *ri = &reg->items[item];
191 WORD x, y;
193 SetDrMd(rp, JAM1);
194 SetFont(rp, reg->dri->dri_Font);
196 x = reg->left + ri->x1;
197 y = reg->top + ri->y1;
200 SetAPen(rp, reg->dri->dri_Pens[(reg->active == item) ? TEXTPEN : BACKGROUNDPEN]);
201 Move(rp, x + ri->tx + 1, y + ri->ty);
202 Text(rp, ri->text, ri->textlen);
203 SetAPen(rp, reg->dri->dri_Pens[TEXTPEN]);
204 Move(rp, x + ri->tx, y + ri->ty);
205 Text(rp, ri->text, ri->textlen);
207 /* upper / at left side */
209 SetAPen(rp, reg->dri->dri_Pens[SHINEPEN]);
210 WritePixel(rp, x + reg->slopew, y + 2);
211 Move(rp, x + reg->slopew / 2, y + 3 + reg->slopew - 1);
212 Draw(rp, x + reg->slopew - 1, y + 3);
214 /* --- at top side */
216 RectFill(rp, x + reg->slopew + 1, y + 1, x + reg->slopew + 2, y + 1);
217 RectFill(rp, x + reg->slopew + 3, y, x + ri->w - 1 - reg->slopew - 3, y);
219 SetAPen(rp, reg->dri->dri_Pens[SHADOWPEN]);
220 RectFill(rp, x + ri->w - 1 - reg->slopew - 2, y + 1, x + ri->w - 1 - reg->slopew - 1, y + 1);
222 /* upper \ at right side */
224 WritePixel(rp, x + ri->w - 1 - reg->slopew, y + 2);
225 Move(rp, x + ri->w - 1 - reg->slopew + 1, y + 3);
226 Draw(rp, x + ri->w - 1 - reg->slopew / 2, y + 3 + reg->slopew - 1);
228 /* lower / at left side. */
230 if ((item == 0) || (reg->active == item))
232 SetAPen(rp, reg->dri->dri_Pens[SHINEPEN]);
234 else
236 SetAPen(rp, reg->dri->dri_Pens[BACKGROUNDPEN]);
238 Move(rp, x, y + ri->h - 2);
239 Draw(rp, x + reg->slopew / 2 - 1, y + ri->h - 2 - reg->slopew + 1);
241 /* lower \ at the lefst side from the previous item */
243 if (item > 0)
245 if (reg->active == item)
247 SetAPen(rp, reg->dri->dri_Pens[BACKGROUNDPEN]);
249 else
251 SetAPen(rp, reg->dri->dri_Pens[SHADOWPEN]);
253 Move(rp, x + reg->slopew / 2, y + ri->h - 2 - reg->slopew + 1);
254 Draw(rp, x + reg->slopew - 1, y + ri->h - 2);
257 /* lower \ at right side. */
259 if (reg->active == item + 1)
261 SetAPen(rp, reg->dri->dri_Pens[BACKGROUNDPEN]);
263 else
265 SetAPen(rp, reg->dri->dri_Pens[SHADOWPEN]);
267 Move(rp, x + ri->w - 1 - reg->slopew / 2 + 1, y + ri->h - 2 - reg->slopew + 1);
268 Draw(rp, x + ri->w - 1, y + ri->h - 2);
270 if (reg->active == item)
272 SetAPen(rp, reg->dri->dri_Pens[BACKGROUNDPEN]);
273 RectFill(rp, x, y + ri->h - 1, x + ri->w - 1, y + ri->h - 1);
275 else
277 WORD x1, x2;
279 x1 = x;
280 x2 = x + ri->w - 1;
282 if (reg->active == item - 1)
283 x1 += reg->slopew;
284 else if (reg->active == item + 1)
285 x2 -= reg->slopew;
287 SetAPen(rp, reg->dri->dri_Pens[SHINEPEN]);
288 RectFill(rp, x1, y + ri->h - 1, x2, y + ri->h - 1);
293 #if 0
294 /* \ at left side from previous item */
296 if (item != 0)
298 if (reg->active == item)
300 SetAPen(rp, reg->dri->dri_Pens[BACKGROUNDPEN]);
302 else
304 SetAPen(rp, reg->dri->dri_Pens[SHADOWPEN]);
307 Move(rp, x + reg->slopew / 2, y + ri->h - 2 - reg->slopew + 1);
308 Draw(rp, x + reg->slopew - 1, y + ri->h - 2);
310 #endif
314 /****************************************************************************************/
316 static void renderregister(struct RastPort *rp, struct Register *reg)
318 WORD i;
320 SetDrMd(rp, JAM1);
322 SetAPen(rp, reg->dri->dri_Pens[SHINEPEN]);
324 RectFill(rp, reg->left,
325 reg->top + reg->height - 1,
326 reg->left + REGISTER_SPACE_LEFT - 1,
327 reg->top + reg->height - 1);
329 RectFill(rp, reg->left + reg->width - REGISTER_SPACE_RIGHT,
330 reg->top + reg->height - 1,
331 reg->left + reg->width - 1,
332 reg->top + reg->height - 1);
334 for(i = 0; i < reg->numitems; i++)
336 renderregisteritem(rp, reg, i);
342 /****************************************************************************************/
344 static BOOL handleregisterinput(struct Register *reg, struct IntuiMessage *msg)
346 struct Window *win = msg->IDCMPWindow;
347 BOOL retval = FALSE;
349 if ((msg->Class == IDCMP_MOUSEBUTTONS) &&
350 (msg->Code == SELECTDOWN))
352 WORD i;
353 WORD x = win->MouseX - reg->left;
354 WORD y = win->MouseY - reg->top;
356 for(i = 0; i < reg->numitems; i++)
358 if ((x >= reg->items[i].x1) &&
359 (y >= reg->items[i].y1) &&
360 (x <= reg->items[i].x2) &&
361 (y <= reg->items[i].y2))
363 if (reg->active != i)
365 WORD oldactive = reg->active;
367 reg->active = i;
368 renderregisteritem(win->RPort, reg, oldactive);
369 renderregisteritem(win->RPort, reg, i);
371 break;
376 return retval;
381 /****************************************************************************************/
383 static void makewin(void)
385 win = OpenWindowTags(0, WA_PubScreen, (IPTR)scr,
386 WA_Title, (IPTR) "Register Tabs",
387 WA_InnerWidth, myregister.width + 8,
388 WA_InnerHeight, myregister.height + 8,
389 WA_CloseGadget, TRUE,
390 WA_DepthGadget, TRUE,
391 WA_Activate, TRUE,
392 WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_MOUSEBUTTONS,
393 TAG_DONE);
395 if (!win) cleanup("Can't open window!");
398 /****************************************************************************************/
400 static void handleall(void)
402 struct IntuiMessage *msg;
404 BOOL quitme = FALSE;
406 while(!quitme)
408 WaitPort(win->UserPort);
410 while((msg = (struct IntuiMessage *)GetMsg(win->UserPort)))
412 if (!handleregisterinput(&myregister, msg))
414 switch(msg->Class)
416 case IDCMP_CLOSEWINDOW:
417 quitme = TRUE;
418 break;
421 ReplyMsg((struct Message *)msg);
423 } /* while((msg = (struct IntuiMessage *)GetMsg(win->UserPort))) */
425 } /* while(!quitme) */
428 /****************************************************************************************/
430 int main(void)
432 openlibs();
433 getvisual();
434 initregister(&myregister, myregisteritems);
435 layoutregister(&myregister, scr, dri, TRUE);
436 makewin();
437 setregisterpos(&myregister, win->BorderLeft + 4, win->BorderTop + 4);
438 renderregister(win->RPort, &myregister);
439 handleall();
440 cleanup(0);
441 return 0;
444 /****************************************************************************************/
445 /****************************************************************************************/
446 /****************************************************************************************/
447 /****************************************************************************************/
448 /****************************************************************************************/
449 /****************************************************************************************/