summaryrefslogtreecommitdiff
path: root/iup/src/iup_spin.c
diff options
context:
space:
mode:
Diffstat (limited to 'iup/src/iup_spin.c')
-rwxr-xr-xiup/src/iup_spin.c301
1 files changed, 301 insertions, 0 deletions
diff --git a/iup/src/iup_spin.c b/iup/src/iup_spin.c
new file mode 100755
index 0000000..6fadab4
--- /dev/null
+++ b/iup/src/iup_spin.c
@@ -0,0 +1,301 @@
+/** \file
+ * \brief Spin control
+ *
+ * See Copyright Notice in "iup.h"
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "iup.h"
+#include "iupcbs.h"
+#include "iupkey.h"
+
+#include "iup_object.h"
+#include "iup_attrib.h"
+#include "iup_str.h"
+#include "iup_stdcontrols.h"
+#include "iup_childtree.h"
+
+
+static Ihandle* spin_timer = NULL;
+
+
+static int iSpinCallCB(Ihandle* ih, int dub, int ten, int sign)
+{
+ IFni cb;
+
+ /* get the callback on the spin or on the spinbox */
+ Ihandle* spinbox = (Ihandle*)iupAttribGet(ih->parent, "_IUPSPIN_BOX");
+ if (spinbox)
+ ih = spinbox;
+ else
+ ih = ih->parent;
+
+ cb = (IFni) IupGetCallback(ih, "SPIN_CB");
+ if (cb)
+ {
+ return cb(ih, sign*(dub && ten ? 100 :
+ ten ? 10 :
+ dub ? 2 : 1));
+ }
+
+ return IUP_DEFAULT;
+}
+
+static int iSpinTimerCB(Ihandle* ih)
+{
+ Ihandle* spin_button = (Ihandle*)iupAttribGet(ih, "_IUPSPIN_BUTTON");
+ char* status = iupAttribGet(ih, "_IUPSPIN_STATUS");
+ int spin_dir = iupAttribGetInt(ih, "_IUPSPIN_DIR");
+ int count = iupAttribGetInt(ih, "_IUPSPIN_COUNT");
+ char* reconfig = NULL;
+
+ if(count == 0) /* first time */
+ reconfig = "50";
+ else if(count == 14) /* 300 + 14*50 = 1000 (1 second) */
+ reconfig = "25";
+ else if(count == 34) /* 300 + 14*50 + 20*50 = 2000 (2 seconds) */
+ reconfig = "10";
+
+ if (reconfig)
+ {
+ IupSetAttribute(ih, "RUN", "NO");
+ IupSetAttribute(ih, "TIME", reconfig);
+ IupSetAttribute(ih, "RUN", "YES");
+ }
+
+ iupAttribSetInt(ih, "_IUPSPIN_COUNT", count + 1);
+
+ return iSpinCallCB(spin_button, iup_isshift(status), iup_iscontrol(status), spin_dir);
+}
+
+static void iSpinPrepareTimer(Ihandle* ih, char* status, char* dir)
+{
+ (void)ih;
+
+ iupAttribSetStr(spin_timer, "_IUPSPIN_BUTTON", (char*)ih);
+
+ iupAttribStoreStr(spin_timer, "_IUPSPIN_STATUS", status);
+
+ iupAttribSetStr(spin_timer, "_IUPSPIN_DIR", dir);
+ iupAttribSetStr(spin_timer, "_IUPSPIN_COUNT", "0");
+
+ IupSetAttribute(spin_timer, "TIME", "400");
+ IupSetAttribute(spin_timer, "RUN", "YES");
+}
+
+static int iSpinK_SP(Ihandle* ih)
+{
+ int dir = iupAttribGetInt(ih, "_IUPSPIN_DIR");
+
+ return iSpinCallCB(ih, 0, 0, dir);
+}
+
+static int iSpinK_sSP(Ihandle* ih)
+{
+ int dir = iupAttribGetInt(ih, "_IUPSPIN_DIR");
+
+ return iSpinCallCB(ih, 1, 0, dir);
+}
+
+static int iSpinK_cSP(Ihandle* ih)
+{
+ int dir = iupAttribGetInt(ih, "_IUPSPIN_DIR");
+
+ return iSpinCallCB(ih, 0, 1, dir);
+}
+
+static int iSpinButtonCB(Ihandle* ih, int but, int pressed, int x, int y, char* status)
+{
+ (void)x;
+ (void)y;
+
+ if (pressed && but == IUP_BUTTON1)
+ {
+ int dir = iupAttribGetInt(ih, "_IUPSPIN_DIR");
+
+ iSpinPrepareTimer(ih, status, iupAttribGet(ih, "_IUPSPIN_DIR"));
+
+ return iSpinCallCB(ih, iup_isshift(status), iup_iscontrol(status), dir);
+ }
+ else if (!pressed && but == IUP_BUTTON1)
+ {
+ IupSetAttribute(spin_timer, "RUN", "NO");
+ }
+
+ return IUP_DEFAULT;
+}
+
+static int iSpinCreateMethod(Ihandle* ih, void** params)
+{
+ Ihandle* bt_up;
+ Ihandle* bt_down;
+ (void)params;
+
+ /* Button UP */
+ bt_up = IupButton(NULL, NULL);
+
+ IupSetAttribute(bt_up, "EXPAND", "NO");
+ IupSetAttribute(bt_up, "IMAGE", "IupSpinUpImage");
+ IupSetAttribute(bt_up, "_IUPSPIN_DIR", "1");
+ IupSetAttribute(bt_up, "CANFOCUS", "NO");
+
+ IupSetCallback(bt_up, "BUTTON_CB", (Icallback) iSpinButtonCB);
+ IupSetCallback(bt_up, "K_SP", (Icallback) iSpinK_SP);
+ IupSetCallback(bt_up, "K_sSP", (Icallback) iSpinK_sSP);
+ IupSetCallback(bt_up, "K_cSP", (Icallback) iSpinK_cSP);
+
+ /* Button DOWN */
+ bt_down = IupButton(NULL, NULL);
+
+ IupSetAttribute(bt_down, "EXPAND", "NO");
+ IupSetAttribute(bt_down, "IMAGE", "IupSpinDownImage");
+ IupSetAttribute(bt_down, "_IUPSPIN_DIR", "-1");
+ IupSetAttribute(bt_down, "CANFOCUS", "NO");
+
+ IupSetCallback(bt_down, "BUTTON_CB", (Icallback) iSpinButtonCB);
+ IupSetCallback(bt_down, "K_SP", (Icallback) iSpinK_SP);
+ IupSetCallback(bt_down, "K_sSP", (Icallback) iSpinK_sSP);
+ IupSetCallback(bt_down, "K_cSP", (Icallback) iSpinK_cSP);
+
+ /* manually add the buttons as a children */
+ ih->firstchild = bt_up;
+ bt_up->parent = ih;
+ bt_up->brother = bt_down;
+ bt_down->parent = ih;
+
+ IupSetAttribute(ih, "GAP", "0");
+ IupSetAttribute(ih, "MARGIN", "0x0");
+
+ return IUP_NOERROR;
+}
+
+static int iSpinboxCreateMethod(Ihandle* ih, void** params)
+{
+ Ihandle *spin, *ctrl;
+
+ if (!params || !(params[0]))
+ return IUP_ERROR;
+
+ IupSetAttribute(ih, "GAP", "0");
+ IupSetAttribute(ih, "MARGIN", "0x0");
+ IupSetAttribute(ih, "ALIGNMENT", "ACENTER");
+
+ ctrl = (Ihandle*)(params[0]);
+ iupChildTreeAppend(ih, ctrl);
+
+ spin = IupSpin();
+ iupChildTreeAppend(ih, spin);
+
+ iupAttribSetStr(spin, "_IUPSPIN_BOX", (char*)ih);
+
+ return IUP_NOERROR;
+}
+
+static void iSpinLoadImages(void)
+{
+ Ihandle* img;
+
+ /* Spin UP image */
+ unsigned char iupspin_up_img[] = {
+ 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 0, 1, 1, 1, 1,
+ 1, 1, 1, 0, 0, 0, 1, 1, 1,
+ 1, 1, 0, 0, 0, 0, 0, 1, 1,
+ 1, 0, 0, 0, 0, 0, 0, 0, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0
+ };
+
+ /* Spin DOWN image */
+ unsigned char iupspin_down_img[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 1,
+ 1, 1, 0, 0, 0, 0, 0, 1, 1,
+ 1, 1, 1, 0, 0, 0, 1, 1, 1,
+ 1, 1, 1, 1, 0, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1
+ };
+
+ img = IupImage(9, 6, iupspin_up_img);
+ IupSetAttribute(img, "0", "0 0 0");
+ IupSetAttribute(img, "1", "BGCOLOR");
+ IupSetHandle("IupSpinUpImage", img);
+
+ img = IupImage(9, 6, iupspin_down_img);
+ IupSetAttribute(img, "0", "0 0 0");
+ IupSetAttribute(img, "1", "BGCOLOR");
+ IupSetHandle("IupSpinDownImage", img);
+}
+
+static void iSpinReleaseMethod(Iclass* ic)
+{
+ (void)ic;
+
+ if (spin_timer)
+ {
+ /* no need to destroy the images, they will be destroyed by IupClose automatically */
+ IupDestroy(spin_timer);
+ spin_timer = NULL;
+ }
+}
+
+Iclass* iupSpinboxGetClass(void)
+{
+ Iclass* ic = iupClassNew(iupHboxGetClass());
+
+ ic->name = "spinbox";
+ ic->format = "h"; /* one Ihandle */
+ ic->nativetype = IUP_TYPEVOID;
+ ic->childtype = IUP_CHILDNONE;
+ ic->is_interactive = 0;
+
+ iupClassRegisterCallback(ic, "SPIN_CB", "i");
+
+ /* Class functions */
+ ic->Create = iSpinboxCreateMethod;
+
+ return ic;
+}
+
+Iclass* iupSpinGetClass(void)
+{
+ Iclass* ic = iupClassNew(iupVboxGetClass());
+
+ ic->name = "spin";
+ ic->format = NULL; /* no parameters */
+ ic->nativetype = IUP_TYPEVOID;
+ ic->childtype = IUP_CHILDNONE;
+ ic->is_interactive = 0;
+
+ /* Class functions */
+ ic->Create = iSpinCreateMethod;
+ ic->Release = iSpinReleaseMethod;
+
+ iupClassRegisterCallback(ic, "SPIN_CB", "i");
+
+ if (!spin_timer)
+ {
+ iSpinLoadImages();
+
+ spin_timer = IupTimer();
+ IupSetCallback(spin_timer, "ACTION_CB", (Icallback) iSpinTimerCB);
+ }
+
+ return ic;
+}
+
+Ihandle* IupSpin(void)
+{
+ return IupCreate("spin");
+}
+
+Ihandle* IupSpinbox(Ihandle* ctrl)
+{
+ void *params[2];
+ params[0] = (void*)ctrl;
+ params[1] = NULL; /* must add NULL because spinbox inherit from Hbox */
+ return IupCreatev("spinbox", params);
+}