⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 walkmenu_render.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
    return status;error_exit:    status = -1;    m->dynamic_info->depth = 0;    goto exit;}/*  *  Compute max item size.  Only zero sized items have to be recomputed */Private intcompute_item_size(menu, std_image)    struct menu *menu;    struct image *std_image;{       register int width, height, nitems, recompute;    register struct menu_item *mi, **mip;    int gen_items = FALSE;    nitems = menu->nitems;    width = height = 0;    recompute = std_image->width == 0;    /*      *  This causes the menu to shrink around the items.     *  When the std_image is available at the client interface zeroing the     *  size of std_image should be rethought.     */    std_image->width = std_image->height = 0;    /* Compute max size if any of the items have changed */    for (mip = menu->item_list;mi = *mip, nitems--; mip++) {	mi->parent = menu;	if (mi->gen_proc) {	    *mip = mi = (mi->gen_proc)(mi, MENU_DISPLAY);	    gen_items = TRUE;	}	    	/* This is an untested (unnecessary?) optimization */	if (recompute) mi->image->width = 0; /* This forces the size to be					      * recompute inside image_get() */	if (mi->image->width == 0) {	    width = imax(image_get(mi->image, std_image, IMAGE_WIDTH), width);	    height = imax((int)image_get(mi->image, std_image, IMAGE_HEIGHT),			  height);	} else {	    width = imax(mi->image->width, width);	    height = imax(mi->image->height, height);	}	    }    std_image->width = width;    std_image->height = height;    return gen_items;}/*  *  Compute the dimensions of the menu. */Private intcompute_dimensions(menu, iwidth, iheight, rect, ncolp, nrowp)	register struct menu *menu;	int iwidth, iheight;	register Rect *rect;	int *ncolp, *nrowp;{       register int ncols, nrows;    ncols = menu->ncols;    nrows = menu->nrows;        /* Fix 1015167: subtract SCREEN_MARGIN everywhere */    if (!(ncols && nrows)) {	if (ncols) {			/* case: ncols=n, nrows=to fit */	    rect->r_width = (ncols * iwidth) +		2*MENU_BORDER + (menu->shadow_pr ? MENU_SHADOW : 0);	    if (rect->r_width > menu_fs->fs_screenrect.r_width	    -SCREEN_MARGIN) {		ncols = (menu_fs->fs_screenrect.r_width - SCREEN_MARGIN			 - 2*MENU_BORDER + (menu->shadow_pr ? MENU_SHADOW : 0))		    / iwidth;	    }	    nrows = (menu->nitems - 1) / ncols + 1;	} else {			/* case: nrows=n, ncols=to fit */	    if (!nrows) nrows = menu->nitems; /* Both zero, fit cols */	    rect->r_height = (nrows * iheight) +		2*MENU_BORDER + (menu->shadow_pr ? MENU_SHADOW : 0);	    if (rect->r_height > menu_fs->fs_screenrect.r_height - SCREEN_MARGIN) {		nrows = (menu_fs->fs_screenrect.r_height - SCREEN_MARGIN			 - 2*MENU_BORDER - (menu->shadow_pr ? MENU_SHADOW : 0))		    / iheight;		ncols = (menu->nitems - 1) / nrows + 1;		nrows = (menu->nitems - 1) / ncols + 1;	    } else {		ncols = (menu->nitems - 1) / nrows + 1;	    }	}    }    rect->r_width = (ncols * iwidth) +	2*MENU_BORDER + (menu->shadow_pr ? MENU_SHADOW : 0);    rect->r_height = (nrows * iheight) +	2*MENU_BORDER + (menu->shadow_pr ? MENU_SHADOW : 0);    if (rect->r_width > menu_fs->fs_screenrect.r_width - SCREEN_MARGIN	|| rect->r_height > menu_fs->fs_screenrect.r_height - SCREEN_MARGIN) {	(void) fprintf(stderr, "menu_show: Menu too large for screen.\n");	return FALSE;    }    *ncolp = ncols;    *nrowp = nrows;    return TRUE;    }/*  *  Compute 3 rects: * 	mrect = menu_image; * 	srect = mrect + shadow * 	irect = input region = menu_rect + stand_off region */Private voidcompute_rects(menu, iep, stand_off, curitem,	      item_width, item_height, ncols, nrows,	      mrect, irect, srect)	struct menu *menu;	struct inputevent *iep;	int stand_off, curitem, item_width, item_height, ncols, nrows;	Rect *mrect, *irect, *srect;{    int left, top;    left = item_width * (menu->column_major ?			 (curitem - 1) / nrows : (curitem - 1) % ncols);    top =  item_height * (menu->column_major ?			  (curitem - 1) % nrows : (curitem - 1) / ncols);    mrect->r_left = iep->ie_locx - left - MENU_BORDER;    mrect->r_top = iep->ie_locy - top - MENU_BORDER - item_height / 2;    if (left != 0) stand_off = FALSE; /* Not on the edge */    /* Move the menu under the cursor so that it is outside/inside the item */    mrect->r_left += stand_off ? STANDOFF : -STANDOFF;    left = mrect->r_left, top = mrect->r_top;    constrainrect(mrect, &menu_fs->fs_screenrect);    if (left != mrect->r_left || top != mrect->r_top) {	iep->ie_locx -= left - mrect->r_left;	iep->ie_locy -= top - mrect->r_top;	(void) win_setmouseposition(menu_fs->fs_windowfd,				    iep->ie_locx, iep->ie_locy);    }    *srect = *mrect; /* Remember total size of affected area */    if (menu->shadow_pr) {	mrect->r_width -= MENU_SHADOW;	mrect->r_height -= MENU_SHADOW;    }    *irect = *mrect;    if (stand_off) {	irect->r_left -= STANDOFF;	irect->r_width += STANDOFF;    }}/*  *  Rop items into supplied pixrect */Private voidrender_items(menu, std_image, pr, ncols, nrows)	struct menu *menu;	struct image *std_image;	struct pixrect *pr;{       register int top, left, n, i, j;    register struct menu_item **mip;    int item_width, item_height;    register total_height, total_width;    item_width = std_image->width;    item_height = std_image->height;    mip = menu->item_list;    n = 0;    total_height = item_height * nrows;    total_width = item_width * ncols;    if (menu->column_major) {	for (j = left = 0; j < ncols; j++) {	    for (i = top = 0; i < nrows; i++) {		if (++n > menu->nitems) break;		if ((*mip)->inactive) {		    image_render((*mip)->image, std_image,				 LINT_CAST(IMAGE_REGION), pr, left, top,				 IMAGE_INACTIVE,				 0);		} else {		    image_render((*mip)->image, std_image,				 LINT_CAST(IMAGE_REGION), pr, left, top,				 0);		}		if (menu->h_line || (*mip)->h_line)  {		    image_vector(0,top+item_height,total_width-1,top+item_height);		}		if (menu->v_line || (*mip)->v_line)  {		    image_vector(left+item_width,0,left+item_width,total_height-1);		}		top += item_height;		mip++;	    }	    left += item_width;	}    } else {	for (i = top = n = 0; i < nrows; i++) {	    for (j = left = 0; j < ncols; j++) {		if (++n > menu->nitems) break;		if ((*mip)->inactive)		    image_render((*mip)->image, std_image,				 LINT_CAST(IMAGE_REGION), pr, left, top,				 IMAGE_INACTIVE,				 0);		else {		    image_render((*mip)->image, std_image,				 LINT_CAST(IMAGE_REGION), pr, left, top,				 0);		}		if (menu->h_line || (*mip)->h_line)  {		    image_vector(0,top+item_height,total_width-1,top+item_height);		}		if (menu->v_line || (*mip)->v_line)  {		    image_vector(left+item_width,0,left+item_width,total_height-1);		}		left += item_width;		mip++;	    }	    top += item_height;	}    }}/*  *  Handle recursive calls for pullright items */Private intrender_pullright(mi, subrect, menurect, itemrect, reenter, fd)	register struct menu_item *mi;	Rectnode *subrect;	Rect *menurect, *itemrect;	int  fd;{       register struct menu *m, *(*gen_proc)();    struct rectnode menu_node, active_node;    int status;    if (gen_proc = mi->gen_pullright) {	m = (gen_proc)(mi, MENU_DISPLAY);	if (!m) {	    (void) fprintf(stderr,	      "menu_show: gen_proc failed to generate a pullright menu.\n");	    return -1;	}	mi->value = (caddr_t)m;    } else {	m = (struct menu *)LINT_CAST(mi->value);    }    menu_node.rn_next = subrect, menu_node.rn_rect = *menurect;    active_node.rn_next = &menu_node, active_node.rn_rect = *itemrect;    status =	menu_render(m, mi->parent->dynamic_info, mi, &active_node, reenter, fd);    if (gen_proc)	mi->value = (caddr_t)(gen_proc)(mi, MENU_DISPLAY_DONE);    return status;}Private voidpaint_shadow(pr, shadow_pr, save_pr)	register struct pixrect *pr, *shadow_pr, *save_pr;{    if (shadow_pr) { 	/* Draw borders with shadows */	(void) pr_rop(pr, 0, 0, pr->pr_width - MENU_SHADOW, MENU_BORDER,	       	      PIX_SET, PIXRECT_NULL, 0, 0);	(void) pr_rop(pr, 0, MENU_BORDER,	       	      MENU_BORDER, pr->pr_height - MENU_SHADOW - 2*MENU_BORDER,	       	      PIX_SET, PIXRECT_NULL, 0, 0);	(void) pr_rop(pr,	       	      pr->pr_width - MENU_SHADOW - MENU_BORDER, MENU_BORDER,	       	      MENU_BORDER, pr->pr_height - MENU_SHADOW - 2*MENU_BORDER,	       	      PIX_SET, PIXRECT_NULL, 0, 0);	(void) pr_rop(pr, 0, pr->pr_height - MENU_SHADOW - MENU_BORDER,	       	      pr->pr_width - MENU_SHADOW, MENU_BORDER,	       	      PIX_SET, PIXRECT_NULL, 0, 0);	/* Fill in with background */	(void) pr_rop(pr, pr->pr_width - MENU_SHADOW, 0,		      MENU_SHADOW, pr->pr_height,		      PIX_SRC, save_pr, pr->pr_width - MENU_SHADOW, 0);	(void) pr_rop(pr, 0, pr->pr_height - MENU_SHADOW,		      pr->pr_width - MENU_SHADOW, MENU_SHADOW,		      PIX_SRC, save_pr, 0, pr->pr_height - MENU_SHADOW);	/* Rop shadow over background */	(void) pr_replrop(pr, pr->pr_width - MENU_SHADOW, MENU_SHADOW,		   	  MENU_SHADOW, pr->pr_height - MENU_SHADOW,		   	  PIX_SRC /* |PIX_DST opaque shadow */, shadow_pr,		   	  pr->pr_width - MENU_SHADOW, MENU_SHADOW);	(void) pr_replrop(pr, MENU_SHADOW, pr->pr_height - MENU_SHADOW,		   	  pr->pr_width - 2 * MENU_SHADOW, MENU_SHADOW,		   	  PIX_SRC /* |PIX_DST  */, shadow_pr,		   	  MENU_SHADOW, pr->pr_height - MENU_SHADOW);    } else { 	/* Draw borders without shadows */	(void) pr_rop(pr, 0, 0, pr->pr_width, MENU_BORDER, PIX_SET,		      PIXRECT_NULL, 0, 0);	(void) pr_rop(pr, 0, MENU_BORDER - 1,	              MENU_BORDER, pr->pr_height - 2*MENU_BORDER,	       	      PIX_SET, PIXRECT_NULL, 0, 0);	(void) pr_rop(pr, pr->pr_width - MENU_BORDER - 1, MENU_BORDER - 1,	       	      MENU_BORDER, pr->pr_height - 2*MENU_BORDER, PIX_SET,	       	      PIXRECT_NULL, 0, 0);	(void) pr_rop(pr, 0, pr->pr_height - MENU_BORDER - 1,	       	      pr->pr_width, MENU_BORDER,	       	      PIX_SET, PIXRECT_NULL, 0, 0);    }}Private voidpaint_menu(image, rect, shadow)	register struct pixrect *image;	register Rect *rect;	register int shadow;{    if (menu_fs->fs_pixwin->pw_pixrect->pr_depth > 1 && shadow) {	rect->r_width -= MENU_SHADOW;	rect->r_height -= MENU_SHADOW;    }    (void) pw_preparesurface_full(menu_fs->fs_pixwin, rect, 1);    (void) pw_write(menu_fs->fs_pixwin,	     	    rect->r_left, rect->r_top, rect->r_width, rect->r_height,	     	    PIX_SRC, image, 0, 0);    if (menu_fs->fs_pixwin->pw_pixrect->pr_depth > 1 && shadow) {	Rect shadow_rect;	shadow_rect.r_left = rect->r_left + rect->r_width;	shadow_rect.r_top = rect->r_top + MENU_SHADOW;	shadow_rect.r_width = MENU_SHADOW;	shadow_rect.r_height = rect->r_height;		(void) pw_preparesurface_full(menu_fs->fs_pixwin, &shadow_rect, 1);	(void) pw_write(menu_fs->fs_pixwin,		 	shadow_rect.r_left,		 	shadow_rect.r_top,		 	MENU_SHADOW, rect->r_height,		 	PIX_SRC /* | PIX_DST  opaque shadow */, image,		 	image->pr_width - MENU_SHADOW, MENU_SHADOW);          shadow_rect.r_left = rect->r_left + MENU_SHADOW;	 shadow_rect.r_top = rect->r_top + rect->r_height;	 shadow_rect.r_width = rect->r_width - MENU_SHADOW;         shadow_rect.r_height = MENU_SHADOW;	 (void)pw_preparesurface_full(menu_fs->fs_pixwin, &shadow_rect, 1); 	 (void) pw_write(menu_fs->fs_pixwin,		 	shadow_rect.r_left,			shadow_rect.r_top, 		 	shadow_rect.r_width, MENU_SHADOW,		 	PIX_SRC /* | PIX_DST opaque shadow */, image,		 	MENU_SHADOW, image->pr_height - MENU_SHADOW);	rect->r_width += MENU_SHADOW;	rect->r_height += MENU_SHADOW;    }}/*  *  Provide feedback directly to the pixwin. *  Someday this should be a client settable option. */Private voidfeedback(m, r, n, ncols, nrows, state)	register struct menu *m;	struct rect *r;	int n, ncols, nrows;	Menu_feedback state;{    struct menu_item *mi = m->item_list[n - 1];    int max_width = m->default_image.width;    int max_height = m->default_image.height;    if (!mi->no_feedback && !m->feedback_proc && !mi->inactive) {	int left, top;	register int margin = m->default_image.margin;	n--; /* Convert to zero origin */	left = (r->r_left + MENU_BORDER + margin		+ (m->column_major ? n / nrows : n % ncols) * max_width);	top = (r->r_top + MENU_BORDER + margin	       + (m->column_major ? n % nrows : n / ncols) * max_height);	(void) pw_writebackground(menu_fs->fs_pixwin, left, top,		 max_width - 2  * margin,		 max_height - 2 * margin,		 PIX_NOT(PIX_DST));    } else if (m->feedback_proc)	(m->feedback_proc)(mi, state); /* FIXME: Pass rect or region? */}/*  *  Menu must be completely on the screen. */Private voidconstrainrect(rconstrain, rbound)	register struct rect *rconstrain, *rbound;{   /*    * Bias algorithm to have too big rconstrain fall off right/bottom.    */    if (rect_right(rconstrain) > rect_right(rbound)) {	rconstrain->r_left = rbound->r_left + rbound->r_width	    - rconstrain->r_width;    }    if (rconstrain->r_left < rbound->r_left) {	rconstrain->r_left = rbound->r_left + SCREEN_MARGIN;    }    if (rect_bottom(rconstrain) > rect_bottom(rbound)) {	rconstrain->r_top = rbound->r_top + rbound->r_height	    - rconstrain->r_height;    }    if (rconstrain->r_top < rbound->r_top) {	rconstrain->r_top = rbound->r_top + SCREEN_MARGIN;    }}/* *  Clean up any client generated items */Private voiddestroy_gen_items(menu)    struct menu *menu;{       register int nitems;    register struct menu_item *mi, **mip;    nitems = menu->nitems;    /* Give client a chance to clean up any generated items */    for (mip = menu->item_list;mi = *mip, nitems--; mip++)	if (mi->gen_proc) *mip = (mi->gen_proc)(mi, MENU_DISPLAY_DONE);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -