summaryrefslogtreecommitdiff
path: root/iup/srccontrols/iup_gauge.c
diff options
context:
space:
mode:
Diffstat (limited to 'iup/srccontrols/iup_gauge.c')
-rwxr-xr-xiup/srccontrols/iup_gauge.c435
1 files changed, 435 insertions, 0 deletions
diff --git a/iup/srccontrols/iup_gauge.c b/iup/srccontrols/iup_gauge.c
new file mode 100755
index 0000000..8732eee
--- /dev/null
+++ b/iup/srccontrols/iup_gauge.c
@@ -0,0 +1,435 @@
+/** \file
+ * \brief Gauge 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 <cd.h>
+#include <cdiup.h>
+#include <cddbuf.h>
+
+#include "iup_object.h"
+#include "iup_attrib.h"
+#include "iup_str.h"
+#include "iup_drv.h"
+#include "iup_stdcontrols.h"
+#include "iup_controls.h"
+#include "iup_cdutil.h"
+
+#define IGAUGE_DEFAULTCOLOR "64 96 192"
+#define IGAUGE_DEFAULTSIZE "120x14"
+
+#define IGAUGE_GAP 3
+#define IGAUGE_BLOCKS 20
+
+#define gaugeround(_) ((int)((_)+.5))
+
+
+struct _IcontrolData
+{
+ iupCanvas canvas; /* from IupCanvas (must reserve it) */
+
+ int w;
+ int h;
+
+ int show_text;
+ int dashed;
+ int horiz_padding, vert_padding; /* internal margin */
+
+ long bgcolor;
+ long fgcolor;
+ long light_shadow;
+ long mid_shadow;
+ long dark_shadow;
+
+ double value; /* min<=value<max */
+ double vmin;
+ double vmax;
+
+ char* text;
+
+ cdCanvas *cddbuffer;
+ cdCanvas *cdcanvas;
+};
+
+
+static void iGaugeDrawText(Ihandle* ih, int xmid)
+{
+ int x, y, xmin, xmax, ymin, ymax;
+ char* text = ih->data->text;
+
+ cdCanvasNativeFont(ih->data->cddbuffer, IupGetAttribute(ih, "FONT"));
+ cdCanvasTextAlignment(ih->data->cddbuffer, CD_CENTER);
+ cdCanvasBackOpacity(ih->data->cddbuffer, CD_TRANSPARENT);
+
+ x = (int)(0.5 * ih->data->w);
+ y = (int)(0.5 * ih->data->h);
+
+ if(text == NULL)
+ {
+ char* m = iupStrGetMemory(30);
+ sprintf(m, "%.1f%%", 100 * (ih->data->value - ih->data->vmin) / (ih->data->vmax - ih->data->vmin));
+ text = m;
+ }
+
+ cdCanvasGetTextBox(ih->data->cddbuffer, x, y, text, &xmin, &xmax, &ymin, &ymax);
+
+ if(xmid < xmin)
+ {
+ cdCanvasForeground(ih->data->cddbuffer, ih->data->fgcolor);
+ cdCanvasText(ih->data->cddbuffer, x, y, text);
+ }
+ else if(xmid > xmax)
+ {
+ cdCanvasForeground(ih->data->cddbuffer, ih->data->bgcolor);
+ cdCanvasText(ih->data->cddbuffer, x, y, text);
+ }
+ else
+ {
+ cdCanvasClip(ih->data->cddbuffer, CD_CLIPAREA);
+ cdCanvasClipArea(ih->data->cddbuffer, xmin, xmid, ymin, ymax);
+ cdCanvasForeground(ih->data->cddbuffer, ih->data->bgcolor);
+ cdCanvasText(ih->data->cddbuffer, x, y, text);
+
+ cdCanvasClipArea(ih->data->cddbuffer, xmid, xmax, ymin, ymax);
+ cdCanvasForeground(ih->data->cddbuffer, ih->data->fgcolor);
+ cdCanvasText(ih->data->cddbuffer, x, y, text);
+ cdCanvasClip(ih->data->cddbuffer, CD_CLIPOFF);
+ }
+}
+
+static void iGaugeDrawGauge(Ihandle* ih)
+{
+ int border = 3; /* includes the pixel used to draw the 3D border */
+ int xstart = ih->data->horiz_padding+border;
+ int ystart = ih->data->vert_padding+border;
+ int xend = ih->data->w-1 - (ih->data->horiz_padding+border);
+ int yend = ih->data->h-1 - (ih->data->vert_padding+border);
+
+ cdCanvasBackground(ih->data->cddbuffer, ih->data->bgcolor);
+ cdCanvasClear(ih->data->cddbuffer);
+
+ cdIupDrawSunkenRect(ih->data->cddbuffer, 0, 0, ih->data->w-1, ih->data->h-1,
+ ih->data->light_shadow, ih->data->mid_shadow, ih->data->dark_shadow);
+
+ cdCanvasForeground(ih->data->cddbuffer, ih->data->fgcolor);
+
+ if (ih->data->dashed)
+ {
+ float step = (xend - xstart + 1) / (float)IGAUGE_BLOCKS;
+ float boxw = step - IGAUGE_GAP;
+ float vx = (float)((xend-xstart + 1) * (ih->data->value - ih->data->vmin) / (ih->data->vmax - ih->data->vmin));
+ int intvx = (int)(100 * vx);
+ float i = 0;
+
+ if(ih->data->value == ih->data->vmin)
+ return;
+
+ while(gaugeround(100*(i + boxw)) <= intvx)
+ {
+ cdCanvasBox(ih->data->cddbuffer, xstart + gaugeround(i),
+ xstart + gaugeround(i + boxw) - 1, ystart, yend);
+ i += step;
+ }
+ }
+ else
+ {
+ int xmid = xstart + gaugeround((xend-xstart + 1) * (ih->data->value - ih->data->vmin) / (ih->data->vmax - ih->data->vmin));
+
+ if(ih->data->value != ih->data->vmin)
+ cdCanvasBox(ih->data->cddbuffer, xstart, xmid, ystart, yend );
+
+ if(ih->data->show_text)
+ iGaugeDrawText(ih, xmid);
+ }
+}
+
+static int iGaugeResize_CB(Ihandle* ih)
+{
+ if (!ih->data->cddbuffer)
+ {
+ /* update canvas size */
+ cdCanvasActivate(ih->data->cdcanvas);
+
+ /* this can fail if canvas size is zero */
+ ih->data->cddbuffer = cdCreateCanvas(CD_DBUFFER, ih->data->cdcanvas);
+ }
+
+ if (!ih->data->cddbuffer)
+ return IUP_DEFAULT;
+
+ /* update size */
+ cdCanvasActivate(ih->data->cddbuffer);
+ cdCanvasGetSize(ih->data->cddbuffer,&ih->data->w,&ih->data->h,NULL,NULL);
+
+ /* update render */
+ iGaugeDrawGauge(ih);
+
+ return IUP_DEFAULT;
+}
+
+static void iGaugeRepaint(Ihandle* ih)
+{
+ if (!ih->data->cddbuffer)
+ return;
+
+ /* update render */
+ iGaugeDrawGauge(ih);
+
+ /* update display */
+ cdCanvasFlush(ih->data->cddbuffer);
+}
+
+static int iGaugeRedraw_CB(Ihandle* ih)
+{
+ if (!ih->data->cddbuffer)
+ return IUP_DEFAULT;
+
+ /* update display */
+ cdCanvasFlush(ih->data->cddbuffer);
+ return IUP_DEFAULT;
+}
+
+static void iGaugeCropValue(Ihandle* ih)
+{
+ if(ih->data->value>ih->data->vmax)
+ ih->data->value = ih->data->vmax;
+ else if(ih->data->value<ih->data->vmin)
+ ih->data->value = ih->data->vmin;
+}
+
+static int iGaugeSetFgColorAttrib(Ihandle* ih, const char* value)
+{
+ ih->data->fgcolor = cdIupConvertColor(value);
+ iGaugeRepaint(ih);
+ return 1;
+}
+
+static int iGaugeSetBgColorAttrib(Ihandle* ih, const char* value)
+{
+ if (!value)
+ value = iupControlBaseGetParentBgColor(ih);
+
+ ih->data->bgcolor = cdIupConvertColor(value);
+ cdIupCalcShadows(ih->data->bgcolor, &ih->data->light_shadow, &ih->data->mid_shadow, &ih->data->dark_shadow);
+
+ iGaugeRepaint(ih);
+ return 1;
+}
+
+static int iGaugeSetValueAttrib(Ihandle* ih, const char* value)
+{
+ if(value == NULL)
+ ih->data->value = 0;
+ else
+ ih->data->value = atof(value);
+ iGaugeCropValue(ih);
+
+ iGaugeRepaint(ih);
+ return 0; /* do not store value in hash table */
+}
+
+static char* iGaugeGetValueAttrib(Ihandle* ih)
+{
+ char* value = iupStrGetMemory(30);
+ sprintf(value, "%g", ih->data->value);
+ return value;
+}
+
+static int iGaugeSetMinAttrib(Ihandle* ih, const char* value)
+{
+ ih->data->vmin = atof(value);
+ iGaugeCropValue(ih);
+
+ iGaugeRepaint(ih);
+ return 0; /* do not store value in hash table */
+}
+
+static char* iGaugeGetMinAttrib(Ihandle* ih)
+{
+ char* value = iupStrGetMemory(30);
+ sprintf(value, "%g", ih->data->vmin);
+ return value;
+}
+
+static int iGaugeSetMaxAttrib(Ihandle* ih, const char* value)
+{
+ ih->data->vmax = atof(value);
+ iGaugeCropValue(ih);
+ iGaugeRepaint(ih);
+ return 0; /* do not store value in hash table */
+}
+
+static char* iGaugeGetMaxAttrib(Ihandle* ih)
+{
+ char* value = iupStrGetMemory(30);
+ sprintf(value, "%g", ih->data->vmax);
+ return value;
+}
+
+static int iGaugeSetShowTextAttrib(Ihandle* ih, const char* value)
+{
+ if(iupStrEqualNoCase(value, "YES"))
+ ih->data->show_text = 1;
+ else if(iupStrEqualNoCase(value, "NO"))
+ ih->data->show_text = 0;
+
+ iGaugeRepaint(ih);
+ return 0; /* do not store value in hash table */
+}
+
+static char* iGaugeGetShowTextAttrib(Ihandle* ih)
+{
+ if(ih->data->show_text)
+ return "YES";
+ else
+ return "NO";
+}
+
+static int iGaugeSetPaddingAttrib(Ihandle* ih, const char* value)
+{
+ iupStrToIntInt(value, &ih->data->horiz_padding, &ih->data->vert_padding, 'x');
+ iGaugeRepaint(ih);
+ return 0;
+}
+
+static char* iGaugeGetPaddingAttrib(Ihandle* ih)
+{
+ char *str = iupStrGetMemory(50);
+ sprintf(str, "%dx%d", ih->data->horiz_padding, ih->data->vert_padding);
+ return str;
+}
+
+static int iGaugeSetDashedAttrib(Ihandle* ih, const char* value)
+{
+ if(iupStrEqualNoCase(value, "YES"))
+ ih->data->dashed = 1;
+ else if(iupStrEqualNoCase(value, "NO"))
+ ih->data->dashed = 0;
+
+ iGaugeRepaint(ih);
+ return 0; /* do not store value in hash table */
+}
+
+static char* iGaugeGetDashedAttrib(Ihandle* ih)
+{
+ if(ih->data->dashed)
+ return "YES";
+ else
+ return "NO";
+}
+
+static int iGaugeSetTextAttrib(Ihandle* ih, const char* value)
+{
+ if (ih->data->text)
+ free(ih->data->text);
+
+ ih->data->text = iupStrDup(value);
+
+ iGaugeRepaint(ih);
+ return 0; /* do not store value in hash table */
+}
+
+static char* iGaugeGetTextAttrib(Ihandle* ih)
+{
+ return ih->data->text;
+}
+
+static void iGaugeUnMapMethod(Ihandle* ih)
+{
+ if (ih->data->cddbuffer)
+ cdKillCanvas(ih->data->cddbuffer);
+
+ if (ih->data->cdcanvas)
+ cdKillCanvas(ih->data->cdcanvas);
+}
+
+static int iGaugeMapMethod(Ihandle* ih)
+{
+ ih->data->cdcanvas = cdCreateCanvas(CD_IUP, ih);
+ if (!ih->data->cdcanvas)
+ return IUP_ERROR;
+
+ /* this can fail if canvas size is zero */
+ ih->data->cddbuffer = cdCreateCanvas(CD_DBUFFER, ih->data->cdcanvas);
+
+ return IUP_NOERROR;
+}
+
+static int iGaugeCreateMethod(Ihandle* ih, void **params)
+{
+ (void)params;
+
+ /* free the data allocated by IupCanvas */
+ if (ih->data)
+ free(ih->data);
+ ih->data = iupALLOCCTRLDATA();
+
+ /* change the IupCanvas default values */
+ iupAttribSetStr(ih, "BORDER", "NO");
+ IupSetAttribute(ih, "SIZE", IGAUGE_DEFAULTSIZE);
+ ih->expand = IUP_EXPAND_NONE;
+
+ /* default values */
+ iupAttribSetStr(ih, "FGCOLOR", IGAUGE_DEFAULTCOLOR);
+ ih->data->fgcolor = cdIupConvertColor(IGAUGE_DEFAULTCOLOR);
+ ih->data->vmax = 1;
+ ih->data->bgcolor = CD_GRAY;
+ ih->data->light_shadow = CD_WHITE;
+ ih->data->mid_shadow = CD_GRAY;
+ ih->data->dark_shadow = CD_DARK_GRAY;
+ ih->data->show_text = 1;
+
+ /* IupCanvas callbacks */
+ IupSetCallback(ih, "RESIZE_CB", (Icallback)iGaugeResize_CB);
+ IupSetCallback(ih, "ACTION", (Icallback)iGaugeRedraw_CB);
+
+ return IUP_NOERROR;
+}
+
+Iclass* iupGaugeGetClass(void)
+{
+ Iclass* ic = iupClassNew(iupCanvasGetClass());
+
+ ic->name = "gauge";
+ ic->format = NULL; /* no parameters */
+ ic->nativetype = IUP_TYPECANVAS;
+ ic->childtype = IUP_CHILDNONE;
+ ic->is_interactive = 0;
+
+ /* Class functions */
+ ic->Create = iGaugeCreateMethod;
+ ic->Map = iGaugeMapMethod;
+ ic->UnMap = iGaugeUnMapMethod;
+
+ /* Do not need to set base attributes because they are inherited from IupCanvas */
+
+ /* IupGauge only */
+ iupClassRegisterAttribute(ic, "MIN", iGaugeGetMinAttrib, iGaugeSetMinAttrib, IUPAF_SAMEASSYSTEM, "0", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+ iupClassRegisterAttribute(ic, "MAX", iGaugeGetMaxAttrib, iGaugeSetMaxAttrib, IUPAF_SAMEASSYSTEM, "1", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+ iupClassRegisterAttribute(ic, "VALUE", iGaugeGetValueAttrib, iGaugeSetValueAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+ iupClassRegisterAttribute(ic, "DASHED", iGaugeGetDashedAttrib, iGaugeSetDashedAttrib, NULL, NULL, IUPAF_NOT_MAPPED);
+ iupClassRegisterAttribute(ic, "PADDING", iGaugeGetPaddingAttrib, iGaugeSetPaddingAttrib, IUPAF_SAMEASSYSTEM, "0x0", IUPAF_NOT_MAPPED);
+ iupClassRegisterAttribute(ic, "TEXT", iGaugeGetTextAttrib, iGaugeSetTextAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+ iupClassRegisterAttribute(ic, "SHOW_TEXT", iGaugeGetShowTextAttrib, iGaugeSetShowTextAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED);
+ iupClassRegisterAttribute(ic, "FGCOLOR", NULL, iGaugeSetFgColorAttrib, IGAUGE_DEFAULTCOLOR, NULL, IUPAF_NOT_MAPPED);
+
+ /* Overwrite IupCanvas Attributes */
+ iupClassRegisterAttribute(ic, "BGCOLOR", iupControlBaseGetBgColorAttrib, iGaugeSetBgColorAttrib, NULL, "255 255 255", IUPAF_NO_INHERIT); /* overwrite canvas implementation, set a system default to force a new default */
+
+ return ic;
+}
+
+Ihandle *IupGauge(void)
+{
+ return IupCreate("gauge");
+}