diff options
author | Pixel <pixel@nobis-crew.org> | 2009-11-04 11:56:41 -0800 |
---|---|---|
committer | Pixel <pixel@nobis-crew.org> | 2009-11-04 11:59:33 -0800 |
commit | d577d991b97ae2b5ee1af23641bcffc3f83af5b2 (patch) | |
tree | 590639d50205d1bcfaff2a7d2dc6ebf3f373c7ed /iup/src/mot/iupmot_val.c |
Initial import. Contains the im, cd and iup librairies, and a "working" Makefile for them under linux.
Diffstat (limited to 'iup/src/mot/iupmot_val.c')
-rwxr-xr-x | iup/src/mot/iupmot_val.c | 488 |
1 files changed, 488 insertions, 0 deletions
diff --git a/iup/src/mot/iupmot_val.c b/iup/src/mot/iupmot_val.c new file mode 100755 index 0000000..200d2b4 --- /dev/null +++ b/iup/src/mot/iupmot_val.c @@ -0,0 +1,488 @@ +/** \file + * \brief Valuator Control + * + * See Copyright Notice in "iup.h" + */ + +#include <Xm/Xm.h> +#include <Xm/Scale.h> +#include <Xm/SeparatoG.h> +#include <X11/keysym.h> + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <math.h> +#include <memory.h> +#include <stdarg.h> +#include <limits.h> + +#include "iup.h" +#include "iupcbs.h" + +#include "iup_object.h" +#include "iup_childtree.h" +#include "iup_attrib.h" +#include "iup_dialog.h" +#include "iup_str.h" +#include "iup_val.h" +#include "iup_image.h" +#include "iup_drv.h" + +#include "iupmot_drv.h" +#include "iupmot_color.h" + + +void iupdrvValGetMinSize(Ihandle* ih, int *w, int *h) +{ + int ticks_size = 0; + if (iupAttribGetInt(ih, "SHOWTICKS")) + ticks_size = 8; + + if (ih->data->type == IVAL_HORIZONTAL) + { + *w = 30; + *h = 20+ticks_size; + } + else + { + *w = 20+ticks_size; + *h = 30; + } +} + +static void motValRemoveOldTicks(Widget scale) +{ + WidgetList children = (WidgetList)0; + Cardinal num_children = (Cardinal)0; + Cardinal i; + String name; + + XtVaGetValues(scale, XmNchildren, &children, + XmNnumChildren, &num_children, + NULL); + + for (i = 0; i < num_children; i++) + { + if (XmIsSeparatorGadget(children[i])) + { + if ((name = XtName(children[i])) != (String)0) + { + if ((strcmp(name, "BigTic") == 0) || + (strcmp(name, "MedTic") == 0) || + (strcmp(name, "SmallTic") == 0)) + { + XtDestroyWidget(children[i]); + } + } + } + } +} + +static int motValSetShowTicksAttrib(Ihandle* ih, const char* value) +{ + int tick_freq, show_ticks; + + if (!ih->data->show_ticks) /* can only set if already not zero */ + return 0; + + show_ticks = atoi(value); + if (show_ticks<2) show_ticks=2; + ih->data->show_ticks = show_ticks; + + motValRemoveOldTicks(ih->handle); + + /* Defines the interval frequency for tick marks */ + tick_freq = SHRT_MAX/(show_ticks-1); + XmScaleSetTicks(ih->handle, tick_freq, 0, 0, 8, 0, 0); + return 0; +} + +static int motValSetPageStepAttrib(Ihandle* ih, const char* value) +{ + int pagesize; + ih->data->pagestep = atof(value); + pagesize = (int)(ih->data->pagestep*SHRT_MAX); + XtVaSetValues(ih->handle, XmNscaleMultiple, pagesize, NULL); + return 0; /* do not store value in hash table */ +} + +static int motValSetStepAttrib(Ihandle* ih, const char* value) +{ + ih->data->step = atof(value); + return 0; /* do not store value in hash table */ +} + +static int motValSetValueAttrib(Ihandle* ih, const char* value) +{ + int ival; + + ih->data->val = atof(value); + iupValCropValue(ih); + + ival = (int)(((ih->data->val-ih->data->vmin)/(ih->data->vmax - ih->data->vmin))*SHRT_MAX); + XtVaSetValues(ih->handle, XmNvalue, ival, NULL); + + return 0; /* do not store value in hash table */ +} + +static int motValSetBgColorAttrib(Ihandle* ih, const char* value) +{ + Pixel color; + unsigned char r, g, b; + if (!iupStrToRGB(value, &r, &g, &b)) + return 0; + + r = (r*8)/10; + g = (g*8)/10; + b = (b*8)/10; + + color = iupmotColorGetPixel(r, g, b); + if (color != (Pixel)-1) + { + Widget w = XtNameToWidget(ih->handle, "*Scrollbar"); + XtVaSetValues(w, XmNtroughColor, color, NULL); + } + + return iupdrvBaseSetBgColorAttrib(ih, value); +} + +static int motValSetBackgroundAttrib(Ihandle* ih, const char* value) +{ + Pixel color; + + /* ignore given value, must use only from parent */ + value = iupAttribGetInheritNativeParent(ih, "BACKGROUND"); + + color = iupmotColorGetPixelStr(value); + if (color != (Pixel)-1) + { + XtVaSetValues(ih->handle, XmNbackground, color, NULL); + return 1; + } + else + { + Pixmap pixmap = (Pixmap)iupImageGetImage(value, ih, 0); + if (pixmap) + { + XtVaSetValues(ih->handle, XmNbackgroundPixmap, pixmap, NULL); + return 1; + } + } + return 0; +} + + +/*********************************************************************************************/ + + +static void motValCallAction(Ihandle* ih, int ival, int cb_state) +{ + double old_val = ih->data->val; + IFn cb; + + ih->data->val = (((double)ival/(double)SHRT_MAX)*(ih->data->vmax - ih->data->vmin)) + ih->data->vmin; + iupValCropValue(ih); + + cb = (IFn)IupGetCallback(ih, "VALUECHANGED_CB"); + if (cb) + { + if (ih->data->val == old_val) + return; + + cb(ih); + } + else + { + IFnd cb_old; + if (cb_state == 0) + cb_old = (IFnd) IupGetCallback(ih, "MOUSEMOVE_CB"); + else if (cb_state == -1) + cb_old = (IFnd) IupGetCallback(ih, "BUTTON_RELEASE_CB"); + else + cb_old = (IFnd) IupGetCallback(ih, "BUTTON_PRESS_CB"); + + if (cb_old) + cb_old(ih, ih->data->val); + } +} + +static void motValIncPageValue(Ihandle *ih, int dir) +{ + int pagesize, ival; + pagesize = (int)(ih->data->pagestep*SHRT_MAX); + + if (ih->data->inverted) + dir *= -1; + + XtVaGetValues(ih->handle, XmNvalue, &ival, NULL); + ival += dir*pagesize; + if (ival < 0) ival = 0; + if (ival > SHRT_MAX) ival = SHRT_MAX; + XtVaSetValues(ih->handle, XmNvalue, ival, NULL); + + motValCallAction(ih, ival, 1); +} + +static void motValIncLineValue(Ihandle *ih, int dir) +{ + int linesize, ival; + linesize = (int)(ih->data->step*SHRT_MAX); + + if (ih->data->inverted) + dir *= -1; + + XtVaGetValues(ih->handle, XmNvalue, &ival, NULL); + ival += dir*linesize; + if (ival < 0) ival = 0; + if (ival > SHRT_MAX) ival = SHRT_MAX; + XtVaSetValues(ih->handle, XmNvalue, ival, NULL); + + motValCallAction(ih, ival, 1); +} + +static void motValKeyPressEvent(Widget w, Ihandle *ih, XKeyEvent *evt, Boolean *cont) +{ + KeySym motcode; + + *cont = True; + iupmotKeyPressEvent(w, ih, (XEvent*)evt, cont); + if (*cont == False) + return; + + motcode = XKeycodeToKeysym(iupmot_display, evt->keycode, 0); + + /* add missing support for numeric keyboard */ + /* add missing support for left/right in vertical + and up/down in horizontal */ + if (motcode == XK_Left || motcode == XK_KP_Left || + motcode == XK_Up || motcode == XK_KP_Up) + { + motValIncLineValue(ih, -1); + *cont = False; + return; + } + if (motcode == XK_Right || motcode == XK_KP_Right || + motcode == XK_Down || motcode == XK_KP_Down) + { + motValIncLineValue(ih, 1); + *cont = False; + return; + } + if (motcode == XK_Prior || motcode == XK_KP_Page_Up) + { + motValIncPageValue(ih, -1); + *cont = False; + return; + } + if (motcode == XK_Next || motcode == XK_KP_Page_Down) + { + motValIncPageValue(ih, 1); + *cont = False; + return; + } + + /* change Home and End default behaviour */ + if (ih->data->inverted) + { + if (motcode==XK_Home || motcode==XK_KP_Home) + { + int ival = SHRT_MAX; /* set to maximum */ + XtVaSetValues(ih->handle, XmNvalue, ival, NULL); + motValCallAction(ih, ival, 1); + *cont = False; + return; + } + if (motcode==XK_End || motcode==XK_KP_End) + { + int ival = 0; /* set to minimum */ + XtVaSetValues(ih->handle, XmNvalue, ival, NULL); + motValCallAction(ih, ival, 1); + *cont = False; + return; + } + } + else + { + /* add missing support for numeric keyboard */ + if (motcode==XK_KP_Home) + { + int ival = 0; /* set to minimum */ + XtVaSetValues(ih->handle, XmNvalue, ival, NULL); + motValCallAction(ih, ival, 1); + *cont = False; + return; + } + if (motcode==XK_KP_End) + { + int ival = SHRT_MAX; /* set to maximum */ + XtVaSetValues(ih->handle, XmNvalue, ival, NULL); + motValCallAction(ih, ival, 1); + *cont = False; + return; + } + } +} + +static void motValValueChangedCallback(Widget w, Ihandle* ih, XmScaleCallbackStruct *cbs) +{ + int cb_state = 1; + + if(cbs->reason == XmCR_DRAG) + cb_state = 0; + else if (cbs->event && (cbs->event->type==ButtonRelease || cbs->event->type==KeyRelease)) + cb_state = -1; + + motValCallAction(ih, cbs->value, cb_state); + + (void)w; +} + +static void motValButtonPressReleaseEvent(Widget w, Ihandle* ih, XButtonEvent* evt, Boolean* cont) +{ + (void)w; + (void)cont; + + /* When Button1 is pressed, the Scrollbar loses its focus to the scale, + So we avoid calling GETFOCUS/KILLFOCUS. + */ + + if (evt->type==ButtonPress && evt->button==Button1) + { + iupAttribSetStr(ih, "_IUPVAL_IGNOREFOCUS", "1"); + } + if (evt->type==ButtonRelease && evt->button==Button1) + { + iupAttribSetStr(ih, "_IUPVAL_IGNOREFOCUS", NULL); + iupAttribSetStr(ih, "_IUPVAL_IGNOREKILLFOCUS", "1"); + } +} + +static void motValFocusChangeEvent(Widget w, Ihandle *ih, XEvent *evt, Boolean *cont) +{ + if (iupAttribGet(ih, "_IUPVAL_IGNOREFOCUS")) + return; + + if (evt->type == FocusOut && iupAttribGet(ih, "_IUPVAL_IGNOREKILLFOCUS")) + { + iupAttribSetStr(ih, "_IUPVAL_IGNOREKILLFOCUS", NULL); + return; + } + + iupmotFocusChangeEvent(w, ih, evt, cont); +} + + +/*********************************************************************************************/ + + +static int motValMapMethod(Ihandle* ih) +{ + int num_args = 0; + Arg args[30]; + int show_ticks; + + /* Core */ + iupmotSetArg(args, num_args, XmNmappedWhenManaged, False); /* not visible when managed */ + iupmotSetArg(args, num_args, XmNx, 0); /* x-position */ + iupmotSetArg(args, num_args, XmNy, 0); /* y-position */ + iupmotSetArg(args, num_args, XmNwidth, 10); /* default width to avoid 0 */ + iupmotSetArg(args, num_args, XmNheight, 10); /* default height to avoid 0 */ + /* Primitive */ + if (iupAttribGetBoolean(ih, "CANFOCUS")) + iupmotSetArg(args, num_args, XmNtraversalOn, True); + else + iupmotSetArg(args, num_args, XmNtraversalOn, False); + iupmotSetArg(args, num_args, XmNhighlightThickness, 2); + iupmotSetArg(args, num_args, XmNnavigationType, XmTAB_GROUP); + /* Scale */ + iupmotSetArg(args, num_args, XmNminimum, 0); + iupmotSetArg(args, num_args, XmNmaximum, SHRT_MAX); + iupmotSetArg(args, num_args, XmNslidingMode, XmSLIDER); + iupmotSetArg(args, num_args, XmNsliderMark, XmETCHED_LINE); + iupmotSetArg(args, num_args, XmNsliderSize, 16); + iupmotSetArg(args, num_args, XmNshowValue, XmNONE); + + if (ih->data->type == IVAL_HORIZONTAL) + { + iupmotSetArg(args, num_args, XmNorientation, XmHORIZONTAL); + if (ih->data->inverted) + iupmotSetArg(args, num_args, XmNprocessingDirection, XmMAX_ON_LEFT); + else + iupmotSetArg(args, num_args, XmNprocessingDirection, XmMAX_ON_RIGHT); + } + else + { + iupmotSetArg(args, num_args, XmNorientation, XmVERTICAL); + if (ih->data->inverted) + iupmotSetArg(args, num_args, XmNprocessingDirection, XmMAX_ON_TOP); + else + iupmotSetArg(args, num_args, XmNprocessingDirection, XmMAX_ON_BOTTOM); + } + + ih->handle = XtCreateManagedWidget( + iupDialogGetChildIdStr(ih), /* child identifier */ + xmScaleWidgetClass, /* widget class */ + iupChildTreeGetNativeParentHandle(ih), /* widget parent */ + args, num_args); + + if (!ih->handle) + return IUP_ERROR; + + /* callbacks */ + XtAddEventHandler(ih->handle, EnterWindowMask, False, (XtEventHandler)iupmotEnterLeaveWindowEvent, (XtPointer)ih); + XtAddEventHandler(ih->handle, LeaveWindowMask, False, (XtEventHandler)iupmotEnterLeaveWindowEvent, (XtPointer)ih); + + /* XmScale changes the default behavior of these, must set directly into the scrollbar */ + /* XtAddEventHandler(ih->handle, FocusChangeMask, False, (XtEventHandler)iupmotFocusChangeEvent, (XtPointer)ih); */ + /* XtAddEventHandler(ih->handle, KeyPressMask, False, (XtEventHandler)iupmotKeyPressEvent, (XtPointer)ih); */ + + XtAddCallback(ih->handle, XmNdragCallback, (XtCallbackProc)motValValueChangedCallback, (XtPointer)ih); + XtAddCallback(ih->handle, XmNvalueChangedCallback, (XtCallbackProc)motValValueChangedCallback, (XtPointer)ih); + XtAddCallback(ih->handle, XmNhelpCallback, (XtCallbackProc)iupmotHelpCallback, (XtPointer)ih); + + { + Widget sb = XtNameToWidget(ih->handle, "Scrollbar"); /* TODO: Test this in other Motifs */ + if (sb) + { + XtAddEventHandler(sb, FocusChangeMask, False, (XtEventHandler)motValFocusChangeEvent, (XtPointer)ih); + XtAddEventHandler(sb, KeyPressMask, False, (XtEventHandler)motValKeyPressEvent, (XtPointer)ih); + XtAddEventHandler(sb, ButtonPressMask|ButtonReleaseMask, False, (XtEventHandler)motValButtonPressReleaseEvent, (XtPointer)ih); + } + } + + /* Ticks can only be created before XtRealizeWidget */ + show_ticks = iupAttribGetInt(ih, "SHOWTICKS"); + if (show_ticks) + { + if (show_ticks<2) show_ticks=2; + ih->data->show_ticks = show_ticks; /* non zero value, can be changed later, but not to zero */ + } + + ih->serial = iupDialogGetChildId(ih); /* must be after using the string */ + + /* initialize the widget */ + XtRealizeWidget(ih->handle); + + return IUP_NOERROR; +} + +void iupdrvValInitClass(Iclass* ic) +{ + /* Driver Dependent Class functions */ + ic->Map = motValMapMethod; + + /* Driver Dependent Attribute functions */ + + /* Visual */ + iupClassRegisterAttribute(ic, "BGCOLOR", NULL, motValSetBgColorAttrib, IUPAF_SAMEASSYSTEM, "DLGBGCOLOR", IUPAF_DEFAULT); + iupClassRegisterAttribute(ic, "BACKGROUND", NULL, motValSetBackgroundAttrib, IUPAF_SAMEASSYSTEM, "DLGBGCOLOR", IUPAF_DEFAULT); + + /* Special */ + + /* IupVal only */ + iupClassRegisterAttribute(ic, "VALUE", iupValGetValueAttrib, motValSetValueAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "PAGESTEP", iupValGetPageStepAttrib, motValSetPageStepAttrib, IUPAF_SAMEASSYSTEM, "0.1", IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "SHOWTICKS", iupValGetShowTicksAttrib, motValSetShowTicksAttrib, IUPAF_SAMEASSYSTEM, "0", IUPAF_DEFAULT); + iupClassRegisterAttribute(ic, "STEP", iupValGetStepAttrib, motValSetStepAttrib, IUPAF_SAMEASSYSTEM, "0.01", IUPAF_NO_INHERIT); +} |