📄 spinbutton.c
字号:
break; }}/* * SetValues() routine for SpinButton widget. Most of the real work * is done in SetItems() and SetNumeric(). If items is set we store * our own XmStrings. * This function was built with static spin-buttons in mind, meaning that * is-numeric or editable resources won't be changed constantly. These * resources can be changed, but this function doesn't handle them in * a super-efficient manor. for example, changing child-type will cause * the label to be resize even if it isn't managed. */static BooleanSetValues(current, request, new)DtSpinButtonWidget current;DtSpinButtonWidget request;DtSpinButtonWidget new;{ DtSpinButtonPart *new_p = (DtSpinButtonPart*)&(new->spin_button); DtSpinButtonPart *cur_p = (DtSpinButtonPart*)&(current->spin_button); Boolean store_info; char *widget_name; Boolean label_size_changed = FALSE; Arg args[20]; int n; CheckResources(new); if (new_p->text != cur_p->text) { XtWarning(SPIN_TEXT); new_p->text = cur_p->text; } /* * Editable resource changed. If the widget (textField or Label) * doesn't exist, then create it. */ if (new_p->editable != cur_p->editable) { if (new_p->editable) { XtUnmanageChild(new_p->label); if (new_p->text == NULL) { widget_name = XtMalloc(strlen(XtName(new)) + 10); sprintf(widget_name, "%s_TF", XtName(new)); n = 0; XtSetArg(args[n], XmNcolumns, new_p->text_columns); n++; XtSetArg(args[n], XmNmaxLength, new_p->text_max_length); n++; XtSetArg(args[n], XmNmarginWidth, 2); n++; XtSetArg(args[n], XmNmarginHeight, 2); n++; new_p->text = XtCreateManagedWidget(widget_name, xmTextFieldWidgetClass, (Widget)new, args, n); XtAddCallback(new_p->text, XmNlosingFocusCallback, text_losing_focus_cb, (XtPointer)new); XtAddCallback(new_p->text, XmNactivateCallback, text_activate_cb, (XtPointer)new); XtAddCallback(new_p->text, XmNfocusCallback, text_focus_cb, (XtPointer)new); XtFree(widget_name); } else XtManageChild(new_p->text); } else { XtUnmanageChild(new_p->text); if (new_p->label == NULL) { widget_name = XtMalloc(strlen(XtName(new)) + 10); sprintf(widget_name, "%s_Label", XtName(new)); n = 0; XtSetArg(args[n], XmNalignment, new_p->alignment); n++; XtSetArg(args[n], XmNrecomputeSize, FALSE); n++; XtSetArg(args[n], XmNlabelString, InitLabel); n++; XtSetArg(args[n], XmNmarginLeft, LABEL_PADDING); n++; XtSetArg(args[n], XmNmarginRight, LABEL_PADDING); n++; XtSetArg(args[n], XmNmarginWidth, 0); n++; XtSetArg(args[n], XmNmarginHeight, 0); n++; new_p->label = XtCreateManagedWidget(widget_name, xmLabelWidgetClass, (Widget)new, args, n); XtOverrideTranslations((Widget)new_p->label, child_trans); XtFree(widget_name); } else XtManageChild(new_p->label); } /* * Text-fields and labels have different shadows. Only * change if user didn't change the shadow resource. */ if (SPIN_SHADOW(new) == SPIN_SHADOW(current)) SPIN_SHADOW(new) = (new_p->editable) ? TEXT_FIELD_SHADOW : LABEL_SHADOW; } /* Check arrow sensitivity (up arrow is right arrow)*/ if (new_p->arrow_sensitivity != cur_p->arrow_sensitivity) { XtSetSensitive(new_p->up_arrow, ((new_p->arrow_sensitivity == XmARROWS_SENSITIVE) || (new_p->arrow_sensitivity == XmARROWS_RIGHT_SENSITIVE))); XtSetSensitive(new_p->down_arrow, ((new_p->arrow_sensitivity == XmARROWS_SENSITIVE) || (new_p->arrow_sensitivity == XmARROWS_LEFT_SENSITIVE))); } /* * Check arrow layout. Only need to change arrows if going to or * from XmARROWS_SPLIT. The LayoutChildren() routine actually * positions the arrows in the correct place. */ if (new_p->arrow_layout != cur_p->arrow_layout) { if (new_p->arrow_layout == XmARROWS_SPLIT) { XtSetArg(args[0], XmNarrowDirection, XmARROW_RIGHT); XtSetValues(new_p->up_arrow, args, 1); XtSetArg(args[0], XmNarrowDirection, XmARROW_LEFT); XtSetValues(new_p->down_arrow, args, 1); } else if (cur_p->arrow_layout == XmARROWS_SPLIT) { XtSetArg(args[0], XmNarrowDirection, XmARROW_UP); XtSetValues(new_p->up_arrow, args, 1); XtSetArg(args[0], XmNarrowDirection, XmARROW_DOWN); XtSetValues(new_p->down_arrow, args, 1); } } if (new_p->text && (new_p->text == cur_p->text)) { n = 0; if (new_p->text_columns != cur_p->text_columns) { XtSetArg(args[n], XmNcolumns, new_p->text_columns); n++; } if (new_p->text_max_length != cur_p->text_max_length) { XtSetArg(args[n], XmNmaxLength, new_p->text_max_length); n++; } if (n > 0) XtSetValues(new_p->text, args, n); } /* * LabelWidget alignment has changed. */ if (new_p->label && (new_p->alignment != cur_p->alignment)) { XtSetArg(args[0], XmNalignment, new_p->alignment); XtSetValues(new_p->label, args, 1); } store_info = ((new_p->items != cur_p->items) || (new_p->item_count != cur_p->item_count) || (new_p->decimal_points != cur_p->decimal_points) || (new_p->maximum != cur_p->maximum) || (new_p->minimum != cur_p->minimum) || (new_p->numeric_increment != cur_p->numeric_increment) || ((new_p->child_type == XmNUMERIC) && (new_p->position != cur_p->position))); if (store_info) StoreResourceInfo(new_p, cur_p, (new_p->items != cur_p->items)); if (new_p->label && (store_info || (new_p->label != cur_p->label) || (new_p->child_type != cur_p->child_type))) { SetMaximumLabelSize(new_p); label_size_changed = TRUE; } if (store_info || (new_p->alignment != cur_p->alignment) || (new_p->editable != cur_p->editable) || (new_p->position != cur_p->position) || (new_p->label != cur_p->label) || (new_p->child_type != cur_p->child_type)) { if (new_p->editable) SetTextFieldData(new); else SetLabelData(new); } /* * Must recalculate the spin_Button and re-layout the children. * If this is not editable, then set the label to its' maximum * size; it will get chopped if it is too big. This is needed * because we shrink the label down, and SetSpinButtonSize() uses * the label's core sizes to figure what size to become. */ if ((new_p->editable != cur_p->editable) || (SPIN_MARGIN_W(new) != SPIN_MARGIN_W(current)) || (SPIN_MARGIN_H(new) != SPIN_MARGIN_H(current)) || (SPIN_SHADOW(new) != SPIN_SHADOW(current)) || (new_p->arrow_layout != cur_p->arrow_layout) || (!new_p->editable && label_size_changed)) { ClearShadow(current, TRUE); if (new_p->recompute_size) SetSpinButtonSize(new); LayoutChildren(new); DrawShadow(new); } return(FALSE);}/* * This function clears the shadow around our widget. If all is TRUE, * then clear all 4 sides; otherwise, only clear the right and bottom * sides (during resize). */ static voidClearShadow(w, all)DtSpinButtonWidget w;Boolean all;{ Dimension shadow = SPIN_SHADOW(w); Dimension margin_w = SPIN_MARGIN_W(w); Dimension margin_h = SPIN_MARGIN_H(w); if ((shadow > 0) && XtIsRealized(w)) { if (all) { XClearArea(XtDisplayOfObject((Widget)w), XtWindowOfObject((Widget)w), margin_w, margin_h, w->spin_button.old_width - (margin_w * 2), shadow, FALSE); XClearArea(XtDisplayOfObject((Widget)w), XtWindowOfObject((Widget)w), margin_w, margin_h, shadow, w->spin_button.old_height - (margin_h * 2), FALSE); } XClearArea(XtDisplayOfObject((Widget)w), XtWindowOfObject((Widget)w), margin_w, w->spin_button.old_height - margin_h - shadow, w->spin_button.old_width - (margin_w * 2), shadow, FALSE); XClearArea(XtDisplayOfObject((Widget)w), XtWindowOfObject((Widget)w), w->spin_button.old_width - margin_w - shadow, margin_h, shadow, w->spin_button.old_height - (margin_h * 2), FALSE); } DrawHighlight(w, TRUE);}/* * This functions draws the shadow around our spin-button. */static voidDrawShadow(w)DtSpinButtonWidget w;{ Dimension shadow = SPIN_SHADOW(w); Dimension margin_w = SPIN_MARGIN_W(w); Dimension margin_h = SPIN_MARGIN_H(w); if ((shadow > 0) && XtIsRealized(w)) { _XmDrawShadows(XtDisplayOfObject((Widget)w), XtWindowOfObject((Widget)w), w->manager.top_shadow_GC, w->manager.bottom_shadow_GC, margin_w, margin_h, w->core.width - (margin_w * 2), w->core.height - (margin_h * 2), shadow, XmSHADOW_OUT); } DrawHighlight(w, FALSE);}/* * This function sets up the items information for the SpinButton, as * well as variables needed for child_type. */static voidStoreResourceInfo(spin_p, old_p, do_items)DtSpinButtonPart *spin_p;DtSpinButtonPart *old_p;Boolean do_items;{ XmStringTable table; int i, base = 1; if (do_items && spin_p->items) { /* Free up current items if needed */ if (old_p && old_p->items) { for (i = 0; i < old_p->item_count; i++) { XmStringFree(old_p->items[i]); } XtFree((char*)old_p->items); } /* * Loop through all the items, copy them into our space. */ table = (XmStringTable)XtMalloc(sizeof(XmString) * spin_p->item_count); for (i = 0; i < spin_p->item_count; i++) { table[i] = XmStringCopy(spin_p->items[i]); } spin_p->items = table; for (i = 0; i < spin_p->item_count; i++) spin_p->items[i] = table[i]; } /* * Store the numeric information */ /* get base number for convert ints to floats */ for (i = 0; i < spin_p->decimal_points; i++) base *= 10; /* Set new initial values */ spin_p->min = (float)spin_p->minimum/base; spin_p->max = (float)spin_p->maximum/base; spin_p->increment = (float)spin_p->numeric_increment/base; spin_p->current = spin_p->position/base; /* Create format string used to build correct XmString value */ spin_p->float_format[0] = '%'; sprintf((char*)(spin_p->float_format+1), ".%df", spin_p->decimal_points);}/* Caller must free string */static char*GetTextString(xm_string)XmString xm_string;{ XmStringContext context; XmStringComponentType type; XmStringCharSet charset; XmStringDirection direction; XmStringComponentType unknown_tag; unsigned short ul; unsigned char *uv; char *text = NULL; Boolean done = FALSE; XmStringInitContext(&context, xm_string); /* Loop until 1st char* found */ while (!done) { type = XmStringGetNextComponent(context, &text, &charset, &direction, &unknown_tag, &ul, &uv); switch (type) { case XmSTRING_COMPONENT_END: done = TRUE; break; case XmSTRING_COMPONENT_TEXT: case XmSTRING_COMPONENT_LOCALE_TEXT: done = TRUE; break; default: break; } } XmStringFreeContext(context); return(text);}/* * Take the string out of the list and put it into the text-field. * text-fields don't handle xm-strings, so we must get the char* * out of it (only getting the first segment). This is slower than * storing the text-strings (char*) ourselves, but that would take * up a lot of memory. Since this setting happens during a user * action, speed isn't a problem. */static voidSetTextFieldData(spin)DtSpinButtonWidget spin;{ DtSpinButtonPart *spin_p = (DtSpinButtonPart*)&(spin->spin_button); char string[NUMERIC_LENGTH]; XmString xm_string; char *text; Arg arg; if (spin_p->child_type == XmNUMERIC) { sprintf(string, spin_p->float_format, (float)spin_p->current); XtSetArg(arg, XmNvalue, string); XtSetValues(spin_p->text, &arg, 1); } else { if (spin_p->items == NULL){ XtSetArg(arg, XmNvalue, ""); XtSetValues(spin_p->text, &arg, 1); return; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -