separate wait functions to make it easier to override in arch specific code
[AROS.git] / workbench / demos / gtmultiselect.c
blob1dc2d76dd8b54b2293a4a2a124f14a51da646b9f
1 #include <intuition/intuition.h>
2 #include <libraries/gadtools.h>
3 #include <graphics/gfx.h>
4 #include <graphics/gfxmacros.h>
5 #include <aros/asmcall.h>
6 #include <proto/exec.h>
7 #include <proto/intuition.h>
8 #include <proto/graphics.h>
9 #include <proto/gadtools.h>
10 #include <proto/alib.h>
12 #include <stdio.h>
13 #include <string.h>
14 #include <stdlib.h>
15 #include <ctype.h>
17 #define SHOW_CHECKMARK 1
18 #define SHOW_SELECTFILL 0
20 #define WINWIDTH 200
21 #define WINHEIGHT 200
22 #define LVENTRIES 40
24 struct IntuitionBase *IntuitionBase;
25 struct GfxBase *GfxBase;
26 struct Library *GadToolsBase;
27 struct Screen *scr;
28 struct DrawInfo *dri;
29 APTR vi;
30 struct Window *win;
31 struct Gadget *gadlist, *gad, *lvgad;
32 struct RastPort *rp;
33 struct Node lvnode[LVENTRIES];
34 struct List lvlist;
35 struct Hook myrenderhook;
36 WORD greenpen = -1;
38 #define IS_SELECTED(node) (node->ln_Pri == 1)
39 #define DO_SELECT(node) node->ln_Pri = 1
40 #define DO_UNSELECT(node) node->ln_Pri = 0
42 static void cleanup(char *msg)
44 if(msg) printf("gtmultiselect: %s\n", msg);
46 if (win) CloseWindow(win);
47 if (gadlist) FreeGadgets(gadlist);
49 if (greenpen != -1) ReleasePen(scr->ViewPort.ColorMap, greenpen);
51 if (vi) FreeVisualInfo(vi);
52 if (dri) FreeScreenDrawInfo(scr, dri);
53 if (scr) UnlockPubScreen(0, scr);
55 if (GadToolsBase) CloseLibrary(GadToolsBase);
56 if (GfxBase) CloseLibrary((struct Library *)GfxBase);
57 if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
59 exit(0);
62 static void openlibs(void)
64 if (!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 39)))
66 cleanup("Can't open intuition.library!");
69 if (!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 39)))
71 cleanup("Can't open graphics.library!");
74 if (!(GadToolsBase = OpenLibrary("gadtools.library", 39)))
76 cleanup("Can't open gadtools.library!");
80 static void getvisual(void)
82 if (!(scr = LockPubScreen(0))) cleanup("Can't lock pub screen!");
83 if (!(dri = GetScreenDrawInfo(scr))) cleanup("Can't get drawinfo!");
84 if (!(vi = GetVisualInfoA(scr, NULL))) cleanup("Can' get visualinfo!");
86 greenpen = ObtainBestPen(scr->ViewPort.ColorMap, 0, 0x76767676, 0, OBP_FailIfBad, FALSE, TAG_DONE);
90 AROS_UFH3(IPTR, MyRenderFunc,
91 AROS_UFHA(struct Hook *, hook, A0),
92 AROS_UFHA(struct Node *, node, A2),
93 AROS_UFHA(struct LVDrawMsg *, msg, A1)
96 AROS_USERFUNC_INIT
98 IPTR retval;
100 if (msg->lvdm_MethodID == LV_DRAW)
102 struct DrawInfo *dri = msg->lvdm_DrawInfo;
103 struct RastPort *rp = msg->lvdm_RastPort;
104 struct TextExtent te;
105 WORD numfit;
107 WORD min_x = msg->lvdm_Bounds.MinX;
108 WORD min_y = msg->lvdm_Bounds.MinY;
109 WORD max_x = msg->lvdm_Bounds.MaxX;
110 WORD max_y = msg->lvdm_Bounds.MaxY;
111 WORD width, height;
113 UWORD erasepen;
115 if (msg->lvdm_State == LVR_SELECTED)
117 if (IS_SELECTED(node))
119 DO_UNSELECT(node);
121 else
123 DO_SELECT(node);
127 #if SHOW_SELECTFILL
128 erasepen = IS_SELECTED(node) ? FILLPEN : BACKGROUNDPEN;
129 #else
130 erasepen = BACKGROUNDPEN;
131 #endif
133 SetDrMd(rp, JAM1);
135 SetAPen(rp, dri->dri_Pens[erasepen]);
136 RectFill(rp, min_x, min_y, max_x, max_y);
138 #if SHOW_CHECKMARK
139 numfit = TextFit(rp, node->ln_Name, strlen(node->ln_Name),
140 &te, NULL, 1, max_x - min_x + 1 - 16, max_y - min_y + 1);
141 #else
142 numfit = TextFit(rp, node->ln_Name, strlen(node->ln_Name),
143 &te, NULL, 1, max_x - min_x + 1, max_y - min_y + 1);
144 #endif
146 SetAPen(rp, dri->dri_Pens[TEXTPEN]);
148 /* Render text */
149 #if SHOW_CHECKMARK
150 Move(rp, min_x + 16, min_y + rp->Font->tf_Baseline);
151 #else
152 Move(rp, min_x, min_y + rp->Font->tf_Baseline);
153 #endif
154 Text(rp, node->ln_Name, numfit);
156 #if SHOW_CHECKMARK
157 if (IS_SELECTED(node))
159 min_y += 1;
160 max_y -= 1;
161 min_x += 1;
162 height = max_y - min_y + 1;
163 width = height;
164 max_x = min_x + width - 1;
166 SetAPen(rp, greenpen);
167 Move(rp, min_x, min_y + height / 3); Draw(rp, min_x, max_y);
168 Move(rp, min_x + 1, min_y + height / 3); Draw(rp, min_x + 1, max_y);
170 SetAPen(rp, dri->dri_Pens[SHADOWPEN]);
171 Move(rp, min_x + 2, min_y + height / 3); Draw(rp, min_x + 2, max_y);
173 SetAPen(rp, greenpen);
174 Move(rp, min_x + 1, max_y); Draw(rp, max_x - 1, min_y);
175 Move(rp, min_x + 2, max_y); Draw(rp, max_x, min_y);
177 SetAPen(rp, dri->dri_Pens[SHADOWPEN]);
178 Move(rp, min_x + 3, max_y); Draw(rp, max_x + 1, min_y);
181 #endif
183 retval = LVCB_OK;
185 else
187 retval = LVCB_UNKNOWN;
190 if (retval != LVCB_OK) {
191 /* FIXME: Should we alert the user or something? */
194 return TRUE;
196 AROS_USERFUNC_EXIT
199 static void makegadgets(void)
201 struct NewGadget ng;
202 WORD i;
204 gad = CreateContext(&gadlist);
206 memset(&ng, 0, sizeof(ng));
208 ng.ng_VisualInfo = vi;
209 ng.ng_LeftEdge = scr->WBorLeft + 4;
210 ng.ng_TopEdge = scr->WBorTop + scr->Font->ta_YSize + 1 + 4;
211 ng.ng_Width = WINWIDTH - scr->WBorRight - scr->WBorLeft - 8;
212 ng.ng_Height = WINHEIGHT - scr->WBorTop - scr->Font->ta_YSize - 1 - scr->WBorBottom - 8;
214 NewList(&lvlist);
215 for(i = 0; i < LVENTRIES; i++)
217 char s[30];
219 sprintf(s, "Item %d", i);
221 lvnode[i].ln_Name = strdup(s);
222 AddTail(&lvlist, &lvnode[i]);
226 struct TagItem lv_tags[] =
228 {GTLV_Labels , (IPTR)&lvlist },
229 {GTLV_CallBack , (IPTR)&myrenderhook },
230 {GTLV_ItemHeight, dri->dri_Font->tf_YSize + 4 },
231 {TAG_DONE }
234 myrenderhook.h_Entry = AROS_ASMSYMNAME(MyRenderFunc);
236 gad = lvgad = CreateGadgetA(LISTVIEW_KIND, gad, &ng, lv_tags);
239 if (!gad) cleanup("Can't create gadgets!");
242 static void makewin(void)
244 win = OpenWindowTags(0, WA_PubScreen, (IPTR)scr,
245 WA_Left, 20,
246 WA_Top, 20,
247 WA_Width, WINWIDTH,
248 WA_Height, WINHEIGHT,
249 WA_Title, (IPTR)"GadTools MultiSelect Listview",
250 WA_CloseGadget, TRUE,
251 WA_DragBar, TRUE,
252 WA_DepthGadget, TRUE,
253 WA_IDCMP, IDCMP_CLOSEWINDOW | LISTVIEWIDCMP,
254 WA_Activate, TRUE,
255 WA_Gadgets, (IPTR)gadlist,
256 TAG_DONE);
259 if (!win) cleanup("Can't create parent window!");
261 GT_RefreshWindow(win, NULL);
264 static void handleall(void)
266 struct IntuiMessage *imsg;
267 BOOL quitme = FALSE;
269 while(!quitme)
271 WaitPort(win->UserPort);
272 while((imsg = GT_GetIMsg(win->UserPort)))
274 switch(imsg->Class)
276 case IDCMP_CLOSEWINDOW:
277 quitme = TRUE;
278 break;
280 GT_ReplyIMsg(imsg);
287 int main(void)
289 openlibs();
290 getvisual();
291 makegadgets();
292 makewin();
293 handleall();
294 cleanup(0);
295 return 0;