home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
125.lha
/
MenuText
/
menutext.c
< prev
next >
Wrap
C/C++ Source or Header
|
1986-11-20
|
8KB
|
241 lines
/*
* This program will create new text for a specified menu item.
* The new text will reside in a node linked on to the UserData
* field of the window it resides in.
*
* Problem: the new text will never be de-allocated unless by
* this program (ie it stays around and waits for the window to
* close). Or by another program that looks at the window->UserData
* field. Use the RESTORE program I've included with this one to
* unlink the new menuitems before closing the window.
*
* ((c)) 1987, John Russell. Unlimited distribution, but donations to
* starving programmers welcome.
*
*/
#include "intuition/intuition.h"
#include "stdio.h"
#include "exec/memory.h"
char *name = "John Russell";
char *address = "5 Alderdice Place";
char *province = "St. John's, Newfoundland, Canada";
char *postal_code = "A1B 2P8";
char *phone = "(709) 726-7847";
void copy();
char *gets(); /* I couldn't seem to get this to "clip" properly */
struct IntuitionBase *IntuitionBase;
struct node {
struct node *next; /* link to next node */
char text[46]; /* buffer for menu text */
char *old_text; /* save location for program's pointer */
short old_item_width; /* save location for hitbox width */
struct MenuItem *altered; /* pointer to menuitem we alter */
} *node,*ptr,*findnode();
main(argc, argv)
int argc;
char *argv[];
{
struct Window *window;
struct Screen *screen;
struct MenuItem *item;
struct Menu *menu,*main_menu;
int x,text;
short width;
char line_buf[100]; /* buffer for gets() to handle too-long strings */
text = argc-1; /* *argv[text] == text to assign */
if ((IntuitionBase=(struct IntuitionBase *)
OpenLibrary("intuition.library",0L))==NULL) {
puts("Where is Intuition gone???\n");
exit(0);
}
/* print instructions if wrong number of arguments */
if ((argc > 6) || (argc < 5)) {
puts("Usage: menutext <window> <menunum> <itemnum>\n\
[ <subitemnum> ] <new_text | \"-ask\">");
puts("\nEG - menutext FooBar 1 4 testing\n\
menutext VT100 2 1 3 high_speed\n\
menutext Notepad 1 1 -ask");
exit(0);
}
Forbid();
screen = IntuitionBase->FirstScreen; /* address of Workbench screen structure */
while (screen) { /* do all screens */
window = screen->FirstWindow;
while (window) { /* do all windows */
if (compare(argv[1],window->Title)==0) { /* search for name */
x=atoi(argv[2]); /* menu # */
menu = window->MenuStrip;
main_menu = menu; /* main menu of window for SetMenuStrip */
while (--x > 0) { /* scan menu list */
if ((menu = menu->NextMenu) == NULL)
goto quit;
}
x = atoi(argv[3]); /* item # */
item = menu->FirstItem;
submenu:
while (--x > 0) { /* scan item list */
if ((item = item->NextItem) == NULL)
goto quit;
}
if (argc==6) { /* descend into sub-menu? */
argc=0;
item=item->SubItem;
x=atoi(argv[4]); /* sub-item # */
goto submenu;
}
ClearMenuStrip(window); /* disable menu structure */
/*
* First check to see if this menu item has already been redefined, by
* scanning the list from window->UserData. If it has, do no node creation
* or re-linking, just copy the text over the node's old text.
*
* If this is the first time the menu item has received new text, create
* a new node, record which menu item is being altered, and preserve a
* pointer to the original text used by the program, so we can undo all
* of this later. Also record how wide the original hitbox was for future
* reference.
*
* A new hitbox width is created if a new, longer string is put into the
* menu. If a keyboard shortcut exists for that item, the hitbox is widened
* to take that into account.
*
*/
if ( (node = findnode(window,item)) == NULL) {
node = (struct node *)
AllocMem(sizeof(struct node),MEMF_CHIP|MEMF_CLEAR);
node->next = window->UserData; /* insert in first place */
window->UserData = node; /* link into window structure */
node->altered = item;
node->old_text = item->ItemFill->IText; /* save old text */
node->old_item_width = item->Width; /* save old width */
item->ItemFill->IText = node->text; /* change menu itself */
}
if (compare(argv[text],"-ask")) {
copy(argv[text],node->text); /* special strncpy() */
}
else {
printf("Enter new menu text: ");
gets(line_buf,45); /* "45" ignored? seems that way */
copy(line_buf,node->text);
}
/* alter width if necessary, so you don't have long menutexts with very */
/* short complemented or boxed areas. font-size is fixed at 8 because */
/* the "TextAttr" structure is not in the Intuition manual, and the RKM */
/* is not handy. */
width = ((length(node->text)) * 8) +
(item->Flags & COMMSEQ ? COMMWIDTH : 0);
if (width > node->old_item_width) {
item->Width = width; /* don't shorten, just lengthen */
}
/* debugging info left in. This program, although it works fine, can be */
/* (and will be) revised extensively. */
ptr = window->UserData;
printf("Replacing menutext \"%s\" with \"%s\"\n\n",
node->old_text,node->text);
printf("Current changed definitions:\n");
while (ptr) {
printf("\tOld text: %s\n\tNew text: %s\n\n",
ptr->old_text,ptr->text);
ptr = ptr->next;
}
SetMenuStrip(window,main_menu); /* give it back */
}
window = window->NextWindow;
}
screen = screen->NextScreen;
}
quit:
Permit();
CloseLibrary(IntuitionBase);
}
compare(string1,string2) /* if spaces in windowname, only check first word */
char *string1,*string2;
{
while ((*string1 != '\0') && (*string1 != ' ')) {
if (*string1++ != *string2++) /* space and null both end conditions */
return(1);
}
return(0); /* return weird values like strcmp() */
}
void copy(string1,string2) /* modified strncpy */
char *string1,*string2;
{
int count = 44; /* (44 + space + null) will fill available buffer */
while ((*string1 != '\0') && count) {
*string2++ = *string1++;
count--;
}
*string2++ = ' '; /* always end string with space + null */
*string2++ = '\0'; /* otherwise menus with shortcuts are messy */
}
struct node *findnode(window,item) /* does item already have attached node? */
struct Window *window;
struct MenuItem *item;
{
struct node *ptr;
ptr = window->UserData;
while (ptr) {
if (ptr->altered == item) /* if desired item already redefined */
return(ptr); /* this is the node to use */
ptr = ptr->next;
}
return(NULL); /* search failed, send message to create and link node */
}
length(string) /* I hate (and don't really trust) std C string functions */
char *string;
{
int x=0;
while (*string++)
x++;
return(x);
}