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

📄 spinbutton.c

📁 安装DDD之前
💻 C
📖 第 1 页 / 共 5 页
字号:
	else {	    xm_string = spin_p->items[spin_p->position];	    if ((text = GetTextString(xm_string))) {		XtSetArg(arg, XmNvalue, text);		XtSetValues(spin_p->text, &arg, 1);		XtFree(text);	    }	}    }}/* * Set the maximum size of the label, depending on the * characteristics of the list of items.  Not very efficient * if switching from numeric to non-numeric. */static voidSetMaximumLabelSize(spin_p)DtSpinButtonPart *spin_p;{    XmString xm_string;    XmFontList font_list;    char string[NUMERIC_LENGTH];    Dimension width, height;    Dimension longest = 0;    Dimension highest = 0;    Arg args[5];    int i;    /* Get font info from the widget */    XtSetArg(args[0], XmNfontList, &font_list);    XtGetValues(spin_p->label, args, 1);    if (spin_p->child_type == XmNUMERIC) {	/* Find out maximum size of the widget from min/max */	sprintf(string, spin_p->float_format, spin_p->min);	xm_string = XmStringCreateSimple(string);	XmStringExtent(font_list, xm_string, &longest, &highest);	XmStringFree(xm_string);	sprintf(string, spin_p->float_format, spin_p->max);	xm_string = XmStringCreateSimple(string);	XmStringExtent(font_list, xm_string, &width, &height);	XmStringFree(xm_string);		longest = (width > longest) ? width : longest;	highest = (height > highest) ? height : highest;    }    else if (spin_p->items) {	/*	 * Loop through all the items to find the biggest dimensions	 */	for (i = 0; i < spin_p->item_count; i++) {	    XmStringExtent(font_list, spin_p->items[i], &width, &height);	    longest = (width > longest) ? width : longest;	    highest = (height > highest) ? height : highest;	}    }    else	XmStringExtent(font_list, InitLabel, &longest, &highest);    spin_p->label_max_length = longest + (LABEL_PADDING * 2);    spin_p->label_max_height = highest;    XtResizeWidget(spin_p->label, spin_p->label_max_length, highest,		   spin_p->label->core.border_width);}/* * Put the current list item into the label. */static voidSetLabelData(spin)DtSpinButtonWidget spin;{    DtSpinButtonPart *spin_p = (DtSpinButtonPart*)&(spin->spin_button);    XmString xm_string;    char string[NUMERIC_LENGTH];    int index = spin_p->position;    Arg arg;    if (spin_p->child_type == XmNUMERIC) {	sprintf(string, spin_p->float_format, (float)spin_p->current);	xm_string = XmStringCreateSimple(string);	XtSetArg(arg, XmNlabelString, xm_string);	XtSetValues(spin_p->label, &arg, 1);    }    else {	/*	 * If the item is not empty, get the current item from the list, else	 * use InitLabel.	 */	xm_string = (spin_p->items) ? spin_p->items[index] : InitLabel;	XtSetArg(arg, XmNlabelString, xm_string);	XtSetValues(spin_p->label, &arg, 1);    }}/* * Timout dispatch routine.  This calls the appropriate callback function * to simulate up or down arrow activation. */static voidtimer_dispatch(client_data, id)XtPointer client_data;XtIntervalId *id;{    DtSpinButtonWidget spin_w = (DtSpinButtonWidget)client_data;    DtSpinButtonPart *spin_p = (DtSpinButtonPart*)&(spin_w->spin_button);    timer = 0;    spin_p->init_cb = FALSE;    if (spin_p->which_arrow == XmARROW_UP) {	if (spin_p->grabbed) {	    XtRemoveGrab(spin_p->up_arrow);	    spin_p->grabbed = FALSE;	}	up_cb(NULL, client_data, NULL);    }    else {	if (spin_p->grabbed) {	    XtRemoveGrab(spin_p->down_arrow);	    spin_p->grabbed = FALSE;	}	down_cb(NULL, client_data, NULL);    }}static voidTextFieldActivate(spin_p)DtSpinButtonPart *spin_p;{    XmTextFieldWidget w = (XmTextFieldWidget)(spin_p->text);    XmAnyCallbackStruct cb;    char string[NUMERIC_LENGTH];    char *data = NULL;    char *text = NULL;    Arg arg;    Boolean free_me = TRUE;        XtSetArg(arg, XmNvalue, &data);    XtGetValues((Widget)w, &arg, 1);    if (spin_p->child_type == XmNUMERIC) {	sprintf(string, spin_p->float_format, (float)spin_p->current);	text = string;	free_me = FALSE;    }    else if (spin_p->items)	text = GetTextString(spin_p->items[spin_p->position]);    if (text && data && (strcmp(text, data) == 0)) {	if (free_me)	    XtFree(text);	return;    }    /* Only send callback if both are not NULL */    else if (!((text == NULL) && (data == NULL))) {	cb.reason = XmCR_ACTIVATE;	cb.event  = NULL;	XtCallCallbackList((Widget)w, w->text.activate_callback,			   (XtPointer)&cb);	if (text && free_me)	    XtFree(text);    }}/* * This function calls the appropriate callback for the spin-button. * It gathers the correct arguments and fills in the callback structure. */static BooleanSendCallback(spin, event, value_changed, position, current, crossed)DtSpinButtonWidget spin;XEvent *event;Boolean value_changed;int position;float current; /* Used for numeric */Boolean crossed;{    DtSpinButtonPart *spin_p = (DtSpinButtonPart*)&(spin->spin_button);    DtSpinButtonCallbackStruct cb;    XmString xm_string = NULL;    char string[NUMERIC_LENGTH];    if (spin_p->child_type == XmNUMERIC) {	sprintf(string, spin_p->float_format, (float)current);	xm_string = XmStringCreateSimple(string);    }    else {	xm_string = (spin_p->items) ? spin_p->items[position] : InitLabel;	xm_string = XmStringCopy(xm_string);    }    if (event)	cb.reason = XmCR_OK;    else if (spin_p->which_arrow == XmARROW_UP)	cb.reason = XmCR_SPIN_UP;    else	cb.reason = XmCR_SPIN_DOWN;    cb.doit = TRUE;    cb.event = event;    cb.widget = (Widget)spin;    cb.position = position;    cb.value = xm_string;    cb.crossed_boundary = crossed;    if (value_changed) {	XtCallCallbackList((Widget)spin, spin_p->value_changed_callback, 			   (XtPointer)&cb);	cb.doit = TRUE;    }    else {	XtCallCallbackList((Widget)spin, spin_p->modify_verify_callback, 			   (XtPointer)&cb);    }    XmStringFree(xm_string);    return(cb.doit);}/* * This function gets called by the up/down arm callback functions. * We set up the timer and send the modify-verify and value-changed * callbacks.  * There are potential problems if the user does some weird stuff  * in the callbacks.  I have added protection against the case where * a user does a grab (with XtAddGrab/XtPopup/etc.) in the callbacks. * Grabbing in the callback would cause us to lose the button-release * (disarm), which would make the timer go on forever.  A grab is * done after the callbacks just to make sure we will receive the * button-release.  The button-release will call disarm_cb() which will * un-grab and disable the timer.  I have also added a leave callback * which helps to protect against these kinds of problems.   * If the callback goes into another event-loop (which I hope would * never happen), we would spin continuously (since our XtAddGrab never * get called), until the user left the window (which would call  * grab_leave_cb).  The grabbed flag gets set if we do the grab, so that * we know if we can remove the grab.  Our XtAddGrab() might not get called * if the callback enters another event-loop. * * The event sent in the callback will be NULL during continuous spinning. */static voidFinishUpDown(spin, arrow_call_data, new_position, new_current, crossed)DtSpinButtonWidget spin;XtPointer arrow_call_data;int new_position;float new_current;Boolean crossed;{    DtSpinButtonPart *spin_p = (DtSpinButtonPart*)&(spin->spin_button);    XmArrowButtonCallbackStruct *arrow_data;    XEvent *last_event = NULL;    int repeat_delay = spin_p->repeat_delay;    if (spin_p->init_cb)    	repeat_delay = spin_p->initial_delay;    timer = XtAppAddTimeOut(XtWidgetToApplicationContext((Widget)spin),			    repeat_delay, timer_dispatch, (XtPointer)spin);    /* Try to get Xevent */    if ((arrow_data = (XmArrowButtonCallbackStruct*)arrow_call_data))	last_event = arrow_data->event;    /*      * Send modify_verify callback.  If user says no, then     * clear the timer and reset the state before returning.     */    if (SendCallback(spin, last_event, FALSE, new_position,		     new_current, crossed) == FALSE) {	XtRemoveTimeOut(timer);	timer = (XtIntervalId)NULL;	spin->spin_button.init_cb = TRUE;	return;    }    /* User said yes, so set widget values */    spin_p->position = new_position;    spin_p->current = new_current;    if (spin_p->editable)	SetTextFieldData(spin);    else	SetLabelData(spin);    /* send value_changed callback */    (void)SendCallback(spin, last_event, TRUE, spin_p->position,		       spin_p->current, crossed);    /* See notes at top of function on XtAddGrab usage */    spin_p->grabbed = TRUE;    if (spin_p->which_arrow == XmARROW_UP)	XtAddGrab(spin_p->up_arrow, FALSE, FALSE);    else	XtAddGrab(spin_p->down_arrow, FALSE, FALSE);}/* * Show the next value in the SpinButton.  If numeric, just add the * increment value.  If using string-table, get the next one in the * table.  This function takes care of wrap around.  Set the arrow * type.  This is needed for the timer_dispatch function.  up_cb * gets called the first time the button is pressed, and each time the * timer goes off. * All widget internals are expected to be correct here; they * get verified when set by the user. */static voidup_cb(w, client_data, call_data)Widget w;XtPointer client_data;XtPointer call_data;{    DtSpinButtonWidget spin = (DtSpinButtonWidget)client_data;    DtSpinButtonPart *spin_p = (DtSpinButtonPart*)&(spin->spin_button);    Boolean crossed_boundary = FALSE;    int new_position = spin_p->position;    float new_current = spin_p->current;    if (spin_p->editable)	TextFieldActivate(spin_p);    /*     * If non-numeric and no items then ignore the user activate event.     */    if ((spin_p->child_type == XmSTRING) && (spin_p->items == NULL))	return;        if (spin_p->child_type == XmNUMERIC) {	if ((new_current + spin_p->increment) > spin_p->max) {	    if (spin_p->wrap) {		new_position = spin_p->minimum;		new_current = spin_p->min;		crossed_boundary = TRUE;	    }	    else		XBell(XtDisplayOfObject((Widget)spin), 0);	}	else {	    new_position += spin_p->numeric_increment;	    new_current += spin_p->increment;	}    }    else if (spin_p->items) {	if (new_position == (spin_p->item_count - 1)) {	    if (spin_p->wrap) {		new_position = 0;		crossed_boundary = TRUE;	    }	    else		XBell(XtDisplayOfObject((Widget)spin), 0);	}	else	    new_position++;    }    spin_p->which_arrow = XmARROW_UP;    FinishUpDown(spin, call_data, new_position, new_current, crossed_boundary);}/* * Show the previous value in the SpinButton.  If numeric, just decrement * the increment value.  If using string-table, get the previous one in the * table.  This function takes care of wrap around. Set the arrow * type.  This is needed for the timer_dispatch function.  down_cb * gets called the first time the button is pressed, and each time the * timer goes off. * All widget internals are expected to be correct here; they * get verified when set by the user. */static voiddown_cb(w, client_data, call_data)Widget w;XtPointer client_data;XtPointer call_data;{    DtSpinButtonWidget spin = (DtSpinButtonWidget)client_data;    DtSpinButtonPart *spin_p = (DtSpinButtonPart*)&(spin->spin_button);    Boolean crossed_boundary = FALSE;    int new_position = spin_p->position;    f

⌨️ 快捷键说明

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