summaryrefslogtreecommitdiff
path: root/iup/srccontrols/matrix/iupmat_aux.c
diff options
context:
space:
mode:
authorPixel <pixel@nobis-crew.org>2009-11-04 11:56:41 -0800
committerPixel <pixel@nobis-crew.org>2009-11-04 11:59:33 -0800
commitd577d991b97ae2b5ee1af23641bcffc3f83af5b2 (patch)
tree590639d50205d1bcfaff2a7d2dc6ebf3f373c7ed /iup/srccontrols/matrix/iupmat_aux.c
Initial import. Contains the im, cd and iup librairies, and a "working" Makefile for them under linux.
Diffstat (limited to 'iup/srccontrols/matrix/iupmat_aux.c')
-rwxr-xr-xiup/srccontrols/matrix/iupmat_aux.c480
1 files changed, 480 insertions, 0 deletions
diff --git a/iup/srccontrols/matrix/iupmat_aux.c b/iup/srccontrols/matrix/iupmat_aux.c
new file mode 100755
index 0000000..f8b85bb
--- /dev/null
+++ b/iup/srccontrols/matrix/iupmat_aux.c
@@ -0,0 +1,480 @@
+/** \file
+ * \brief iupmatrix control
+ * auxiliary functions
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "iup.h"
+#include "iupcbs.h"
+
+#include <cd.h>
+
+#include "iup_object.h"
+#include "iup_attrib.h"
+#include "iup_str.h"
+#include "iup_drvfont.h"
+#include "iup_stdcontrols.h"
+
+#include "iupmat_def.h"
+#include "iupmat_aux.h"
+#include "iupmat_getset.h"
+
+
+static int iMatrixAuxIsFullVisibleLast(Ihandle* ih, int m)
+{
+ int i, sum = 0;
+ ImatLinColData *p;
+
+ if (m == IMAT_PROCESS_LIN)
+ p = &(ih->data->lines);
+ else
+ p = &(ih->data->columns);
+
+ for(i = p->first; i <= p->last; i++)
+ sum += p->sizes[i];
+
+ if (sum > p->visible_size)
+ return 0;
+ else
+ return 1;
+}
+
+int iupMatrixAuxIsCellFullVisible(Ihandle* ih, int lin, int col)
+{
+ if(((lin >= ih->data->lines.first) &&
+ (lin <= ih->data->lines.last) &&
+ (col >= ih->data->columns.first) &&
+ (col <= ih->data->columns.last)))
+ {
+ if (col == ih->data->columns.last && !iMatrixAuxIsFullVisibleLast(ih, IMAT_PROCESS_COL))
+ return 0;
+ if (lin == ih->data->lines.last && !iMatrixAuxIsFullVisibleLast(ih, IMAT_PROCESS_LIN))
+ return 0;
+
+ return 1;
+ }
+
+ return 0;
+}
+
+int iupMatrixAuxIsCellVisible(Ihandle* ih, int lin, int col)
+{
+ if(((lin >= ih->data->lines.first) &&
+ (lin <= ih->data->lines.last) &&
+ (col >= ih->data->columns.first) &&
+ (col <= ih->data->columns.last)))
+ {
+ return 1;
+ }
+
+ return 0;
+}
+
+void iupMatrixAuxGetVisibleCellDim(Ihandle* ih, int lin, int col, int* x, int* y, int* w, int* h)
+{
+ int i;
+
+ /* find the position where the column starts */
+ *x = ih->data->columns.sizes[0];
+ for(i = ih->data->columns.first; i < col; i++)
+ *x += ih->data->columns.sizes[i];
+
+ /* find the column size */
+ *w = ih->data->columns.sizes[col] - 1;
+
+ /* find the position where the line starts */
+ *y = ih->data->lines.sizes[0];
+ for(i = ih->data->lines.first; i < lin; i++)
+ *y += ih->data->lines.sizes[i];
+
+ /* find the line size */
+ *h = ih->data->lines.sizes[lin] - 1;
+}
+
+/* Calculate the size, in pixels, of the invisible columns/lines,
+ the left/above of the first column/line.
+ In fact the start position of the visible area.
+ Depends on the first visible column/line.
+ -> m : choose will operate on lines or columns [IMAT_PROCESS_LIN|IMAT_PROCESS_COL]
+*/
+void iupMatrixAuxUpdateVisiblePos(Ihandle* ih, int m)
+{
+ char* POS;
+ int i, sb, visible_pos;
+ ImatLinColData *p;
+
+ if (m == IMAT_PROCESS_LIN)
+ {
+ p = &(ih->data->lines);
+ sb = IUP_SB_VERT;
+ POS = "POSY";
+ }
+ else
+ {
+ p = &(ih->data->columns);
+ sb = IUP_SB_HORIZ;
+ POS = "POSX";
+ }
+
+ visible_pos = 0;
+ for(i = 1; i < p->first; i++)
+ visible_pos += p->sizes[i];
+
+ if (ih->data->canvas.sb & sb)
+ {
+ float pos;
+
+ if (p->total_size)
+ {
+ while ((visible_pos + p->visible_size > p->total_size) && p->first>1)
+ {
+ /* invalid position, must recalculate first */
+ p->first--;
+ visible_pos -= p->sizes[p->first];
+ }
+
+ pos = (float)visible_pos/(float)p->total_size;
+ }
+ else
+ pos = 0;
+
+ iupMatrixAuxUpdateLast(p);
+ IupSetfAttribute(ih, POS, "%.5f", (double)pos);
+ }
+ else
+ iupMatrixAuxUpdateLast(p);
+}
+
+/* Calculate which is the last visible column/line of the matrix.
+ Depends on the first visible column/line. */
+void iupMatrixAuxUpdateLast(ImatLinColData *p)
+{
+ int i, sum = 0;
+
+ if (p->visible_size > 0)
+ {
+ /* Find which is the last column/line
+ Start in the first visible and continue adding the widths
+ up to the visible size */
+ for(i = p->first; i < p->num; i++)
+ {
+ sum += p->sizes[i];
+ if(sum >= p->visible_size)
+ break;
+ }
+
+ if (i == p->num)
+ p->last = i-1;
+ else
+ p->last = i;
+ }
+ else
+ {
+ /* There is no space for any column, set the last column as 0 */
+ p->last = 0;
+ }
+}
+
+int iupMatrixAuxGetColumnWidth(Ihandle* ih, int col)
+{
+ int width = 0, pixels = 0;
+ char* str = iupStrGetMemory(100);
+ char* value;
+
+ /* can only be called for valid columns */
+
+ sprintf(str, "WIDTH%d", col);
+ value = iupAttribGet(ih, str);
+ if (!value)
+ {
+ sprintf(str, "RASTERWIDTH%d", col);
+ value = iupAttribGet(ih, str);
+ if (value)
+ pixels = 1;
+ }
+
+ if (!value)
+ {
+ /* Use the titles to define the size */
+ if (col == 0)
+ {
+ if (!ih->data->callback_mode || ih->data->use_title_size)
+ {
+ /* find the largest title */
+ int lin, max_width = 0;
+ for(lin = 0; lin < ih->data->lines.num; lin++)
+ {
+ char* title_value = iupMatrixCellGetValue(ih, lin, 0);
+ if (title_value)
+ {
+ iupdrvFontGetMultiLineStringSize(ih, title_value, &width, NULL);
+ if (width > max_width)
+ max_width = width;
+ }
+ }
+ width = max_width;
+ }
+ }
+ else if (ih->data->use_title_size)
+ {
+ char* title_value = iupMatrixCellGetValue(ih, 0, col);
+ if (title_value)
+ iupdrvFontGetMultiLineStringSize(ih, title_value, &width, NULL);
+ }
+ if (width)
+ return width + IMAT_PADDING_W + IMAT_FRAME_W;
+
+ if (col != 0)
+ value = iupAttribGetStr(ih, "WIDTHDEF");
+ }
+
+ if (iupStrToInt(value, &width))
+ {
+ if (width <= 0)
+ return 0;
+ else
+ {
+ if (pixels)
+ return width + IMAT_PADDING_W + IMAT_FRAME_W;
+ else
+ {
+ int charwidth;
+ iupdrvFontGetCharSize(ih, &charwidth, NULL);
+ return iupWIDTH2RASTER(width, charwidth) + IMAT_PADDING_W + IMAT_FRAME_W;
+ }
+ }
+ }
+ return 0;
+}
+
+int iupMatrixAuxGetLineHeight(Ihandle* ih, int lin)
+{
+ int height = 0, pixels = 0;
+ char* str = iupStrGetMemory(100);
+ char* value;
+
+ /* can only be called for valid lines */
+
+ sprintf(str, "HEIGHT%d", lin);
+ value = iupAttribGet(ih, str);
+ if(!value)
+ {
+ sprintf(str, "RASTERHEIGHT%d", lin);
+ value = iupAttribGet(ih, str);
+ if(value)
+ pixels = 1;
+ }
+
+ if (!value)
+ {
+ /* Use the titles to define the size */
+ if (lin == 0)
+ {
+ if (!ih->data->callback_mode || ih->data->use_title_size)
+ {
+ /* find the highest title */
+ int col, max_height = 0;
+ for(col = 0; col < ih->data->columns.num; col++)
+ {
+ char* title_value = iupMatrixCellGetValue(ih, 0, col);
+ if (title_value && title_value[0])
+ {
+ iupdrvFontGetMultiLineStringSize(ih, title_value, NULL, &height);
+ if (height > max_height)
+ max_height = height;
+ }
+ }
+ height = max_height;
+ }
+ }
+ else if (ih->data->use_title_size)
+ {
+ char* title_value = iupMatrixCellGetValue(ih, lin, 0);
+ if (title_value && title_value[0])
+ iupdrvFontGetMultiLineStringSize(ih, title_value, NULL, &height);
+ }
+ if (height)
+ return height + IMAT_PADDING_H + IMAT_FRAME_H;
+
+ if (lin != 0)
+ value = iupAttribGetStr(ih, "HEIGHTDEF");
+ }
+
+ if (iupStrToInt(value, &height))
+ {
+ if (height <= 0)
+ return 0;
+ else
+ {
+ if (pixels)
+ return height + IMAT_PADDING_H + IMAT_FRAME_H;
+ else
+ {
+ int charheight;
+ iupdrvFontGetCharSize(ih, NULL, &charheight);
+ return iupHEIGHT2RASTER(height, charheight) + IMAT_PADDING_H + IMAT_FRAME_H;
+ }
+ }
+ }
+ return 0;
+}
+
+/* Fill the sizes vector with the width/heigh of all the columns/lines.
+ Calculate the value of total_size */
+static void iMatrixAuxFillSizeVec(Ihandle* ih, int m)
+{
+ int i;
+ ImatLinColData *p;
+
+ if (m == IMAT_PROCESS_LIN)
+ p = &(ih->data->lines);
+ else
+ p = &(ih->data->columns);
+
+ /* Calculate total width/height of the matrix and the width/height of each column */
+ p->total_size = 0;
+ for(i = 0; i < p->num; i++)
+ {
+ if (m == IMAT_PROCESS_LIN)
+ p->sizes[i] = iupMatrixAuxGetLineHeight(ih, i);
+ else
+ p->sizes[i] = iupMatrixAuxGetColumnWidth(ih, i);
+
+ if (i > 0)
+ p->total_size += p->sizes[i];
+ }
+}
+
+static void iMatrixAuxUpdateVisibleSize(Ihandle* ih, int m)
+{
+ char* D;
+ ImatLinColData *p;
+ int canvas_size;
+
+ if (m == IMAT_PROCESS_LIN)
+ {
+ D = "DY";
+ p = &(ih->data->lines);
+ canvas_size = ih->data->h;
+ }
+ else
+ {
+ D = "DX";
+ p = &(ih->data->columns);
+ canvas_size = ih->data->w;
+ }
+
+ /* Matrix useful area is the current size minus the title area */
+ p->visible_size = canvas_size - p->sizes[0];
+ if (p->visible_size > p->total_size)
+ p->visible_size = p->total_size;
+
+ if (p->total_size)
+ IupSetfAttribute(ih, D, "%f", (double)p->visible_size/(double)p->total_size);
+ else
+ IupSetAttribute(ih, D, "1.0");
+}
+
+void iupMatrixAuxCalcSizes(Ihandle* ih)
+{
+ iMatrixAuxFillSizeVec(ih, IMAT_PROCESS_COL);
+ iMatrixAuxFillSizeVec(ih, IMAT_PROCESS_LIN);
+
+ iMatrixAuxUpdateVisibleSize(ih, IMAT_PROCESS_COL);
+ iMatrixAuxUpdateVisibleSize(ih, IMAT_PROCESS_LIN);
+
+ /* when removing lines the first can be positioned after the last line */
+ if (ih->data->lines.first > ih->data->lines.num-1)
+ {
+ if (ih->data->lines.num==1)
+ ih->data->lines.first = 1;
+ else
+ ih->data->lines.first = ih->data->lines.num-1;
+ }
+ if (ih->data->columns.first > ih->data->columns.num-1)
+ {
+ if (ih->data->columns.num == 1)
+ ih->data->columns.first = 1;
+ else
+ ih->data->columns.first = ih->data->columns.num-1;
+ }
+
+ iupMatrixAuxUpdateVisiblePos(ih, IMAT_PROCESS_COL);
+ iupMatrixAuxUpdateVisiblePos(ih, IMAT_PROCESS_LIN);
+
+ ih->data->need_calcsize = 0;
+}
+
+int iupMatrixAuxGetLinColFromXY(Ihandle* ih, int x, int y, int* l, int* c)
+{
+ int size, lin, col;
+
+ size = ih->data->columns.sizes[0]; /* always visible when non zero */
+ if (x < size)
+ col = 0; /* It is in the column of titles */
+ else
+ {
+ for(col = ih->data->columns.first; col <= ih->data->columns.last; col++) /* for all visible columns */
+ {
+ size += ih->data->columns.sizes[col];
+ if (x < size)
+ break;
+ }
+ if (col > ih->data->columns.last)
+ col = -1;
+ }
+
+ size = ih->data->lines.sizes[0]; /* always visible when non zero */
+ if (y < size)
+ lin = 0; /* It is in the line of titles */
+ else
+ {
+ for(lin = ih->data->lines.first; lin <= ih->data->lines.last; lin++) /* for all visible lines */
+ {
+ size += ih->data->lines.sizes[lin];
+ if (y < size)
+ break;
+ }
+ if(lin > ih->data->lines.last)
+ lin = -1;
+ }
+
+ if (col == -1 || lin == -1)
+ return 0;
+
+ *l = lin;
+ *c = col;
+ return 1;
+}
+
+int iupMatrixAuxCallLeaveCellCb(Ihandle* ih)
+{
+ IFnii cb = (IFnii)IupGetCallback(ih, "LEAVEITEM_CB");
+ if(cb)
+ return cb(ih, ih->data->lines.focus_cell, ih->data->columns.focus_cell);
+ return IUP_DEFAULT;
+}
+
+void iupMatrixAuxCallEnterCellCb(Ihandle* ih)
+{
+ IFnii cb = (IFnii)IupGetCallback(ih, "ENTERITEM_CB");
+ if (cb)
+ cb(ih, ih->data->lines.focus_cell, ih->data->columns.focus_cell);
+}
+
+int iupMatrixAuxCallEditionCbLinCol(Ihandle* ih, int lin, int col, int mode, int update)
+{
+ IFniiii cb;
+
+ if (iupAttribGetBoolean(ih, "READONLY"))
+ return IUP_IGNORE;
+
+ cb = (IFniiii)IupGetCallback(ih, "EDITION_CB");
+ if(cb)
+ return cb(ih, lin, col, mode, update);
+ return IUP_DEFAULT;
+}