From d577d991b97ae2b5ee1af23641bcffc3f83af5b2 Mon Sep 17 00:00:00 2001 From: Pixel Date: Wed, 4 Nov 2009 11:56:41 -0800 Subject: Initial import. Contains the im, cd and iup librairies, and a "working" Makefile for them under linux. --- iup/srccontrols/matrix/iupmat_mark.c | 720 +++++++++++++++++++++++++++++++++++ 1 file changed, 720 insertions(+) create mode 100755 iup/srccontrols/matrix/iupmat_mark.c (limited to 'iup/srccontrols/matrix/iupmat_mark.c') diff --git a/iup/srccontrols/matrix/iupmat_mark.c b/iup/srccontrols/matrix/iupmat_mark.c new file mode 100755 index 0000000..99aad32 --- /dev/null +++ b/iup/srccontrols/matrix/iupmat_mark.c @@ -0,0 +1,720 @@ +/** \file + * \brief iupmatrix control + * cell selection + * + * See Copyright Notice in "iup.h" + */ + +/**************************************************************************/ +/* Functions to cell selection (mark) */ +/**************************************************************************/ + +#include +#include +#include +#include + +#include "iup.h" +#include "iupcbs.h" + +#include + +#include "iup_object.h" +#include "iup_attrib.h" +#include "iup_str.h" +#include "iup_stdcontrols.h" + +#include "iupmat_def.h" +#include "iupmat_mark.h" +#include "iupmat_getset.h" +#include "iupmat_draw.h" + + +static void iMatrixMarkLinSet(Ihandle* ih, int lin, int mark) +{ + /* called when MARKMODE=LIN */ + if (mark==-1) + mark = !(ih->data->lines.flags[lin] & IUPMAT_MARK); + + if (mark) + ih->data->lines.flags[lin] |= IUPMAT_MARK; + else + ih->data->lines.flags[lin] &= ~IUPMAT_MARK; +} + +static void iMatrixMarkColSet(Ihandle* ih, int col, int mark) +{ + /* called when MARKMODE=COL */ + if (mark==-1) + mark = !(ih->data->columns.flags[col] & IUPMAT_MARK); + + if (mark) + ih->data->columns.flags[col] |= IUPMAT_MARK; + else + ih->data->columns.flags[col] &= ~IUPMAT_MARK; +} + +static void iMatrixMarkCellSet(Ihandle* ih, int lin, int col, int mark, IFniii markedit_cb, IFnii mark_cb, char* str) +{ + /* called only when MARKMODE=CELL */ + if (mark == -1) + mark = !iupMatrixMarkCellGet(ih, lin, col, mark_cb, str); + + if (ih->data->callback_mode) + { + if (markedit_cb) + markedit_cb(ih, lin, col, mark); + else + { + sprintf(str, "MARK%d:%d", lin, col); + if (mark) + iupAttribSetStr(ih, str, "1"); + else + iupAttribSetStr(ih, str, NULL); + } + } + else + { + if (mark) + ih->data->cells[lin][col].flags |= IUPMAT_MARK; + else + ih->data->cells[lin][col].flags &= ~IUPMAT_MARK; + } +} + +int iupMatrixMarkCellGet(Ihandle* ih, int lin, int col, IFnii mark_cb, char* str) +{ + /* called independent from MARKMODE */ + + if (ih->data->mark_mode == IMAT_MARK_NO) + return 0; + + if (ih->data->mark_mode == IMAT_MARK_CELL) + { + if (ih->data->callback_mode) + { + if (mark_cb) + return mark_cb(ih, lin, col); + else + { + int mark = 0; + char* value; + sprintf(str, "MARK%d:%d", lin, col); + value = iupAttribGet(ih, str); + iupStrToInt(value, &mark); + return mark; + } + } + else + return ih->data->cells[lin][col].flags & IUPMAT_MARK; + } + else + { + if (ih->data->lines.flags[lin] & IUPMAT_MARK || ih->data->columns.flags[col] & IUPMAT_MARK) + return 1; + else + return 0; + } +} + +static void iMatrixMarkItem(Ihandle* ih, int lin1, int col1, int mark, IFniii markedit_cb, IFnii mark_cb, char* str) +{ + int lin, col; + + if (ih->data->mark_full1 == IMAT_PROCESS_LIN) + { + if (ih->data->mark_mode == IMAT_MARK_CELL) + { + for (col = 1; col < ih->data->columns.num; col++) + iMatrixMarkCellSet(ih, lin1, col, mark, markedit_cb, mark_cb, str); + } + else + { + iMatrixMarkLinSet(ih, lin1, mark); + iupMatrixDrawLineTitle(ih, lin1, lin1); + } + + iupMatrixDrawCells(ih, lin1, 1, lin1, ih->data->columns.num-1); + } + else if (ih->data->mark_full1 == IMAT_PROCESS_COL) + { + if (ih->data->mark_mode == IMAT_MARK_CELL) + { + for(lin = 1; lin < ih->data->lines.num; lin++) + iMatrixMarkCellSet(ih, lin, col1, mark, markedit_cb, mark_cb, str); + } + else + { + iMatrixMarkColSet(ih, col1, mark); + iupMatrixDrawColumnTitle(ih, col1, col1); + } + + iupMatrixDrawCells(ih, 1, col1, ih->data->lines.num-1, col1); + } + else if (ih->data->mark_mode == IMAT_MARK_CELL) + { + iMatrixMarkCellSet(ih, lin1, col1, mark, markedit_cb, mark_cb, str); + iupMatrixDrawCells(ih, lin1, col1, lin1, col1); + } +} + +static void iMatrixMarkBlock(Ihandle* ih, int lin1, int col1, int lin2, int col2, int mark, IFniii markedit_cb, IFnii mark_cb, char* str) +{ + int lin, col; + + if (lin1 > lin2) {int t = lin1; lin1 = lin2; lin2 = t;} + if (col1 > col2) {int t = col1; col1 = col2; col2 = t;} + + if (ih->data->mark_full1 == IMAT_PROCESS_LIN) + { + for(lin=lin1; lin<=lin2; lin++) + iMatrixMarkItem(ih, lin, 0, mark, markedit_cb, mark_cb, str); + } + else if(ih->data->mark_full1 == IMAT_PROCESS_COL) + { + for(col=col1; col<=col2; col++) + iMatrixMarkItem(ih, 0, col, mark, markedit_cb, mark_cb, str); + } + else if (ih->data->mark_mode == IMAT_MARK_CELL) + { + for(lin=lin1; lin<=lin2; lin++) + { + for(col=col1; col<=col2; col++) + iMatrixMarkItem(ih, lin, col, mark, markedit_cb, mark_cb, str); + } + } +} + +void iupMatrixMarkMouseBlock(Ihandle* ih, int lin2, int col2) +{ + /* called only when "shift" is pressed and MARKMULTIPLE=YES */ + IFniii markedit_cb = NULL; + IFnii mark_cb = NULL; + char str[100]; + + iupMatrixPrepareDrawData(ih); + + ih->data->mark_full2 = 0; + + if (lin2 == 0 && col2 == 0) + return; + /* If it was pointing for a column title... */ + else if (lin2 == 0) + { + if ((ih->data->mark_mode == IMAT_MARK_CELL && ih->data->mark_multiple) || + ih->data->mark_mode & IMAT_MARK_COL) + ih->data->mark_full2 = IMAT_PROCESS_COL; + } + /* If it was pointing for a line title... */ + else if (col2 == 0) + { + if ((ih->data->mark_mode == IMAT_MARK_CELL && ih->data->mark_multiple) || + ih->data->mark_mode & IMAT_MARK_LIN) + ih->data->mark_full2 = IMAT_PROCESS_LIN; + } + + /* if new block is not the same, does nothing */ + if (ih->data->mark_full1 != ih->data->mark_full2) + return; + + if (ih->data->mark_mode == IMAT_MARK_CELL && ih->data->callback_mode) + { + markedit_cb = (IFniii)IupGetCallback(ih, "MARKEDIT_CB"); + mark_cb = (IFnii)IupGetCallback(ih, "MARK_CB"); + } + + /* Unmark previous block */ + if (ih->data->mark_lin1 != -1 && ih->data->mark_lin2 != -1 && + ih->data->mark_col1 != -1 && ih->data->mark_col2 != -1) + iMatrixMarkBlock(ih, ih->data->mark_lin1, ih->data->mark_col1, ih->data->mark_lin2, ih->data->mark_col2, 0, markedit_cb, mark_cb, str); + + ih->data->mark_lin2 = lin2; + ih->data->mark_col2 = col2; + + /* Unmark new block */ + iMatrixMarkBlock(ih, ih->data->mark_lin1, ih->data->mark_col1, ih->data->mark_lin2, ih->data->mark_col2, 1, markedit_cb, mark_cb, str); +} + +void iupMatrixMarkMouseReset(Ihandle* ih) +{ + ih->data->mark_lin1 = -1; + ih->data->mark_col1 = -1; + ih->data->mark_lin2 = -1; + ih->data->mark_col2 = -1; + + ih->data->mark_full1 = 0; + ih->data->mark_full2 = 0; +} + +void iupMatrixMarkMouseItem(Ihandle* ih, int ctrl, int lin1, int col1) +{ + int mark = 1, mark_full_all, lin, col; + IFniii markedit_cb = NULL; + IFnii mark_cb = NULL; + char str[100]; + + iupMatrixMarkMouseReset(ih); + iupMatrixPrepareDrawData(ih); + + if (!ih->data->mark_multiple || ih->data->mark_continuous || !ctrl) + { + iupMatrixMarkClearAll(ih, 1); + iupMatrixDraw(ih, 0); + } + else + mark = -1; /* toggle mark state */ + + ih->data->mark_full1 = 0; + mark_full_all = 0; + + if (lin1 == 0 && col1 == 0) + { + if ((ih->data->mark_mode == IMAT_MARK_CELL && ih->data->mark_multiple) || + ih->data->mark_mode == IMAT_MARK_COL || + ih->data->mark_mode == IMAT_MARK_LIN) + mark_full_all = 1; + } + /* If it was pointing for a column title... */ + else if (lin1 == 0) + { + if ((ih->data->mark_mode == IMAT_MARK_CELL && ih->data->mark_multiple) || + ih->data->mark_mode & IMAT_MARK_COL) + ih->data->mark_full1 = IMAT_PROCESS_COL; + } + /* If it was pointing for a line title... */ + else if (col1 == 0) + { + if ((ih->data->mark_mode == IMAT_MARK_CELL && ih->data->mark_multiple) || + ih->data->mark_mode & IMAT_MARK_LIN) + ih->data->mark_full1 = IMAT_PROCESS_LIN; + } + + if (ih->data->mark_mode == IMAT_MARK_CELL && ih->data->callback_mode) + { + markedit_cb = (IFniii)IupGetCallback(ih, "MARKEDIT_CB"); + mark_cb = (IFnii)IupGetCallback(ih, "MARK_CB"); + } + + if (mark_full_all) + { + if (ih->data->mark_mode == IMAT_MARK_CELL) + { + char str[100]; + for (col = 1; col < ih->data->columns.num; col++) + { + for(lin = 1; lin < ih->data->lines.num; lin++) + iMatrixMarkCellSet(ih, lin, col, mark, markedit_cb, mark_cb, str); + } + } + else if (ih->data->mark_mode == IMAT_MARK_LIN) + { + for(lin = 1; lin < ih->data->lines.num; lin++) + iMatrixMarkLinSet(ih, lin, mark); + + iupMatrixDrawLineTitle(ih, 1, ih->data->lines.num-1); + } + else if (ih->data->mark_mode == IMAT_MARK_COL) + { + for (col = 1; col < ih->data->columns.num; col++) + iMatrixMarkColSet(ih, col, mark); + + iupMatrixDrawColumnTitle(ih, 1, ih->data->columns.num-1); + } + + iupMatrixDrawCells(ih, 1, 1, ih->data->lines.num-1, ih->data->columns.num-1); + } + else + iMatrixMarkItem(ih, lin1, col1, mark, markedit_cb, mark_cb, str); + + ih->data->mark_lin1 = lin1; + ih->data->mark_col1 = col1; +} + +static void iMatrixMarkAllLinCol(ImatLinColData *p, int mark) +{ + int i; + for(i = 1; i < p->num; i++) + { + if (mark) + p->flags[i] |= IUPMAT_MARK; + else + p->flags[i] &= ~IUPMAT_MARK; + } +} + +void iupMatrixMarkClearAll(Ihandle* ih, int check) +{ + /* "!check" is used to clear all marks independent from MARKMODE */ + + if (ih->data->mark_mode == IMAT_MARK_CELL || !check) + { + int lin, col; + IFniii markedit_cb = NULL; + char str[100]; + + if (check) + markedit_cb = (IFniii)IupGetCallback(ih, "MARKEDIT_CB"); + + for(lin = 1; lin < ih->data->lines.num; lin++) + { + for(col = 1; col < ih->data->columns.num; col++) + iMatrixMarkCellSet(ih, lin, col, 0, markedit_cb, NULL, str); + } + } + + if (ih->data->mark_mode & IMAT_MARK_LIN || !check) + iMatrixMarkAllLinCol(&(ih->data->lines), 0); + + if (ih->data->mark_mode & IMAT_MARK_COL || !check) + iMatrixMarkAllLinCol(&(ih->data->columns), 0); +} + +int iupMatrixColumnIsMarked(Ihandle* ih, int col) +{ + if (col == 0 || /* Line titles are never marked... */ + !(ih->data->mark_mode & IMAT_MARK_COL)) + return 0; + + return ih->data->columns.flags[col] & IUPMAT_MARK; +} + +int iupMatrixLineIsMarked(Ihandle* ih, int lin) +{ + if (lin == 0 || /* Column titles are never marked... */ + !(ih->data->mark_mode & IMAT_MARK_LIN)) + return 0; + + return ih->data->lines.flags[lin] & IUPMAT_MARK; +} + +int iupMatrixSetMarkedAttrib(Ihandle* ih, const char* value) +{ + int lin, col, mark; + char str[100]; + IFniii markedit_cb; + + if (ih->data->mark_mode == IMAT_MARK_NO) + return 0; + + if (!value) + iupMatrixMarkClearAll(ih, 1); + else if (*value == 'C' || *value == 'c') /* columns */ + { + if (ih->data->mark_mode == IMAT_MARK_LIN) + return 0; + + value++; /* skip C mark */ + if ((int)strlen(value) != ih->data->columns.num-1) + return 0; + + markedit_cb = (IFniii)IupGetCallback(ih, "MARKEDIT_CB"); + + for(col = 1; col < ih->data->columns.num; col++) + { + if (*value++ == '1') + mark = 1; + else + mark = 0; + + /* mark all the cells for that column */ + if (ih->data->mark_mode == IMAT_MARK_CELL) + { + for(lin = 1; lin < ih->data->lines.num; lin++) + iMatrixMarkCellSet(ih, lin, col, mark, markedit_cb, NULL, str); + } + else + iMatrixMarkColSet(ih, col, mark); + } + + if (ih->data->mark_mode & IMAT_MARK_LIN) + iMatrixMarkAllLinCol(&(ih->data->lines), 0); + } + else if (*value == 'L' || *value == 'l') /* lines */ + { + if (ih->data->mark_mode == IMAT_MARK_COL) + return 0; + + value++; /* skip L mark */ + if ((int)strlen(value) != ih->data->lines.num-1) + return 0; + + markedit_cb = (IFniii)IupGetCallback(ih, "MARKEDIT_CB"); + + for(lin = 1; lin < ih->data->lines.num; lin++) + { + if (*value++ == '1') + mark = 1; + else + mark = 0; + + /* Mark all the cells for that line */ + if (ih->data->mark_mode == IMAT_MARK_CELL) + { + for(col = 1; col < ih->data->columns.num; col++) + iMatrixMarkCellSet(ih, lin, col, mark, markedit_cb, NULL, str); + } + else + iMatrixMarkLinSet(ih, lin, mark); + } + + if (ih->data->mark_mode & IMAT_MARK_COL) + iMatrixMarkAllLinCol(&(ih->data->columns), 0); + } + else if (ih->data->mark_mode == IMAT_MARK_CELL) /* cells */ + { + if ((int)strlen(value) != (ih->data->lines.num-1)*(ih->data->columns.num-1)) + return 0; + + markedit_cb = (IFniii)IupGetCallback(ih, "MARKEDIT_CB"); + + for(lin = 1; lin < ih->data->lines.num; lin++) + { + for(col = 1; col < ih->data->columns.num; col++) + { + if (*value++ == '1') + mark = 1; + else + mark = 0; + + iMatrixMarkCellSet(ih, lin, col, mark, markedit_cb, NULL, str); + } + } + } + + if (ih->handle) + iupMatrixDraw(ih, 1); + + return 0; +} + +char* iupMatrixGetMarkedAttrib(Ihandle* ih) +{ + int lin, col, size; + IFnii mark_cb; + char str[100]; + char* p, *value = NULL; + int exist_mark = 0; /* Show if there is someone marked */ + + if (ih->data->mark_mode == IMAT_MARK_NO) + return NULL; + + mark_cb = (IFnii)IupGetCallback(ih, "MARK_CB"); + + if (ih->data->mark_mode == IMAT_MARK_CELL) + { + size = (ih->data->lines.num-1) * (ih->data->columns.num-1) + 1; + value = iupStrGetMemory(size); + p = value; + + for(lin = 1; lin < ih->data->lines.num; lin++) + { + for(col = 1; col < ih->data->columns.num; col++) + { + if (iupMatrixMarkCellGet(ih, lin, col, mark_cb, str)) + { + exist_mark = 1; + *p++ = '1'; + } + else + *p++ = '0'; + } + } + *p = 0; + } + else + { + int marked_lines = 0, marked_cols = 0; + + if (ih->data->mark_mode == IMAT_MARK_LINCOL) /* must find which format to return */ + { + /* look for a marked column */ + for(col = 1; col < ih->data->columns.num; col++) + { + if (ih->data->columns.flags[col] & IUPMAT_MARK) + { + marked_cols = 1; /* at least one column is marked */ + break; + } + } + + if (!marked_cols) + marked_lines = 1; + } + else if (ih->data->mark_mode == IMAT_MARK_LIN) + marked_lines = 1; + else if (ih->data->mark_mode == IMAT_MARK_COL) + marked_cols = 1; + + if (marked_lines) + { + size = 1 + (ih->data->lines.num-1) + 1; + value = iupStrGetMemory(size); + p = value; + + *p++ = 'L'; + + for(lin = 1; lin < ih->data->lines.num; lin++) + { + if (ih->data->lines.flags[lin] & IUPMAT_MARK) + { + exist_mark = 1; + *p++ = '1'; + } + else + *p++ = '0'; + } + *p = 0; + } + else if (marked_cols) + { + size = 1 + (ih->data->columns.num-1) + 1; + value = iupStrGetMemory(size); + p = value; + + *p++ = 'C'; + + for(col = 1; col < ih->data->columns.num; col++) + { + if (ih->data->columns.flags[col] & IUPMAT_MARK) + { + exist_mark = 1; + *p++ = '1'; + } + else + *p++ = '0'; + } + *p = 0; + } + } + + return exist_mark? value: NULL; +} + +int iupMatrixSetMarkAttrib(Ihandle* ih, const char* name_id, const char* value) +{ + int lin = 0, col = 0; + + if (ih->data->mark_mode == IMAT_MARK_NO) + return 0; + + if (iupStrToIntInt(name_id, &lin, &col, ':') == 2) + { + if (!iupMatrixCheckCellPos(ih, lin, col)) + return 0; + + if (ih->data->mark_mode == IMAT_MARK_CELL) + { + int mark; + + if (lin == 0 || col == 0) /* title can NOT have a mark */ + return 0; + + mark = iupStrBoolean(value); + + if (ih->data->callback_mode) + { + IFniii markedit_cb = (IFniii)IupGetCallback(ih, "MARKEDIT_CB"); + if (markedit_cb) + markedit_cb(ih, lin, col, mark); + else if (mark) + return 1; /* store the attribute */ + } + else + { + if (mark) + ih->data->cells[lin][col].flags |= IUPMAT_MARK; + else + ih->data->cells[lin][col].flags &= ~IUPMAT_MARK; + } + + if (ih->handle) + { + /* This assumes that the matrix has been draw completely previously */ + iupMatrixPrepareDrawData(ih); + iupMatrixDrawCells(ih, lin, col, lin, col); + } + } + else + { + int mark = iupStrBoolean(value); + + if (ih->data->mark_mode & IMAT_MARK_LIN && lin!=0) + { + if (mark) + ih->data->lines.flags[lin] |= IUPMAT_MARK; + else + ih->data->lines.flags[lin] &= ~IUPMAT_MARK; + } + + if (ih->data->mark_mode & IMAT_MARK_COL && col!=0) + { + if (mark) + ih->data->columns.flags[col] |= IUPMAT_MARK; + else + ih->data->columns.flags[col] &= ~IUPMAT_MARK; + } + + if (ih->handle) + { + /* This assumes that the matrix has been draw completely previously */ + iupMatrixPrepareDrawData(ih); + iupMatrixDrawCells(ih, lin, col, lin, col); + } + } + } + + return 0; +} + +char* iupMatrixGetMarkAttrib(Ihandle* ih, const char* name_id) +{ + int lin = 0, col = 0; + + if (ih->data->mark_mode == IMAT_MARK_NO) + return "0"; + + if (iupStrToIntInt(name_id, &lin, &col, ':') == 2) + { + if (!iupMatrixCheckCellPos(ih, lin, col)) + return NULL; + + if (ih->data->mark_mode == IMAT_MARK_CELL) + { + if (lin == 0 || col == 0) /* title can NOT have a mark */ + return NULL; + + if (ih->data->callback_mode) + { + IFnii mark_cb = (IFnii)IupGetCallback(ih, "MARK_CB"); + if (mark_cb) + { + if (mark_cb(ih, lin, col)) + return "1"; + else + return "0"; + } + else + return NULL; /* let check the hash table */ + } + else + { + if (ih->data->cells[lin][col].flags & IUPMAT_MARK) + return "1"; + else + return "0"; + } + } + else + { + if (ih->data->mark_mode & IMAT_MARK_LIN && lin!=0 && ih->data->lines.flags[lin] & IUPMAT_MARK) + return "1"; + + if (ih->data->mark_mode & IMAT_MARK_COL && col!=0 && ih->data->columns.flags[col] & IUPMAT_MARK) + return "1"; + + return "0"; + } + } + + return NULL; +} -- cgit v1.2.3