4 * Tearoff menu generating routines
6 * © 1994-1998 Straylight
9 /*----- Licensing note ----------------------------------------------------*
11 * This file is part of Straylight's Steel library.
13 * Steel is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2, or (at your option)
18 * Steel is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with Steel. If not, write to the Free Software Foundation,
25 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
39 /*---------------------------------------------------------------------------
41 The syntax of menu strings is a subset of the system used by the
42 RISC_OSlib menu segment:
44 menu_description ::= <flags> <item> <sep> { <flags> <item> <sep> }
45 flags ::= '!' | '~' | '>' | ' ' | '@'
47 item ::= <a bunch of other characters>[#<Short-cut string>]
49 flags have meanings as follows:
53 '>' item has a menu dbox attached
57 ---------------------------------------------------------------------------*/
59 static BOOL tearoff__parse(tearoff t,char **p,tearoff__item *item,int *y)
68 item->sub=(tearoff)-1;
69 item->subMenuWarning = FALSE;
72 item->subMenu = FALSE;
73 item->subShaded = FALSE;
94 item->subMenuWarning=TRUE;
107 for (eptr=*p;*eptr!=0 && *eptr!='|' && *eptr!=',';eptr++,len++)
108 if (*eptr=='#') hash=len;
109 if (ind=mem_alloc(len+1),!ind)
111 werr(FALSE,msgs_lookup("menuNEM:Not enough memory to construct menu."));
114 itm=(tearoff__item *)(t+1);
116 if (hash) item->keys=ind+hash+1;
117 while (**p!=0 && **p!='|' && **p!=',')
120 if (*ind=='#') *ind=0;
141 static int tearoff__itemCount(char *s)
160 tearoff tearoff_create(char *title,char *items,BOOL tearable,
161 tearoff_selectProc proc, int max, void *handle)
166 int ino=tearoff__itemCount(items);
168 if (t=mem_alloc(sizeof(tearoff__str) + ino*sizeof(tearoff__item)),!t)
170 werr(FALSE,msgs_lookup("Not enough memory to construct menu."));
173 t->menuTitle=malloc(strlen(title)+1);
176 werr(FALSE,msgs_lookup("Not enough memory to construct menu."));
179 strcpy(t->menuTitle,title);
191 t->userHandle=handle;
197 itm=((tearoff__item *)(t+1))-1;
199 if (t->tearoff) y-=tearoff__HEIGHT;
204 werr(TRUE,msgs_lookup("(tearoff_create): Menu item undercount."));
205 if (!tearoff__parse(t,&items,itm,&y))
208 mem_free(t->indirected);
214 werr(TRUE,msgs_lookup("(tearoff_create): Menu item overcount."));
215 if (ino!=t->numberOfItems)
216 werr(TRUE,msgs_lookup("(tearoff_create): Menu item count mismatch."));
220 void tearoff_attachSubMenu(tearoff to,int itm,tearoff sub)
224 if (to->numberOfItems < itm)
226 werr(TRUE,"(tearoff_attachSubMenu): Item does not exist");
229 item = (tearoff__item *)(to+1);
232 item->subMenu = TRUE;
235 void tearoff_destroy(tearoff t)
241 i=(tearoff__item *)(t+1);
242 for (c=1;c<=t->numberOfItems;c++,i++)
244 mem_free(t->menuTitle);
248 void tearoff_selectItem(tearoff t, int item, tearoff_selectType type)
254 BOOL riscos3=(wimpt_getVersion()>=300);
256 i = (tearoff__item *)(t + 1);
258 if (i->selType == type) return;
261 if (t->open && !t->folded)
268 wimp_update_wind(&r,&more);
276 icon.flags=wimp_IVCENTRE |
282 if (i->shaded) icon.flags |= wimp_INOSELECT;
283 if (!riscos3 && i->selType == tearoff_TICKED)
285 icon.flags |= wimp_ITEXT;
286 strcpy(icon.data.text, "\x80");
288 if (riscos3 && i->selType == tearoff_TICKED)
290 icon.flags |= wimp_ISPRITE | wimp_INDIRECT;
291 icon.data.indirectsprite.name = "\x80";
292 icon.data.indirectsprite.spritearea = (sprite_area *)1;
293 icon.data.indirectsprite.nameisname = 4;
295 if (i->selType == tearoff_RADIOED)
297 icon.flags |= wimp_ITEXT;
298 strcpy(icon.data.text, "\x8F");
300 if (i->selType == tearoff_NONE)
302 icon.flags |= wimp_ITEXT;
303 strcpy(icon.data.text, "");
305 wimpt_noerr(wimp_ploticon(&icon));
307 wimp_get_rectangle(&r,&more);
312 void tearoff_shadeItem(tearoff t, int item, BOOL shaded)
318 i = (tearoff__item *)(t + 1);
320 if (i->shaded == shaded) return;
323 if (t->open && !t->folded)
325 if (t->selected==item)
327 /* Close menu structure here */
336 wimp_update_wind(&r,&more);
339 tearoff__doRedraw(t, &r);
340 wimp_get_rectangle(&r,&more);
345 void tearoff_changeItemText(tearoff t,int item,char *text)
349 int len=0,hash=0,oldWidth;
351 i=(tearoff__item *)(t+1);
355 i->text=i->keys=NULL;
356 for (eptr=text;*eptr!=0;eptr++,len++)
357 if (*eptr=='#') hash=len;
358 if (ind=mem_alloc(len+1),!ind)
360 werr(FALSE,msgs_lookup("menuNEM:Not enough memory to construct menu."));
364 if (hash) i->keys=ind+hash+1;
368 if (*ind=='#') *ind=0;
376 tearoff_calculateMenuWidth(t);
377 if (oldWidth!=t->width)
378 tearoff_rebuildMenu(t);
382 tearoff_highlightItem(t->selected,t,FALSE);
384 tearoff_highlightItem(item,t,FALSE);
390 void tearoff_changeTitle(tearoff t,char *title)
393 mem_free(t->menuTitle);
395 t->menuTitle=mem_alloc(strlen(title)+1);
398 strcpy(t->menuTitle,title);
402 tearoff_calculateMenuWidth(t);
403 if (t->width!=oldWidth)
404 tearoff_rebuildMenu(t);
406 win_settitle(t->w,title);
410 tearoff tearoff_extendMenu(tearoff t,char *items)
413 int ino=tearoff__itemCount(items),i,y;
417 if (t=mem_reAlloc(t, sizeof(tearoff__str) +
418 (ino+t->numberOfItems)*sizeof(tearoff__item)),!t)
420 werr(FALSE,msgs_lookup("Not enough memory to construct menu."));
423 itm=((tearoff__item *)(t+1));
424 itm+=(t->numberOfItems-1);
426 if (itm->dotted) y-=24;
431 werr(TRUE,msgs_lookup("(tearoff_create): Menu item undercount."));
432 if (!tearoff__parse(t,&items,itm,&y))
438 BOOL tearoff_isShaded(tearoff t,int item)
442 i=(tearoff__item *)(t+1);
448 tearoff_selectType tearoff_howSelected(tearoff t,int item)
452 i=(tearoff__item *)(t+1);