iup-stack/iup/srccontrols/iup_cells.c

934 lines
26 KiB
C
Executable File

/** \file
* \brief Cells Control.
*
* See Copyright Notice in "iup.h"
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "iup.h"
#include "iupcbs.h"
#include "iupkey.h"
#include <cd.h>
#include <cd_old.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"
#include "iup_register.h"
#define ICELLS_OUT -999
struct _IcontrolData
{
iupCanvas canvas; /* from IupCanvas (must reserve it) */
cdCanvas* cd_canvas; /* 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 */
IupSetInt(ih, "POSX", posx);
IupSetInt(ih, "POSY", 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);
IupSetInt(ih, "POSY", 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);
IupSetInt(ih, "POSX", 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 iCellsAdjustScroll(Ihandle* ih, int canvas_w, int canvas_h)
{
int virtual_height, virtual_width;
/* Getting the virtual size */
iCellsGetVirtualSize(ih, &virtual_width, &virtual_height);
IupSetInt(ih, "XMAX", virtual_width);
IupSetInt(ih, "YMAX", virtual_height);
/* Setting the object scrollbar position */
IupSetInt(ih, "DX", canvas_w);
IupSetInt(ih, "DY", canvas_h);
}
/* 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 oldxmin, oldxmax, oldymin, oldymax, oldclip;
int w = ih->data->w;
int h = ih->data->h;
IFniiiiiiC draw_cb;
cdCanvas* old_cnv = cdActiveCanvas();
/* Getting clipping area for post restore */
oldclip = cdCanvasClip(ih->data->cd_canvas, CD_QUERY);
cdCanvasGetClipArea(ih->data->cd_canvas, &oldxmin, &oldxmax, &oldymin, &oldymax);
if (ih->data->clipped) /* Clipping the cell area */
{
int cxmin, cxmax, cymin, cymax;
cdCanvasClip(ih->data->cd_canvas, 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->cd_canvas, cxmin, cxmax, cymin, cymax);
}
draw_cb = (IFniiiiiiC)IupGetCallback(ih, "DRAW_CB");
if (draw_cb)
{
if (old_cnv != ih->data->cd_canvas) /* backward compatibility code */
cdActivate(ih->data->cd_canvas);
draw_cb(ih, i, j, xmin, xmax, ymin, ymax, ih->data->cd_canvas);
if (old_cnv && old_cnv != ih->data->cd_canvas)
{
cdActivate(old_cnv);
cdCanvasActivate(ih->data->cd_canvas);
}
}
cdCanvasClip(ih->data->cd_canvas, oldclip);
cdCanvasClipArea(ih->data->cd_canvas, 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->cd_canvas, CD_BLACK);
cdCanvasRect(ih->data->cd_canvas, 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->cd_canvas, ih->data->bgcolor);
cdCanvasClear(ih->data->cd_canvas);
/* 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->cd_canvas == 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->cd_canvas);
}
static int iCellsRedraw_CB(Ihandle* ih)
{
if (!ih->data->cd_canvas)
return IUP_DEFAULT;
/* update display */
cdCanvasFlush(ih->data->cd_canvas);
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 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++)
{
if (!(xmin > w))
{
int hspan = iCellsGetHspan(ih, i, j);
int 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;
/* 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)
{
int fline = iCellsGetFirstLine(ih);
int fcol = iCellsGetFirstCol(ih);
ret = cb(ih, fline, fcol);
}
if (ret == IUP_DEFAULT)
iCellsRepaint(ih);
return IUP_DEFAULT;
}
static int iCellsResize_CB(Ihandle* ih, int w, int h)
{
/* recalculate scrollbars limits */
iCellsAdjustScroll(ih, w, h);
/* This could have changed the scrollbar visibility,
so the canvas client size can change, so updated it twice. */
IupGetIntInt(ih, "DRAWSIZE", &w, &h);
IupSetInt(ih, "DX", w);
IupSetInt(ih, "DY", h);
/* update canvas size */
cdCanvasActivate(ih->data->cd_canvas);
cdCanvasGetSize(ih->data->cd_canvas, &ih->data->w, &ih->data->h, NULL, NULL);
/* 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 int iCellsMotion_CB(Ihandle* ih, int x, int y, char* r)
{
int i, j;
IFniiiis cb;
y = cdIupInvertYAxis(y, ih->data->h);
/* 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. */
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 char* iCellsGetImageCanvasAttrib(Ihandle* ih)
{
return (char*)ih->data->cd_canvas;
}
static char* iCellsGetCanvasAttrib(Ihandle* ih)
{
cdCanvas* cd_canvas_front = (cdCanvas*)IupGetAttribute(ih, "_CD_CANVAS"); /* front buffer canvas */
return (char*)cd_canvas_front;
}
static char* iCellsGetFirstLineAttrib(Ihandle* ih)
{
return iupStrReturnInt(iCellsGetFirstLine(ih));
}
static char* iCellsGetFirstColAttrib(Ihandle* ih)
{
return iupStrReturnInt(iCellsGetFirstCol(ih));
}
static char* iCellsGetLimitsAttrib(Ihandle* ih, int i, int j)
{
int xmin, xmax, ymin, ymax;
iCellsGetLimits(ih, i, j, &xmin, &xmax, &ymin, &ymax);
return iupStrReturnStrf("%d:%d:%d:%d", xmin, xmax, ymin, ymax);
}
static int iCellsSetBufferizeAttrib(Ihandle* ih, const char* value)
{
if (iupStrBoolean(value))
ih->data->bufferize = 1;
else
{
ih->data->bufferize = 0;
iCellsAdjustScroll(ih, ih->data->w, ih->data->h);
iCellsRepaint(ih);
}
return 0;
}
static char* iCellsGetBufferizeAttrib(Ihandle* ih)
{
return iupStrReturnBoolean (ih->data->bufferize);
}
static int iCellsSetRepaintAttrib(Ihandle* ih, const char* value)
{
(void)value; /* not used */
ih->data->bufferize = 0;
iCellsAdjustScroll(ih, ih->data->w, ih->data->h);
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)
{
return iupStrReturnInt(ih->data->non_scrollable_cols);
}
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)
{
return iupStrReturnInt(ih->data->non_scrollable_lins);
}
static int iCellsSetBoxedAttrib(Ihandle* ih, const char* value)
{
ih->data->boxed = iupStrBoolean(value);
iCellsRepaint(ih);
return 0;
}
static char* iCellsGetBoxedAttrib(Ihandle* ih)
{
return iupStrReturnBoolean(ih->data->boxed);
}
static int iCellsSetClippedAttrib(Ihandle* ih, const char* value)
{
ih->data->clipped = iupStrBoolean(value);
iCellsRepaint(ih);
return 0;
}
static char* iCellsGetClippedAttrib(Ihandle* ih)
{
return iupStrReturnBoolean(ih->data->clipped);
}
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->cd_canvas = cdCreateCanvas(CD_IUPDBUFFER, ih);
if (!ih->data->cd_canvas)
return IUP_ERROR;
return IUP_NOERROR;
}
static void iCellsUnMapMethod(Ihandle* ih)
{
if (ih->data->cd_canvas)
{
cdKillCanvas(ih->data->cd_canvas);
ih->data->cd_canvas = NULL;
}
}
static int iCellsCreateMethod(Ihandle* ih, void **params)
{
(void)params;
/* free the data allocated by IupCanvas */
free(ih->data);
ih->data = iupALLOCCTRLDATA();
/* change the IupCanvas default values */
iupAttribSet(ih, "SCROLLBAR", "YES");
iupAttribSet(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* iupCellsNewClass(void)
{
Iclass* ic = iupClassNew(iupRegisterFindClass("canvas"));
ic->name = "cells";
ic->format = NULL; /* no parameters */
ic->nativetype = IUP_TYPECANVAS;
ic->childtype = IUP_CHILDNONE;
ic->is_interactive = 1;
ic->has_attrib_id = 2; /* has attributes with two IDs that must be parsed */
/* Class functions */
ic->New = iupCellsNewClass;
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", "iiiiiiC");
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);
iupClassRegisterAttributeId2(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");
}