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/srccontrols/iup_cells.c |
Initial import. Contains the im, cd and iup librairies, and a "working" Makefile for them under linux.
Diffstat (limited to 'iup/srccontrols/iup_cells.c')
-rwxr-xr-x | iup/srccontrols/iup_cells.c | 974 |
1 files changed, 974 insertions, 0 deletions
diff --git a/iup/srccontrols/iup_cells.c b/iup/srccontrols/iup_cells.c new file mode 100755 index 0000000..d9a7fe4 --- /dev/null +++ b/iup/srccontrols/iup_cells.c @@ -0,0 +1,974 @@ +/** \file + * \brief Cells Control. + * + * See Copyright Notice in "iup.h" + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#undef CD_NO_OLD_INTERFACE + +#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 ICELLS_OUT -999 + +struct _IcontrolData +{ + iupCanvas canvas; /* from IupCanvas (must reserve it) */ + + cdCanvas* cdcanvas; /* cd canvas for drawing */ + cdCanvas* cddbuffer; /* image canvas for double buffering */ + int w; /* control width (pixels) */ + int h; /* control height (pixels) */ + int clipped; /* cells bounding box clipping activated */ + int boxed; /* draw cells bounding box activated */ + int bufferize; /* bufferize on */ + int non_scrollable_lins; /* number of non-scrollable lines */ + int non_scrollable_cols; /* number of non-scrollable columns */ + long int bgcolor; /* Empty area color and bgcolor */ +}; + + +/* Function to inquire application cell data (line height) */ +static int iCellsGetHeight(Ihandle* ih, int i) +{ + int size; + + IFni cb = (IFni)IupGetCallback(ih, "HEIGHT_CB"); + if (!cb) + return 30; /* default value */ + + size = cb(ih, i); + if (size < 0) + size = 0; + + return size; +} + +/* Function to inquire application cell data (column width) */ +static int iCellsGetWidth(Ihandle* ih, int j) +{ + int size; + + IFni cb = (IFni)IupGetCallback(ih, "WIDTH_CB"); + if (!cb) + return 60; /* default value */ + + size = cb(ih, j); + if (size < 0) + size = 0; + + return size; +} + +/* Function used to calculate a cell limits */ +static int iCellsGetLimits(Ihandle* ih, int i, int j, int* xmin, int* xmax, int* ymin, int* ymax) +{ + int result = 1; + int xmin_sum = 0; + int ymin_sum = 0; + int w = ih->data->w; + int h = ih->data->h; + int _xmin, _xmax, _ymin, _ymax; + + /* Adjusting the inital position according to the cell's type. If it + * is non-scrollable, the origin is always zero, otherwise the origin + * is the scrollbar position */ + int posx = (j <= ih->data->non_scrollable_cols)? 0: IupGetInt(ih, "POSX"); + int posy = (i <= ih->data->non_scrollable_lins)? 0: IupGetInt(ih, "POSY"); + int idx; + + /* Adding to the origin, the cells' width and height */ + for (idx = 1; idx < j; idx++) + xmin_sum += iCellsGetWidth(ih, idx); + + for (idx = 1; idx < i; idx++) + ymin_sum += iCellsGetHeight(ih, idx); + + /* Finding the cell origin */ + _xmin = xmin_sum - posx; + _ymax = h - (ymin_sum - posy) - 1; + + /* Computing the cell limit, based on its origin and size */ + _xmax = _xmin + iCellsGetWidth(ih, j); + _ymin = _ymax - iCellsGetHeight(ih, i); + + /* Checking if the cell is visible */ + if (_xmax < 0 || _xmin > w || _ymin > h || _ymax < 0) + result = 0; + + if (xmin != NULL) + *xmin = _xmin; + + if (xmax != NULL) + *xmax = _xmax; + + if (ymin != NULL) + *ymin = _ymin; + + if (ymax != NULL) + *ymax = _ymax; + + return result; +} + +/* Function to inquire application cell data (vertical span) */ +static int iCellsGetVspan(Ihandle* ih, int i, int j) +{ + int result = 1; /* default value */ + + IFnii cb = (IFnii)IupGetCallback(ih, "VSPAN_CB"); + if (cb) + result = cb(ih, i, j); + + if (result < 0) + result = 1; + + return result; +} + +/* Function to inquire application cell data (horizontal span) */ +static int iCellsGetHspan(Ihandle* ih, int i, int j) +{ + int result = 1; /* default value */ + + IFnii cb = (IFnii)IupGetCallback(ih, "HSPAN_CB"); + if (cb) + result = cb(ih, i, j); + + if (result < 0) + result = 1; + + return result; +} + +/* Function to inquire application cell data (#columns) */ +static int iCellsGetNCols(Ihandle* ih) +{ + int result = 10; /* default value */ + + Icallback cb = IupGetCallback(ih, "NCOLS_CB"); + if (cb) + result = cb(ih); + + if (result < 0) + result = 0; + + return result; +} + +/* Function to inquire application cell data (# lines) */ +static int iCellsGetNLines(Ihandle* ih) +{ + int result = 10; /* default value */ + + Icallback cb = IupGetCallback(ih, "NLINES_CB"); + if (cb) + result = cb(ih); + + if (result < 0) + result = 0; + + return result; +} + +/* Recalculation of first visible line */ +static int iCellsGetFirstLine(Ihandle* ih) +{ + int i, j; + int nlines = iCellsGetNLines(ih); + int ncols = iCellsGetNCols(ih); + + if (ih->data->non_scrollable_lins >= nlines) + return 1; + + /* Looping the lines until a visible one is found */ + for (i = 1; i <= nlines; i++) { + for (j = 1; j <= ncols; j++) { + if (iCellsGetLimits(ih, i, j, NULL, NULL, NULL, NULL)) + return i; + } + } + return ICELLS_OUT; +} + +/* Recalculation of first visible column */ +static int iCellsGetFirstCol(Ihandle* ih) +{ + int i, j; + int ncols = iCellsGetNCols(ih); + int nlines = iCellsGetNLines(ih); + + if (ih->data->non_scrollable_cols >= ncols) + return 1; + + /* Looping the columns until a visible one is found */ + for (j = 1; j <= ncols; j++) { + for (i = 1; i <= nlines; i++) { + if (iCellsGetLimits(ih, i, j, NULL, NULL, NULL, NULL)) + return j; + } + } + return ICELLS_OUT; +} + +/* Function used to get the cells groups virtual size */ +static void iCellsGetVirtualSize(Ihandle* ih, int* wi, int* he) +{ + int i, j; + *wi = 0; *he = 0; + + /* Looping through all lines and columns, adding its width and heights + * to the return values. So, the cells virtual size is computed */ + for (i = 1; i <= iCellsGetNLines(ih); i++) + *he = *he + iCellsGetHeight(ih, i); + for (j = 1; j <= iCellsGetNCols(ih); j++) + *wi = *wi + iCellsGetWidth(ih, j); +} + +/* Function used to calculate a group of columns height */ +static int iCellsGetRangedHeight(Ihandle* ih, int from, int to) +{ + int i; + int result = 0; + + /* Looping through a column adding the line height */ + for (i = from; i <= to; i++) + result += iCellsGetHeight(ih, i); + + return result; +} + +/* Function used to calculate a group of lines width */ +static int iCellsGetRangedWidth(Ihandle* ih, int from, int to) +{ + int j; + int result = 0; + + /* Looping through a column adding the column width */ + for (j = from; j <= to; j++) + result += iCellsGetWidth(ih, j); + + return result; +} + +/* Function used to turn a cell visible */ +static void iCellsSetFullVisible(Ihandle* ih, int i, int j) +{ + int xmin, xmax, ymin, ymax; + int posx = IupGetInt(ih, "POSX"); + int posy = IupGetInt(ih, "POSY"); + int dx = 0; + int dy = 0; + + /* Getting the frontiers positions for the visible cell */ + int min_x = iCellsGetRangedWidth(ih, 1, ih->data->non_scrollable_cols); + int max_y = ih->data->h - iCellsGetRangedHeight(ih, 1, ih->data->non_scrollable_lins); + + /* Getting the cell's area limit */ + iCellsGetLimits(ih, i, j, &xmin, &xmax, &ymin, &ymax); + + /* Adjusting the diference of the scrollbars' position (horizontal) */ + if (xmax > ih->data->w) + dx = xmax - ih->data->w; + + /* Giving priority to xmin position. This can be seen by the usage + * of dx at the left part of the expression (using the last dx). + * This is the case wher the cell cannot be fitted. */ + if (xmin - dx < min_x) + dx = - (min_x - xmin); + + /* Adjusting the diference of the scrollbars' position (horizontal) */ + if (ymax > max_y) + dy = - (ymax - max_y); + if (ymin < 0) + dy = -ymin; + + /* Adding the diference to scrollbars' position */ + posx += dx; + posy += dy; + + /* Setting iup scrollbars' attributes */ + IupSetfAttribute(ih, "POSX", "%d", posx); + IupSetfAttribute(ih, "POSY", "%d", posy); +} + +/* Function used to make a cell the first visible one */ +static void iCellsAdjustOrigin(Ihandle* ih, int lin, int col) +{ + int xmin_sum, ymin_sum; + + /* If the origin line is a non-scrollable one, the scrollbar position is + * set to zero. Otherwise, the sum of the previous widths will be + * set to the scrollbar position. This algorithm is applied to both + * scrollbars */ + if (lin <= ih->data->non_scrollable_lins) + { + IupSetAttribute(ih, "POSY", "0"); + } + else if (lin <= iCellsGetNLines(ih)) + { + ymin_sum = iCellsGetRangedHeight(ih, ih->data->non_scrollable_lins+1, lin-1); + IupSetfAttribute(ih, "POSY", "%d", ymin_sum); + } + + /* As said before... */ + if (col <= ih->data->non_scrollable_cols) + { + IupSetAttribute(ih, "POSX", "0"); + } + else if (col <= iCellsGetNCols(ih)) + { + xmin_sum = iCellsGetRangedWidth(ih, ih->data->non_scrollable_cols+1, col-1); + IupSetfAttribute(ih, "POSX", "%d", xmin_sum); + } +} + +/* Function used for the scrollbar's update; usually needed when the + * object has modified its size or the cells sizes has changed. */ +static void iCellsAdjustScrolls(Ihandle* ih) +{ + int virtual_height, virtual_width; + + /* Getting the virtual size */ + iCellsGetVirtualSize(ih, &virtual_width, &virtual_height); + + IupSetfAttribute(ih, "YMAX", "%d", virtual_height-1); + IupSetfAttribute(ih, "XMAX", "%d", virtual_width-1); + + /* Setting the object scrollbar position */ + IupSetfAttribute(ih, "DY", "%d", ih->data->h); + IupSetfAttribute(ih, "DX", "%d", ih->data->w); +} + +/* Function used to call the client; is used when a cell must be repainted. */ +static void iCellsCallDrawCb(Ihandle* ih, int xmin, int xmax, int ymin, int ymax, int i, int j) +{ + int cxmin, cxmax, cymin, cymax; + int oldxmin, oldxmax, oldymin, oldymax, oldclip; + int w = ih->data->w; + int h = ih->data->h; + IFniiiiii draw_cb; + cdCanvas* old_cnv = cdActiveCanvas(); + + /* Getting clipping area for post restore */ + oldclip = cdCanvasClip(ih->data->cddbuffer, CD_QUERY); + cdCanvasGetClipArea(ih->data->cddbuffer, &oldxmin, &oldxmax, &oldymin, &oldymax); + + if (ih->data->clipped) /* Clipping the cell area */ + { + cdCanvasClip(ih->data->cddbuffer, CD_CLIPAREA); + cxmin = xmin < 0 ? 0 : xmin; + cymin = ymin < 0 ? 0 : ymin; + cxmax = xmax > w ? w : xmax; + cymax = ymax > h ? h : ymax; + cdCanvasClipArea(ih->data->cddbuffer, xmin, xmax, ymin, ymax); + } + + draw_cb = (IFniiiiii)IupGetCallback(ih, "DRAW_CB"); + if (draw_cb) + { + if (old_cnv != ih->data->cddbuffer) /* backward compatibility code */ + cdActivate(ih->data->cddbuffer); + + draw_cb(ih, i, j, xmin, xmax, ymin, ymax); + + if (old_cnv && old_cnv != ih->data->cddbuffer) + { + cdActivate(old_cnv); + cdCanvasActivate(ih->data->cddbuffer); + } + } + + cdCanvasClip(ih->data->cddbuffer, oldclip); + cdCanvasClipArea(ih->data->cddbuffer, oldxmin, oldxmax, oldymin, oldymax); +} + +/* Render function for one cell in a given coordinate. */ +static void iCellsRenderCellIn(Ihandle* ih, int i, int j, int xmin, int xmax, int ymin, int ymax) +{ + int k; + int w = ih->data->w; + int h = ih->data->h; + int hspan = 1; + int vspan = 1; + + /* Checking if the cells is out of range. (no span will affect it!) */ + if (xmin > w || ymax < 0) + return; + + /* Calculating cell spans */ + hspan = iCellsGetHspan(ih, i, j); + vspan = iCellsGetVspan(ih, i, j); + + /* if any span is set to zero, then another cell invaded its space and + * the cell does not need to draw itself */ + if (hspan == 0 || vspan == 0) + return; + + /* Increasing cell's width and height according to its spans */ + for(k = 1; k < hspan; k++) + xmax += iCellsGetWidth(ih, j+k); + for(k = 1; k < vspan; k++) + ymin -= iCellsGetHeight(ih, i+k); + + /* Checking if the cell expanded enough to appear inside the canvas */ + if (xmax < 0 || ymin > h) + return; + + /* Calling application's draw callback */ + iCellsCallDrawCb(ih, xmin, xmax, ymin, ymax, i, j); + + /* Drawing a box in cell's area */ + if (ih->data->boxed) + { + cdCanvasForeground(ih->data->cddbuffer, CD_BLACK); + cdCanvasRect(ih->data->cddbuffer, xmin, xmax, ymin, ymax); + } +} + +/* Repaint function for all cells in a given range */ +static void iCellsRenderRangedCells(Ihandle* ih, int linfrom, int linto, int colfrom, int colto) +{ + int i, j; + int xmin, xmax, ymin, ymax; + int refxmin, refxmax; + + /* Getting first cell limits: this function is slow to be called everytime */ + iCellsGetLimits(ih, linfrom, colfrom, &xmin, &xmax, &ymin, &ymax); + + /* Initializing current reference position */ + refxmin = xmin; + refxmax = xmax; + + /* Looping through the cells adding next cell width and height */ + for (i = linfrom; i <= linto; i++) + { + xmin = refxmin; + xmax = refxmax; + for (j = colfrom; j <= colto; j++) + { + iCellsRenderCellIn(ih, i, j, xmin, xmax, ymin, ymax); + xmin = xmax; + xmax = xmin + (j == colto ? 0 : iCellsGetWidth(ih, j+1)); + } + ymax = ymin; + ymin = ymax - (i == linto ? 0 : iCellsGetHeight(ih, i+1)); + } +} + +/* Repaint function for all cells */ +static void iCellsRenderCells(Ihandle* ih) +{ + int sline = ih->data->non_scrollable_lins; + int scol = ih->data->non_scrollable_cols; + int nlines = iCellsGetNLines(ih); + int ncols = iCellsGetNCols(ih); + + cdCanvasBackground(ih->data->cddbuffer, ih->data->bgcolor); + cdCanvasClear(ih->data->cddbuffer); + + /* Repainting the four parts of the cells: common cells, non-scrollable + * columns, non-scrollable lines, and non-scrollable margin + * (line and column) */ + iCellsRenderRangedCells(ih, sline+1, nlines, scol+1, ncols); + iCellsRenderRangedCells(ih, sline+1, nlines, 1, scol); + iCellsRenderRangedCells(ih, 1, sline, scol+1, ncols); + iCellsRenderRangedCells(ih, 1, sline, 1, scol); +} + +static void iCellsRepaint(Ihandle* ih) +{ + if (ih->data->cddbuffer == NULL) + return; + + /* If object is buffering, it will not be drawn */ + if (ih->data->bufferize == 1) + return; + + /* update render */ + iCellsRenderCells(ih); + + /* update display */ + cdCanvasFlush(ih->data->cddbuffer); +} + +static int iCellsRedraw_CB(Ihandle* ih) +{ + if (ih->data->cddbuffer == NULL) + return IUP_DEFAULT; + + /* update display */ + cdCanvasFlush(ih->data->cddbuffer); + return IUP_DEFAULT; +} + +/* Function used to calculate the cell coordinates limited by a hint */ +static int iCellsGetRangedCoord(Ihandle* ih, int x, int y, int* lin, int* col, int linfrom, int linto, int colfrom, int colto) +{ + int i, j, k; + int hspan, vspan; + int rxmax, rymin; + int xmin, xmax, ymin, ymax; + int refxmin, refxmax; + int w = ih->data->w; + + /* Getting the first cell's limit -- based on the range */ + iCellsGetLimits(ih, linfrom, colfrom, &xmin, &xmax, &ymin, &ymax); + + /* Initializing reference position */ + refxmin = xmin; + refxmax = xmax; + + /* Looping through the cells adding next cell width and height */ + for (i = linfrom; i <= linto; i++) + { + xmin = refxmin; + xmax = refxmax; + if (!(ymax < 0)) + { + for (j = colfrom; j <= colto; j++) + { + hspan = 1; + vspan = 1; + if (!(xmin > w)) + { + hspan = iCellsGetHspan(ih, i, j); + vspan = iCellsGetVspan(ih, i, j); + if (hspan != 0 && vspan != 0) + { + rxmax = xmax; + rymin = ymin; + for(k = 1; k < hspan; k++) + rxmax += iCellsGetWidth(ih, j+k); + for(k = 1; k < vspan; k++) + rymin -= iCellsGetHeight(ih, i+k); + + /* A cell was found */ + if (x >= xmin && x <= rxmax && y >= rymin && y <= ymax) + { + *lin = i; + *col = j; + return 1; + } + } + xmin = xmax; + xmax = xmin + (j == colto ? 0 : iCellsGetWidth(ih, j+1)); + } + } + } + ymax = ymin; + ymin = ymax - (i == linto ? 0 : iCellsGetHeight(ih, i+1)); + } + + /* No cell selected... */ + *lin = ICELLS_OUT; + *col = ICELLS_OUT; + return 0; +} + +/* Function used to calculate the cell coordinates */ +static int iCellsGetCoord(Ihandle* ih, int x, int y, int* lin, int* col) +{ + int pck = 0; + int sline = ih->data->non_scrollable_lins; + int scol = ih->data->non_scrollable_cols; + int nlines = iCellsGetNLines(ih); + int ncols = iCellsGetNCols(ih); + + /* Trying to pick a cell (raster coordinates) at the four + * parts of the cells (reverse order of the repainting): + * non-scrollable margin (line and column), non-scrollable + * columns, non-scrollable lines, and common cells. */ + pck = iCellsGetRangedCoord(ih, x, y, lin, col, 1, sline, 1, scol); + if (pck) + return 1; + + pck = iCellsGetRangedCoord(ih, x, y, lin, col, 1, sline, scol+1, ncols); + if (pck) + return 1; + + pck = iCellsGetRangedCoord(ih, x, y, lin, col, sline+1, nlines, 1, scol); + if (pck) + return 1; + + pck = iCellsGetRangedCoord(ih, x, y, lin, col, 1, nlines, 1, ncols); + return pck; +} + +static int iCellsScroll_CB(Ihandle* ih) +{ + IFnii cb; + int ret = IUP_DEFAULT; + int fline = -999; + int fcol = -999; + + fline = iCellsGetFirstLine(ih); + fcol = iCellsGetFirstCol(ih); + + /* Checking the existence of a scroll bar callback. If the application + * has set one, it will be called now. If the application returns + * IUP_DEFAULT, the cells will be repainted. */ + cb = (IFnii)IupGetCallback(ih, "SCROLLING_CB"); + if (cb) + ret = cb(ih, fline, fcol); + + if (ret == IUP_DEFAULT) + iCellsRepaint(ih); + + return IUP_DEFAULT; +} + +static int iCellsMotion_CB(Ihandle* ih, int x, int y, char* r) +{ + int i, j; + + /* Checking the existence of a motion bar callback. If the application + * has set one, it will be called now. However, before calling the + * callback, we need to find out which cell is under the mouse + * position. */ + IFniiiis cb = (IFniiiis)IupGetCallback(ih, "MOUSEMOTION_CB"); + if (!cb) + return IUP_DEFAULT; + + iCellsGetCoord(ih, x, y, &i, &j); + return cb(ih, i, j, x, y, r); +} + +static int iCellsResize_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 canvas size */ + cdCanvasActivate(ih->data->cddbuffer); + cdCanvasGetSize(ih->data->cddbuffer, &ih->data->w, &ih->data->h, NULL, NULL); + + /* recalculate scrollbars positions and size */ + iCellsAdjustScrolls(ih); + + /* update render */ + iCellsRenderCells(ih); + + return IUP_DEFAULT; +} + +static int iCellsButton_CB(Ihandle* ih, int b, int m, int x, int y, char* r) +{ + int i, j; + IFniiiiiis cb; + + y = cdIupInvertYAxis(y, ih->data->h); + + /* Treating the button event. The application will receive + * a button press callback. */ + cb = (IFniiiiiis)IupGetCallback(ih, "MOUSECLICK_CB"); + if (!cb) + return IUP_DEFAULT; + + iCellsGetCoord(ih, x, y, &i, &j); + return cb(ih, b, m, i, j, x, y, r); +} + +static char* iCellsGetImageCanvasAttrib(Ihandle* ih) +{ + return (char*)ih->data->cddbuffer; +} + +static char* iCellsGetCanvasAttrib(Ihandle* ih) +{ + return (char*)ih->data->cdcanvas; +} + +static char* iCellsGetFirstLineAttrib(Ihandle* ih) +{ + char* buffer = iupStrGetMemory(80); + sprintf( buffer, "%d", iCellsGetFirstLine(ih) ); + return buffer; +} + +static char* iCellsGetFirstColAttrib(Ihandle* ih) +{ + char* buffer = iupStrGetMemory(80); + sprintf(buffer, "%d", iCellsGetFirstCol(ih) ); + return buffer; +} + +static char* iCellsGetLimitsAttrib(Ihandle* ih, const char* name_id) +{ + char* buffer = iupStrGetMemory(80); + int xmin, xmax, ymin, ymax; + int i, j; + + if (iupStrToIntInt(name_id, &i, &j, ':') != 2) + return NULL; + + iCellsGetLimits(ih, i, j, &xmin, &xmax, &ymin, &ymax); + sprintf(buffer, "%d:%d:%d:%d", xmin, xmax, ymin, ymax); + return buffer; +} + +static int iCellsSetBufferizeAttrib(Ihandle* ih, const char* value) +{ + if (value == NULL || iupStrEqualNoCase(value, "NO")) + { + ih->data->bufferize = 0; + iCellsAdjustScrolls(ih); + iCellsRepaint(ih); + } + else + ih->data->bufferize = 1; + + return 0; +} + +static char* iCellsGetBufferizeAttrib(Ihandle* ih) +{ + if (ih->data->bufferize) + return "YES"; + else + return "NO"; +} + +static int iCellsSetRepaintAttrib(Ihandle* ih, const char* value) +{ + (void)value; /* not used */ + ih->data->bufferize = 0; + iCellsAdjustScrolls(ih); + iCellsRepaint(ih); + return 0; /* do not store value in hash table */ +} + +static int iCellsSetBgColorAttrib(Ihandle* ih, const char* value) +{ + if (!value) + value = iupControlBaseGetParentBgColor(ih); + + ih->data->bgcolor = cdIupConvertColor(value); + + iCellsRepaint(ih); + return 1; +} + +static int iCellsSetOriginAttrib(Ihandle* ih, const char* value) +{ + int lin = -9; + int col = -9; + iupStrToIntInt(value, &lin, &col, ':'); + iCellsAdjustOrigin(ih, lin, col); + iCellsRepaint(ih); + return 1; +} + +static int iCellsSetNonScrollableColsAttrib(Ihandle* ih, const char* value) +{ + if (iupStrToInt(value, &ih->data->non_scrollable_cols)) + iCellsRepaint(ih); + return 0; +} + +static char* iCellsGetNonScrollableColsAttrib(Ihandle* ih) +{ + char* buffer = iupStrGetMemory(80); + sprintf(buffer, "%d", ih->data->non_scrollable_cols); + return buffer; +} + +static int iCellsSetNonScrollableLinesAttrib(Ihandle* ih, const char* value) +{ + if (iupStrToInt(value, &ih->data->non_scrollable_lins)) + iCellsRepaint(ih); + return 0; +} + +static char* iCellsGetNonScrollableLinesAttrib(Ihandle* ih) +{ + char* buffer = iupStrGetMemory(80); + sprintf(buffer, "%d", ih->data->non_scrollable_lins); + return buffer; +} + +static int iCellsSetBoxedAttrib(Ihandle* ih, const char* value) +{ + if (iupStrEqualNoCase(value, "NO")) + ih->data->boxed = 0; + else + ih->data->boxed = 1; + + iCellsRepaint(ih); + return 0; +} + +static char* iCellsGetBoxedAttrib(Ihandle* ih) +{ + if (ih->data->boxed) + return "YES"; + else + return "NO"; +} + +static int iCellsSetClippedAttrib(Ihandle* ih, const char* value) +{ + if (iupStrEqualNoCase(value, "NO")) + ih->data->clipped = 0; + else + ih->data->clipped = 1; + + iCellsRepaint(ih); + return 0; +} + +static char* iCellsGetClippedAttrib(Ihandle* ih) +{ + if (ih->data->clipped) + return "YES"; + else + return "NO"; +} + +static int iCellsSetFullVisibleAttrib(Ihandle* ih, const char* value) +{ + int i, j; + if (iupStrToIntInt(value, &i, &j, ':') != 2) + return 0; + + iCellsSetFullVisible(ih, i, j); + iCellsRepaint(ih); + return 0; /* do not store value in hash table */ +} + + +/****************************************************************************/ + + +static int iCellsMapMethod(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 void iCellsUnMapMethod(Ihandle* ih) +{ + if (ih->data->cddbuffer) + cdKillCanvas(ih->data->cddbuffer); + + if (ih->data->cdcanvas) + cdKillCanvas(ih->data->cdcanvas); +} + +static int iCellsCreateMethod(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, "SCROLLBAR", "YES"); + iupAttribSetStr(ih, "BORDER", "NO"); + + /* default values */ + ih->data->boxed = 1; + ih->data->clipped = 1; + + /* IupCanvas callbacks */ + IupSetCallback(ih, "RESIZE_CB", (Icallback)iCellsResize_CB); + IupSetCallback(ih, "ACTION", (Icallback)iCellsRedraw_CB); + IupSetCallback(ih, "BUTTON_CB", (Icallback)iCellsButton_CB); + IupSetCallback(ih, "MOTION_CB", (Icallback)iCellsMotion_CB); + IupSetCallback(ih, "SCROLL_CB", (Icallback)iCellsScroll_CB); + + return IUP_NOERROR; +} + +Iclass* iupCellsGetClass(void) +{ + Iclass* ic = iupClassNew(iupCanvasGetClass()); + + ic->name = "cells"; + ic->format = NULL; /* no parameters */ + ic->nativetype = IUP_TYPECANVAS; + ic->childtype = IUP_CHILDNONE; + ic->is_interactive = 1; + ic->has_attrib_id = 1; /* has attributes with IDs that must be parsed */ + + /* Class functions */ + ic->Create = iCellsCreateMethod; + ic->Map = iCellsMapMethod; + ic->UnMap = iCellsUnMapMethod; + + /* Do not need to set base attributes because they are inherited from IupCanvas */ + + /* IupCells Callbacks */ + iupClassRegisterCallback(ic, "SCROLLING_CB", "ii"); + iupClassRegisterCallback(ic, "MOUSEMOTION_CB", "iiiis"); + iupClassRegisterCallback(ic, "MOUSECLICK_CB", "iiiiiis"); + iupClassRegisterCallback(ic, "DRAW_CB", "iiiiiiv"); + iupClassRegisterCallback(ic, "VSPAN_CB", "ii"); + iupClassRegisterCallback(ic, "HSPAN_CB", "ii"); + iupClassRegisterCallback(ic, "NCOLS_CB", ""); + iupClassRegisterCallback(ic, "NLINES_CB", ""); + iupClassRegisterCallback(ic, "HEIGHT_CB", "i"); + iupClassRegisterCallback(ic, "WIDTH_CB", "i"); + + /* IupCells only */ + iupClassRegisterAttribute(ic, "BOXED", iCellsGetBoxedAttrib, iCellsSetBoxedAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED); + iupClassRegisterAttribute(ic, "CLIPPED", iCellsGetClippedAttrib, iCellsSetClippedAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED); + iupClassRegisterAttribute(ic, "NON_SCROLLABLE_LINES", iCellsGetNonScrollableLinesAttrib, iCellsSetNonScrollableLinesAttrib, IUPAF_SAMEASSYSTEM, "0", IUPAF_NOT_MAPPED); + iupClassRegisterAttribute(ic, "NON_SCROLLABLE_COLS", iCellsGetNonScrollableColsAttrib, iCellsSetNonScrollableColsAttrib, IUPAF_SAMEASSYSTEM, "0", IUPAF_NOT_MAPPED); + iupClassRegisterAttribute(ic, "NO_COLOR", iupControlBaseGetBgColorAttrib, iCellsSetBgColorAttrib, NULL, NULL, IUPAF_NO_INHERIT); + + iupClassRegisterAttribute(ic, "BUFFERIZE", iCellsGetBufferizeAttrib, iCellsSetBufferizeAttrib, NULL, NULL, IUPAF_DEFAULT); + iupClassRegisterAttribute(ic, "ORIGIN", NULL, iCellsSetOriginAttrib, NULL, NULL, IUPAF_DEFAULT); + + iupClassRegisterAttribute(ic, "FULL_VISIBLE", NULL, iCellsSetFullVisibleAttrib, NULL, NULL, IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "REPAINT", NULL, iCellsSetRepaintAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT); + iupClassRegisterAttributeId(ic, "LIMITS", iCellsGetLimitsAttrib, NULL, IUPAF_READONLY|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "FIRST_COL", iCellsGetFirstColAttrib, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "FIRST_LINE", iCellsGetFirstLineAttrib, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "IMAGE_CANVAS", iCellsGetImageCanvasAttrib, NULL, NULL, NULL, IUPAF_NO_STRING|IUPAF_READONLY|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "CANVAS", iCellsGetCanvasAttrib, NULL, NULL, NULL, IUPAF_NO_STRING|IUPAF_READONLY|IUPAF_NO_INHERIT); + + /* Overwrite IupCanvas Attributes */ + iupClassRegisterAttribute(ic, "BGCOLOR", iupControlBaseGetBgColorAttrib, iCellsSetBgColorAttrib, NULL, "255 255 255", IUPAF_NO_INHERIT); /* overwrite canvas implementation, set a system default to force a new default */ + + return ic; +} + +Ihandle* IupCells(void) +{ + return IupCreate("cells"); +} |