home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Professional
/
OS2PRO194.ISO
/
os2
/
editor
/
me
/
menubar.m
< prev
next >
Wrap
Text File
|
1994-01-31
|
12KB
|
518 lines
/*
MENUBAR
Macro to implement a simple menubar system for interacting with
ME. You can change this so that the menu items invoke any editor
primitive or any user-defined macro. This macro package relies
on ME's feature of calling internal C functions in order to
display the menubar and submenus.
The menubar definiton should be in a file with an .MNU extension.
In this macro, the CTRL-B key is used to bring up the menubar; you
can change this key by altering the assign_key() call in the init()
function here.
The menubar definition must be in the following format :
[optional comment lines]
.....
MENUBAR menu-name [COLOR color]
{
text-of-menubar-item-1
[MENU
{
subpopup1-text [->function-to-call]
......
}]
}
Please note that items enclosed by square brackets are optional. In this
case, the subpopup definition after a menubar item is optional. Also,
the function to invoke after an item is chosed is optional. Look at the
accompanying file MENUBAR.MNU for an actual menubar definition. The
menubar definition starts with first line with the word MENUBAR starting
at column 1.
(C) Copyright 1988 Marc Adler/Magma Systems All Rights Reserved
*/
#define HORIZ 1
#define VERT 2
#define TOP_LEFT 3
#define TOP_RIGHT 4
#define BOT_LEFT 5
#define BOT_RIGHT 6
#define DOWN 208
#define UP 200
#define LEFT 203
#define RIGHT 205
#define MAXMENUBARITEMS 16
string BoxChars[10];
int MenuRow1, MenuCol1, MenuRow2, MenuCol2;
int MenuColor;
string MenuName;
int MenubarBuf;
int MenubarItemBufID;
int debug;
int MenubarWindow;
int MenuBuf[MAXMENUBARITEMS];
string MenuNames[MAXMENUBARITEMS];
int PopupWindow[MAXMENUBARITEMS];
int NumMenus;
string MenubarText;
int CurrMenuItem;
int OriginalFileBufID;
/*
Init() - initialization function - done once when the macro is loaded
*/
init()
{
/* Set up the values for box-drawing characters */
BoxChars[HORIZ] = "═";
BoxChars[VERT] = "║";
BoxChars[TOP_LEFT] = "╔";
BoxChars[TOP_RIGHT] = "╗";
BoxChars[BOT_LEFT] = "╚";
BoxChars[BOT_RIGHT] = "╝";
/* Set the dimensions of the menubar */
MenuRow1 = 1;
MenuCol1 = 0;
MenuRow2 = 3;
MenuCol2 = 79;
/* CTRL-B will invoke the default menubar macro */
assign_key("do_default_menu", 2);
}
do_default_menu()
{
do_menu("menubar");
}
/*
Do_Menu() - driver for reading, parsing, and displaying a menubar. The
passed argument is the root part of the menubar file name.
*/
do_menu(menuname)
string menuname;
{
debug = 0;
menubar_already_here = 0;
OriginalFileBufID = old_buf = currbuf();
/* Open the Menubar definition file if it doesn't exist already. */
if (!index(menuname, ".mnu"))
menuname = strcat(menuname, ".mnu");
if ((MenubarBuf = find_buffer(menuname)) <= 0)
MenubarBuf = create_buffer(menuname);
else
menubar_already_here = 1;
new_buf = setcurrbuf(MenubarBuf);
setcol(1);
vidsetcursor(32, 0);
/* Parse the defn. If there's an error, abort. */
if (!menubar_already_here)
{
if (MenuParse() < 0)
{
delete_buffer(new_buf);
show_buffer(old_buf);
return;
}
}
/* Create a window for the menubar and attach the menubar buffer to it. */
/* This is the ME paradigm for creating popup windows. */
MenubarWindow = create_window(MenuRow1+1,MenuCol1+1,MenuRow2-1,MenuCol2-1,MenuColor);
attach_window(MenubarWindow, new_buf);
gobof();
DrawBox(0, 0, 2, 79, MenuColor);
/* Everything is displayed --- get the user input */
MenubarProcess();
/* After we're done, get rid of the menubar's window, */
/* and go back to the file we were editing. */
remove_window(MenubarWindow);
show_buffer(old_buf);
refresh();
}
/*
MenuParse() - parse the menubar defn which is in the menubar buffer.
Returns 1 if everything went OK, -1 if there was an error.
*/
MenuParse()
{
int old_buf, new_buf;
/* Span all initial comment lines */
while (index(currline(), "MENUBAR") != 1)
if (!down())
return -1;
/* The first token should be the word "MENUBAR" */
if (get_token() != "MENUBAR")
{
get_tty_str("The file is not a menubar definition file");
return -1;
}
/* The next token is the name of the menubar */
MenuName = get_token();
/*
The cursor is either at the COLOR or the name of the first item
*/
if ((s = get_token()) == "COLOR")
MenuColor = get_int_token();
else
MenuColor = 07;
old_buf = currbuf();
NumMenus = 1;
while (1)
{
/* The token should be the name of the popup */
go_past_func = index(currline(), "->");
if ((mname = get_token()) == "" || mname == "}")
break;
/* After this, the token ptr should be at the first item of the popup */
MenuNames[NumMenus] = mname;
if (go_past_func)
{
down();
gobol();
}
if (index(currline(), "MENU") > 0)
{
MenuBuf[NumMenus] = new_buf = create_buffer(strcat(mname, ".men"));
down();
if (index(ltrim(currline()), "{"))
{
down();
gobol();
}
}
else
MenuBuf[NumMenus] = new_buf = 0;
NumMenus++;
if (debug)
get_tty_str("The name of the popup is [%s]", mname);
itemcnt = 1;
if (new_buf) /* We have a submenu */
{
/* Get each line until we encounter a line with a right curly brace. */
/* Insert the entire line into the buffer which holds the submenu. */
while (index(cl = ltrim(currline()), "}") == 0)
{
if (debug)
get_tty_str("Inserting item [%s]", cl);
oldcol = currcol();
setcurrbuf(new_buf);
if (itemcnt > 1)
{
goeol();
insert("\n");
}
gobol();
insert(ltrim(cl));
itemcnt++;
setcurrbuf(old_buf);
setcol(oldcol);
if (!down())
break;
gobol();
} /* end while */
/* Move to the next line after the right curly brace */
if (!down() || currline() == "")
break;
gobol();
} /* end if submenu */
} /* end while */
/* We form the menubar's text line by concatinating the menubar items. */
/* We then stick this line on top of the menubar buffer. Since the */
/* menubar window only shows 1 line, this is the line that we'll see. */
MenubarText = MenuNames[1];
for (i = 2; i <= NumMenus; i++)
MenubarText = sprintf("%s %s", MenubarText, MenuNames[i]);
gobof();
insert(MenubarText); insert("\n");
gobol();
/* Success!!! */
return 1;
}
get_token()
{
string s;
if (is_eol() || currchar() == ' ')
if (!nextword())
return "";
if (is_eof())
return "";
start = currcol();
while (!is_eol() && currchar() != ' ')
right();
s = substr(currline(), start, currcol() - start);
nextword();
if (debug)
get_tty_str(sprintf("GET_TOKEN returns [%s]", s));
return s;
}
get_int_token()
{
n = atoi(get_token());
if (debug)
get_tty_str(sprintf("GET_INT_TOKEN - n is %d", n));
return n;
}
/* ------------------------- MENU PROCESSING ------------------------- */
#define ESC 27
#define UP 200
#define DOWN 208
MenubarProcess()
{
CurrMenuItem = 1;
do_it:
highlite_word(1);
if (MenuBuf[CurrMenuItem])
{
DrawPopup(currcol());
c = MenuProcess();
clear_mark();
if (PopupWindow[CurrMenuItem])
remove_window(PopupWindow[CurrMenuItem]);
if (c == '\r' || c == ESC)
return;
show_buffer(setcurrbuf(MenubarBuf));
DrawBox(0, 0, 2, 79, MenuColor);
}
else
c = get_tty_char();
if (c != '\r' && c != ESC)
{
switch (c)
{
case LEFT :
MenuLeft();
break;
case RIGHT :
MenuRight();
break;
default :
bell();
break;
}
}
goto do_it;
}
MenuProcess()
{
markline();
do_it:
while ((c = get_tty_char()) != '\r' && c != ESC)
{
switch (c)
{
case UP :
MenuUp();
break;
case DOWN :
MenuDown();
break;
case LEFT :
return(LEFT);
case RIGHT :
return(RIGHT);
default :
bell();
break;
}
}
if (c == '\r')
{
cln = currlinenum();
if ((i = index(currline(), "->")) > 0)
{
macname = substr(currline(), i+2, 100);
/*
If we want to perform the macro on the original file we
were editing, then we must switch back to the old buffer.
*/
menubuf = currbuf();
show_buffer(OriginalFileBufID);
setprompt(2);
domacro(macname);
setprompt(0);
setcurrbuf(menubuf);
}
if (debug)
get_tty_str("After indirect call - before DrawBox");
DrawBox(MenuRow1-1, MenuCol1, MenuRow2-1, MenuCol2, MenuColor);
/*
goto do_it;
*/
}
return c;
}
/*
DrawPopup() - displays a submenu
*/
DrawPopup(startcol)
{
/*
BUGS - figure out how wide the submenu should be
*/
setcurrbuf(MenuBuf[CurrMenuItem]);
x1 = startcol - 1;
x2 = x1 + 16;
wid = create_window(4, x1+1, lastlinenum()+3, x2-1, 7);
attach_window(wid, MenuBuf[CurrMenuItem]);
PopupWindow[CurrMenuItem] = wid;
gobof();
DrawBox(2, x1, lastlinenum()+3, x2, MenuColor);
}
/*
HighliteWord() - draws the current word with highliting (if rev is 1)
*/
highlite_word(rev)
{
/* Determine the proper attribute to draw the word with */
if (rev)
rev = (MenuColor % 16) * 16 + (MenuColor / 16);
else
rev = MenuColor;
/* Get the starting & ending columns of the word */
col = currcol();
endpos = index(substr(currline(), col, 100), " ") + col - 1;
word = substr(currline(), col, endpos - col);
/* Redraw the word with the specified attribute */
display(1, col, endpos-1, rev, word);
}
/*
MenuLeft() - move left one item in the menubar
*/
MenuLeft()
{
highlite_word(0);
if (!is_bol())
CurrMenuItem--;
prevword();
highlite_word(1);
}
/*
MenuRight() - move right one item in the menubar
*/
MenuRight()
{
if (index(substr(currline(), currcol(), 100), " ") > 0)
{
highlite_word(0); /* remove highliting */
if (!is_eol())
CurrMenuItem++;
nextword(); /* move to the next item */
highlite_word(1); /* highlite the new item */
}
}
/*
MenuUp() - move up one line in the submenu
*/
MenuUp()
{
if (currlinenum() > 1)
{
clear_mark(); /* remove highlite from the old line */
up();
markline(); /* highlight the new line */
}
}
/*
MenuDown() - move down one line in the submenu
*/
MenuDown()
{
if (currlinenum() < lastlinenum())
{
clear_mark(); /* remove highlite from the old line */
down();
markline(); /* highlight the new line */
}
}
/*
DrawBox() - draws a box using the passed coordinates and attribute.
*/
DrawBox(row1, col1, row2, col2, color)
{
width = col2 - col1 + 1;
horiz_line = repstr(BoxChars[HORIZ], width - 2);
blank_line = repstr(" ", width - 2);
display(row1, col1 + 1, col1 + width - 1, color, horiz_line);
display(row2, col1 + 1, col1 + width - 1, color, horiz_line);
for (r = row1+1; r < row2; r++)
{
display(r, col1, col1, color, BoxChars[VERT]);
display(r, col2, col2, color, BoxChars[VERT]);
}
display(row1, col1, col1, color, BoxChars[TOP_LEFT]);
display(row1, col2, col2, color, BoxChars[TOP_RIGHT]);
display(row2, col1, col1, color, BoxChars[BOT_LEFT]);
display(row2, col2, col2, color, BoxChars[BOT_RIGHT]);
}