home *** CD-ROM | disk | FTP | other *** search
- /*
- #### # # # #
- # # # # # The FreeWare C library for
- # # ## ### # # # # ### RISC OS machines
- # # # # # # # # # # # ___________________________________
- # # #### ### ## # # # #
- # # # # # # # # # # Please refer to the accompanying
- #### ### #### # # ##### # ### documentation for conditions of use
- ________________________________________________________________________
-
- File: Menu.NewMenu.c
- Author: Copyright © 1993 Shaun Blackmore and Jason Williams
- Version: 1.00 (30 Apr 1993)
- Purpose: Creates a new menu given a textual description string
- */
-
-
- #include <stdlib.h>
- #include <string.h>
-
- #include "DeskLib:Core.h"
- #include "DeskLib:Error.h"
- #include "DeskLib:Screen.h"
- #include "DeskLib:Wimp.h"
-
-
- /* Description format:
- * opt :- " " no special options (i.e. leading spaces are skipped)
- * "!" ticked
- * "~" shaded
- * ">" has submenu/subwindow
- * "-" dotted
- * name :- any character except "," and "|"
- * entry :- {opt}* name
- * sep :- "," to separate normal items
- * "|" to separate items and place a dotted line between them
- * descr :- entry {sep entry}*
- *
- * EXAMPLE:
- * ">Info, Create, Quit"
- * "!Ticked,~Disabled|>Submenu"
- */
-
-
- extern void Menu__CountItems(char *description, int *numitems, int *menuwidth)
- /* For internal use - counts the number of items in a menu description
- * string, and also returns the widest menu item (in terms of characters)
- */
- {
- char *s;
- int width = 0, maxwidth = 0, count = 0;
- BOOL in_option = TRUE;
-
- for (s = description; *s; s++)
- {
- if (*s == ',' || *s == '|')
- {
- if (width > maxwidth)
- maxwidth = width;
- count++;
- width = 0;
- in_option = TRUE;
- }
- else
- {
- if (in_option)
- {
- if(*s != '!' && *s != '>' && *s != '~' && *s != ' ')
- {
- in_option = FALSE;
- width++;
- }
- }
- else
- width++;
- }
- }
-
- *numitems = count + 1; /* Count last item and its width */
-
- if (width > maxwidth)
- maxwidth=width;
-
- *menuwidth = maxwidth + 2; /* Add room for a gap/sublink arrows, etc */
- }
-
-
- extern BOOL Menu__Create(menu_item *item, char *description, int numitems)
- {
- menu_item *it;
- char *s, *t;
- int i, index;
- BOOL foundtext;
-
- s = description;
- for (i = 0; i < numitems; i++)
- {
- it = &item[i];
- it->menuflags.value = 0;
- it->submenu.value = NULL;
- it->iconflags.value = icon_TEXT | icon_FILLED;
- it->iconflags.data.foreground = 7;
-
- foundtext = FALSE;
- do
- {
- switch(*s++)
- {
- case '!':
- it->menuflags.data.ticked = TRUE;
- break;
-
- case '~':
- it->iconflags.data.shaded = TRUE;
- break;
-
- case '>':
- it->menuflags.data.notifysub = TRUE; /* Ask for sublink warnings */
- it->submenu.value = 1; /* This is sublink item '1' */
- break;
-
- case ' ': /* No option */
- break;
-
- default: /* Any other == start of menu item text, so don't lose it */
- s--;
- foundtext = TRUE;
- break;
- }
- } while (!foundtext);
-
- t = s;
- for (index = 0; ; index++)
- if (t[index] == 0 || t[index] == '|' || t[index] == ',')
- break;
-
- if (index <= wimp_MAXNAME)
- t = it->icondata.text; /* Copy text directly into menu item */
- else
- {
- /* Copy text into indirected menu item */
- it->iconflags.data.indirected = TRUE;
- it->icondata.indirecttext.buffer = malloc(index + 1);
- if (it->icondata.indirecttext.buffer == NULL)
- return(Error_OutOfMemory(FALSE, "menus"));
-
- it->icondata.indirecttext.bufflen = index + 1;
- it->icondata.indirecttext.validstring = (char *) -1;
-
- t = it->icondata.indirecttext.buffer;
- }
-
- while (*s != 0 && *s != ',' && *s != '|')
- *t++ = *s++;
-
- *t = 0;
- if (*s++ == '|') /* Step over separator... */
- it->menuflags.data.dotted = TRUE; /* ...setting 'dotted' if needed */
- }
-
- return(TRUE);
- }
-
-
-
- extern menu_ptr Menu_New(char *title, char *description)
- {
- menu_ptr menu;
- menu_item *item;
- int numitems, maxwidth;
-
- Menu__CountItems(description, &numitems, &maxwidth);
-
- if (strlen(title) > maxwidth) /* Make sure it is wide enough for title */
- maxwidth = strlen(title);
-
- menu = (menu_ptr) malloc(sizeof(menu_block) + (numitems * sizeof(menu_item)));
-
- if (menu == NULL)
- return((menu_ptr) Error_OutOfMemory(FALSE, "menus"));
-
- item = (menu_item *) &(menu[1]);
-
- /* Copy the string. If it's less than 12 characters we need it to be
- * zero-terminated. We can let it go to 12 chars without any terminator
- * though, so we don't need to bother terminating after the strncpy.
- */
- strncpy(menu->title, title, wimp_MAXNAME);
-
- menu->titlefore = 7;
- menu->titleback = 2;
- menu->workfore = 7;
- menu->workback = 0;
- menu->width = maxwidth * 8 * screen_delta.x;
- menu->height = 44;
- menu->gap = 0;
-
- if (!Menu__Create(item, description, numitems))
- return((menu_ptr) NULL);
- item[numitems - 1].menuflags.data.last = TRUE;
-
- return(menu);
- }
-
-