1693 lines
52 KiB
C
1693 lines
52 KiB
C
|
/** \file
|
||
|
* \brief iupmatrix control
|
||
|
* draw functions
|
||
|
*
|
||
|
* See Copyright Notice in "iup.h"
|
||
|
*/
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
#include "iup.h"
|
||
|
#include "iupcbs.h"
|
||
|
|
||
|
#include <cd.h>
|
||
|
#include <cd_old.h>
|
||
|
|
||
|
#include "iup_object.h"
|
||
|
#include "iup_attrib.h"
|
||
|
#include "iup_str.h"
|
||
|
#include "iup_drv.h"
|
||
|
#include "iup_drvfont.h"
|
||
|
#include "iup_stdcontrols.h"
|
||
|
#include "iup_image.h"
|
||
|
|
||
|
#include "iup_controls.h"
|
||
|
#include "iup_cdutil.h"
|
||
|
|
||
|
#include "iupmat_def.h"
|
||
|
#include "iupmat_cd.h"
|
||
|
#include "iupmat_draw.h"
|
||
|
#include "iupmat_aux.h"
|
||
|
#include "iupmat_getset.h"
|
||
|
#include "iupmat_mark.h"
|
||
|
|
||
|
|
||
|
#define IMAT_FEEDBACK_SIZE 16
|
||
|
|
||
|
static unsigned char imatrix_toggleoff_alpha[IMAT_FEEDBACK_SIZE * IMAT_FEEDBACK_SIZE] =
|
||
|
{
|
||
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||
|
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255,
|
||
|
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255,
|
||
|
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255,
|
||
|
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255,
|
||
|
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255,
|
||
|
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255,
|
||
|
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255,
|
||
|
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255,
|
||
|
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255,
|
||
|
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255,
|
||
|
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255,
|
||
|
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255,
|
||
|
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255,
|
||
|
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255,
|
||
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
|
||
|
};
|
||
|
|
||
|
static unsigned char imatrix_toggleon_alpha[IMAT_FEEDBACK_SIZE * IMAT_FEEDBACK_SIZE] =
|
||
|
{
|
||
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||
|
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255,
|
||
|
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255,
|
||
|
255, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 255,
|
||
|
255, 0, 0, 0, 0, 89, 252, 89, 0, 0, 0, 0, 0, 0, 0, 255,
|
||
|
255, 0, 0, 0, 84, 239, 106, 239, 84, 0, 0, 0, 0, 0, 0, 255,
|
||
|
255, 0, 0, 84, 239, 60, 0, 60, 239, 84, 0, 0, 0, 0, 0, 255,
|
||
|
255, 0, 84, 239, 60, 0, 0, 0, 60, 239, 84, 0, 0, 0, 0, 255,
|
||
|
255, 16, 227, 60, 0, 0, 0, 0, 0, 60, 239, 84, 0, 0, 0, 255,
|
||
|
255, 0, 8, 0, 0, 0, 0, 0, 0, 0, 60, 239, 84, 0, 0, 255,
|
||
|
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 239, 84, 0, 255,
|
||
|
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 227, 16, 255,
|
||
|
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 255,
|
||
|
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255,
|
||
|
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255,
|
||
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
|
||
|
};
|
||
|
|
||
|
static unsigned char imatrix_dropdown_alpha[IMAT_FEEDBACK_SIZE * IMAT_FEEDBACK_SIZE] =
|
||
|
{
|
||
|
000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000,
|
||
|
000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000,
|
||
|
000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000,
|
||
|
000, 000, 000, 000, 000, 000, 000, 128, 128, 000, 000, 000, 000, 000, 000, 000,
|
||
|
000, 000, 000, 000, 000, 000, 128, 255, 255, 128, 000, 000, 000, 000, 000, 000,
|
||
|
000, 000, 000, 000, 000, 128, 255, 255, 255, 255, 128, 000, 000, 000, 000, 000,
|
||
|
000, 000, 000, 000, 128, 255, 255, 255, 255, 255, 255, 128, 000, 000, 000, 000,
|
||
|
000, 000, 000, 128, 255, 255, 255, 255, 255, 255, 255, 255, 128, 000, 000, 000,
|
||
|
000, 000, 128, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 128, 000, 000,
|
||
|
000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000,
|
||
|
000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000,
|
||
|
000, 000, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 000, 000,
|
||
|
000, 000, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 000, 000,
|
||
|
000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000,
|
||
|
000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000,
|
||
|
000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000
|
||
|
};
|
||
|
|
||
|
static unsigned char imatrix_sortup_alpha[IMAT_FEEDBACK_SIZE * IMAT_FEEDBACK_SIZE] =
|
||
|
{
|
||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||
|
0, 0, 32, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 32, 0,
|
||
|
0, 0, 32, 239, 60, 0, 0, 0, 0, 0, 0, 0, 60, 239, 32, 0,
|
||
|
0, 0, 0, 84, 239, 60, 0, 0, 0, 0, 0, 60, 239, 84, 0, 0,
|
||
|
0, 0, 0, 0, 84, 239, 60, 0, 0, 0, 60, 239, 84, 0, 0, 0,
|
||
|
0, 0, 8, 0, 0, 84, 239, 60, 0, 60, 239, 84, 0, 0, 8, 0,
|
||
|
0, 0, 32, 32, 0, 0, 84, 239, 106, 239, 84, 0, 0, 32, 32, 0,
|
||
|
0, 0, 32, 239, 60, 0, 0, 89, 252, 89, 0, 0, 60, 239, 32, 0,
|
||
|
0, 0, 0, 84, 239, 60, 0, 0, 31, 0, 0, 60, 239, 84, 0, 0,
|
||
|
0, 0, 0, 0, 84, 239, 60, 0, 0, 0, 60, 239, 84, 0, 0, 0,
|
||
|
0, 0, 0, 0, 0, 84, 239, 60, 0, 60, 239, 84, 0, 0, 0, 0,
|
||
|
0, 0, 0, 0, 0, 0, 84, 239, 106, 239, 84, 0, 0, 0, 0, 0,
|
||
|
0, 0, 0, 0, 0, 0, 0, 89, 252, 89, 0, 0, 0, 0, 0, 0,
|
||
|
0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0,
|
||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||
|
};
|
||
|
|
||
|
static unsigned char imatrix_sortdown_alpha[IMAT_FEEDBACK_SIZE * IMAT_FEEDBACK_SIZE] =
|
||
|
{
|
||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||
|
0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0,
|
||
|
0, 0, 0, 0, 0, 0, 0, 89, 252, 89, 0, 0, 0, 0, 0, 0,
|
||
|
0, 0, 0, 0, 0, 0, 84, 239, 106, 239, 84, 0, 0, 0, 0, 0,
|
||
|
0, 0, 0, 0, 0, 84, 239, 60, 0, 60, 239, 84, 0, 0, 0, 0,
|
||
|
0, 0, 0, 0, 84, 239, 60, 0, 0, 0, 60, 239, 84, 0, 0, 0,
|
||
|
0, 0, 0, 84, 239, 60, 0, 0, 31, 0, 0, 60, 239, 84, 0, 0,
|
||
|
0, 0, 32, 239, 60, 0, 0, 89, 252, 89, 0, 0, 60, 239, 32, 0,
|
||
|
0, 0, 32, 32, 0, 0, 84, 239, 106, 239, 84, 0, 0, 32, 32, 0,
|
||
|
0, 0, 8, 0, 0, 84, 239, 60, 0, 60, 239, 84, 0, 0, 8, 0,
|
||
|
0, 0, 0, 0, 84, 239, 60, 0, 0, 0, 60, 239, 84, 0, 0, 0,
|
||
|
0, 0, 0, 84, 239, 60, 0, 0, 0, 0, 0, 60, 239, 84, 0, 0,
|
||
|
0, 0, 32, 239, 60, 0, 0, 0, 0, 0, 0, 0, 60, 239, 32, 0,
|
||
|
0, 0, 32, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 32, 0,
|
||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||
|
};
|
||
|
|
||
|
|
||
|
/**************************************************************************/
|
||
|
/* Private functions */
|
||
|
/**************************************************************************/
|
||
|
|
||
|
static void iMatrixDrawSetCellClipping(Ihandle* ih, int x1, int x2, int y1, int y2)
|
||
|
{
|
||
|
int old_clip = cdCanvasClip(ih->data->cd_canvas, CD_QUERY);
|
||
|
if (old_clip == CD_CLIPAREA)
|
||
|
{
|
||
|
cdCanvasGetClipArea(ih->data->cd_canvas, &(ih->data->clip_x1), &(ih->data->clip_x2), &(ih->data->clip_y1), &(ih->data->clip_y2));
|
||
|
y1 = iupMATRIX_INVERTYAXIS(ih, y1);
|
||
|
y2 = iupMATRIX_INVERTYAXIS(ih, y2);
|
||
|
if (x1 > x2) { int tmp = x1; x1 = x2; x2 = tmp; }
|
||
|
if (y1 > y2) { int tmp = y1; y1 = y2; y2 = tmp; }
|
||
|
if (x1 < ih->data->clip_x1) x1 = ih->data->clip_x1;
|
||
|
if (x2 > ih->data->clip_x2) x2 = ih->data->clip_x2;
|
||
|
if (y1 < ih->data->clip_y1) y1 = ih->data->clip_y1;
|
||
|
if (y2 > ih->data->clip_y2) y2 = ih->data->clip_y2;
|
||
|
if (x1 > x2) x2 = x1;
|
||
|
if (y1 > y2) y2 = y1;
|
||
|
cdCanvasClipArea(ih->data->cd_canvas, x1, x2, y1, y2);
|
||
|
cdCanvasClip(ih->data->cd_canvas, CD_CLIPAREA);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void iMatrixDrawResetCellClipping(Ihandle* ih)
|
||
|
{
|
||
|
int old_clip = cdCanvasClip(ih->data->cd_canvas, CD_QUERY);
|
||
|
if (old_clip == CD_CLIPAREA)
|
||
|
cdCanvasClipArea(ih->data->cd_canvas, ih->data->clip_x1, ih->data->clip_x2, ih->data->clip_y1, ih->data->clip_y2);
|
||
|
}
|
||
|
|
||
|
static int iMatrixDrawCallDrawCB(Ihandle* ih, int lin, int col, int x1, int x2, int y1, int y2, IFniiiiiiC draw_cb)
|
||
|
{
|
||
|
int ret;
|
||
|
|
||
|
iMatrixDrawSetCellClipping(ih, x1, x2, y1, y2);
|
||
|
|
||
|
ret = draw_cb(ih, lin, col, x1, x2, iupMATRIX_INVERTYAXIS(ih, y1), iupMATRIX_INVERTYAXIS(ih, y2), ih->data->cd_canvas);
|
||
|
|
||
|
iMatrixDrawResetCellClipping(ih);
|
||
|
|
||
|
if (ret == IUP_DEFAULT)
|
||
|
return 0;
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
/* Change the CD foreground color, for the selected color to draw a cell with
|
||
|
its FOREGROUND COLOR. This involves checking if there is a color attribute
|
||
|
that cell. If no, uses a color attribute for the line, else if no for the
|
||
|
column, else if no for the entire matrix. Finally, if not find any of
|
||
|
these, use the default color.
|
||
|
-> lin, col - cell coordinates, in IUP format - i.e., l,l represents the left
|
||
|
top cell of the matrix; lin and col values = 0 represents the
|
||
|
title lines and columns.
|
||
|
-> marked - indicate if a cell is marked. If yes, its color is attenuated.
|
||
|
*/
|
||
|
static unsigned long iMatrixDrawSetFgColor(Ihandle* ih, int lin, int col, int marked, int active)
|
||
|
{
|
||
|
unsigned char r = 0, g = 0, b = 0;
|
||
|
iupMatrixGetFgRGB(ih, lin, col, &r, &g, &b, marked, active);
|
||
|
return cdCanvasForeground(ih->data->cd_canvas, cdEncodeColor(r, g, b));
|
||
|
}
|
||
|
|
||
|
/* Change the CD foreground color, for the selected color to draw a cell with
|
||
|
its BACKGROUND COLOR. This involves checking if there is a color attribute
|
||
|
that cell. If no, uses a color attribute for the line, else if no for the
|
||
|
column, else if no for the entire matrix. Finally, if not find any of
|
||
|
these, use the default color.
|
||
|
-> lin, col - cell coordinates, in IUP format - i.e., l,l represents the left
|
||
|
top cell of the matrix; lin and col values = 0 represents the
|
||
|
title lines and columns.
|
||
|
-> marked - indicate if a cell is marked. If yes, its color is attenuated.
|
||
|
*/
|
||
|
static unsigned long iMatrixDrawSetBgColor(Ihandle* ih, int lin, int col, int marked, int active)
|
||
|
{
|
||
|
unsigned char r = 255, g = 255, b = 255;
|
||
|
iupMatrixGetBgRGB(ih, lin, col, &r, &g, &b, marked, active);
|
||
|
return cdCanvasForeground(ih->data->cd_canvas, cdEncodeColor(r, g, b));
|
||
|
}
|
||
|
|
||
|
static unsigned long iMatrixDrawSetTypeColor(Ihandle* ih, const char* color, int marked, int active)
|
||
|
{
|
||
|
unsigned char r = 0, g = 0, b = 0;
|
||
|
iupMatrixGetTypeRGB(ih, color, &r, &g, &b, marked, active);
|
||
|
return cdCanvasForeground(ih->data->cd_canvas, cdEncodeColor(r, g, b));
|
||
|
}
|
||
|
|
||
|
static int iMatrixDrawFrameVertLineTitleHighlight(Ihandle* ih, int lin, int col, int x, int y1, int y2, long framecolor)
|
||
|
{
|
||
|
if (ih->data->flat)
|
||
|
return 1;
|
||
|
|
||
|
if (col > 0)
|
||
|
{
|
||
|
int transp = iupMatrixGetFrameVertColor(ih, lin, col - 1, &framecolor, 0); /* framecolor is ignored here */
|
||
|
if (transp)
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
cdCanvasForeground(ih->data->cd_canvas, CD_WHITE);
|
||
|
iupMATRIX_LINE(ih, x, y1, x, y2);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int iMatrixDrawFrameHorizLineTitleHighlight(Ihandle* ih, int lin, int col, int x1, int x2, int y, long framecolor)
|
||
|
{
|
||
|
if (ih->data->flat)
|
||
|
return 1;
|
||
|
|
||
|
if (lin > 0)
|
||
|
{
|
||
|
int transp = iupMatrixGetFrameHorizColor(ih, lin - 1, col, &framecolor, 0); /* framecolor is ignored here */
|
||
|
if (transp)
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
cdCanvasForeground(ih->data->cd_canvas, CD_WHITE);
|
||
|
iupMATRIX_LINE(ih, x1, y, x2, y);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int iMatrixDrawFrameHorizLineCell(Ihandle* ih, int lin, int col, int x1, int x2, int y, long framecolor)
|
||
|
{
|
||
|
int transp = iupMatrixGetFrameHorizColor(ih, lin, col, &framecolor, 0);
|
||
|
if (transp)
|
||
|
return 1;
|
||
|
|
||
|
cdCanvasForeground(ih->data->cd_canvas, framecolor);
|
||
|
iupMATRIX_LINE(ih, x1, y, x2, y); /* horizontal line */
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int iMatrixDrawFrameHorizLineTitle(Ihandle* ih, int col, int x1, int x2, int y, long framecolor)
|
||
|
{
|
||
|
int transp = iupMatrixGetFrameHorizColor(ih, 0, col, &framecolor, 1);
|
||
|
if (transp)
|
||
|
return 1;
|
||
|
|
||
|
cdCanvasForeground(ih->data->cd_canvas, framecolor);
|
||
|
iupMATRIX_LINE(ih, x1, y, x2, y); /* horizontal line */
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int iMatrixDrawFrameVertLineTitle(Ihandle* ih, int lin, int x, int y1, int y2, long framecolor)
|
||
|
{
|
||
|
int transp = iupMatrixGetFrameVertColor(ih, lin, 0, &framecolor, 1);
|
||
|
if (transp)
|
||
|
return 1;
|
||
|
|
||
|
cdCanvasForeground(ih->data->cd_canvas, framecolor);
|
||
|
iupMATRIX_LINE(ih, x, y1, x, y2); /* vertical line */
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int iMatrixDrawFrameVertLineCell(Ihandle* ih, int lin, int col, int x, int y1, int y2, long framecolor)
|
||
|
{
|
||
|
int transp = iupMatrixGetFrameVertColor(ih, lin, col, &framecolor, 0);
|
||
|
if (transp)
|
||
|
return 1;
|
||
|
|
||
|
cdCanvasForeground(ih->data->cd_canvas, framecolor);
|
||
|
iupMATRIX_LINE(ih, x, y1, x, y2); /* vertical line */
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static void iMatrixDrawFrameRectTitle(Ihandle* ih, int lin, int col, int x1, int x2, int y1, int y2, long framecolor, int framehighlight)
|
||
|
{
|
||
|
/* avoid drawing over the frame of the next cell */
|
||
|
x2 -= IMAT_FRAME_W / 2;
|
||
|
y2 -= IMAT_FRAME_H / 2;
|
||
|
|
||
|
|
||
|
/********************* VERTICAL *************************/
|
||
|
|
||
|
|
||
|
/* right vertical line */
|
||
|
iMatrixDrawFrameVertLineCell(ih, lin, col, x2, y1, y2, framecolor);
|
||
|
if (col == 0)
|
||
|
{
|
||
|
/* left vertical line */
|
||
|
iMatrixDrawFrameVertLineTitle(ih, lin, x1, y1, y2, framecolor);
|
||
|
x1++;
|
||
|
}
|
||
|
else if (col == 1 && ih->data->columns.dt[0].size == 0)
|
||
|
{
|
||
|
/* If does not have line titles then draw the left vertical line */
|
||
|
iMatrixDrawFrameVertLineCell(ih, lin, col - 1, x1, y1, y2, framecolor);
|
||
|
x1++;
|
||
|
}
|
||
|
|
||
|
/* Titles have a bright vertical line near the frame, at left */
|
||
|
if (framehighlight)
|
||
|
iMatrixDrawFrameVertLineTitleHighlight(ih, lin, col, x1, y1 + 1, y2 - 1, framecolor);
|
||
|
|
||
|
|
||
|
/********************* HORIZONTAL *************************/
|
||
|
|
||
|
|
||
|
/* bottom horizontal line */
|
||
|
iMatrixDrawFrameHorizLineCell(ih, lin, col, x1, x2, y2, framecolor);
|
||
|
if (lin == 0)
|
||
|
{
|
||
|
/* top horizontal line */
|
||
|
iMatrixDrawFrameHorizLineTitle(ih, col, x1, x2, y1, framecolor);
|
||
|
y1++;
|
||
|
}
|
||
|
else if (lin == 1 && ih->data->lines.dt[0].size == 0)
|
||
|
{
|
||
|
/* If does not have column titles then draw the top horizontal line */
|
||
|
iMatrixDrawFrameHorizLineCell(ih, lin - 1, col, x1, x2 - 1, y1, framecolor);
|
||
|
y1++;
|
||
|
}
|
||
|
|
||
|
/* Titles have a bright horizontal line near the frame, at top */
|
||
|
if (framehighlight)
|
||
|
iMatrixDrawFrameHorizLineTitleHighlight(ih, lin, col, x1, x2 - 1, y1, framecolor);
|
||
|
}
|
||
|
|
||
|
static void iMatrixDrawFrameRectCell(Ihandle* ih, int lin, int col, int x1, int x2, int y1, int y2, long framecolor)
|
||
|
{
|
||
|
int transp;
|
||
|
|
||
|
if (col == 1 && ih->data->columns.dt[0].size == 0)
|
||
|
{
|
||
|
/* If does not have line titles then draw the >> left line << of the cell frame */
|
||
|
iMatrixDrawFrameVertLineCell(ih, lin, col - 1, x1, y1, y2 - 1, framecolor);
|
||
|
}
|
||
|
|
||
|
if (lin == 1 && ih->data->lines.dt[0].size == 0)
|
||
|
{
|
||
|
/* If does not have column titles then draw the >> top line << of the cell frame */
|
||
|
iMatrixDrawFrameHorizLineCell(ih, lin - 1, col, x1, x2 - 1, y1, framecolor);
|
||
|
}
|
||
|
|
||
|
/* bottom line */
|
||
|
transp = iMatrixDrawFrameHorizLineCell(ih, lin, col, x1, x2 - 1, y2 - 1, framecolor);
|
||
|
|
||
|
/* right line */
|
||
|
iMatrixDrawFrameVertLineCell(ih, lin, col, x2 - 1, y1, transp ? y2 - 1 : y2 - 2, framecolor);
|
||
|
}
|
||
|
|
||
|
static void iMatrixDrawFeedbackImage(Ihandle* ih, int x1, int x2, int y1, int y2, int lin, int col, int active, int marked, const char*name, unsigned char* alpha)
|
||
|
{
|
||
|
int x, y;
|
||
|
Ihandle* image = IupImageGetHandle(name);
|
||
|
if (image)
|
||
|
{
|
||
|
long bgcolor;
|
||
|
int image_width = IupGetInt(image, "WIDTH");
|
||
|
int image_height = IupGetInt(image, "HEIGHT");
|
||
|
unsigned char r = 255, g = 255, b = 255;
|
||
|
iupMatrixGetBgRGB(ih, lin, col, &r, &g, &b, marked, active);
|
||
|
bgcolor = cdEncodeColor(r, g, b);
|
||
|
|
||
|
y = (y2 + y1 + image_height) / 2;
|
||
|
x = (x2 + x1 - image_width) / 2;
|
||
|
|
||
|
cdIupDrawImage(ih->data->cd_canvas, image, x, iupMATRIX_INVERTYAXIS(ih, y), 0, 0, !active, bgcolor);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
static unsigned char red[IMAT_FEEDBACK_SIZE * IMAT_FEEDBACK_SIZE];
|
||
|
static unsigned char green[IMAT_FEEDBACK_SIZE * IMAT_FEEDBACK_SIZE];
|
||
|
static unsigned char blue[IMAT_FEEDBACK_SIZE * IMAT_FEEDBACK_SIZE];
|
||
|
static unsigned char last_r = 0, last_g = 0, last_b = 0;
|
||
|
static int init = 1;
|
||
|
|
||
|
unsigned char r = 0, g = 0, b = 0;
|
||
|
iupMatrixGetFgRGB(ih, lin, col, &r, &g, &b, marked, active);
|
||
|
|
||
|
if (init || last_r != r || last_g != g || last_b != b)
|
||
|
{
|
||
|
int count = IMAT_FEEDBACK_SIZE * IMAT_FEEDBACK_SIZE;
|
||
|
|
||
|
memset(red, r, count);
|
||
|
memset(green, g, count);
|
||
|
memset(blue, b, count);
|
||
|
|
||
|
last_r = r;
|
||
|
last_g = g;
|
||
|
last_b = b;
|
||
|
init = 0;
|
||
|
}
|
||
|
|
||
|
y = (y2 + y1 + IMAT_FEEDBACK_SIZE) / 2;
|
||
|
x = (x2 + x1 - IMAT_FEEDBACK_SIZE) / 2;
|
||
|
|
||
|
cdCanvasPutImageRectRGBA(ih->data->cd_canvas, IMAT_FEEDBACK_SIZE, IMAT_FEEDBACK_SIZE, red, green, blue, alpha, x, iupMATRIX_INVERTYAXIS(ih, y), IMAT_FEEDBACK_SIZE, IMAT_FEEDBACK_SIZE, 0, 0, 0, 0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static int iMatrixDrawSortSign(Ihandle* ih, int x2, int y1, int y2, int col, int active)
|
||
|
{
|
||
|
int x1;
|
||
|
|
||
|
char* sort = iupAttribGetId(ih, "SORTSIGN", col);
|
||
|
if (!sort || iupStrEqualNoCase(sort, "NO"))
|
||
|
return 0;
|
||
|
|
||
|
/* feedback area */
|
||
|
iupMatrixDrawSetDropFeedbackArea(&x1, &y1, &x2, &y2);
|
||
|
|
||
|
if (iupStrEqualNoCase(sort, "DOWN"))
|
||
|
iMatrixDrawFeedbackImage(ih, x1, x2, y1, y2, 0, col, active, 0, iupAttribGet(ih, "SORTIMAGEDOWN"), imatrix_sortdown_alpha);
|
||
|
else
|
||
|
iMatrixDrawFeedbackImage(ih, x1, x2, y1, y2, 0, col, active, 0, iupAttribGet(ih, "SORTIMAGEUP"), imatrix_sortup_alpha);
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
static void iMatrixDrawDropdownButton(Ihandle* ih, int x2, int y1, int y2, int lin, int col, int marked, int active)
|
||
|
{
|
||
|
int x1;
|
||
|
|
||
|
/* feedback area */
|
||
|
iupMatrixDrawSetDropFeedbackArea(&x1, &y1, &x2, &y2);
|
||
|
|
||
|
iMatrixDrawFeedbackImage(ih, x1, x2, y1, y2, lin, col, active, marked, iupAttribGet(ih, "DROPIMAGE"), imatrix_dropdown_alpha);
|
||
|
}
|
||
|
|
||
|
static void iMatrixDrawToggle(Ihandle* ih, int x1, int x2, int y1, int y2, int lin, int col, int marked, int active, int toggle_centered)
|
||
|
{
|
||
|
int togglevalue = 0;
|
||
|
|
||
|
/* toggle area */
|
||
|
iupMatrixDrawSetToggleFeedbackArea(toggle_centered, &x1, &y1, &x2, &y2);
|
||
|
|
||
|
if (toggle_centered)
|
||
|
{
|
||
|
char* value = iupMatrixGetValueDisplay(ih, lin, col);
|
||
|
togglevalue = iupStrBoolean(value);
|
||
|
}
|
||
|
else
|
||
|
togglevalue = iupAttribGetIntId2(ih, "TOGGLEVALUE", lin, col);
|
||
|
|
||
|
/* toggle check */
|
||
|
if (togglevalue)
|
||
|
iMatrixDrawFeedbackImage(ih, x1, x2, y1, y2, lin, col, active, marked, iupAttribGet(ih, "TOGGLEIMAGEON"), imatrix_toggleon_alpha);
|
||
|
else
|
||
|
iMatrixDrawFeedbackImage(ih, x1, x2, y1, y2, lin, col, active, marked, iupAttribGet(ih, "TOGGLEIMAGEOFF"), imatrix_toggleoff_alpha);
|
||
|
}
|
||
|
|
||
|
static void iMatrixDrawBackground(Ihandle* ih, int x1, int x2, int y1, int y2, int marked, int active, int lin, int col)
|
||
|
{
|
||
|
/* avoid drawing over the frame of the next cell */
|
||
|
x2 -= IMAT_FRAME_W / 2;
|
||
|
y2 -= IMAT_FRAME_H / 2;
|
||
|
|
||
|
iMatrixDrawSetBgColor(ih, lin, col, marked, active);
|
||
|
iupMATRIX_BOX(ih, x1, x2, y1, y2);
|
||
|
}
|
||
|
|
||
|
static void iMatrixDrawText(Ihandle* ih, int x1, int x2, int y1, int y2, int col_alignment, int lin_alignment, int marked, int active, int lin, int col, const char* text)
|
||
|
{
|
||
|
int text_alignment;
|
||
|
int charheight, x, y, hidden_text_marks = 0;
|
||
|
|
||
|
iupdrvFontGetCharSize(ih, NULL, &charheight);
|
||
|
|
||
|
if (lin == 0 || ih->data->hidden_text_marks)
|
||
|
{
|
||
|
int text_w;
|
||
|
iupdrvFontGetMultiLineStringSize(ih, text, &text_w, NULL);
|
||
|
if (text_w > x2 - x1 + 1 - IMAT_PADDING_W - IMAT_FRAME_W)
|
||
|
{
|
||
|
if (lin == 0)
|
||
|
col_alignment = IMAT_ALIGN_START;
|
||
|
|
||
|
if (ih->data->hidden_text_marks)
|
||
|
hidden_text_marks = 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Set the color used to draw the text */
|
||
|
iMatrixDrawSetFgColor(ih, lin, col, marked, active);
|
||
|
|
||
|
IupCdSetFont(ih, ih->data->cd_canvas, iupMatrixGetFont(ih, lin, col));
|
||
|
|
||
|
/* Set the clip area to the cell region informed, the text maybe greater than the cell */
|
||
|
if (hidden_text_marks)
|
||
|
{
|
||
|
int crop = iupdrvFontGetStringWidth(ih, "...") + 2;
|
||
|
iMatrixDrawSetCellClipping(ih, x1, x2 - crop, y1, y2);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
iMatrixDrawSetCellClipping(ih, x1, x2, y1, y2);
|
||
|
}
|
||
|
|
||
|
/* Create an space between text and cell frame */
|
||
|
x1 += IMAT_PADDING_W / 2; x2 -= IMAT_PADDING_W / 2;
|
||
|
y1 += IMAT_PADDING_H / 2; y2 -= IMAT_PADDING_H / 2;
|
||
|
|
||
|
iupMatrixGetCellAlign(ih, lin, col, &col_alignment, &lin_alignment);
|
||
|
|
||
|
if (lin_alignment == IMAT_ALIGN_CENTER)
|
||
|
{
|
||
|
y = iupROUND((y1 + y2) / 2.0);
|
||
|
|
||
|
if (col_alignment == IMAT_ALIGN_CENTER)
|
||
|
{
|
||
|
x = iupROUND((x1 + x2) / 2.0);
|
||
|
text_alignment = CD_CENTER;
|
||
|
}
|
||
|
else if (col_alignment == IMAT_ALIGN_START)
|
||
|
{
|
||
|
x = x1;
|
||
|
text_alignment = CD_WEST;
|
||
|
}
|
||
|
else /* RIGHT */
|
||
|
{
|
||
|
x = x2;
|
||
|
text_alignment = CD_EAST;
|
||
|
}
|
||
|
}
|
||
|
else if (lin_alignment == IMAT_ALIGN_START)
|
||
|
{
|
||
|
y = y1;
|
||
|
|
||
|
if (col_alignment == IMAT_ALIGN_CENTER)
|
||
|
{
|
||
|
x = iupROUND((x1 + x2) / 2.0);
|
||
|
text_alignment = CD_NORTH;
|
||
|
}
|
||
|
else if (col_alignment == IMAT_ALIGN_START)
|
||
|
{
|
||
|
x = x1;
|
||
|
text_alignment = CD_NORTH_WEST;
|
||
|
}
|
||
|
else /* RIGHT */
|
||
|
{
|
||
|
x = x2;
|
||
|
text_alignment = CD_NORTH_EAST;
|
||
|
}
|
||
|
}
|
||
|
else /* lin_alignment == IMAT_ALIGN_END */
|
||
|
{
|
||
|
y = y2;
|
||
|
|
||
|
if (col_alignment == IMAT_ALIGN_CENTER)
|
||
|
{
|
||
|
x = iupROUND((x1 + x2) / 2.0);
|
||
|
text_alignment = CD_SOUTH;
|
||
|
}
|
||
|
else if (col_alignment == IMAT_ALIGN_START)
|
||
|
{
|
||
|
x = x1;
|
||
|
text_alignment = CD_SOUTH_WEST;
|
||
|
}
|
||
|
else /* RIGHT */
|
||
|
{
|
||
|
x = x2;
|
||
|
text_alignment = CD_SOUTH_EAST;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
cdCanvasTextAlignment(ih->data->cd_canvas, text_alignment);
|
||
|
iupMATRIX_TEXT(ih, x, y, text);
|
||
|
|
||
|
iMatrixDrawResetCellClipping(ih);
|
||
|
|
||
|
if (hidden_text_marks)
|
||
|
{
|
||
|
cdCanvasTextAlignment(ih->data->cd_canvas, CD_EAST);
|
||
|
y = (int)((y1 + y2) / 2.0 - 0.5);
|
||
|
x = x2 + IMAT_PADDING_W / 2;
|
||
|
iupMATRIX_TEXT(ih, x, y, "...");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void iMatrixDrawColor(Ihandle* ih, int x1, int x2, int y1, int y2, int marked, int active, const char* color, long framecolor)
|
||
|
{
|
||
|
x1 += IMAT_PADDING_W / 2 + IMAT_FRAME_H / 2;
|
||
|
x2 -= IMAT_PADDING_W / 2 + IMAT_FRAME_W / 2;
|
||
|
y1 += IMAT_PADDING_H / 2 + IMAT_FRAME_H / 2;
|
||
|
y2 -= IMAT_PADDING_H / 2 + IMAT_FRAME_H / 2;
|
||
|
|
||
|
if (!iupAttribGetBoolean(ih, "TYPECOLORINACTIVE"))
|
||
|
active = 1; /* draw as active */
|
||
|
|
||
|
/* Fill the box with the color */
|
||
|
iMatrixDrawSetTypeColor(ih, color, marked, active);
|
||
|
iupMATRIX_BOX(ih, x1, x2, y1, y2);
|
||
|
|
||
|
/* Draw the frame */
|
||
|
cdCanvasForeground(ih->data->cd_canvas, framecolor);
|
||
|
iupMATRIX_RECT(ih, x1, x2, y1, y2);
|
||
|
}
|
||
|
|
||
|
static void iMatrixDrawFill(Ihandle* ih, int x1, int x2, int y1, int y2, int marked, int active, int lin, int col, const char* value, long framecolor)
|
||
|
{
|
||
|
int empty, fill = 0;
|
||
|
|
||
|
iupStrToInt(value, &fill);
|
||
|
if (fill < 0) fill = 0;
|
||
|
if (fill > 100) fill = 100;
|
||
|
|
||
|
/* Create an space between text and cell frame */
|
||
|
x1 += IMAT_PADDING_W / 2; x2 -= IMAT_PADDING_W / 2;
|
||
|
y1 += IMAT_PADDING_H / 2; y2 -= IMAT_PADDING_H / 2;
|
||
|
|
||
|
empty = ((x2 - x1)*(100 - fill)) / 100;
|
||
|
|
||
|
/* Fill the box with the color */
|
||
|
iMatrixDrawSetFgColor(ih, lin, col, marked, active);
|
||
|
iupMATRIX_BOX(ih, x1, x2 - empty, y1, y2);
|
||
|
|
||
|
if (ih->data->show_fill_value)
|
||
|
{
|
||
|
int y = (int)((y1 + y2) / 2.0 - 0.5);
|
||
|
int empty1 = ((x2 - x1)*fill) / 100;
|
||
|
char text[50];
|
||
|
sprintf(text, "%d%%", fill);
|
||
|
IupCdSetFont(ih, ih->data->cd_canvas, iupMatrixGetFont(ih, lin, col));
|
||
|
cdCanvasTextAlignment(ih->data->cd_canvas, CD_CENTER);
|
||
|
|
||
|
iMatrixDrawSetCellClipping(ih, x1 + empty1, x2, y1, y2);
|
||
|
iupMATRIX_TEXT(ih, (x1 + x2) / 2, y, text);
|
||
|
iMatrixDrawResetCellClipping(ih);
|
||
|
|
||
|
iMatrixDrawSetBgColor(ih, lin, col, marked, active);
|
||
|
iMatrixDrawSetCellClipping(ih, x1, x2 - empty, y1, y2);
|
||
|
iupMATRIX_TEXT(ih, (x1 + x2) / 2, y, text);
|
||
|
iMatrixDrawResetCellClipping(ih);
|
||
|
}
|
||
|
|
||
|
|
||
|
/* Draw the frame */
|
||
|
cdCanvasForeground(ih->data->cd_canvas, framecolor);
|
||
|
iupMATRIX_RECT(ih, x1, x2, y1, y2);
|
||
|
}
|
||
|
|
||
|
static void iMatrixDrawImage(Ihandle* ih, int x1, int x2, int y1, int y2, int col_alignment, int lin_alignment, int marked, int active, int lin, int col, const char* name)
|
||
|
{
|
||
|
Ihandle* image;
|
||
|
|
||
|
iMatrixDrawSetCellClipping(ih, x1, x2, y1, y2);
|
||
|
|
||
|
/* Create an space between image and cell frame */
|
||
|
x1 += IMAT_PADDING_W / 2; x2 -= IMAT_PADDING_W / 2;
|
||
|
y1 += IMAT_PADDING_H / 2; y2 -= IMAT_PADDING_H / 2;
|
||
|
|
||
|
image = IupImageGetHandle(name);
|
||
|
if (image)
|
||
|
{
|
||
|
long bgcolor;
|
||
|
int x, y;
|
||
|
int image_width = IupGetInt(image, "WIDTH");
|
||
|
int image_height = IupGetInt(image, "HEIGHT");
|
||
|
unsigned char r = 255, g = 255, b = 255;
|
||
|
iupMatrixGetBgRGB(ih, lin, col, &r, &g, &b, marked, active);
|
||
|
bgcolor = cdEncodeColor(r, g, b);
|
||
|
|
||
|
if (lin_alignment == IMAT_ALIGN_CENTER)
|
||
|
y = (y2 + y1 + image_height) / 2;
|
||
|
else if (lin_alignment == IMAT_ALIGN_START)
|
||
|
y = y1;
|
||
|
else /* BOTTOM */
|
||
|
y = y2 + image_height;
|
||
|
|
||
|
if (col_alignment == IMAT_ALIGN_CENTER)
|
||
|
x = (x2 + x1 - image_width) / 2;
|
||
|
else if (col_alignment == IMAT_ALIGN_START)
|
||
|
x = x1;
|
||
|
else /* RIGHT */
|
||
|
x = x2 - image_width;
|
||
|
|
||
|
cdIupDrawImage(ih->data->cd_canvas, image, x, iupMATRIX_INVERTYAXIS(ih, y), 0, 0, !active, bgcolor);
|
||
|
}
|
||
|
|
||
|
iMatrixDrawResetCellClipping(ih);
|
||
|
}
|
||
|
|
||
|
/* Put the cell contents in the screen, using the specified color and Alignment.
|
||
|
-> y1, y2 : vertical limits of the cell
|
||
|
-> x1, x2 : horizontal limits of the complete cell
|
||
|
-> col_alignment : Alignment type (horizontal) assigned to the text. The options are:
|
||
|
[IMAT_ALIGN_CENTER,IMAT_ALIGN_START,IMAT_ALIGN_END]
|
||
|
-> marked : mark state
|
||
|
-> lin, col - cell coordinates */
|
||
|
static void iMatrixDrawCellValue(Ihandle* ih, int x1, int x2, int y1, int y2, int col_alignment, int lin_alignment, int marked, int active, int lin, int col, IFniiiiiiC draw_cb, long framecolor)
|
||
|
{
|
||
|
char *value;
|
||
|
|
||
|
/* avoid drawing over the frame of the next cell */
|
||
|
x2 -= IMAT_FRAME_W / 2;
|
||
|
y2 -= IMAT_FRAME_H / 2;
|
||
|
|
||
|
/* avoid drawing over the frame of the cell */
|
||
|
x2 -= IMAT_FRAME_W / 2;
|
||
|
y2 -= IMAT_FRAME_H / 2;
|
||
|
|
||
|
if (lin == 0 || col == 0)
|
||
|
{
|
||
|
/* avoid drawing over the frame of the cell */
|
||
|
x1 += IMAT_FRAME_W / 2;
|
||
|
y1 += IMAT_FRAME_H / 2;
|
||
|
|
||
|
if (col == 0) x1 += IMAT_FRAME_W / 2;
|
||
|
if (lin == 0) y1 += IMAT_FRAME_H / 2;
|
||
|
}
|
||
|
else if ((col == 1 && ih->data->columns.dt[0].size == 0) || (lin == 1 && ih->data->lines.dt[0].size == 0))
|
||
|
{
|
||
|
/* avoid drawing over the frame of the cell */
|
||
|
x1 += IMAT_FRAME_W / 2;
|
||
|
y1 += IMAT_FRAME_H / 2;
|
||
|
}
|
||
|
|
||
|
if (draw_cb && !iMatrixDrawCallDrawCB(ih, lin, col, x1, x2, y1, y2, draw_cb))
|
||
|
return;
|
||
|
|
||
|
value = iupMatrixGetValueDisplay(ih, lin, col);
|
||
|
|
||
|
/* Put the text */
|
||
|
if (value && *value)
|
||
|
{
|
||
|
int type = iupMatrixGetType(ih, lin, col);
|
||
|
if (type == IMAT_TYPE_TEXT)
|
||
|
iMatrixDrawText(ih, x1, x2, y1, y2, col_alignment, lin_alignment, marked, active, lin, col, value);
|
||
|
else if (type == IMAT_TYPE_COLOR)
|
||
|
iMatrixDrawColor(ih, x1, x2, y1, y2, marked, active, value, framecolor);
|
||
|
else if (type == IMAT_TYPE_FILL)
|
||
|
iMatrixDrawFill(ih, x1, x2, y1, y2, marked, active, lin, col, value, framecolor);
|
||
|
else if (type == IMAT_TYPE_IMAGE)
|
||
|
iMatrixDrawImage(ih, x1, x2, y1, y2, col_alignment, lin_alignment, marked, active, lin, col, value);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void iMatrixDrawTitleCorner(Ihandle* ih)
|
||
|
{
|
||
|
if (ih->data->lines.dt[0].size && ih->data->columns.dt[0].size)
|
||
|
{
|
||
|
long framecolor = cdIupConvertColor(iupAttribGetStr(ih, "FRAMECOLOR"));
|
||
|
int active = iupdrvIsActive(ih);
|
||
|
IFniiiiiiC draw_cb = (IFniiiiiiC)IupGetCallback(ih, "DRAW_CB");
|
||
|
int col_alignment = iupMatrixGetColAlignmentLin0(ih);
|
||
|
int lin_alignment = iupMatrixGetLinAlignment(ih, 0);
|
||
|
int framehighlight = iupAttribGetInt(ih, "FRAMETITLEHIGHLIGHT");
|
||
|
|
||
|
iMatrixDrawBackground(ih, 0, ih->data->columns.dt[0].size, 0, ih->data->lines.dt[0].size, 0, active, 0, 0);
|
||
|
|
||
|
iMatrixDrawFrameRectTitle(ih, 0, 0, 0, ih->data->columns.dt[0].size, 0, ih->data->lines.dt[0].size, framecolor, framehighlight);
|
||
|
|
||
|
iMatrixDrawCellValue(ih, 0, ih->data->columns.dt[0].size, 0, ih->data->lines.dt[0].size, col_alignment, lin_alignment, 0, active, 0, 0, draw_cb, framecolor);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void iMatrixDrawFocus(Ihandle* ih)
|
||
|
{
|
||
|
int x1, y1, x2, y2, dx, dy;
|
||
|
|
||
|
if (iupAttribGetBoolean(ih, "HIDEFOCUS"))
|
||
|
return;
|
||
|
|
||
|
/* there are no cells that can get the focus */
|
||
|
if (ih->data->columns.num <= 1 || ih->data->lines.num <= 1)
|
||
|
return;
|
||
|
|
||
|
if (!iupMatrixAuxIsCellVisible(ih, ih->data->lines.focus_cell, ih->data->columns.focus_cell))
|
||
|
return;
|
||
|
|
||
|
iupMatrixGetVisibleCellDim(ih, ih->data->lines.focus_cell, ih->data->columns.focus_cell, &x1, &y1, &dx, &dy);
|
||
|
|
||
|
x2 = x1 + dx - 1;
|
||
|
y2 = y1 + dy - 1;
|
||
|
|
||
|
if (ih->data->noscroll_as_title && (ih->data->columns.focus_cell < ih->data->columns.num_noscroll || ih->data->lines.focus_cell < ih->data->lines.num_noscroll))
|
||
|
{
|
||
|
x1++;
|
||
|
y1++;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (ih->data->columns.focus_cell == 1 && ih->data->columns.dt[0].size == 0)
|
||
|
x1++;
|
||
|
if (ih->data->lines.focus_cell == 1 && ih->data->lines.dt[0].size == 0)
|
||
|
y1++;
|
||
|
}
|
||
|
|
||
|
cdIupDrawFocusRect(ih->data->cd_canvas, x1, iupMATRIX_INVERTYAXIS(ih, y1), x2, iupMATRIX_INVERTYAXIS(ih, y2));
|
||
|
}
|
||
|
|
||
|
static void iMatrixDrawColRes(Ihandle* ih)
|
||
|
{
|
||
|
cdCanvasForeground(ih->data->cd_canvas, ih->data->colres_color);
|
||
|
cdCanvasLine(ih->data->cd_canvas, ih->data->colres_x, ih->data->colres_y1,
|
||
|
ih->data->colres_x, ih->data->colres_y2);
|
||
|
}
|
||
|
|
||
|
|
||
|
/**************************************************************************/
|
||
|
/* Exported functions */
|
||
|
/**************************************************************************/
|
||
|
|
||
|
void iupMatrixDrawSetDropFeedbackArea(int *x1, int *y1, int *x2, int *y2)
|
||
|
{
|
||
|
*x2 -= IMAT_PADDING_W / 2 + IMAT_FRAME_W / 2;
|
||
|
*x1 = *x2 - IMAT_FEEDBACK_SIZE - IMAT_PADDING_W / 2;
|
||
|
|
||
|
*y1 += IMAT_PADDING_H / 2 + IMAT_FRAME_H / 2;
|
||
|
*y2 -= IMAT_PADDING_H / 2 + IMAT_FRAME_H / 2;
|
||
|
}
|
||
|
|
||
|
void iupMatrixDrawSetToggleFeedbackArea(int toggle_centered, int *x1, int *y1, int *x2, int *y2)
|
||
|
{
|
||
|
if (toggle_centered)
|
||
|
{
|
||
|
*x1 = (*x2 + *x1) / 2 - IMAT_FEEDBACK_SIZE / 2;
|
||
|
*x2 = *x1 + IMAT_FEEDBACK_SIZE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
*x2 -= IMAT_PADDING_W / 2 + IMAT_FRAME_W / 2;
|
||
|
*x1 = *x2 - IMAT_FEEDBACK_SIZE - IMAT_PADDING_W / 2;
|
||
|
}
|
||
|
|
||
|
*y1 += IMAT_PADDING_H / 2 + IMAT_FRAME_H / 2;
|
||
|
*y2 -= IMAT_PADDING_H / 2 + IMAT_FRAME_H / 2;
|
||
|
}
|
||
|
|
||
|
static int iMatrixAdjustVisibleColToMergedCells(Ihandle *ih, int *col1, int lin1, int lin2)
|
||
|
{
|
||
|
int lin, adjusted = 0, merged;
|
||
|
int startCol;
|
||
|
int new_col1 = *col1;
|
||
|
|
||
|
/* check merged cells at col1 */
|
||
|
for (lin = lin1; lin <= lin2; lin++)
|
||
|
{
|
||
|
merged = iupMatrixGetMerged(ih, lin, *col1);
|
||
|
if (merged)
|
||
|
{
|
||
|
iupMatrixGetMergedRect(ih, merged, NULL, NULL, &startCol, NULL);
|
||
|
|
||
|
if (startCol < new_col1)
|
||
|
{
|
||
|
new_col1 = startCol;
|
||
|
adjusted = 1;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (adjusted)
|
||
|
*col1 = new_col1;
|
||
|
|
||
|
return adjusted;
|
||
|
}
|
||
|
|
||
|
static int iMatrixAdjustVisibleLinToMergedCells(Ihandle *ih, int *lin1, int col1, int col2)
|
||
|
{
|
||
|
int col, adjusted = 0, merged;
|
||
|
int startLin;
|
||
|
int new_lin1 = *lin1;
|
||
|
|
||
|
/* check merged cells at lin1 */
|
||
|
for (col = col1; col <= col2; col++)
|
||
|
{
|
||
|
merged = iupMatrixGetMerged(ih, *lin1, col);
|
||
|
if (merged)
|
||
|
{
|
||
|
iupMatrixGetMergedRect(ih, merged, &startLin, NULL, NULL, NULL);
|
||
|
|
||
|
if (startLin < new_lin1)
|
||
|
{
|
||
|
new_lin1 = startLin;
|
||
|
adjusted = 1;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (adjusted)
|
||
|
*lin1 = new_lin1;
|
||
|
|
||
|
return adjusted;
|
||
|
}
|
||
|
|
||
|
/* Draw the line titles, visible, between lin and lastlin, include it.
|
||
|
Line titles marked will be draw with the appropriate feedback.
|
||
|
-> lin1 - First line to have its title drawn
|
||
|
-> lin2 - Last line to have its title drawn */
|
||
|
static void iMatrixDrawTitleLines(Ihandle* ih, int lin1, int lin2)
|
||
|
{
|
||
|
int x1, y1, x2, y2, first_lin, adjust_merged_lin = 0;
|
||
|
int lin, col_alignment, active, framehighlight;
|
||
|
long framecolor;
|
||
|
IFniiiiiiC draw_cb;
|
||
|
|
||
|
/* here col==0 always */
|
||
|
|
||
|
if (!ih->data->columns.dt[0].size)
|
||
|
return;
|
||
|
|
||
|
if (ih->data->merge_info_count)
|
||
|
adjust_merged_lin = iMatrixAdjustVisibleLinToMergedCells(ih, &lin1, 0, 0);
|
||
|
|
||
|
if (ih->data->lines.num_noscroll > 1 && lin1 == 1 && lin2 == ih->data->lines.num_noscroll - 1)
|
||
|
{
|
||
|
first_lin = 0;
|
||
|
y1 = 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (lin1 > ih->data->lines.last ||
|
||
|
lin2 < ih->data->lines.first)
|
||
|
return;
|
||
|
|
||
|
if (!adjust_merged_lin && lin1 < ih->data->lines.first)
|
||
|
lin1 = ih->data->lines.first;
|
||
|
if (lin2 > ih->data->lines.last)
|
||
|
lin2 = ih->data->lines.last;
|
||
|
|
||
|
first_lin = ih->data->lines.first;
|
||
|
y1 = 0;
|
||
|
for (lin = 0; lin < ih->data->lines.num_noscroll; lin++)
|
||
|
y1 += ih->data->lines.dt[lin].size;
|
||
|
}
|
||
|
|
||
|
/* Start the position of the line title */
|
||
|
x1 = 0;
|
||
|
x2 = ih->data->columns.dt[0].size;
|
||
|
|
||
|
iupMATRIX_CLIPAREA(ih, x1, x2, y1, iupMatrixGetHeight(ih) - 1);
|
||
|
cdCanvasClip(ih->data->cd_canvas, CD_CLIPAREA);
|
||
|
|
||
|
/* Find the initial position of the first line */
|
||
|
if (first_lin == ih->data->lines.first)
|
||
|
y1 -= ih->data->lines.first_offset;
|
||
|
for (lin = first_lin; lin < lin1; lin++)
|
||
|
y1 += ih->data->lines.dt[lin].size;
|
||
|
if (adjust_merged_lin)
|
||
|
{
|
||
|
for (lin = first_lin; lin > lin1; lin--)
|
||
|
y1 -= ih->data->lines.dt[lin].size;
|
||
|
}
|
||
|
|
||
|
framecolor = cdIupConvertColor(iupAttribGetStr(ih, "FRAMECOLOR"));
|
||
|
framehighlight = iupAttribGetInt(ih, "FRAMETITLEHIGHLIGHT");
|
||
|
active = iupdrvIsActive(ih);
|
||
|
draw_cb = (IFniiiiiiC)IupGetCallback(ih, "DRAW_CB");
|
||
|
|
||
|
col_alignment = iupMatrixGetColAlignment(ih, 0);
|
||
|
|
||
|
/* Draw the titles */
|
||
|
for (lin = lin1; lin <= lin2; lin++)
|
||
|
{
|
||
|
int merged;
|
||
|
|
||
|
/* If it is a hidden line (size = 0), don't draw the title */
|
||
|
if (ih->data->lines.dt[lin].size == 0)
|
||
|
continue;
|
||
|
|
||
|
merged = 0;
|
||
|
if (ih->data->merge_info_count)
|
||
|
merged = iupMatrixGetMerged(ih, lin, 0);
|
||
|
|
||
|
y2 = y1 + ih->data->lines.dt[lin].size;
|
||
|
|
||
|
if (merged)
|
||
|
{
|
||
|
int startLin, endLin, startCol, endCol;
|
||
|
iupMatrixGetMergedRect(ih, merged, &startLin, &endLin, &startCol, &endCol);
|
||
|
|
||
|
if (lin == startLin && 0 == startCol) /* merged start */
|
||
|
{
|
||
|
int i;
|
||
|
for (i = startLin + 1; i <= endLin; i++)
|
||
|
y2 += ih->data->lines.dt[i].size;
|
||
|
}
|
||
|
else
|
||
|
continue; /* ignore internal merged */
|
||
|
}
|
||
|
|
||
|
/* If it doesn't have title, the loop just calculate the final position */
|
||
|
if (ih->data->columns.dt[0].size)
|
||
|
{
|
||
|
int marked = iupMatrixLineIsMarked(ih, lin);
|
||
|
int lin_alignment = iupMatrixGetLinAlignment(ih, lin);
|
||
|
|
||
|
iMatrixDrawBackground(ih, x1, x2, y1, y2, marked, active, lin, 0);
|
||
|
|
||
|
iMatrixDrawFrameRectTitle(ih, lin, 0, x1, x2, y1, y2, framecolor, framehighlight);
|
||
|
|
||
|
iMatrixDrawCellValue(ih, x1, x2, y1, y2, col_alignment, lin_alignment, marked, active, lin, 0, draw_cb, framecolor);
|
||
|
}
|
||
|
|
||
|
y1 = y2;
|
||
|
}
|
||
|
|
||
|
cdCanvasClip(ih->data->cd_canvas, CD_CLIPOFF);
|
||
|
}
|
||
|
|
||
|
/* Draw the column titles, visible, between col and lastcol, include it.
|
||
|
Column titles marked will be draw with the appropriate feedback.
|
||
|
-> col1 - First column to have its title drawn
|
||
|
-> col2 - Last column to have its title drawn */
|
||
|
static void iMatrixDrawTitleColumns(Ihandle* ih, int col1, int col2)
|
||
|
{
|
||
|
int x1, y1, x2, y2, first_col, adjust_merged_col = 0;
|
||
|
int col, active, col_alignment, lin_alignment, framehighlight;
|
||
|
long framecolor;
|
||
|
IFniiiiiiC draw_cb;
|
||
|
|
||
|
/* here lin==0 always */
|
||
|
|
||
|
if (!ih->data->lines.dt[0].size)
|
||
|
return;
|
||
|
|
||
|
if (ih->data->merge_info_count)
|
||
|
adjust_merged_col = iMatrixAdjustVisibleColToMergedCells(ih, &col1, 0, 0);
|
||
|
|
||
|
if (ih->data->columns.num_noscroll > 1 && col1 == 1 && col2 == ih->data->columns.num_noscroll - 1)
|
||
|
{
|
||
|
first_col = 0;
|
||
|
x1 = 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (col1 > ih->data->columns.last ||
|
||
|
col2 < ih->data->columns.first)
|
||
|
return;
|
||
|
|
||
|
if (!adjust_merged_col && col1 < ih->data->columns.first)
|
||
|
col1 = ih->data->columns.first;
|
||
|
if (col2 > ih->data->columns.last)
|
||
|
col2 = ih->data->columns.last;
|
||
|
|
||
|
first_col = ih->data->columns.first;
|
||
|
x1 = 0;
|
||
|
for (col = 0; col < ih->data->columns.num_noscroll; col++)
|
||
|
x1 += ih->data->columns.dt[col].size;
|
||
|
}
|
||
|
|
||
|
/* Start the position of the first column title */
|
||
|
y1 = 0;
|
||
|
y2 = ih->data->lines.dt[0].size;
|
||
|
|
||
|
iupMATRIX_CLIPAREA(ih, x1, iupMatrixGetWidth(ih) - 1, y1, y2);
|
||
|
cdCanvasClip(ih->data->cd_canvas, CD_CLIPAREA);
|
||
|
|
||
|
/* Find the initial position of the first column */
|
||
|
if (first_col == ih->data->columns.first)
|
||
|
x1 -= ih->data->columns.first_offset;
|
||
|
for (col = first_col; col < col1; col++)
|
||
|
x1 += ih->data->columns.dt[col].size;
|
||
|
if (adjust_merged_col)
|
||
|
{
|
||
|
for (col = first_col; col > col1; col--)
|
||
|
x1 -= ih->data->columns.dt[col].size;
|
||
|
}
|
||
|
|
||
|
framecolor = cdIupConvertColor(iupAttribGetStr(ih, "FRAMECOLOR"));
|
||
|
framehighlight = iupAttribGetInt(ih, "FRAMETITLEHIGHLIGHT");
|
||
|
active = iupdrvIsActive(ih);
|
||
|
draw_cb = (IFniiiiiiC)IupGetCallback(ih, "DRAW_CB");
|
||
|
col_alignment = iupMatrixGetColAlignmentLin0(ih);
|
||
|
lin_alignment = iupMatrixGetLinAlignment(ih, 0);
|
||
|
|
||
|
/* Draw the titles */
|
||
|
for (col = col1; col <= col2; col++)
|
||
|
{
|
||
|
int merged;
|
||
|
|
||
|
/* If it is hidden column (size = 0), do not draw the title */
|
||
|
if (ih->data->columns.dt[col].size == 0)
|
||
|
continue;
|
||
|
|
||
|
merged = 0;
|
||
|
if (ih->data->merge_info_count)
|
||
|
merged = iupMatrixGetMerged(ih, 0, col);
|
||
|
|
||
|
x2 = x1 + ih->data->columns.dt[col].size;
|
||
|
|
||
|
if (merged)
|
||
|
{
|
||
|
int startLin, endLin, startCol, endCol;
|
||
|
iupMatrixGetMergedRect(ih, merged, &startLin, &endLin, &startCol, &endCol);
|
||
|
|
||
|
if (0 == startLin && col == startCol) /* merged start */
|
||
|
{
|
||
|
int i;
|
||
|
for (i = startCol + 1; i <= endCol; i++)
|
||
|
x2 += ih->data->columns.dt[i].size;
|
||
|
}
|
||
|
else
|
||
|
continue; /* ignore internal merged */
|
||
|
}
|
||
|
|
||
|
/* If it doesn't have title, the loop just calculate the final position */
|
||
|
if (ih->data->lines.dt[0].size)
|
||
|
{
|
||
|
int sort = 0;
|
||
|
int marked = iupMatrixColumnIsMarked(ih, col);
|
||
|
|
||
|
iMatrixDrawBackground(ih, x1, x2, y1, y2, marked, active, 0, col);
|
||
|
|
||
|
iMatrixDrawFrameRectTitle(ih, 0, col, x1, x2, y1, y2, framecolor, framehighlight);
|
||
|
|
||
|
if (iMatrixDrawSortSign(ih, x2, y1, y2, col, active))
|
||
|
sort = IMAT_PADDING_W / 2 + IMAT_FEEDBACK_SIZE + IMAT_PADDING_W / 2; /* same space is used by the sort sign */
|
||
|
|
||
|
iMatrixDrawCellValue(ih, x1, x2 - sort, y1, y2, col_alignment, lin_alignment, marked, active, 0, col, draw_cb, framecolor);
|
||
|
}
|
||
|
|
||
|
x1 = x2;
|
||
|
}
|
||
|
|
||
|
cdCanvasClip(ih->data->cd_canvas, CD_CLIPOFF);
|
||
|
}
|
||
|
|
||
|
/* Redraw a block of cells of the matrix. Handle marked cells, change
|
||
|
automatically the background color of them.
|
||
|
- lin1, col1 : cell coordinates that mark the left top corner of the area to be redrawn
|
||
|
- lin2, col2 : cell coordinates that mark the right bottom corner of the area to be redrawn */
|
||
|
static void iMatrixDrawCells(Ihandle* ih, int lin1, int col1, int lin2, int col2)
|
||
|
{
|
||
|
int x1, y1, x2, y2, old_x2, old_y1, old_y2, toggle_centered;
|
||
|
int col_alignment, lin, col, active, first_col, first_lin;
|
||
|
int i, adjust_merged_col = 0, adjust_merged_lin = 0;
|
||
|
long framecolor, framehighlight;
|
||
|
IFnii mark_cb;
|
||
|
IFnii dropcheck_cb;
|
||
|
IFniiiiiiC draw_cb;
|
||
|
|
||
|
if (ih->data->merge_info_count)
|
||
|
{
|
||
|
adjust_merged_lin = iMatrixAdjustVisibleLinToMergedCells(ih, &lin1, col1, col2);
|
||
|
adjust_merged_col = iMatrixAdjustVisibleColToMergedCells(ih, &col1, lin1, lin2);
|
||
|
}
|
||
|
|
||
|
x2 = iupMatrixGetWidth(ih) - 1;
|
||
|
y2 = iupMatrixGetHeight(ih) - 1;
|
||
|
|
||
|
old_x2 = x2;
|
||
|
old_y1 = 0;
|
||
|
old_y2 = y2;
|
||
|
|
||
|
if (ih->data->lines.num <= 1 ||
|
||
|
ih->data->columns.num <= 1)
|
||
|
return;
|
||
|
|
||
|
if (ih->data->columns.num_noscroll > 1 && col1 == 1 && col2 == ih->data->columns.num_noscroll - 1)
|
||
|
{
|
||
|
first_col = 0;
|
||
|
x1 = 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (col1 > ih->data->columns.last ||
|
||
|
col2 < ih->data->columns.first)
|
||
|
return;
|
||
|
|
||
|
if (!adjust_merged_col && col1 < ih->data->columns.first)
|
||
|
col1 = ih->data->columns.first;
|
||
|
if (col2 > ih->data->columns.last)
|
||
|
col2 = ih->data->columns.last;
|
||
|
|
||
|
first_col = ih->data->columns.first;
|
||
|
x1 = 0;
|
||
|
for (col = 0; col< ih->data->columns.num_noscroll; col++)
|
||
|
x1 += ih->data->columns.dt[col].size;
|
||
|
}
|
||
|
|
||
|
if (ih->data->lines.num_noscroll>1 && lin1 == 1 && lin2 == ih->data->lines.num_noscroll - 1)
|
||
|
{
|
||
|
first_lin = 0;
|
||
|
y1 = 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (lin1 > ih->data->lines.last ||
|
||
|
lin2 < ih->data->lines.first)
|
||
|
return;
|
||
|
|
||
|
if (!adjust_merged_lin && lin1 < ih->data->lines.first)
|
||
|
lin1 = ih->data->lines.first;
|
||
|
if (lin2 > ih->data->lines.last)
|
||
|
lin2 = ih->data->lines.last;
|
||
|
|
||
|
first_lin = ih->data->lines.first;
|
||
|
y1 = 0;
|
||
|
for (lin = 0; lin < ih->data->lines.num_noscroll; lin++)
|
||
|
y1 += ih->data->lines.dt[lin].size;
|
||
|
}
|
||
|
|
||
|
iupMATRIX_CLIPAREA(ih, x1, x2, y1, y2);
|
||
|
cdCanvasClip(ih->data->cd_canvas, CD_CLIPOFF); /* wait for background */
|
||
|
|
||
|
/* Find the initial position of the first column */
|
||
|
if (first_col == ih->data->columns.first)
|
||
|
x1 -= ih->data->columns.first_offset;
|
||
|
for (col = first_col; col < col1; col++)
|
||
|
x1 += ih->data->columns.dt[col].size;
|
||
|
if (adjust_merged_col)
|
||
|
{
|
||
|
for (col = first_col-1; col >= col1; col--)
|
||
|
x1 -= ih->data->columns.dt[col].size;
|
||
|
}
|
||
|
|
||
|
/* Find the initial position of the first line */
|
||
|
if (first_lin == ih->data->lines.first)
|
||
|
y1 -= ih->data->lines.first_offset;
|
||
|
for (lin = first_lin; lin < lin1; lin++)
|
||
|
y1 += ih->data->lines.dt[lin].size;
|
||
|
if (adjust_merged_lin)
|
||
|
{
|
||
|
for (lin = first_lin-1; lin >= lin1; lin--)
|
||
|
y1 -= ih->data->lines.dt[lin].size;
|
||
|
}
|
||
|
|
||
|
/* Find the final position of the last column */
|
||
|
x2 = x1;
|
||
|
for (; col <= col2; col++)
|
||
|
x2 += ih->data->columns.dt[col].size;
|
||
|
|
||
|
/* Find the final position of the last line */
|
||
|
y2 = y1;
|
||
|
for (; lin <= lin2; lin++)
|
||
|
y2 += ih->data->lines.dt[lin].size;
|
||
|
|
||
|
if ((col2 == ih->data->columns.num - 1) && (old_x2 > x2))
|
||
|
{
|
||
|
long emptyarea_color = cdIupConvertColor(ih->data->bgcolor_parent);
|
||
|
cdCanvasForeground(ih->data->cd_canvas, emptyarea_color);
|
||
|
|
||
|
/* If it was drawn until the last column and remains space in the right of it,
|
||
|
then delete this area with the the background color. */
|
||
|
iupMATRIX_BOX(ih, x2, old_x2, old_y1, old_y2);
|
||
|
}
|
||
|
|
||
|
if ((lin2 == ih->data->lines.num - 1) && (old_y2 > y2))
|
||
|
{
|
||
|
long emptyarea_color = cdIupConvertColor(ih->data->bgcolor_parent);
|
||
|
cdCanvasForeground(ih->data->cd_canvas, emptyarea_color);
|
||
|
|
||
|
/* If it was drawn until the last line visible and remains space below it,
|
||
|
then delete this area with the the background color. */
|
||
|
iupMATRIX_BOX(ih, 0, old_x2, y2, old_y2);
|
||
|
}
|
||
|
|
||
|
/* after the background */
|
||
|
cdCanvasClip(ih->data->cd_canvas, CD_CLIPAREA);
|
||
|
|
||
|
/***** Draw the cell values and frame */
|
||
|
old_y1 = y1;
|
||
|
framecolor = cdIupConvertColor(iupAttribGetStr(ih, "FRAMECOLOR"));
|
||
|
framehighlight = iupAttribGetInt(ih, "FRAMETITLEHIGHLIGHT");
|
||
|
active = iupdrvIsActive(ih);
|
||
|
|
||
|
mark_cb = (IFnii)IupGetCallback(ih, "MARK_CB");
|
||
|
dropcheck_cb = (IFnii)IupGetCallback(ih, "DROPCHECK_CB");
|
||
|
draw_cb = (IFniiiiiiC)IupGetCallback(ih, "DRAW_CB");
|
||
|
toggle_centered = iupAttribGetBoolean(ih, "TOGGLECENTERED");
|
||
|
|
||
|
for (col = col1; col <= col2; col++) /* For all the columns in the region */
|
||
|
{
|
||
|
int last_x2, last_y2;
|
||
|
|
||
|
if (ih->data->columns.dt[col].size == 0)
|
||
|
continue;
|
||
|
|
||
|
col_alignment = iupMatrixGetColAlignment(ih, col);
|
||
|
|
||
|
x2 = x1 + ih->data->columns.dt[col].size;
|
||
|
last_x2 = x2;
|
||
|
|
||
|
for (lin = lin1; lin <= lin2; lin++) /* For all lines in the region */
|
||
|
{
|
||
|
int drop = 0;
|
||
|
int marked = 0;
|
||
|
int lin_alignment;
|
||
|
int merged;
|
||
|
|
||
|
if (ih->data->lines.dt[lin].size == 0)
|
||
|
continue;
|
||
|
|
||
|
merged = 0;
|
||
|
if (ih->data->merge_info_count)
|
||
|
merged = iupMatrixGetMerged(ih, lin, col);
|
||
|
|
||
|
y2 = y1 + ih->data->lines.dt[lin].size;
|
||
|
last_y2 = y2;
|
||
|
|
||
|
if (merged)
|
||
|
{
|
||
|
int startLin, endLin, startCol, endCol;
|
||
|
iupMatrixGetMergedRect(ih, merged, &startLin, &endLin, &startCol, &endCol);
|
||
|
|
||
|
if (lin == startLin && col == startCol) /* merged start */
|
||
|
{
|
||
|
for (i = startLin + 1; i <= endLin; i++)
|
||
|
y2 += ih->data->lines.dt[i].size;
|
||
|
for (i = startCol + 1; i <= endCol; i++)
|
||
|
x2 += ih->data->columns.dt[i].size;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
x2 = last_x2;
|
||
|
y1 = last_y2;
|
||
|
continue; /* ignore internal merged */
|
||
|
}
|
||
|
}
|
||
|
|
||
|
lin_alignment = iupMatrixGetLinAlignment(ih, lin);
|
||
|
|
||
|
/* If the cell is marked, then draw it with attenuation color */
|
||
|
marked = iupMatrixGetMark(ih, lin, col, mark_cb);
|
||
|
|
||
|
if (ih->data->noscroll_as_title && (lin < ih->data->lines.num_noscroll || col < ih->data->columns.num_noscroll))
|
||
|
{
|
||
|
iMatrixDrawBackground(ih, x1, x2, y1, y2, marked, active, lin, 0);
|
||
|
iMatrixDrawFrameRectTitle(ih, lin, col, x1, x2, y1, y2, framecolor, framehighlight);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
iMatrixDrawBackground(ih, x1, x2, y1, y2, marked, active, lin, col);
|
||
|
|
||
|
iMatrixDrawFrameRectCell(ih, lin, col, x1, x2, y1, y2, framecolor);
|
||
|
|
||
|
if (dropcheck_cb)
|
||
|
{
|
||
|
int ret = dropcheck_cb(ih, lin, col);
|
||
|
if (ret == IUP_DEFAULT)
|
||
|
{
|
||
|
iMatrixDrawDropdownButton(ih, x2, y1, y2, lin, col, marked, active);
|
||
|
|
||
|
drop = IMAT_PADDING_W / 2 + IMAT_FEEDBACK_SIZE + IMAT_PADDING_W / 2;
|
||
|
}
|
||
|
else if (ret == IUP_CONTINUE)
|
||
|
{
|
||
|
iMatrixDrawToggle(ih, x1, x2, y1, y2, lin, col, marked, active, toggle_centered);
|
||
|
|
||
|
if (toggle_centered)
|
||
|
{
|
||
|
y1 = last_y2;
|
||
|
continue; /* do not draw the cell contents */
|
||
|
}
|
||
|
|
||
|
drop = IMAT_PADDING_W / 2 + IMAT_FEEDBACK_SIZE + IMAT_PADDING_W / 2;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* draw the cell contents */
|
||
|
iMatrixDrawCellValue(ih, x1, x2 - drop, y1, y2, col_alignment, lin_alignment, marked, active, lin, col, draw_cb, framecolor);
|
||
|
|
||
|
x2 = last_x2;
|
||
|
y1 = last_y2;
|
||
|
}
|
||
|
|
||
|
x1 = last_x2;
|
||
|
y1 = old_y1; /* must reset also y */
|
||
|
}
|
||
|
|
||
|
cdCanvasClip(ih->data->cd_canvas, CD_CLIPOFF);
|
||
|
}
|
||
|
|
||
|
static void iMatrixDrawMatrix(Ihandle* ih)
|
||
|
{
|
||
|
iupMatrixPrepareDrawData(ih);
|
||
|
|
||
|
/* fill the background because there will be empty cells */
|
||
|
if ((ih->data->lines.num == 1) || (ih->data->columns.num == 1))
|
||
|
{
|
||
|
cdCanvasBackground(ih->data->cd_canvas, cdIupConvertColor(ih->data->bgcolor_parent));
|
||
|
cdCanvasClear(ih->data->cd_canvas);
|
||
|
}
|
||
|
|
||
|
/* Draw the corner between line and column titles, if necessary */
|
||
|
iMatrixDrawTitleCorner(ih);
|
||
|
|
||
|
/* If there are columns, then draw their titles */
|
||
|
if (ih->data->columns.num_noscroll > 1)
|
||
|
iMatrixDrawTitleColumns(ih, 1, ih->data->columns.num_noscroll - 1);
|
||
|
iMatrixDrawTitleColumns(ih, ih->data->columns.first, ih->data->columns.last);
|
||
|
|
||
|
/* If there are lines, then draw their titles */
|
||
|
if (ih->data->lines.num_noscroll > 1)
|
||
|
iMatrixDrawTitleLines(ih, 1, ih->data->lines.num_noscroll - 1);
|
||
|
iMatrixDrawTitleLines(ih, ih->data->lines.first, ih->data->lines.last);
|
||
|
|
||
|
/* If there are ordinary cells, then draw them */
|
||
|
if (ih->data->columns.num_noscroll > 1 && ih->data->lines.num_noscroll > 1)
|
||
|
iMatrixDrawCells(ih, 1, 1, ih->data->lines.num_noscroll - 1, ih->data->columns.num_noscroll - 1);
|
||
|
if (ih->data->columns.num_noscroll > 1)
|
||
|
iMatrixDrawCells(ih, ih->data->lines.first, 1, ih->data->lines.last, ih->data->columns.num_noscroll - 1);
|
||
|
if (ih->data->lines.num_noscroll > 1)
|
||
|
iMatrixDrawCells(ih, 1, ih->data->columns.first, ih->data->lines.num_noscroll - 1, ih->data->columns.last);
|
||
|
iMatrixDrawCells(ih, ih->data->lines.first, ih->data->columns.first, ih->data->lines.last, ih->data->columns.last);
|
||
|
|
||
|
if (iupAttribGetBoolean(ih, "FRAMEBORDER"))
|
||
|
{
|
||
|
long framecolor = cdIupConvertColor(iupAttribGetStr(ih, "FRAMECOLOR"));
|
||
|
cdCanvasForeground(ih->data->cd_canvas, framecolor);
|
||
|
|
||
|
/* if vertical scrollbar is visible */
|
||
|
if (!iupAttribGetBoolean(ih, "YHIDDEN"))
|
||
|
{
|
||
|
int posy = IupGetInt(ih, "POSY");
|
||
|
int dy = IupGetInt(ih, "DY");
|
||
|
int ymax = IupGetInt(ih, "YMAX");
|
||
|
int height = iupMatrixGetHeight(ih);
|
||
|
|
||
|
int width = iupMatrixGetWidth(ih);
|
||
|
if (width > ih->data->columns.total_size)
|
||
|
width = ih->data->columns.total_size;
|
||
|
|
||
|
/* if scrollbar at top, top line is not necessary */
|
||
|
if (posy > 0)
|
||
|
iupMATRIX_LINE(ih, 0, 0, width - 1, 0); /* top horizontal line */
|
||
|
|
||
|
/* if scrollbar at bottom, bottom line is not necessary */
|
||
|
if (posy < ymax - dy)
|
||
|
iupMATRIX_LINE(ih, 0, height - 1, width - 1, height - 1); /* bottom horizontal line */
|
||
|
}
|
||
|
|
||
|
/* if horizontal scrollbar is visible */
|
||
|
if (!iupAttribGetBoolean(ih, "XHIDDEN"))
|
||
|
{
|
||
|
int posx = IupGetInt(ih, "POSX");
|
||
|
int dx = IupGetInt(ih, "DX");
|
||
|
int xmax = IupGetInt(ih, "XMAX");
|
||
|
int width = iupMatrixGetWidth(ih);
|
||
|
|
||
|
int height = iupMatrixGetHeight(ih);
|
||
|
if (height > ih->data->lines.total_size)
|
||
|
height = ih->data->lines.total_size;
|
||
|
|
||
|
/* if scrollbar at left, left line is not necessary */
|
||
|
if (posx > 0)
|
||
|
iupMATRIX_LINE(ih, 0, 0, 0, height - 1); /* left vertical line */
|
||
|
|
||
|
/* if scrollbar at right, right line is not necessary */
|
||
|
if (posx < xmax - dx)
|
||
|
iupMATRIX_LINE(ih, width - 1, 0, width - 1, height - 1); /* right vertical line */
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void iupMatrixDrawCells(Ihandle* ih, int lin1, int col1, int lin2, int col2)
|
||
|
{
|
||
|
#ifdef USE_OLD_DRAW
|
||
|
iMatrixDrawCells(ih, lin1, col1, lin2, col2);
|
||
|
#else
|
||
|
(void)ih;
|
||
|
(void)lin1;
|
||
|
(void)col1;
|
||
|
(void)lin2;
|
||
|
(void)col2;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void iupMatrixDrawTitleColumns(Ihandle* ih, int col1, int col2)
|
||
|
{
|
||
|
#ifdef USE_OLD_DRAW
|
||
|
iMatrixDrawTitleColumns(ih, col1, col2);
|
||
|
#else
|
||
|
(void)ih;
|
||
|
(void)col1;
|
||
|
(void)col2;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void iupMatrixDrawTitleLines(Ihandle* ih, int lin1, int lin2)
|
||
|
{
|
||
|
#ifdef USE_OLD_DRAW
|
||
|
iMatrixDrawTitleLines(ih, lin1, lin2);
|
||
|
#else
|
||
|
(void)ih;
|
||
|
(void)lin1;
|
||
|
(void)lin2;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void iupMatrixDraw(Ihandle* ih, int update)
|
||
|
{
|
||
|
#ifdef USE_OLD_DRAW
|
||
|
cdCanvasActivate(ih->data->cd_canvas);
|
||
|
|
||
|
if (ih->data->need_calcsize)
|
||
|
iupMatrixAuxCalcSizes(ih);
|
||
|
|
||
|
iMatrixDrawMatrix(ih);
|
||
|
|
||
|
ih->data->need_redraw = 0;
|
||
|
#endif
|
||
|
|
||
|
if (update)
|
||
|
iupMatrixDrawUpdate(ih);
|
||
|
}
|
||
|
|
||
|
void iupMatrixDrawUpdate(Ihandle* ih)
|
||
|
{
|
||
|
#ifdef USE_OLD_DRAW
|
||
|
cdCanvasFlush(ih->data->cd_canvas);
|
||
|
|
||
|
if (ih->data->has_focus)
|
||
|
iMatrixDrawFocus(ih);
|
||
|
|
||
|
if (ih->data->colres_feedback)
|
||
|
iMatrixDrawColRes(ih);
|
||
|
|
||
|
if (!ih->data->edit_hide_onfocus && ih->data->editing)
|
||
|
IupUpdate(ih->data->datah);
|
||
|
#else
|
||
|
iupdrvRedrawNow(ih);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
static int iMatrixDrawHasFlatScrollBar(Ihandle* ih)
|
||
|
{
|
||
|
char* value = iupAttribGetStr(ih, "FLATSCROLLBAR");
|
||
|
if (value && !iupStrEqualNoCase(value, "NO"))
|
||
|
return 1;
|
||
|
else
|
||
|
return 0;
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
#ifndef USE_OLD_DRAW
|
||
|
void iupMatrixDrawCB(Ihandle* ih)
|
||
|
{
|
||
|
/* called only from the ACTION callback */
|
||
|
if (ih->data->need_calcsize)
|
||
|
{
|
||
|
int sb_resize = iupMatrixAuxCalcSizes(ih); /* does not use cd_canvas, can be done before Activate, */
|
||
|
if (sb_resize) /* but it can trigger a resize+redraw event */
|
||
|
{
|
||
|
/* if (!iMatrixDrawHasFlatScrollBar(ih)) */
|
||
|
{
|
||
|
/* TODO: this is not working in all situations, so it is disabled. */
|
||
|
/* return; */
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
cdCanvasActivate(ih->data->cd_canvas);
|
||
|
|
||
|
iMatrixDrawMatrix(ih);
|
||
|
|
||
|
ih->data->need_redraw = 0;
|
||
|
|
||
|
if (ih->data->has_focus)
|
||
|
iMatrixDrawFocus(ih);
|
||
|
|
||
|
if (ih->data->colres_feedback)
|
||
|
iMatrixDrawColRes(ih);
|
||
|
|
||
|
cdCanvasFlush(ih->data->cd_canvas);
|
||
|
|
||
|
cdCanvasDeactivate(ih->data->cd_canvas);
|
||
|
|
||
|
if (!ih->data->edit_hide_onfocus && ih->data->editing)
|
||
|
IupUpdate(ih->data->datah);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
int iupMatrixDrawSetRedrawAttrib(Ihandle* ih, const char* value)
|
||
|
{
|
||
|
#ifdef USE_OLD_DRAW
|
||
|
int type;
|
||
|
|
||
|
if (value == NULL)
|
||
|
type = 0;
|
||
|
else if (value[0] == 'L' || value[0] == 'l')
|
||
|
type = IMAT_PROCESS_LIN;
|
||
|
else if (value[0] == 'C' || value[0] == 'c')
|
||
|
type = IMAT_PROCESS_COL;
|
||
|
else
|
||
|
type = 0;
|
||
|
|
||
|
if (type) /* lines or columns, including their titles */
|
||
|
{
|
||
|
int min = 0, max = 0;
|
||
|
value++;
|
||
|
|
||
|
/* compatibility code */
|
||
|
if (strchr(value, ':') != NULL)
|
||
|
{
|
||
|
if (iupStrToIntInt(value, &min, &max, ':') != 2)
|
||
|
max = min;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (iupStrToIntInt(value, &min, &max, '-') != 2)
|
||
|
max = min;
|
||
|
}
|
||
|
|
||
|
if (min > max)
|
||
|
return 0;
|
||
|
|
||
|
cdCanvasActivate(ih->data->cd_canvas);
|
||
|
|
||
|
iupMatrixPrepareDrawData(ih);
|
||
|
|
||
|
if (ih->data->need_calcsize)
|
||
|
iupMatrixAuxCalcSizes(ih);
|
||
|
|
||
|
/* ignore empty area, draw only cells */
|
||
|
|
||
|
iMatrixDrawTitleCorner(ih);
|
||
|
|
||
|
if (type == IMAT_PROCESS_LIN)
|
||
|
{
|
||
|
if (min == 0)
|
||
|
{
|
||
|
if (ih->data->columns.num_noscroll > 1)
|
||
|
iMatrixDrawTitleColumns(ih, 1, ih->data->columns.num_noscroll - 1);
|
||
|
iMatrixDrawTitleColumns(ih, ih->data->columns.first, ih->data->columns.last);
|
||
|
}
|
||
|
|
||
|
iMatrixDrawTitleLines(ih, min, max);
|
||
|
if (ih->data->columns.num_noscroll > 1)
|
||
|
iMatrixDrawCells(ih, min, 1, max, ih->data->columns.num_noscroll - 1);
|
||
|
iMatrixDrawCells(ih, min, ih->data->columns.first, max, ih->data->columns.last);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (min == 0)
|
||
|
{
|
||
|
if (ih->data->lines.num_noscroll > 1)
|
||
|
iMatrixDrawTitleLines(ih, 1, ih->data->lines.num_noscroll - 1);
|
||
|
iMatrixDrawTitleLines(ih, ih->data->lines.first, ih->data->lines.last);
|
||
|
}
|
||
|
|
||
|
iMatrixDrawTitleColumns(ih, min, max);
|
||
|
if (ih->data->lines.num_noscroll > 1)
|
||
|
iMatrixDrawCells(ih, 1, min, ih->data->lines.num_noscroll - 1, max);
|
||
|
iMatrixDrawCells(ih, ih->data->lines.first, min, ih->data->lines.last, max);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
cdCanvasActivate(ih->data->cd_canvas);
|
||
|
|
||
|
/* Force CalcSize */
|
||
|
iupMatrixAuxCalcSizes(ih);
|
||
|
|
||
|
iMatrixDrawMatrix(ih);
|
||
|
}
|
||
|
|
||
|
ih->data->need_redraw = 0;
|
||
|
iupMatrixDrawUpdate(ih);
|
||
|
#else
|
||
|
IupRedraw(ih, 0); /* redraw now */
|
||
|
(void)value;
|
||
|
#endif
|
||
|
return 0;
|
||
|
}
|