715 lines
20 KiB
C
715 lines
20 KiB
C
|
/** \file
|
||
|
* \brief iupmatrix edit
|
||
|
* Functions used to edit a node name in place.
|
||
|
*
|
||
|
* See Copyright Notice in "iup.h"
|
||
|
*/
|
||
|
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
#include "iup.h"
|
||
|
#include "iupcbs.h"
|
||
|
#include "iupcontrols.h"
|
||
|
|
||
|
#include <cd.h>
|
||
|
|
||
|
#include "iup_object.h"
|
||
|
#include "iup_attrib.h"
|
||
|
#include "iup_str.h"
|
||
|
#include "iup_stdcontrols.h"
|
||
|
#include "iup_childtree.h"
|
||
|
#include "iup_drvfont.h"
|
||
|
|
||
|
#include "iupmat_def.h"
|
||
|
#include "iupmat_scroll.h"
|
||
|
#include "iupmat_aux.h"
|
||
|
#include "iupmat_edit.h"
|
||
|
#include "iupmat_key.h"
|
||
|
#include "iupmat_getset.h"
|
||
|
#include "iupmat_draw.h"
|
||
|
|
||
|
|
||
|
static void iMatrixEditUpdateValue(Ihandle* ih)
|
||
|
{
|
||
|
char *value = iupMatrixEditGetValue(ih);
|
||
|
|
||
|
iupAttribSet(ih, "CELL_EDITED", "Yes");
|
||
|
|
||
|
if (ih->data->undo_redo) iupAttribSetClassObject(ih, "UNDOPUSHBEGIN", "EDITCELL");
|
||
|
|
||
|
iupMatrixSetValue(ih, ih->data->edit_lin, ih->data->edit_col, value, 1);
|
||
|
|
||
|
if (ih->data->undo_redo) iupAttribSetClassObject(ih, "UNDOPUSHEND", NULL);
|
||
|
|
||
|
iupBaseCallValueChangedCb(ih);
|
||
|
|
||
|
iupAttribSet(ih, "CELL_EDITED", NULL);
|
||
|
|
||
|
iupMatrixPrepareDrawData(ih);
|
||
|
iupMatrixDrawCells(ih, ih->data->edit_lin, ih->data->edit_col, ih->data->edit_lin, ih->data->edit_col);
|
||
|
}
|
||
|
|
||
|
static int iMatrixEditCallEditionCbUpdateValue(Ihandle* ih, int mode, int update)
|
||
|
{
|
||
|
int ret = iupMatrixAuxCallEditionCbLinCol(ih, ih->data->edit_lin, ih->data->edit_col, mode, update);
|
||
|
|
||
|
if (update && ret == IUP_DEFAULT && mode == 0) /* leaving edition mode */
|
||
|
iMatrixEditUpdateValue(ih);
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
static int iMatrixEditFinish(Ihandle* ih, int setfocus, int update, int accept_ignore)
|
||
|
{
|
||
|
if (ih->data->editing)
|
||
|
{
|
||
|
int ret;
|
||
|
|
||
|
/* Avoid calling EDITION_CB twice. Usually because a killfocus. */
|
||
|
if (iupAttribGet(ih, "_IUPMAT_CALL_EDITION"))
|
||
|
return IUP_DEFAULT;
|
||
|
|
||
|
iupAttribSet(ih, "_IUPMAT_CALL_EDITION", "1");
|
||
|
ret = iMatrixEditCallEditionCbUpdateValue(ih, 0, update);
|
||
|
iupAttribSet(ih, "_IUPMAT_CALL_EDITION", NULL);
|
||
|
|
||
|
if (ret == IUP_IGNORE && accept_ignore)
|
||
|
return IUP_IGNORE;
|
||
|
|
||
|
ih->data->editing = 0;
|
||
|
|
||
|
iupAttribSet(ih, "_IUPMAT_IGNOREFOCUS", "1");
|
||
|
|
||
|
IupSetAttribute(ih->data->datah, "VISIBLE", "NO");
|
||
|
IupSetAttribute(ih->data->datah, "ACTIVE", "NO");
|
||
|
|
||
|
if (setfocus)
|
||
|
{
|
||
|
IupSetFocus(ih);
|
||
|
ih->data->has_focus = 1; /* set this so even if getfocus_cb is not called the focus is drawn */
|
||
|
}
|
||
|
|
||
|
iupAttribSet(ih, "_IUPMAT_IGNOREFOCUS", NULL);
|
||
|
|
||
|
#ifdef SunOS
|
||
|
/* Usually when the edit control is hidden the matrix is automatically repainted by the system, except in SunOS. */
|
||
|
iupMatrixDrawUpdate(ih);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
return IUP_DEFAULT;
|
||
|
}
|
||
|
|
||
|
int iupMatrixEditConfirm(Ihandle* ih)
|
||
|
{
|
||
|
return iMatrixEditFinish(ih, 1, 1, 1); /* setfocus + update + accept_ignore */
|
||
|
}
|
||
|
|
||
|
void iupMatrixEditHide(Ihandle* ih)
|
||
|
{
|
||
|
iMatrixEditFinish(ih, 0, 1, 0); /* NO setfocus + update + NO accept_ignore */
|
||
|
}
|
||
|
|
||
|
void iupMatrixEditAbort(Ihandle* ih)
|
||
|
{
|
||
|
iMatrixEditFinish(ih, 1, 0, 0); /* setfocus + NO update + NO accept_ignore */
|
||
|
}
|
||
|
|
||
|
static int iMatrixMenuItemAction_CB(Ihandle* ih_item)
|
||
|
{
|
||
|
Ihandle* ih_menu = ih_item->parent;
|
||
|
Ihandle* ih = (Ihandle*)iupAttribGet(ih_menu, "_IUP_MATRIX");
|
||
|
char* title = IupGetAttribute(ih_item, "TITLE");
|
||
|
IFniinsii cb = (IFniinsii)IupGetCallback(ih, "DROPSELECT_CB");
|
||
|
if(cb)
|
||
|
{
|
||
|
int i = IupGetChildPos(ih_menu, ih_item) + 1;
|
||
|
cb(ih, ih->data->edit_lin, ih->data->edit_col, ih_menu, title, i, 1);
|
||
|
}
|
||
|
|
||
|
IupStoreAttribute(ih_menu, "VALUE", title);
|
||
|
|
||
|
iMatrixEditCallEditionCbUpdateValue(ih, 0, 1); /* always update, similar to iupMatrixEditConfirm */
|
||
|
iupMatrixDrawUpdate(ih);
|
||
|
|
||
|
return IUP_DEFAULT;
|
||
|
}
|
||
|
|
||
|
static void iMatrixEditInitMenu(Ihandle* ih_menu)
|
||
|
{
|
||
|
char *value;
|
||
|
int i = 1;
|
||
|
int v = IupGetInt(ih_menu, "VALUE");
|
||
|
|
||
|
do
|
||
|
{
|
||
|
value = IupGetAttributeId(ih_menu, "", i);
|
||
|
if (value)
|
||
|
{
|
||
|
Ihandle* item = IupItem(value, NULL);
|
||
|
|
||
|
char* img = IupGetAttributeId(ih_menu, "IMAGE", i);
|
||
|
if (img)
|
||
|
IupSetStrAttribute(item, "IMAGE", img);
|
||
|
|
||
|
IupSetCallback(item, "ACTION", (Icallback)iMatrixMenuItemAction_CB);
|
||
|
|
||
|
if (v == i) /* if v==0 no mark will be shown */
|
||
|
IupSetAttribute(item, "VALUE", "On");
|
||
|
|
||
|
IupAppend(ih_menu, item);
|
||
|
}
|
||
|
i++;
|
||
|
} while (value);
|
||
|
}
|
||
|
|
||
|
static int iMatrixEditCallMenuDropCb(Ihandle* ih, int lin, int col)
|
||
|
{
|
||
|
IFnnii cb = (IFnnii)IupGetCallback(ih, "MENUDROP_CB");
|
||
|
if(cb)
|
||
|
{
|
||
|
Ihandle* ih_menu = IupMenu(NULL);
|
||
|
int ret;
|
||
|
char* value = iupMatrixGetValueDisplay(ih, lin, col);
|
||
|
if (!value) value = "";
|
||
|
|
||
|
iupAttribSet(ih_menu, "PREVIOUSVALUE", value);
|
||
|
iupAttribSet(ih_menu, "_IUP_MATRIX", (char*)ih);
|
||
|
|
||
|
ret = cb(ih, ih_menu, lin, col);
|
||
|
if (ret == IUP_DEFAULT)
|
||
|
{
|
||
|
int x, y, w, h;
|
||
|
|
||
|
ih->data->datah = ih_menu;
|
||
|
|
||
|
/* create items and set common callback */
|
||
|
iMatrixEditInitMenu(ih_menu);
|
||
|
|
||
|
/* calc position */
|
||
|
iupMatrixGetVisibleCellDim(ih, lin, col, &x, &y, &w, &h);
|
||
|
|
||
|
x += IupGetInt(ih, "X");
|
||
|
y += IupGetInt(ih, "Y");
|
||
|
|
||
|
IupPopup(ih_menu, x, y+h);
|
||
|
IupDestroy(ih_menu);
|
||
|
|
||
|
/* restore a valid handle */
|
||
|
ih->data->datah = ih->data->texth;
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
IupDestroy(ih_menu);
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int iMatrixEditCallDropdownCb(Ihandle* ih, int lin, int col)
|
||
|
{
|
||
|
IFnnii cb = (IFnnii)IupGetCallback(ih, "DROP_CB");
|
||
|
if(cb)
|
||
|
{
|
||
|
int ret;
|
||
|
char* value = iupMatrixGetValueDisplay(ih, lin, col);
|
||
|
if (!value) value = "";
|
||
|
|
||
|
IupStoreAttribute(ih->data->droph, "PREVIOUSVALUE", value);
|
||
|
if (!IupGetInt(ih->data->droph, "EDITBOX"))
|
||
|
IupSetAttribute(ih->data->droph, "VALUE", "1");
|
||
|
|
||
|
ret = cb(ih, ih->data->droph, lin, col);
|
||
|
if(ret == IUP_DEFAULT)
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int iMatrixEditDropDownAction_CB(Ihandle* ih_list, char* t, int i, int v)
|
||
|
{
|
||
|
Ihandle* ih = ih_list->parent;
|
||
|
IFniinsii cb = (IFniinsii)IupGetCallback(ih, "DROPSELECT_CB");
|
||
|
if(cb)
|
||
|
{
|
||
|
int ret = cb(ih, ih->data->edit_lin, ih->data->edit_col, ih_list, t, i, v);
|
||
|
|
||
|
/* If the user returns IUP_CONTINUE in a dropselect_cb
|
||
|
the value is accepted and the matrix leaves edition mode. */
|
||
|
if (ret == IUP_CONTINUE)
|
||
|
{
|
||
|
if (iupMatrixEditConfirm(ih) == IUP_DEFAULT)
|
||
|
iupMatrixDrawUpdate(ih);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return IUP_DEFAULT;
|
||
|
}
|
||
|
|
||
|
static void iMatrixEditChooseElement(Ihandle* ih)
|
||
|
{
|
||
|
int drop = iMatrixEditCallDropdownCb(ih, ih->data->edit_lin, ih->data->edit_col);
|
||
|
if (drop)
|
||
|
ih->data->datah = ih->data->droph;
|
||
|
else
|
||
|
{
|
||
|
char* value;
|
||
|
|
||
|
ih->data->datah = ih->data->texth;
|
||
|
|
||
|
/* dropdown values are set by the user in DROP_CB.
|
||
|
text value is set here from cell contents. */
|
||
|
iupAttribSet(ih, "EDITVALUE", "Yes");
|
||
|
value = iupMatrixGetValueDisplay(ih, ih->data->edit_lin, ih->data->edit_col);
|
||
|
iupAttribSet(ih, "EDITVALUE", NULL);
|
||
|
if (!value) value = "";
|
||
|
IupStoreAttribute(ih->data->texth, "VALUE", value);
|
||
|
IupStoreAttribute(ih->data->texth, "PREVIOUSVALUE", value);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static int iMatrixEditDropDown_CB(Ihandle* ih_list, int state)
|
||
|
{
|
||
|
/* In Motif if DROPDOWN=YES then when the dropdown button is clicked
|
||
|
the list looses its focus and when the dropped list is closed
|
||
|
the list regain the focus, also when that happen if the list looses its focus
|
||
|
to another control the kill focus callback is not called. */
|
||
|
Ihandle* ih = ih_list->parent;
|
||
|
if (state == 1)
|
||
|
iupAttribSet(ih, "_IUPMAT_DROPDOWN", "1");
|
||
|
|
||
|
return IUP_DEFAULT;
|
||
|
}
|
||
|
|
||
|
static int iMatrixEditKillFocus_CB(Ihandle* ih_edit)
|
||
|
{
|
||
|
Ihandle* ih = ih_edit->parent;
|
||
|
|
||
|
if (IupGetGlobal("MOTIFVERSION"))
|
||
|
{
|
||
|
if (iupAttribGet(ih, "_IUPMAT_DROPDOWN") || /* from iMatrixEditDropDown_CB, in Motif */
|
||
|
iupAttribGet(ih, "_IUPMAT_DOUBLECLICK")) /* from iMatrixMouseLeftPress, in Motif */
|
||
|
{
|
||
|
iupAttribSet(ih, "_IUPMAT_DOUBLECLICK", NULL);
|
||
|
iupAttribSet(ih, "_IUPMAT_DROPDOWN", NULL);
|
||
|
return IUP_DEFAULT;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (iupAttribGet(ih, "_IUPMAT_IGNOREFOCUS"))
|
||
|
return IUP_DEFAULT;
|
||
|
|
||
|
if (ih->data->edit_hide_onfocus)
|
||
|
{
|
||
|
ih->data->edit_hidden_byfocus = 1;
|
||
|
iupMatrixEditHide(ih);
|
||
|
ih->data->edit_hidden_byfocus = 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
IFn cb = (IFn)IupGetCallback(ih, "EDITKILLFOCUS_CB");
|
||
|
if (cb)
|
||
|
cb(ih);
|
||
|
}
|
||
|
|
||
|
return IUP_DEFAULT;
|
||
|
}
|
||
|
|
||
|
int iupMatrixEditIsVisible(Ihandle* ih)
|
||
|
{
|
||
|
if (!IupGetInt(ih, "ACTIVE"))
|
||
|
return 0;
|
||
|
|
||
|
if (!IupGetInt(ih->data->datah, "VISIBLE"))
|
||
|
return 0;
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
void iupMatrixEditUpdatePos(Ihandle* ih)
|
||
|
{
|
||
|
int w, h, x, y, visible;
|
||
|
visible = iupMatrixGetVisibleCellDim(ih, ih->data->edit_lin, ih->data->edit_col, &x, &y, &w, &h);
|
||
|
if (!visible && !ih->data->edit_hide_onfocus)
|
||
|
IupSetAttribute(ih->data->datah, "VISIBLE", "NO");
|
||
|
|
||
|
ih->data->datah->x = x;
|
||
|
ih->data->datah->y = y;
|
||
|
|
||
|
ih->data->datah->currentwidth = w;
|
||
|
ih->data->datah->currentheight = h;
|
||
|
|
||
|
if (ih->data->datah==ih->data->texth && iupAttribGetBoolean(ih, "EDITFITVALUE"))
|
||
|
{
|
||
|
char* value = IupGetAttribute(ih->data->texth, "VALUE");
|
||
|
int value_w, value_h;
|
||
|
|
||
|
value_w = iupdrvFontGetStringWidth(ih->data->texth, value);
|
||
|
iupdrvFontGetCharSize(ih->data->texth, NULL, &value_h);
|
||
|
|
||
|
if (iupAttribGetBoolean(ih->data->texth, "BORDER"))
|
||
|
{
|
||
|
value_w += 2*4;
|
||
|
value_h += 2*4;
|
||
|
}
|
||
|
|
||
|
if (value_w > ih->data->datah->currentwidth)
|
||
|
ih->data->datah->currentwidth = value_w;
|
||
|
if (value_h > ih->data->datah->currentheight)
|
||
|
ih->data->datah->currentheight = value_h;
|
||
|
}
|
||
|
|
||
|
iupClassObjectLayoutUpdate(ih->data->datah);
|
||
|
|
||
|
if (visible && !ih->data->edit_hide_onfocus)
|
||
|
IupSetAttribute(ih->data->datah, "VISIBLE", "YES");
|
||
|
}
|
||
|
|
||
|
int iupMatrixEditShow(Ihandle* ih)
|
||
|
{
|
||
|
return iupMatrixEditShowXY(ih, 0, 0);
|
||
|
}
|
||
|
|
||
|
int iupMatrixEditShowXY(Ihandle* ih, int x, int y)
|
||
|
{
|
||
|
char* mask;
|
||
|
|
||
|
/* work around for Windows when using Multiline */
|
||
|
if (iupAttribGet(ih, "_IUPMAT_IGNORE_SHOW"))
|
||
|
{
|
||
|
iupAttribSet(ih, "_IUPMAT_IGNORE_SHOW", NULL);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/* there are no cells that can be edited */
|
||
|
if (ih->data->columns.num <= 1 || ih->data->lines.num <= 1)
|
||
|
return 0;
|
||
|
|
||
|
if (ih->data->editing || iupMatrixEditIsVisible(ih))
|
||
|
{
|
||
|
if (ih->data->edit_hide_onfocus)
|
||
|
return 0;
|
||
|
|
||
|
iupMatrixEditHide(ih);
|
||
|
}
|
||
|
|
||
|
if (ih->data->noscroll_as_title && (ih->data->lines.focus_cell < ih->data->lines.num_noscroll || ih->data->columns.focus_cell < ih->data->columns.num_noscroll))
|
||
|
return 0;
|
||
|
|
||
|
ih->data->edit_lin = ih->data->lines.focus_cell;
|
||
|
ih->data->edit_col = ih->data->columns.focus_cell;
|
||
|
|
||
|
/* notify application */
|
||
|
if (iMatrixEditCallEditionCbUpdateValue(ih, 1, 0) == IUP_IGNORE) /* only place where mode=1 */
|
||
|
return 0;
|
||
|
|
||
|
if (iMatrixEditCallMenuDropCb(ih, ih->data->edit_lin, ih->data->edit_col))
|
||
|
return 0;
|
||
|
|
||
|
ih->data->editing = 1;
|
||
|
|
||
|
/* select edit control */
|
||
|
iMatrixEditChooseElement(ih);
|
||
|
|
||
|
/* position the cell to make it visible */
|
||
|
/* If the focus is not visible, a scroll is done for that the focus to be visible */
|
||
|
if (!iupMatrixAuxIsCellStartVisible(ih, ih->data->edit_lin, ih->data->edit_col))
|
||
|
iupMatrixScrollToVisible(ih, ih->data->edit_lin, ih->data->edit_col);
|
||
|
|
||
|
/* set attributes */
|
||
|
iupMatrixPrepareDrawData(ih);
|
||
|
IupStoreAttribute(ih->data->datah, "BGCOLOR", iupMatrixGetBgColorStr(ih, ih->data->edit_lin, ih->data->edit_col));
|
||
|
IupStoreAttribute(ih->data->datah, "FGCOLOR", iupMatrixGetFgColorStr(ih, ih->data->edit_lin, ih->data->edit_col));
|
||
|
IupStoreAttribute(ih->data->datah, "FONT", iupMatrixGetFont(ih, ih->data->edit_lin, ih->data->edit_col));
|
||
|
|
||
|
mask = iupMatrixGetMaskStr(ih, "MASK", ih->data->edit_lin, ih->data->edit_col);
|
||
|
if (mask)
|
||
|
{
|
||
|
IupStoreAttribute(ih->data->datah, "MASKCASEI", iupMatrixGetMaskStr(ih, "MASKCASEI", ih->data->edit_lin, ih->data->edit_col));
|
||
|
IupStoreAttribute(ih->data->datah, "MASKNOEMPTY", iupMatrixGetMaskStr(ih, "MASKNOEMPTY", ih->data->edit_lin, ih->data->edit_col));
|
||
|
IupStoreAttribute(ih->data->datah, "MASK", mask);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
mask = iupMatrixGetMaskStr(ih, "MASKINT", ih->data->edit_lin, ih->data->edit_col);
|
||
|
if (mask)
|
||
|
{
|
||
|
IupStoreAttribute(ih->data->datah, "MASKNOEMPTY", iupMatrixGetMaskStr(ih, "MASKNOEMPTY", ih->data->edit_lin, ih->data->edit_col));
|
||
|
IupStoreAttribute(ih->data->datah, "MASKINT", mask);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
mask = iupMatrixGetMaskStr(ih, "MASKFLOAT", ih->data->edit_lin, ih->data->edit_col);
|
||
|
if (mask)
|
||
|
{
|
||
|
IupStoreAttribute(ih->data->datah, "MASKNOEMPTY", iupMatrixGetMaskStr(ih, "MASKNOEMPTY", ih->data->edit_lin, ih->data->edit_col));
|
||
|
IupStoreAttribute(ih->data->datah, "MASKFLOAT", mask);
|
||
|
}
|
||
|
else
|
||
|
IupSetAttribute(ih->data->datah, "MASK", NULL);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
iupMatrixEditUpdatePos(ih);
|
||
|
|
||
|
/* activate and show */
|
||
|
IupSetAttribute(ih->data->datah, "ACTIVE", "YES");
|
||
|
IupSetAttribute(ih->data->datah, "VISIBLE", "YES");
|
||
|
IupSetFocus(ih->data->datah);
|
||
|
|
||
|
if (ih->data->datah == ih->data->texth)
|
||
|
{
|
||
|
if (iupAttribGetBoolean(ih, "EDITALIGN"))
|
||
|
IupSetStrAttribute(ih->data->datah, "ALIGNMENT", IupGetAttributeId(ih, "ALIGNMENT", ih->data->edit_col));
|
||
|
|
||
|
if (x || y)
|
||
|
{
|
||
|
int pos;
|
||
|
|
||
|
x -= ih->data->datah->x;
|
||
|
y -= ih->data->datah->y;
|
||
|
|
||
|
pos = IupConvertXYToPos(ih->data->datah, x, y);
|
||
|
IupSetInt(ih->data->datah, "CARETPOS", pos);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
static int iMatrixEditTextAction_CB(Ihandle* ih_text, int c, char* after)
|
||
|
{
|
||
|
Ihandle* ih = ih_text->parent;
|
||
|
IFniiiis cb = (IFniiiis) IupGetCallback(ih, "ACTION_CB");
|
||
|
|
||
|
if (iupAttribGetBoolean(ih, "EDITFITVALUE"))
|
||
|
{
|
||
|
int value_w, value_h, resize = 0;
|
||
|
|
||
|
value_w = iupdrvFontGetStringWidth(ih_text, after);
|
||
|
iupdrvFontGetCharSize(ih_text, NULL, &value_h);
|
||
|
|
||
|
if (iupAttribGetBoolean(ih_text, "BORDER"))
|
||
|
{
|
||
|
value_w += 2 * 4;
|
||
|
value_h += 2 * 4;
|
||
|
}
|
||
|
|
||
|
if (value_w > ih_text->currentwidth)
|
||
|
{
|
||
|
ih_text->currentwidth = value_w;
|
||
|
resize = 1;
|
||
|
}
|
||
|
if (value_h > ih_text->currentheight)
|
||
|
{
|
||
|
ih_text->currentheight = value_h;
|
||
|
resize = 1;
|
||
|
}
|
||
|
|
||
|
if (resize)
|
||
|
iupClassObjectLayoutUpdate(ih_text);
|
||
|
}
|
||
|
|
||
|
if (cb && iup_isprint(c)) /* only for keys that ARE ASCii characters */
|
||
|
{
|
||
|
int oldc = c;
|
||
|
c = cb(ih, c, ih->data->edit_lin, ih->data->edit_col, 1, after);
|
||
|
if (c == IUP_IGNORE || c == IUP_CLOSE || c == IUP_CONTINUE)
|
||
|
return c;
|
||
|
else if(c == IUP_DEFAULT)
|
||
|
c = oldc;
|
||
|
return c;
|
||
|
}
|
||
|
|
||
|
return IUP_DEFAULT;
|
||
|
}
|
||
|
|
||
|
static int iMatrixEditTextKeyAny_CB(Ihandle* ih_text, int c)
|
||
|
{
|
||
|
Ihandle* ih = ih_text->parent;
|
||
|
IFniiiis cb = (IFniiiis) IupGetCallback(ih, "ACTION_CB");
|
||
|
if (cb && !iup_isprint(c)) /* only for keys that are NOT ASCii characters */
|
||
|
{
|
||
|
int oldc = c;
|
||
|
c = cb(ih, c, ih->data->edit_lin, ih->data->edit_col, 1, IupGetAttribute(ih_text, "VALUE"));
|
||
|
if(c == IUP_IGNORE || c == IUP_CLOSE || c == IUP_CONTINUE)
|
||
|
return c;
|
||
|
else if(c == IUP_DEFAULT)
|
||
|
c = oldc;
|
||
|
}
|
||
|
|
||
|
switch (c)
|
||
|
{
|
||
|
case K_cUP:
|
||
|
case K_cDOWN:
|
||
|
case K_cLEFT:
|
||
|
case K_cRIGHT:
|
||
|
if (iupMatrixEditConfirm(ih) == IUP_DEFAULT)
|
||
|
{
|
||
|
iupMatrixProcessKeyPress(ih, c);
|
||
|
return IUP_IGNORE;
|
||
|
}
|
||
|
break;
|
||
|
case K_UP:
|
||
|
if (!IupGetInt(ih_text, "MULTILINE") || IupGetInt(ih_text, "CARET") == 1) /* if Multiline CARET will be "L,C" */
|
||
|
{
|
||
|
/* if at the first line of the text */
|
||
|
if (iupMatrixEditConfirm(ih) == IUP_DEFAULT)
|
||
|
{
|
||
|
iupMatrixProcessKeyPress(ih, c);
|
||
|
return IUP_IGNORE;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
case K_DOWN:
|
||
|
{
|
||
|
/* if at the last line of the text */
|
||
|
if (!IupGetInt(ih_text, "MULTILINE") || IupGetInt(ih_text, "LINECOUNT") == IupGetInt(ih_text, "CARET")) /* if Multiline CARET will be "L,C" */
|
||
|
{
|
||
|
if (iupMatrixEditConfirm(ih) == IUP_DEFAULT)
|
||
|
{
|
||
|
iupMatrixProcessKeyPress(ih, c);
|
||
|
return IUP_IGNORE;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
case K_LEFT:
|
||
|
if (IupGetInt(ih_text, "CARETPOS") == 0)
|
||
|
{
|
||
|
/* if at the first character */
|
||
|
if (iupMatrixEditConfirm(ih) == IUP_DEFAULT)
|
||
|
{
|
||
|
iupMatrixProcessKeyPress(ih, c);
|
||
|
return IUP_IGNORE;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
case K_RIGHT:
|
||
|
{
|
||
|
/* if at the last character */
|
||
|
if (IupGetInt(ih_text, "COUNT") == IupGetInt(ih_text, "CARETPOS"))
|
||
|
{
|
||
|
if (iupMatrixEditConfirm(ih) == IUP_DEFAULT)
|
||
|
{
|
||
|
iupMatrixProcessKeyPress(ih, c);
|
||
|
return IUP_IGNORE;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
case K_ESC:
|
||
|
iupMatrixEditAbort(ih);
|
||
|
return IUP_IGNORE; /* always ignore to avoid the defaultesc behavior from here */
|
||
|
case K_CR:
|
||
|
if (iupMatrixEditConfirm(ih) == IUP_DEFAULT)
|
||
|
{
|
||
|
if (iupStrEqualNoCase(IupGetGlobal("DRIVER"), "Win32") && IupGetInt(ih_text, "MULTILINE"))
|
||
|
{
|
||
|
/* work around for Windows when using Multiline */
|
||
|
iupAttribSet(ih, "_IUPMAT_IGNORE_SHOW", "1");
|
||
|
}
|
||
|
|
||
|
if (iupMatrixAuxCallLeaveCellCb(ih) != IUP_IGNORE)
|
||
|
{
|
||
|
iupMATRIX_ScrollKeyCr(ih);
|
||
|
iupMatrixAuxCallEnterCellCb(ih);
|
||
|
}
|
||
|
iupMatrixDrawUpdate(ih);
|
||
|
}
|
||
|
return IUP_IGNORE; /* always ignore to avoid the defaultenter behavior from here */
|
||
|
}
|
||
|
|
||
|
return IUP_CONTINUE;
|
||
|
}
|
||
|
|
||
|
static int iMatrixEditDropDownKeyAny_CB(Ihandle* ih_list, int c)
|
||
|
{
|
||
|
Ihandle* ih = ih_list->parent;
|
||
|
IFniiiis cb = (IFniiiis)IupGetCallback(ih, "ACTION_CB");
|
||
|
if (cb)
|
||
|
{
|
||
|
int oldc = c;
|
||
|
c = cb(ih, c, ih->data->edit_lin, ih->data->edit_col, 1, "");
|
||
|
if (c == IUP_IGNORE || c == IUP_CLOSE || c == IUP_CONTINUE)
|
||
|
return c;
|
||
|
else if(c == IUP_DEFAULT)
|
||
|
c = oldc;
|
||
|
}
|
||
|
|
||
|
switch (c)
|
||
|
{
|
||
|
case K_CR:
|
||
|
if (iupMatrixEditConfirm(ih) == IUP_DEFAULT)
|
||
|
{
|
||
|
if (iupMatrixAuxCallLeaveCellCb(ih) != IUP_IGNORE)
|
||
|
{
|
||
|
iupMATRIX_ScrollKeyCr(ih);
|
||
|
iupMatrixAuxCallEnterCellCb(ih);
|
||
|
}
|
||
|
iupMatrixDrawUpdate(ih);
|
||
|
return IUP_IGNORE;
|
||
|
}
|
||
|
break;
|
||
|
case K_ESC:
|
||
|
iupMatrixEditAbort(ih);
|
||
|
return IUP_IGNORE;
|
||
|
}
|
||
|
|
||
|
return IUP_CONTINUE;
|
||
|
}
|
||
|
|
||
|
char* iupMatrixEditGetValue(Ihandle* ih)
|
||
|
{
|
||
|
if (ih->data->datah == ih->data->droph)
|
||
|
{
|
||
|
if (!IupGetInt(ih->data->droph, "EDITBOX"))
|
||
|
return IupGetAttribute(ih->data->datah, IupGetAttribute(ih->data->droph, "VALUE"));
|
||
|
else
|
||
|
return IupGetAttribute(ih->data->droph, "VALUE");
|
||
|
}
|
||
|
else
|
||
|
return IupGetAttribute(ih->data->datah, "VALUE");
|
||
|
}
|
||
|
|
||
|
void iupMatrixEditCreate(Ihandle* ih)
|
||
|
{
|
||
|
/******** EDIT *************/
|
||
|
ih->data->texth = IupText(NULL);
|
||
|
ih->data->texth->currentwidth = 20; /* just to avoid initial size 0x0 */
|
||
|
ih->data->texth->currentheight = 10;
|
||
|
ih->data->texth->flags |= IUP_INTERNAL;
|
||
|
iupChildTreeAppend(ih, ih->data->texth);
|
||
|
|
||
|
IupSetCallback(ih->data->texth, "ACTION", (Icallback)iMatrixEditTextAction_CB);
|
||
|
IupSetCallback(ih->data->texth, "K_ANY", (Icallback)iMatrixEditTextKeyAny_CB);
|
||
|
IupSetCallback(ih->data->texth, "KILLFOCUS_CB", (Icallback)iMatrixEditKillFocus_CB);
|
||
|
IupSetAttribute(ih->data->texth, "VALUE", "");
|
||
|
IupSetAttribute(ih->data->texth, "VISIBLE", "NO");
|
||
|
IupSetAttribute(ih->data->texth, "ACTIVE", "NO");
|
||
|
IupSetAttribute(ih->data->texth, "FLOATING", "IGNORE");
|
||
|
|
||
|
|
||
|
/******** DROPDOWN *************/
|
||
|
ih->data->droph = IupList(NULL);
|
||
|
ih->data->droph->currentwidth = 20; /* just to avoid initial size 0x0 */
|
||
|
ih->data->droph->currentheight = 10;
|
||
|
ih->data->droph->flags |= IUP_INTERNAL;
|
||
|
iupChildTreeAppend(ih, ih->data->droph);
|
||
|
|
||
|
if (IupGetGlobal("MOTIFVERSION"))
|
||
|
IupSetCallback(ih->data->droph, "DROPDOWN_CB", (Icallback)iMatrixEditDropDown_CB);
|
||
|
|
||
|
IupSetCallback(ih->data->droph, "ACTION", (Icallback)iMatrixEditDropDownAction_CB);
|
||
|
IupSetCallback(ih->data->droph, "KILLFOCUS_CB", (Icallback)iMatrixEditKillFocus_CB);
|
||
|
IupSetCallback(ih->data->droph, "K_ANY", (Icallback)iMatrixEditDropDownKeyAny_CB);
|
||
|
IupSetAttribute(ih->data->droph, "DROPDOWN", "YES");
|
||
|
IupSetAttribute(ih->data->droph, "MULTIPLE", "NO");
|
||
|
IupSetAttribute(ih->data->droph, "VISIBLE", "NO");
|
||
|
IupSetAttribute(ih->data->droph, "ACTIVE", "NO");
|
||
|
IupSetAttribute(ih->data->droph, "FLOATING", "IGNORE");
|
||
|
}
|