📄 panel_choice.c
字号:
/* just draw the first possible choice */ paint_choice(ip->panel, dp, 0,ip); break; case PANEL_ALL: /* draw all the choices */ /* draw each choice */ for (i = 0; i <= dp->last; i++) paint_choice(ip->panel, dp, i,ip); break; } /* indicate the current choices */ EACH_CHOICE(dp->value, dp->last, i) update_display(ip, i, TRUE);} /* paint */staticbegin_preview(ip, event)panel_item_handle ip;Event *event;{ preview_choice(ip, find_choice(ip, event), event);}staticpreview_choice(ip, new, event)panel_item_handle ip;int new; /* new choice # to preview */Event *event;{ register choice_data *dp = choice_dp(ip); int new_is_on; /* no change */ if (new == dp->current) return; /* if no new choice cancel the current choice & restore the value */ if (new == NULL_CHOICE) { cancel_preview(ip, event); return; } new_is_on = IN(dp->value, new); switch (dp->choose_one) { case TRUE: /* if no current, un-mark the actual marked choice */ if (dp->current == NULL_CHOICE) update_display(ip, choice_number(dp->value, dp->last), FALSE); else update_display(ip, dp->current, FALSE); /* mark the new choice */ update_display(ip, new, TRUE); break; case FALSE: /* restore the current choice */ update_display(ip, dp->current, dp->actual); /* toggle the mark for new */ update_display(ip, new, !new_is_on); break; } dp->current = new; dp->actual = new_is_on;}staticupdate_preview(ip, event)panel_item_handle ip;Event *event;{ begin_preview(ip, event);}/* ARGSUSED */staticcancel_preview(ip, event)panel_item_handle ip;Event *event;{ register choice_data *dp = choice_dp(ip); /* restore the current choice */ update_display(ip, dp->current, dp->actual); /* restore the value if modified */ if (dp->choose_one && dp->current != NULL_CHOICE) update_display(ip, choice_number(dp->value, dp->last), TRUE); dp->current = NULL_CHOICE;}staticaccept_preview(ip, event)panel_item_handle ip;Event *event;{ register choice_data *dp = choice_dp(ip); u_int value; /* nothing to accept if no current choice */ if (dp->current == NULL_CHOICE) return; /* remove current choice if only one choice allowed * modify the value if current is non-null */ if (dp->choose_one) { CLEAR_SET(dp->value, dp->last); ADD_CHOICE(dp->value, dp->current); } else if (!dp->actual) ADD_CHOICE(dp->value, dp->current); else REMOVE_CHOICE(dp->value, dp->current); /* notify the client */ value = choice_value(dp->choose_one, dp->value, dp->last); (*ip->notify)(ip, value, event); dp->current = NULL_CHOICE;}staticaccept_menu(ip, event)panel_item_handle ip;Event *event;{ register choice_data *dp = choice_dp(ip); int new; /* Make sure the menu title reflects the label. */ panel_sync_menu_title(ip); /* if choices have changed, * change the menu choices. */ if (dp->status.menu_dirty && !ip->menu_status.choices_set) { panel_copy_menu_choices(ip, dp->choices, dp->last); dp->status.menu_dirty = FALSE; } /* cancel any current preview */ cancel_preview(ip, event); /* let the user pick from the menu */ new = display_menu(ip, event); /* preview & accept the new choice */ preview_choice(ip, new, event); accept_preview(ip, event);}static intfind_choice(ip, event)panel_item_handle ip;Event *event;{ register int x = event_x(event); /* locator x */ register int y = event_y(event); /* locator y */ register choice_data *dp = choice_dp(ip); int current_value; /* current choice value */ register int i; /* counter */ current_value = choice_number(dp->value, dp->last); switch (dp->display_level) { case PANEL_NONE: case PANEL_CURRENT: if (!rect_includespoint(&ip->rect, x, y)) return (NULL_CHOICE); /* don't cycle if a multiple checklist */ if (!dp->choose_one) return dp->last == 0 ? 0 : NULL_CHOICE; if (event_shift_is_down(event)) /* choice backward */ return (current_value == 0 ? dp->last : current_value - 1); else /* choice forward */ return (current_value == dp->last ? 0 : current_value + 1); case PANEL_ALL: if(rect_includespoint(&ip->label_rect, x, y) && (dp->choose_one || (!dp->choose_one && dp->last == 0))) /* advance/retreat */ if (event_shift_is_down(event)) /* choice backward */ return (current_value == 0 ? dp->last : current_value - 1); else /* choice forward */ return (current_value == dp->last ? 0 : current_value + 1); for (i = 0; i <= dp->last; i++) if(rect_includespoint(&dp->choice_rects[i], x, y) || ((dp->feedback == PANEL_MARKED) && rect_includespoint(&dp->mark_rects[i], x, y))) return (i); return (NULL_CHOICE); default: /* invalid display level */ return (NULL_CHOICE); }} /* find_choice */static intdisplay_menu(ip, event)panel_item_handle ip;Event *event;/* display_menu modifies the menu of ip to indicate the current feedback (dp->value), displays the menu, allows the user to make a choice, and un-modifies the menu.*/{ register choice_data *dp = choice_dp(ip); struct menuitem *mi; /* selected item */ struct pixrect *pr; /* checked item */ register int i; /* counter */ if (show_menu_mark(ip)) { /* enhance each selected item */ EACH_CHOICE(dp->value, dp->last, i) { pr = (struct pixrect *)LINT_CAST(ip->menu->m_items[i].mi_imagedata); /* clear the off mark */ (void)pr_rop(pr, 0, 0, ip->menu_mark_width, pr->pr_height, PIX_CLR, (struct pixrect *) 0, 0, 0); /* draw the on mark */ pr_ycenter(pr, ip->menu_mark_on); } } /* display the menu */ mi = panel_menu_display(ip, event); /* restore the code in case the user hit MS_LEFT */ event_id(event) = MS_RIGHT; if (show_menu_mark(ip)) { /* restore each enhanced item */ EACH_CHOICE(dp->value, dp->last, i) { pr = (struct pixrect *)LINT_CAST(ip->menu->m_items[i].mi_imagedata); /* clear the on mark */ (void)pr_rop(pr, 0, 0, ip->menu_mark_width, pr->pr_height, PIX_CLR, (struct pixrect *) 0, 0, 0); /* draw the off mark */ pr_ycenter(pr, ip->menu_mark_off); } } return (mi == NULL ? NULL_CHOICE : (int) mi->mi_data);}staticpaint_choice(panel, dp, which_choice,ip)panel_handle panel;register choice_data *dp;register int which_choice;panel_item_handle ip;/* paint_choice paints the choice which_choice. The off mark is drawn if dp->feedback is PANEL_MARKED.*/{ if (dp->display_level == PANEL_NONE) /* don't draw the choice */ return; if (dp->feedback == PANEL_MARKED) /* draw the off mark */ (void)panel_paint_pixrect(panel, dp->mark_off[which_choice], &dp->mark_rects[which_choice],PIX_COLOR(ip->color_index)); /* draw the choice image */ (void)panel_paint_image(panel, &dp->choices[which_choice], &dp->choice_rects[which_choice],PIX_COLOR(ip->color_index));} /* paint_choice */staticupdate_display(ip, which_choice, on)register panel_item_handle ip;register int which_choice;int on;/* update_display updates the display to suggest or un-suggest which_choice depending on the value of on.*/{ register choice_data *dp = choice_dp(ip); register Rect *rp; register Rect *mark_rp; if (dp->display_level == PANEL_NONE || which_choice == NULL_CHOICE) return; if (on) { /* turn the choice on */ rp = &dp->choice_rects[which_choice]; mark_rp = &dp->mark_rects[which_choice]; if (dp->display_level == PANEL_CURRENT) { /* clear the old choice */ (void)panel_clear(ip->panel, &ip->value_rect); paint_choice(ip->panel, dp, which_choice,ip); } switch (dp->feedback) { case PANEL_INVERTED: (void)panel_invert(ip->panel, rp); break; case PANEL_MARKED: /* clear the off mark */ (void)panel_clear(ip->panel, mark_rp); /* draw the on mark */ (void)panel_paint_pixrect(ip->panel, dp->mark_on[which_choice], mark_rp, PIX_COLOR(ip->color_index)); break; case PANEL_NONE: break; } } else { /* turn the choice off */ rp = &dp->choice_rects[which_choice]; mark_rp = &dp->mark_rects[which_choice]; /* un-mark/invert old */ switch (dp->feedback) { case PANEL_INVERTED: (void)panel_invert(ip->panel, rp); break; case PANEL_MARKED: /* clear the on mark */ (void)panel_clear(ip->panel, mark_rp); /* draw the off mark */ (void)panel_paint_pixrect(ip->panel, dp->mark_off[which_choice], mark_rp, PIX_COLOR(ip->color_index)); break; case PANEL_NONE: break; } }} /* update_display */static caddr_tget_attr(ip, which_attr, arg)panel_item_handle ip;register Panel_attribute which_attr;int arg;/* get_attr returns the current value of which_attr.*/{ register choice_data *dp = choice_dp(ip); register int arg_lousy = (arg < 0 || arg > dp->last); switch (which_attr) { case PANEL_VALUE: /* ordinal value or set of values */ return (caddr_t) choice_value(dp->choose_one, dp->value, dp->last); case PANEL_TOGGLE_VALUE: /* on/off value of arg'th choice */ if (arg_lousy) return (caddr_t) 0; return (caddr_t) IN(dp->value, arg); case PANEL_DISPLAY_LEVEL: return (caddr_t) dp->display_level; case PANEL_FEEDBACK: return (caddr_t) dp->feedback; case PANEL_CHOICE_STRINGS: case PANEL_CHOICE_IMAGES: return (caddr_t) NULL; case PANEL_CHOOSE_ONE: return (caddr_t) dp->choose_one; case PANEL_CHOICE_FONT: if (arg_lousy || !is_string(&dp->choices[arg])) return (caddr_t) 0; return (caddr_t) image_font(&dp->choices[arg]); case PANEL_CHOICE_FONTS: return (caddr_t) NULL; case PANEL_CHOICE_STRING: if (arg_lousy || !is_string(&dp->choices[arg])) return (caddr_t) 0; return (caddr_t) image_string(&dp->choices[arg]); case PANEL_CHOICE_IMAGE: if (arg_lousy || !is_pixrect(&dp->choices[arg])) return (caddr_t) 0; return (caddr_t) image_pixrect(&dp->choices[arg]); case PANEL_CHOICE_X: if (arg_lousy) return (caddr_t) 0; return (caddr_t) dp->choice_rects[arg].r_left; case PANEL_CHOICE_Y: if (arg_lousy) return (caddr_t) 0; return (caddr_t) dp->choice_rects[arg].r_top; case PANEL_MARK_X: if (arg_lousy) return (caddr_t) 0; return (caddr_t) dp->mark_rects[arg].r_left; case PANEL_MARK_Y: if (arg_lousy) return (caddr_t) 0; return (caddr_t) dp->mark_rects[arg].r_top; case PANEL_MARK_IMAGE: if (arg_lousy) return (caddr_t) 0; return (caddr_t) dp->mark_on[arg]; case PANEL_NOMARK_IMAGE: if (arg_lousy) return (caddr_t) 0; return (caddr_t) dp->mark_off[arg]; default: return panel_get_generic(ip, which_attr); }} /* get_attr */static struct pr_sizeimage_size(image, above_baseline)register panel_image_handle image;register int *above_baseline;/* image_size returns the size of image. The amount of image above the baseline is also returned.*/{ struct pr_size size; /* full size */ register char *sp; /* string version */ struct pixfont *font; /* font for string */ switch (image->im_type) { case IM_STRING: sp = image_string(image); font = image_font(image); size = pf_textwidth(strlen(sp), font, sp); if (*sp) *above_baseline = -font->pf_char[*sp].pc_home.y + 1; else *above_baseline = 0; break; case IM_PIXRECT: size = image_pixrect(image)->pr_size; *above_baseline = size.y; break; } return (size);} /* image_size *//* Return the index of the first set bit in value_set */static intchoice_number(value_set, last_element)register u_int *value_set;register int last_element;{ register int i; EACH_CHOICE(value_set, last_element, i) return i; return 0;}static u_intchoice_value(choose_one, value_set, last_element)int choose_one;u_int *value_set;int last_element;{ return (choose_one ? (choice_number(value_set, last_element)) : (value_set[0]));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -