3 * creates (and handles) a hierarchical font menu
5 * v. 1.00 (22 August 1993)
7 * © 1993-1998 Straylight
10 /*----- Licensing note ----------------------------------------------------*
12 * This file is part of Straylight's Steel library.
14 * Steel is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2, or (at your option)
19 * Steel is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with Steel. If not, write to the Free Software Foundation,
26 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
45 static BOOL fontMenu__created;
46 static menu fontMenu__menu;
47 static char fontMenu__oldFontPath[256];
48 static BOOL fontMenu__anyFonts;
49 static BOOL fontMenu__includeSystem;
50 static int fontMenu__tick1=-1;
51 static int fontMenu__tick2=-1;
54 * char *fontMenu__fontFamily(char *fontname)
57 * Returns the family name of the given font.
60 * char *fontname == the name of the font.
63 * The family name of the font (i.e. returns "Trinity" for "Trinity.Medium")
64 * as a pointer to a read-only internal static object.
67 static char *fontMenu__fontFamily(char *fontname)
69 char *fontFamily=buffer_find();
71 char c=fontname[index];
72 while (c!='.' && c>31)
74 fontFamily[index++]=c;
77 fontFamily[index]='\0';
82 * char *fontMenu__fontLeaf(char *fontname)
85 * Returns the leafname of the font (i.e. for "Trinity.Bold.Italic", it
86 * returns "Bold.Italic"). If there is no leafname, it returns
90 * char *fontname == the font name
93 * A pointer to the leafname (to an internal static object)
96 static char *fontMenu__fontLeaf(char *fontname)
98 char *fontLeaf=buffer_find();
101 char c=fontname[index];
107 return (msgs_lookup("fontmRF:(Regular)"));
113 c=fontLeaf[outi++]=fontname[index++];
114 fontLeaf[outi-1]='\0';
119 * void fontMenu__handleSubmenu(char *buffer,int *count,menu sub)
122 * Creates one of those submenus for the font menu.
125 * char *buffer == a buffer to store font names
126 * int *count == pointer to the current font count
127 * menu sub == the submenu handle
130 static void fontMenu__handleSubmenu(char *buffer,int *count,menu sub)
134 strcpy(newbuff,buffer);
135 wimpt_noerr(font_list(buffer,count));
138 strcpy(gadbuff,fontMenu__fontFamily(buffer)),
139 *count!=-1 && strcmp(gadbuff,fontMenu__fontFamily(newbuff))==0
142 menu_extend(sub,fontMenu__fontLeaf(buffer));
143 strcpy(newbuff,buffer);
144 wimpt_noerr(font_list(buffer,count));
149 * menu fontMenu_createFontMenu(BOOL includeSystem)
152 * Creates a hierarchical font menu and returns a handle. If the menu is
153 * out-of-date it will be recreated, if not the old handle will be
154 * returned. You must call this before using routines such as
155 * fontMenu_make() (so that the system knows whether you want to use a
156 * menu containing the system font or not). The returned pointer will be
157 * NULL if there are no fonts.
160 * BOOL includeSystem == whether you want to include a 'System font' item
163 * A menu handle for the menu.
166 menu fontMenu_createFontMenu(BOOL includeSystem)
168 char *fontpath=getenv("Font$Path");
170 char currentfont[50];
174 if (fontMenu__includeSystem!=includeSystem && fontMenu__created==TRUE)
176 fontMenu__created=FALSE;
177 menu_dispose(&fontMenu__menu,TRUE);
180 fontMenu__includeSystem=includeSystem;
182 fontMenu__anyFonts=TRUE;
184 fontMenu__anyFonts=FALSE;
185 if (fontMenu__created==TRUE && strcmp(fontpath,fontMenu__oldFontPath)==0)
186 return (fontMenu__menu);
188 if (fontMenu__created==TRUE)
190 strcpy(lastTicked,fontMenu_fontname(fontMenu__tick1,fontMenu__tick2));
191 menu_dispose(&fontMenu__menu,TRUE);
193 if (fontMenu__anyFonts==FALSE)
196 if (includeSystem==FALSE)
198 werr(FALSE,msgs_lookup("fontmNF:No fonts available."));
199 fontMenu__created=FALSE;
204 fontMenu__menu=menu_new
206 msgs_lookup("fontmFT:Fonts"),msgs_lookup("fontmSF:System font")
208 fontMenu__created=TRUE;
209 return (fontMenu__menu);
212 strcpy(fontMenu__oldFontPath,fontpath);
213 wimpt_noerr(font_list(currentfont,&fontCount));
216 fontMenu__menu=menu_new
218 msgs_lookup("fontmFT:Fonts"),msgs_lookup("fontmSF:System font")
220 menu_extend(fontMenu__menu,fontMenu__fontFamily(currentfont));
223 else if (fontCount==-1)
225 werr(FALSE,msgs_lookup("fontmNF:No fonts available."));
226 fontMenu__created=FALSE;
231 fontMenu__menu=menu_new
233 msgs_lookup("fontmFT:Fonts"),fontMenu__fontFamily(currentfont)
241 msgs_lookup("fontmNEM:Not enough memory to create font menu.")
245 while (fontCount!=-1)
249 fontMenu__fontFamily(currentfont),
250 fontMenu__fontLeaf(currentfont)
254 fontMenu__handleSubmenu(currentfont,&fontCount,submenu);
255 menuExt_submenu(fontMenu__menu,subIndex++,submenu);
257 menu_extend(fontMenu__menu,fontMenu__fontFamily(currentfont));
261 if (fontMenu__created)
262 fontMenu_tickGivenName(lastTicked);
264 fontMenu__created=TRUE;
265 return (fontMenu__menu);
269 * menu fontMenu(BOOL includeSystem)
272 * Compatibility. Don't use this function.
275 menu fontMenu(BOOL includeSystem)
277 menu f=fontMenu_createFontMenu(includeSystem);
284 * char *fontMenu_fontname(int item1,int item2)
287 * Returns the font name given by the the menu hit passed. Example code:
294 * char *fontname=fontMenu_fontname(hit[n+1],hit[n+2]);
301 * Type promotion does the rest! If the hits give a silly result, then a
302 * null string (not a null pointer!) is returned.
304 * You should check for the system font yourself (hit[n+1]==1).
307 * int item1 == the item number in the main menu
308 * int item2 == the item number in the submenu
311 * A pointer to a read-only string.
314 char *fontMenu_fontname(int item1,int item2)
317 char *buffer=buffer_find();
319 if (item1==1 && item2==0 && fontMenu__includeSystem==TRUE)
320 return (msgs_lookup("fontmSF:System font"));
329 wimpt_noerr(wimp_decode_menu
331 (wimp_menustr *)menu_syshandle(fontMenu__menu),
335 utils_ctermToNterm(buffer);
336 reg=strstr(buffer,msgs_lookup("fontmRF:(Regular)"));
343 * void fontMenu_submenu(BOOL includeSystem)
346 * Opens a font menu as the submenu of another menu.
349 * BOOL includeSystem == whether we need to include a system font item.
352 void fontMenu_submenu(BOOL includeSystem)
354 wimp_eventstr *e=wimpt_last_event();
355 int x=e->data.msg.data.words[1];
356 int y=e->data.msg.data.words[2];
360 e->e!=wimp_ESENDWANTACK) ||
361 e->data.msg.hdr.action!=wimp_MMENUWARN
364 if (win_anyWindows()==FALSE)
369 msgs_lookup("fontmTMWS:Too many windows - "
370 "%s could not create submenu."),
377 fontMenu(includeSystem);
378 wimpt_noerr(wimp_create_submenu
380 (wimp_menustr *)menu_syshandle(fontMenu__menu),
389 * wimp_menuitem *fontMenu__menuItem(wimp_menustr *m,int item)
392 * Returns a pointer to the menu item given.
395 * wimp_menustr *m == the menu handle
396 * int item == the item number (starting at one)
399 * A pointer to the correct menu item structure.
402 static wimp_menuitem *fontMenu__menuItem(wimp_menustr *m,int item)
404 return ((wimp_menuitem *)(m+1)+item-1);
408 * char *fontMenu__menuText(wimp_menustr *m,int item,char *buffer)
411 * Returns the text of a menu item.
414 * wimp_menustr *m == the menu handle
415 * int item == the item number (1 upwards)
416 * char *buffer == buffer in which to put the string
419 * A pointer to the menu item's text (may or may not be in buffer)
422 static char *fontMenu__menuText(wimp_menustr *m,int item,char *buffer)
426 wimp_menuitem *itm=fontMenu__menuItem(m,item);
427 if (itm->iconflags & wimp_INDIRECT)
429 c=itm->data.indirecttext.buffer[0];
430 for (i=0;i<254 && c>31;i++)
431 c=buffer[i]=itm->data.indirecttext.buffer[i];
437 for (i=0;i<=11 && c>31;i++)
438 c=buffer[i]=itm->data.text[i];
445 * wimp_menustr *fontMenu__submenu(wimp_menustr *m,int item)
448 * Returns the handle of the submenu of a menu item.
451 * wimp_menustr *m == the menu handle
452 * int item == the item number
455 * A pointer to the submenu
458 static wimp_menustr *fontMenu__submenu(wimp_menustr *m,int item)
460 return (fontMenu__menuItem(m,item)->submenu);
464 * void fontMenu_findFont(char *name,int *item1,int *item2)
467 * Finds a font in the font list. Returns the result in two integers,
468 * which are the menu item numbers in the main font menu and the submenu
469 * respectively. -1 is returned as the first item number if the font
473 * char *name == the (case sensitive) name of the font.
474 * int *item1 == where to store the first item number.
475 * int *item2 == where to store the second item number.
478 void fontMenu_findFont(char *name,int *item1,int *item2)
482 wimp_menustr *m=menu_syshandle(fontMenu__menu);
484 char *family=fontMenu__fontFamily(name);
485 char *leaf=fontMenu__fontLeaf(name);
489 strcmp(name,msgs_lookup("fontmSF:System font"))==0 &&
490 fontMenu__includeSystem==TRUE
499 if (strcmp(fontMenu__menuText(m,i,buffer),family)==0)
501 s=fontMenu__submenu(m,i);
505 if (strcmp(fontMenu__menuText(s,j,buffer),leaf)==0)
513 while ((fontMenu__menuItem(s,j-1)->flags&wimp_MLAST)==0);
519 while ((fontMenu__menuItem(m,i-1)->flags&wimp_MLAST)==0);
525 * void fontMenu__tickItem(wimp_menustr *m,item i,BOOL onOrOff)
528 * Ticks a menu item (low-level)
531 * wimp_menustr *m == the menu handle
532 * item i == the menu item
533 * BOOL onOrOff == tick is on or off
536 static void fontMenu__tickItem(wimp_menustr *m,int i,BOOL onOrOff)
539 fontMenu__menuItem(m,i)->flags|=wimp_MTICK;
541 fontMenu__menuItem(m,i)->flags&=~wimp_MTICK;
545 * void fontMenu__doTick(BOOL onOrOff)
548 * Ticks on or off the current font.
551 * BOOL onOrOff == whether we want to tick or untick the font.
554 static void fontMenu__doTick(BOOL onOrOff)
556 wimp_menustr *m=menu_syshandle(fontMenu__menu);
557 if (fontMenu__tick1==1 && fontMenu__tick2==-1)
559 fontMenu__tickItem(m,1,onOrOff);
561 else if (fontMenu__tick1!=-1)
563 fontMenu__tickItem(m,fontMenu__tick1,onOrOff);
566 fontMenu__submenu(m,fontMenu__tick1),
574 * void fontMenu_tick(int item1,int item2)
577 * Ticks the item specified. Only one font may be ticked at a time. If
578 * the menu item specified is silly, no item will be ticked. No range
579 * checking is performed.
582 * int item1 == the item number in the main menu
583 * int item2 == the item number in the submenu
586 void fontMenu_tick(int item1,int item2)
588 fontMenu__doTick(FALSE);
589 fontMenu__tick1=item1;
590 fontMenu__tick2=item2;
591 fontMenu__doTick(TRUE);
595 * void fontMenu_tickGivenName(char *name)
598 * Ticks the item specified by it's name. If the name is silly, no item
602 * char *name == the font name to tick
605 void fontMenu_tickGivenName(char *name)
608 fontMenu_findFont(name,&i1,&i2);
609 fontMenu_tick(i1,i2);