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

📄 panel_choice.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
#ifndef lint#ifdef sccsstatic	char sccsid[] = "@(#)panel_choice.c 1.1 92/07/30 Copyr 1984 Sun Micro";#endif#endif/*****************************************************************************//*                          panel_choice.c                                   *//*            Copyright (c) 1985 by Sun Microsystems, Inc.                   *//*****************************************************************************/#include <suntool/panel_impl.h>#include <sundev/kbd.h>#include "sunwindow/sv_malloc.h"static short check_off_image[] = {#include <images/panel_check_off.pr>};static mpr_static(panel_check_off, 16, 16, 1, check_off_image);static short check_on_image[] = {#include <images/panel_check_on.pr>};static mpr_static(panel_check_on, 16, 16, 1, check_on_image);static short choice_off_image[] = {#include <images/panel_choice_off.pr>};static mpr_static(panel_choice_off, 16, 16, 1, choice_off_image);static short choice_on_image[] = {#include <images/panel_choice_on.pr>};static mpr_static(panel_choice_on, 16, 16, 1, choice_on_image);#define NULL_CHOICE	-1#define	MARK_XOFFSET	3		/* # of pixels to leave after a mark */#define	CHOICE_X_GAP	10		/* # of x pixels between choices */#define	CHOICE_Y_GAP	5		/* # of x pixels between choices *//* assume 8 bits per byte, so byte for nth * element is n/8, bit within that byte is * defined by the loworder three bits of n. */#define WORD(n)         (n >> 5)        /* word for element n */#define BIT(n)          (n & 0x1F)      /* bit in word for element n *//* Create a set with n elements. * Clear a set with n elements. * Copy n elements from one set to another */#define	CREATE_SET(n)		\    ((u_int *) LINT_CAST(calloc((u_int) (WORD(n) + 1), sizeof(u_int))))#define	CLEAR_SET(set, n)	\    (bzero((char *) (set), (int) (WORD(n) + 1) * sizeof(u_int)))#define	COPY_SET(from_set, to_set, n)	\    (bcopy((char *) (from_set), (char *) (to_set), (int) ((WORD(n) + 1) * sizeof(u_int))))/* Add a choice by or-ing in the correct bit. * Remove a choice by and-ing out the correct bit. */#define ADD_CHOICE(set, n)	((set)[WORD(n)] |= (1 << BIT(n)))#define REMOVE_CHOICE(set, n)	((set)[WORD(n)] &= ~(1 << BIT(n)))/* See if the nth bit is on */#define IN(set, n)		(((set)[WORD(n)] >> BIT(n)) & 01)#define	EACH_CHOICE(set, last_element, n)	\   for ((n) = 0; (n) <= (last_element); (n)++) \      if (IN(set, n))#define choice_dp(ip)		(choice_data *) LINT_CAST((ip)->data)static	begin_preview(), update_preview(), cancel_preview(), accept_preview(),	accept_menu(),	paint(),	destroy(),	set_attr(),	layout(),	sync_menu();	static void     update_item_rect();static caddr_t	get_attr();static int	choice_number();static u_int 	choice_value();static struct panel_ops ops  =  {   panel_default_handle_event,		/* handle_event() */   begin_preview,			/* begin_preview() */   update_preview,			/* update_preview() */   cancel_preview,			/* cancel_preview() */   accept_preview,			/* accept_preview() */   accept_menu,				/* accept_menu() */   panel_nullproc,			/* accept_key() */   paint,				/* paint() */   destroy,				/* destroy() */   get_attr,				/* get_attr() */   set_attr,				/* set_attr() */   (caddr_t (*)()) panel_nullproc,	/* remove() */   (caddr_t (*)()) panel_nullproc,	/* restore() */   layout				/* layout() */};static struct pr_size image_size();typedef struct choice_data {		     /* data for a choice item */   struct {      unsigned gap_set      	: 1;      unsigned feedback_set 	: 1;      unsigned choice_fixed 	: 1;      unsigned menu_dirty	: 1;   } status;   int	 		current;             /* current choice */   int	 		actual;	     	     /* actual value of current */   u_int		*value;		     /* bit field of choices */   int	 	 	last;		     /* last possible choice */   Panel_setting	 display_level;	     /* NONE, CURRENT, ALL */   int		 choose_one;	     /* only one choice allowed */   Panel_setting	 feedback;	     /* MARKED, INVERTED, NONE */   struct panel_image 	*choices;	     /* each choice */   Rect 		*choice_rects;	     /* each choice rect */   Rect 		*mark_rects;	     /* each mark rect */   int			 choice_gap;	     /* gap between choices */   int		 	 choices_bold : 1;   /* bold/not choices strings */   struct pixrect      **mark_on;	     /* selection mark images */   struct pixrect      **mark_off;	     /* un-selected mark images */}  choice_data;/*****************************************************************************//* choice item create routine                                                *//* Appends a new choice item to "panel".  Returns a pointer to the new item. *//*****************************************************************************/Panel_itempanel_choice(ip, avlist)register panel_item_handle	ip;Attr_avlist			avlist;{   register choice_data     *dp;    /* choice data */   dp = (choice_data *) LINT_CAST(calloc(1, sizeof(choice_data)));   if (!dp)      return (NULL);   ip->flags |= SHOW_MENU_MARK;   /* default is menu on for choice items */   if (!show_menu_set(ip->panel))      ip->flags |= SHOW_MENU;   ip->ops    = &ops;   ip->data   = (caddr_t) dp;   ip->item_type = PANEL_CHOICE_ITEM;   /* initialize */   dp->value         = CREATE_SET(1);	/* set with one choice */   ADD_CHOICE(dp->value, 0);		/* default is choice 0 selected */   dp->current       = NULL_CHOICE;	/* no current choice */   dp->actual        = FALSE;		/* current choice is off */   dp->last	     = 0;		/* last slot is slot zero */   dp->display_level = PANEL_ALL;	/* default is display all choices */   dp->choose_one    = TRUE;		/* check only one choice */   dp->feedback      = PANEL_MARKED;	/* marked feedback */   /* menu is dirty to start,    * since it must be created to    * match the default single choice    * string.    */   dp->status.menu_dirty = TRUE;   /* initialize choices to a single    * string choice of "".    * Note that we do not call layout_choices() here.    * The default layout is now to not have the label and    * single mark baselines align.  If we lower the label    * at this point, and the client has fixed its position,    * the baseline will not be realigned when choices are added.    * So we settle for a bug in the initial state: label baseline does not    * line up with single mark baseline.  This restores release 3.0    * behavior.    */   dp->choices =        (panel_image_handle) LINT_CAST(sv_malloc(sizeof(struct panel_image)));   panel_make_image(ip->panel->font, &dp->choices[0], IM_STRING, "", 		    FALSE, FALSE);   dp->choice_rects	= (Rect *) LINT_CAST(sv_malloc(sizeof(Rect)));   dp->choice_rects[0]  = ip->value_rect;   /* space between choices */   dp->choice_gap =       (ip->layout == PANEL_HORIZONTAL) ? CHOICE_X_GAP : CHOICE_Y_GAP;   /* set up the default choice marks */   dp->mark_on = (struct pixrect **)        LINT_CAST(malloc(sizeof(struct pixrect *)));   dp->mark_off = (struct pixrect **)        LINT_CAST(sv_malloc(sizeof(struct pixrect *)));   dp->mark_on[0]    = &panel_choice_on;/* for PANEL_MARKED feedback */   dp->mark_off[0]   = &panel_choice_off;/* for PANEL_MARKED feedback */   dp->mark_rects    = (Rect *) LINT_CAST(sv_malloc(sizeof(Rect)));   dp->mark_rects[0] = dp->choice_rects[0];   dp->mark_rects[0].r_width = dp->mark_on[0]->pr_width;   dp->mark_rects[0].r_height = dp->mark_on[0]->pr_height;   /* update the value and item rect */   update_item_rect(ip);    if (!set_attr(ip, avlist))      return NULL;   /* NOTE: append should be done in central create routine. */   return (Panel_item) panel_append(ip);} /* panel_choice */static intset_attr(ip, avlist)register panel_item_handle	ip;register Attr_avlist		avlist;{   register Panel_attribute	attr;	/* each attribute */   register choice_data		*dp = choice_dp(ip);   int                    choices_type	= -1;   /* IM_STRING or IM_PIXRECT */   caddr_t               *choices;		/* choices array */   struct pixfont       **choices_fonts = NULL;	/* choices fonts */   struct pixrect	**mark_images, **nomark_images;   short		  mark_images_set	= FALSE;   short		  nomark_images_set	= FALSE;   Attr_avlist		 orig_avlist = avlist;	/* original avlist */   u_int		 value;			/* initial value */   int			 which_choice, which_arg;   short		 choices_changed	= FALSE;   short		 choices_moved		= FALSE;   while (attr = (Panel_attribute) *avlist++) {      switch (attr) {	 case PANEL_CHOICE_STRINGS:	 case PANEL_CHOICE_IMAGES:	    choices_type = attr == 	       PANEL_CHOICE_STRINGS ? IM_STRING : IM_PIXRECT;	    choices = avlist;	/* base of the array */	    while (*avlist++);	/* skip past the list */	    break;	 case PANEL_CHOICE_STRING:	 case PANEL_CHOICE_IMAGE:	    which_choice = (int) *avlist++;	    if (!modify_choice(ip, attr == PANEL_CHOICE_STRING ? 			  IM_STRING : IM_PIXRECT, which_choice, *avlist++))	       return 0;	    choices_changed = TRUE;	    break;	 case PANEL_CHOICE_FONTS:	    choices_fonts = (struct pixfont **) avlist;	    while (*avlist++);	/* skip past the list */	    break;	 case PANEL_CHOICES_BOLD:	    dp->choices_bold = (*avlist++ != 0);	    for (which_choice = 0; which_choice <= dp->last; which_choice++)	       if (is_string(&dp->choices[which_choice]))		  image_bold(&dp->choices[which_choice]) = dp->choices_bold;	    choices_changed = TRUE;	    break;	 case PANEL_CHOICE_OFFSET:	    dp->choice_gap = (int) *avlist++;	    dp->status.gap_set = TRUE;	    choices_changed = TRUE;	    break;	 case PANEL_CHOOSE_ONE:	    dp->choose_one = (int) *avlist++;	    CLEAR_SET(dp->value,  dp->last);	    if (dp->choose_one) {	       ip->item_type = PANEL_CHOICE_ITEM;	       ADD_CHOICE(dp->value, 1);	    } else {	       ip->item_type = PANEL_TOGGLE_ITEM;	       /* 	       Note that this depends on the fact that PANEL_CHOOSE_ONE	       can only be specified at creat time, as part of the	       PANEL_TOGGLE macro.  So no choices have been set yet.	       */               dp->mark_on[0]    = &panel_check_on;               dp->mark_off[0]   = &panel_check_off;               /* force re-layout and resize of rect */               choices_changed = TRUE;	    }	    break;	 case PANEL_LAYOUT:	    avlist++;	    if (!dp->status.gap_set)	       dp->choice_gap = ip->layout == PANEL_HORIZONTAL ?				CHOICE_X_GAP : CHOICE_Y_GAP;	    choices_changed = TRUE;	    break;	 case PANEL_FEEDBACK:	    dp->feedback = (Panel_setting) *avlist++;	    dp->status.feedback_set = TRUE;	    choices_changed = TRUE;	    break;	 case PANEL_MARK_IMAGES:	    mark_images = (struct pixrect **) avlist;	    mark_images_set = TRUE;	    while (*avlist++);	    break;	 case PANEL_NOMARK_IMAGES:	    nomark_images = (struct pixrect **) avlist;	    nomark_images_set = TRUE;	    while (*avlist++);	    break;	 case PANEL_MARK_IMAGE:	 case PANEL_NOMARK_IMAGE:	    avlist++;	    if (!*avlist)	       *avlist = (caddr_t) &panel_empty_pr;	    avlist++;	    break;	 case PANEL_SHOW_MENU:	    if ((int) *avlist++)               ip->flags |= SHOW_MENU;            else               ip->flags &= ~SHOW_MENU;	    break;	 default:	    /* skip past what we don't care about */	    avlist = attr_skip(attr, avlist);	    break;      }   }   if (set(choices_type)) {      if (!re_alloc_choices(ip, choices_type, choices))	 return 0;      choices_changed = TRUE;   }   if (choices_fonts) {      for (which_choice = which_arg = 0; which_choice <= dp->last; 	   which_choice++, which_arg += choices_fonts[which_arg + 1] ? 1 : 0)	 if (is_string(&dp->choices[which_choice]))	    image_font(&dp->choices[which_choice]) = choices_fonts[which_arg];      choices_changed = TRUE;   }   if (mark_images_set) {      /* reset to empty pixrect if no list */      if (!mark_images[0])	  for (which_choice = 0; which_choice <= dp->last; which_choice++)	     dp->mark_on[which_choice] = &panel_empty_pr;      else	 for (which_choice = which_arg = 0; which_choice <= dp->last; 	      which_choice++, which_arg += mark_images[which_arg + 1] ? 1 : 0)	    dp->mark_on[which_choice] = mark_images[which_arg];      choices_changed = TRUE;   }   if (nomark_images_set) {      /* reset to empty pixrect if no list */      if (!nomark_images[0])	  for (which_choice = 0; which_choice <= dp->last; which_choice++)	     dp->mark_off[which_choice] = &panel_empty_pr;      else	 for (which_choice = which_arg = 0; which_choice <= dp->last; 	      which_choice++, which_arg += nomark_images[which_arg + 1] ? 1 : 0)	    dp->mark_off[which_choice] = nomark_images[which_arg];      choices_changed = TRUE;   }   /* now set things that depend on the new list     * of choices or the attributes that were set above.    */   avlist = orig_avlist;   while (attr = (Panel_attribute) *avlist++) {      switch (attr) {	 case PANEL_MARK_IMAGE:	 case PANEL_NOMARK_IMAGE:	    which_choice = (int) LINT_CAST(*avlist++);	    if (which_choice < 0 || which_choice > dp->last)	       return 0;	    dp->mark_on[which_choice] = (struct pixrect *) LINT_CAST(*avlist++);	    /* may have to relayout the choices */	    choices_changed = TRUE;	    break;	 case PANEL_CHOICE_FONT:	    which_choice = (int) *avlist++;	    if (which_choice < 0 || which_choice > dp->last)	       return 0;	    if (is_string(&dp->choices[which_choice]))	       image_font(&dp->choices[which_choice]) = (Pixfont *) *avlist++;	    choices_changed = TRUE;	    break;	 case PANEL_VALUE:	    value = (u_int) *avlist++;	    if (dp->choose_one) {	       if(value <= dp->last) {		  CLEAR_SET(dp->value,  dp->last);		  ADD_CHOICE(dp->value, value);	       }	    } else	       dp->value[0] = value;	    break;	 	 case PANEL_TOGGLE_VALUE:	    which_choice = (int) *avlist++;	    if (which_choice < 0 || which_choice > dp->last)	       return 0;	    if (*avlist++)	       ADD_CHOICE(dp->value, which_choice);	    else	       REMOVE_CHOICE(dp->value, which_choice);	    break;	 case PANEL_DISPLAY_LEVEL:	    dp->display_level = (Panel_setting) *avlist++;	    /* ignore PANEL_CURRENT for toggles */	    if (dp->display_level == PANEL_CURRENT && !dp->choose_one)	       dp->display_level = PANEL_ALL;	    /* set the default feedback */	    if (!dp->status.feedback_set)	       switch (dp->display_level) {		  case PANEL_NONE:		  case PANEL_CURRENT:		     dp->feedback = PANEL_NONE;		     break;		  default:		     dp->feedback = PANEL_MARKED;	       }	    choices_changed = TRUE;	    break;	 default:	    /* skip past what we don't care about */	    avlist = attr_skip(attr, avlist);	    break;      }   }   /* layout the choices if they have    * changed and no choice or mark has a fixed position.    */   if (choices_changed) {      dp->status.menu_dirty = TRUE;      if (!dp->status.choice_fixed)         layout_choices(ip);    }   /* move any specified choices */   choices_moved = move_specified(ip, orig_avlist);   if (choices_changed || choices_moved)      update_item_rect(ip);   return 1;} /* set_attr */static voidupdate_item_rect(ip)panel_item_handle       ip;{   update_value_rect(ip);   ip->rect = panel_enclosing_rect(&ip->label_rect, &ip->value_rect);}  /* re_alloc_choices allocates dp->choices from choices.  The * old info is reused and then freed. */static intre_alloc_choices(ip, type, choices)register panel_item_handle 	ip;		/* the item */int 				type;		/* IM_STRING or IM_PIXRECT */caddr_t 			choices[];	/* each choice */

⌨️ 快捷键说明

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