home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 1997 March
/
VPR9703A.ISO
/
VPR_DATA
/
DOGA
/
SOURCES
/
POLYEDIT.LZH
/
MODEL
/
MENU.C
< prev
next >
Wrap
C/C++ Source or Header
|
1996-07-25
|
9KB
|
418 lines
/*
* メニュー表示
*
* Copyright Koabayashi 1994.7.9
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include "ml.h"
#include "view.h"
#include "menu.h"
#include "graph.h"
#include "input.h"
#include "model.h"
#define MENU_STEP 15
#ifdef WINDOWS
extern void SetWindowsMenu(int no);
#endif
extern int QuitFlag;
MenuClass *Menu[MAX_MENU] ;
MenuClass *MenuStack[MENU_LEVELS][MAX_MENU] ;
int MenuPos[MAX_MENU+1];
int MenuStackPtr ;
int CurrentX, CurrentY;
static int PopUpMenu( int, int, int, ItemName*, int*, int*, int );
static void PrintMenuLine( int, int, char*, int, int, int, int );
static void QueryMenuEnable(int);
/* メニュー初期化 */
void MenuInit()
{
int i ;
for( i = 0 ; i < MAX_MENU ; i++ )
Menu[i] = NULL ;
MenuStackPtr = 0 ;
}
static short CheckMark[] = {
0x0100, 0x0200, 0x0200, 0x0400, 0x0400, 0x4800, 0x2800, 0x1000,
};
/* タイトルバーの表示 */
void DrawTitleBar()
{
#ifndef WINDOWS
int i ;
graph_fill( 0, 0, DISPLAY_X-1, MENU_WIDTH-2, FRAME_COLOR );
graph_line( 0, MENU_WIDTH-1, DISPLAY_X-1, MENU_WIDTH-1, 0 );
MenuPos[0] = 0;
for( i = 0 ; i < MAX_MENU ; i++ )
{
MenuPos[i+1] = MenuPos[i];
if ( Menu[i] != NULL ) {
graph_puts( Menu[i]->title, MenuPos[i] + FontH, 0, FRAME_COLOR<<4 );
MenuPos[i+1] += (strlen(Menu[i]->title)+2) * FontH;
}
}
DrawCursorPos();
#endif
}
/* メニューイベントの呼び出し */
void CallMenu( x, y )
int x, y ;
{
int i, n ;
int exec ;
DataStruct *top ;
#if 0
x /= MENU_STEP * FontH ;
#endif
for (n = x, i = 0, x = -1; i < MAX_MENU; i++) {
if (MenuPos[i] <= n && n < MenuPos[i+1]) {
x = i;
break;
}
}
exec = -1 ;
if ( 0 <= x && x < MAX_MENU && Menu[x] != NULL && Menu[x]->items > 0 ) {
QueryMenuEnable(x);
n = PopUpMenu( MenuPos[x], MenuPos[x+1]-MenuPos[x], FontV+3, Menu[x]->item, Menu[x]->exec, Menu[x]->check, Menu[x]->items );
if ( n < 0 || (Menu[x]->check[n] & MENU_DISABLE) != 0)
return ;
exec = Menu[x]->exec[n] ;
if ( exec >= 0 )
{
top = StackTop();
StackPushInt( n );
CallFunction( exec, 1, top+1 );
StackRelease( top );
}
} else {
WaitMouseOff();
}
}
void ExecMenu(int x, int y)
{
DataStruct *top ;
if (0 <= x && x < MAX_MENU && Menu[x] != NULL
&& 0 <= y && y < Menu[x]->items && Menu[x]->exec[y] >= 0) {
top = StackTop();
StackPushInt( y );
CallFunction( Menu[x]->exec[y], 1, top+1 );
StackRelease( top );
}
}
static int PopUpMenu( x, w, y, item, exec, check, items )
int x, w, y ;
ItemName *item ;
int *exec ;
int *check;
int items ;
{
int ret, i, n, len, len1, len2 ;
int mx, my ;
int x1, y1, x2, y2 ;
char *p;
int height[MAX_ITEM+1];
len1 = len2 = 0;
height[0] = 0;
for( i = 0 ; i < items ; ++i )
{
if (item[i][0] == '-' && item[i][1] == '-' && item[i][2] == '-') {
height[i+1] = height[i] + 5;
} else {
height[i+1] = height[i] + FontV + 1;
}
if ((p = strchr(item[i], '\t')) != NULL) {
int l1 = p - item[i];
if (l1 > 4 && p[-4] == '(' && p[-3] == '&' && p[-1] == ')') {
l1 -= 4;
}
if (len1 < l1) {
len1 = l1;
}
if (len2 < strlen(p+1)) {
len2 = strlen(p+1);
}
} else {
int l1 = strlen(item[i]);
if (l1 > 4 && item[i][l1-4] == '(' && item[i][l1-3] == '&' && item[i][l1-1] == ')') {
l1 -= 4;
}
if ( len1 < l1) {
len1 = l1;
}
}
}
if (len2 > 0) {
len = len1 + 1 + len2;
} else {
len = len1;
}
x1 = x + 4 ;
x2 = x1 + (len+2) * FontH ;
if (x2 > DISPLAY_X-1) {
x1 -= (x2 - (DISPLAY_X-1));
x2 -= DISPLAY_X-1;
}
y1 = y - 1 ;
y2 = y + height[items] + 1;
if (graph_push(x1, y1, x2-x1+1, y2-y1+1) == FALSE) {
ViewCursor( OFF );
}
#ifdef X68K
graph_fill( x1+1, y1+1, x2-1, y2-1, TMP_COLOR );
#endif
graph_fill( x1+1, y1+1, x2-1, y2-1, FRAME_COLOR );
graph_box( x1, y1, x2, y2, TRUE );
for( i = 0 ; i < items ; ++i )
PrintMenuLine( x+FontH, y+height[i], item[i], len, len2, FRAME_COLOR<<4, check[i] );
ret = -1 ;
do
{
WaitInput();
mx = MouseX ;
my = MouseY ;
if ( my < y && ( mx < x || x+w < mx ) )
{
ret = -1 ;
break ;
}
#if 0
n = ( my - y ) / FontV ;
#else
for (n = 0; n < items; n++) {
if ((my-y) < height[n+1]) {
break;
}
}
#endif
if ( my < y || items <= n )
n = -1 ;
if ( n != ret )
{
if ( ret >= 0 && (check[ret] & MENU_DISABLE) == 0)
{
if ( exec[ret] >= 0 )
PrintMenuLine( x+FontH, y+height[ret], item[ret], len, len2, FRAME_COLOR<<4, check[ret] );
}
if ( n >= 0 && (check[n] & MENU_DISABLE) == 0)
{
if ( exec[n] >= 0 )
PrintMenuLine( x+FontH, y+height[n], item[n], len, len2, FRAME_COLOR, check[n] );
}
ret = n ;
}
if (QuitFlag) {
return -1;
}
}
while( MouseLeft || MouseRight );
if (graph_pop() == FALSE) {
ViewFrame();
ViewLineAll( x1, y1, x2, y2, TRUE );
ViewCursor( ON );
}
return ret ;
}
static void PrintMenuLine( x, y, msg, len, len2, atr, check )
int x, y ;
char *msg ;
int len, len2 ;
int atr ;
int check ;
{
int i, len1;
char *p, *q;
char buf[100] ;
char *format =
" %s ";
if (msg[0] == '-' && msg[1] == '-' && msg[2] == '-') {
x = x-FontH + 4 ;
y = y + 2;
graph_line( x, y-1, x + (len+2) * FontH, y-1, 0);
graph_line( x, y, x + (len+2) * FontH, y, 7);
return;
}
if (len2 == 0) {
#if 0
sprintf( buf, format, msg );
buf[len+1] = '\0' ;
if (buf[len-3] == '(' && buf[len-2] == '&' && buf[len] == ')') {
buf[len-3] = '\0';
}
#endif
int l;
l = strlen(msg);
if (l > 4 && msg[l-4] == '(' && msg[l-3] == '&' && msg[l-1] == ')') {
l -= 4;
}
buf[0] = ' ';
strncpy(buf+1, msg, l);
memset(buf+1+l, ' ', len - l+2);
buf[len+1] = '\0' ;
} else {
len1 = len - len2 - 1;
p = buf;
q = msg;
*p++ = ' ';
for (i = 0; *q && *q != '\t'; i++) {
*p++ = *q++;
}
if (i > 4 && p[-4] == '(' && p[-3] == '&' && p[-1] == ')') {
i -= 4;
p -= 4;
}
if (*q != '\t') {
for (; i < len; i++) {
*p++ = ' ';
}
*p = '\0';
} else {
for (; i < len1 + 1; i++) {
*p++ = ' ';
}
q++;
for (i = 0; *q && *q != '\t'; i++) {
*p++ = *q++;
}
for (; i < len2; i++) {
*p++ = ' ';
}
*p = '\0';
}
}
if (check & MENU_DISABLE) {
#if 0
graph_puts( buf, x, y, (atr & 0xf0) | BG_COLOR );
#else
graph_puts( buf, x+1, y+1, (atr & 0xf0) | 7 );
graph_puts( buf, x, y, (atr & 0xf0) | BG_COLOR | 0x100);
#endif
} else {
graph_puts( buf, x, y, atr );
}
if (check & MENU_CHECK) {
graph_pattern( x + FontH - 8, y + (FontV-8)/2, atr, CheckMark, 8, 8 );
}
}
/* メニューの設定 */
void SetMenu( menu, no )
MenuClass *menu ;
int no ;
{
assert( 0 <= no && no < MAX_MENU );
if ( Menu[no] != NULL )
ObjectFree( (Object*)(Menu[no]) );
Menu[no] = (MenuClass*)ObjectAlloc( sizeof( MenuClass ), MenuClassID );
*(Menu[no]) = *menu ;
#ifdef WINDOWS
SetWindowsMenu(no);
#endif
}
/* 子メニューに行く */
void PushMenu()
{
int i ;
assert( MenuStackPtr < MENU_LEVELS - 1 );
for( i = 0 ; i < MAX_MENU ; i++ )
{
MenuStack[MenuStackPtr][i] = Menu[i] ;
Menu[i] = NULL ;
}
MenuStackPtr++ ;
#ifdef WINDOWS
SetWindowsMenu(-1);
#endif
}
/* 親メニューに戻る */
void PopMenu()
{
int i ;
assert( MenuStackPtr > 0 );
MenuStackPtr-- ;
#ifdef WINDOWS
SetWindowsMenu(-1);
#endif
for( i = 0 ; i < MAX_MENU ; i++ )
{
if ( Menu[i] != NULL )
ObjectFree( (Object*)(Menu[i]) );
Menu[i] = MenuStack[MenuStackPtr][i] ;
#ifdef WINDOWS
SetWindowsMenu(i);
#endif
}
}
static void QueryMenuEnable(int x)
{
int y;
for (y = 0; y < Menu[x]->items; ++y) {
if (Menu[x]->query[y] >= 0) {
DataStruct *top;
CurrentX = x;
CurrentY = y;
top = StackTop();
StackPushInt( x );
StackPushInt( y );
CallFunction( Menu[x]->query[y], 2, top+2 );
StackRelease( top );
CurrentX = CurrentY = -1;
}
}
}
void CurrentMenuItem(char *str)
{
if (CurrentX >= 0 && CurrentY >= 0) {
strncpy(Menu[CurrentX]->item[CurrentY], str, ITEM_LEN);
Menu[CurrentX]->item[CurrentY][ITEM_LEN] = '\0';
}
}
void CurrentMenuFunction(int ident)
{
if (CurrentX >= 0 && CurrentY >= 0) {
Menu[CurrentX]->exec[CurrentY] = ident;
}
}
void CurrentMenuEnable(int check)
{
if (CurrentX >= 0 && CurrentY >= 0) {
Menu[CurrentX]->check[CurrentY] = check;
}
}