|
|
DataMuseum.dkPresents historical artifacts from the history of: Commodore CBM-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Commodore CBM-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 5020 (0x139c)
Types: TextFile
Notes: UNIX file
Names: »dmenu1.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code
└─⟦2d53db1df⟧ UNIX Filesystem
└─⟦this⟧ »hr/src/desk/dmenu1.c«
#include "desk.h"
#define MIN(x,y) ((x) < (y) ? (x) : (y) )
/************************************************************************
Support Routines:
mu_OpenMenu - Open a menu window.
mu_Draw - Draw the menu window frame and contents.
mu_FindItem - Find a menu window and item that contains the pt.
mu_InvertItem - Invert the item of the given menu window.
mu_NClose - Close active menu levels N through last.
************************************************************************/
int mu_OpenMenu(id, pt)
unsigned id;
POINT pt;
{
register MENU *m;
register int dimx, dimy;
#ifdef DEBUG
printf("\tIn mu_OpenMenu:\t%d, (%d,%d)\n", id, pt.x, pt.y);
#endif
m = &mu_menu[id];
if ( id >= NMENU || mu_am.ma_menu )
return -1;
if ( !m->mn_n || !R_point_in(dskBitmap.rect, pt) )
return -1;
/*
* Determine where and how big the window should be, given
* the requirements of the menu and the constraints on the
* window location (dskBitmap.rect).
*/
dimx = LMARGIN + RMARGIN + m->mn_width;
dimy = UMARGIN + DMARGIN + m->mn_height;
if ( dimx + pt.x > dskBitmap.rect.corner.x )
pt.x = dskBitmap.rect.corner.x - dimx;
if ( dimy + pt.y > dskBitmap.rect.corner.y )
pt.y = dskBitmap.rect.corner.y - dimy;
mu_am.ma_menu = &mu_menu[id];
mu_am.ma_elt = -1;
mu_am.ma_rect.origin = pt;
mu_am.ma_rect.corner.x = pt.x + dimx;
mu_am.ma_rect.corner.y = pt.y + dimy;
mu_am.ma_rect = R_Intersection(mu_am.ma_rect, dskBitmap.rect);
mu_am.ma_crect.corner.x = (mu_am.ma_crect.origin.x = mu_am.ma_rect.origin.x) + m->mn_width;
mu_am.ma_crect.corner.y = (mu_am.ma_crect.origin.y = mu_am.ma_rect.origin.y) + m->mn_height;
mu_am.ma_crect = R_offset(mu_am.ma_crect, LMARGIN, UMARGIN);
if ( (mu_am.ma_heap = D_Open(&mu_am.ma_rect)) < 0 )
return -1;
else
{
#ifdef DEBUG
dumpamenu(&mu_am);
#endif
mu_Draw();
return 0;
}
}
mu_Draw()
{
register MENU *m;
register IMENU *mi;
register int i;
POINT pt;
RECT rect;
#ifdef DEBUG
printf("In mu_Draw:\n");
#endif
m = mu_am.ma_menu;
mi= m->mn_item;
/*
* Draw Frame
*/
dskClip = mu_am.ma_rect;
rect.origin = mu_am.ma_rect.origin;
rect.corner.x = mu_am.ma_rect.origin.x + m->mn_width + LMARGIN + 1;
rect.corner.y = mu_am.ma_rect.origin.y + m->mn_height + UMARGIN + 1;
D_Frame(&rect, 1);
rect.origin.x = rect.corner.x;
rect.origin.y += 4;
rect.corner.x += 4;
rect.corner.y += 4;
InvertRect(&rect);
rect.origin.x = mu_am.ma_rect.origin.x + 4;
rect.corner.x -= 4;
rect.origin.y = rect.corner.y - 4;
InvertRect(&rect);
/*
* Draw contents
*/
pt = mu_am.ma_rect.origin;
dskClip = mu_am.ma_crect;
pt.x += LMARGIN + MHFILL;
pt.y += UMARGIN + dskFntA;
for ( i = m->mn_n ; i ; i-- )
{
if ( mi->mi_len == 2*MHFILL )
{
/* Empty item gets a horizontal line */
rect.origin.x = mu_am.ma_crect.origin.x;
rect.corner.x = mu_am.ma_crect.corner.x;
rect.origin.y = pt.y - dskFntA + dskFntH/2;
rect.corner.y = rect.origin.y + 1;
InvertRect(&rect);
}
else if ( mi->mi_clen )
D_Str(mi->mi_str, mi->mi_clen, pt);
pt.y += dskFntH;
mi++;
}
}
/*
** mu_FindItem(pt, ptr) - Return item id of element within point 'pt'.
**
** Entry: pt, physical point coordinate
** ptr, ^ for returning a child menu's origin.
**
** Exit: -1, if not inside any menu element of the active menu
** menu element number, otherwise
**
** Note: A point for fixing the location of a child menu (if any for
** the menu element) is returned indirectly through pointer 'pt',
** in physical coordinates. The point is meaningless if the
** function returns -1. Note, a horizontal menu generates a child
** below it; a vertical menu generates a child to the right of it.
*/
mu_FindItem(pt, ptr)
POINT pt;
register POINT *ptr;
{
register IMENU *mi;
int x;
int i;
int n;
if ( !R_point_in(mu_am.ma_rect, pt) )
return -1;
if ( pt.y < mu_am.ma_crect.origin.y )
n = 0;
else
n = (MIN(pt.y, mu_am.ma_crect.corner.y-1) - mu_am.ma_crect.origin.y)/dskFntH;
ptr->x = mu_am.ma_rect.corner.x;
ptr->y = mu_am.ma_crect.origin.y + n * dskFntH;
mi = &mu_am.ma_menu->mn_item[n];
if ( mi->mi_clen == 0 || (mi->mi_flag & 01) == 0 )
return -1;
return n;
}
mu_InvertItem()
{
register IMENU *mi;
register int n;
RECT rect;
/*
* Don't do inactive or empty menu items
*/
if ( (n = mu_am.ma_elt) == -1 )
return;
mi = &mu_am.ma_menu->mn_item[n];
if ( mi->mi_clen == 0 || (mi->mi_flag & 01) == 0 )
return;
#ifdef DEBUG
printf("\tIn mu_InvertItem:\titem=%d\t", n);
#endif
/*
* Toggle the on/off indicator of the menu item.
*/
mi->mi_flag ^= 02;
/*
* Calculate in physical coordinates the rectangle to
* invert. Then invert it!
*/
rect.origin.x = LMARGIN;
rect.origin.y = UMARGIN + dskFntH*n;
rect.corner.x = LMARGIN + mu_am.ma_crect.corner.x - mu_am.ma_crect.origin.x;
rect.corner.y = rect.origin.y + dskFntH;
rect = R_addp(rect, mu_am.ma_rect.origin);
#ifdef DEBUG
printf("(%d,%d),(%d,%d)\n", rect.origin.x, rect.origin.y, rect.corner.x, rect.corner.y);
#endif
InvertRect(&rect);
}