|
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); }