/** \file * \brief GLText Control. * * See Copyright Notice in "iup.h" */ #include #include #include #include #include "iup.h" #include "iupcbs.h" #include "iupglcontrols.h" #include "iup_object.h" #include "iup_attrib.h" #include "iup_str.h" #include "iup_register.h" #include "iup_childtree.h" #include "iup_glcontrols.h" #include "iup_gldraw.h" #include "iup_glicon.h" #include "iup_glsubcanvas.h" /* In GTK, a child of the IupGLCanvas does not work OK */ /* #define GL_EDITDLG */ #ifdef GL_EDITDLG static void iGLTextEditShowDlg(Ihandle* ih, Ihandle* text) { int x, y; Ihandle* gl_parent = (Ihandle*)iupAttribGet(ih, "_IUP_GLCANVAS_PARENT"); Ihandle* dlg = IupGetDialog(text); Ihandle* parent_dialog = IupGetAttributeHandle(dlg, "PARENTDIALOG"); Ihandle* dialog = IupGetDialog(ih); if (dialog != parent_dialog) IupSetAttributeHandle(dlg, "PARENTDIALOG", dialog); x = IupGetInt(gl_parent, "X") + ih->x; y = IupGetInt(gl_parent, "Y") + ih->y; /* update drop dialog size before calc pos */ IupRefresh(dlg); /* force current size to be updated during Show */ dlg->currentwidth = 0; dlg->currentheight = 0; IupShowXY(dlg, x, y); } #endif static int iGLTextEditKILLFOCUS_CB(Ihandle* text) { Ihandle* ih = (Ihandle*)iupAttribGet(text, "_IUP_GLTEXT"); Ihandle* gl_parent = (Ihandle*)iupAttribGet(ih, "_IUP_GLCANVAS_PARENT"); #ifdef GL_EDITDLG IupHide(IupGetDialog(text)); #else IupSetAttribute(text, "VISIBLE", "NO"); IupSetAttribute(text, "ACTIVE", "NO"); #endif IupSetAttribute(gl_parent, "REDRAW", NULL); /* redraw the whole box */ return IUP_DEFAULT; } static int iGLTextEditKANY_CB(Ihandle* text, int c) { if (c == K_ESC || c == K_CR) { iGLTextEditKILLFOCUS_CB(text); return IUP_IGNORE; /* always ignore to avoid the defaultenter/defaultesc behavior from here */ } return IUP_CONTINUE; } static int iGLTextEditVALUECHANGED_CB(Ihandle* text) { Ihandle* ih = (Ihandle*)iupAttribGet(text, "_IUP_GLTEXT"); Icallback cb = IupGetCallback(ih, "VALUECHANGED_CB"); if (cb) cb(ih); return IUP_DEFAULT; } static void iGLTextEditCreate(Ihandle* ih) { Ihandle* text = IupText(NULL); text->currentwidth = 20; /* just to avoid initial size 0x0 */ text->currentheight = 10; #ifdef GL_EDITDLG { Ihandle* dlg = IupDialog(text); IupSetAttribute(dlg, "RESIZE", "NO"); IupSetAttribute(dlg, "MENUBOX", "NO"); IupSetAttribute(dlg, "MAXBOX", "NO"); IupSetAttribute(dlg, "MINBOX", "NO"); IupSetAttribute(dlg, "BORDER", "NO"); IupSetAttribute(dlg, "NOFLUSH", "Yes"); } #else text->flags |= IUP_INTERNAL; iupChildTreeAppend(ih, text); IupSetAttribute(text, "FLOATING", "IGNORE"); IupSetAttribute(text, "VISIBLE", "NO"); IupSetAttribute(text, "ACTIVE", "NO"); #endif IupSetCallback(text, "VALUECHANGED_CB", (Icallback)iGLTextEditVALUECHANGED_CB); IupSetCallback(text, "KILLFOCUS_CB", (Icallback)iGLTextEditKILLFOCUS_CB); IupSetCallback(text, "K_ANY", (Icallback)iGLTextEditKANY_CB); IupSetAttribute(text, "_IUP_GLTEXT", (char*)ih); IupSetAttribute(ih, "_IUP_GLTEXT_EDIT", (char*)text); } static Ihandle* iGLTextGetEditHandle(Ihandle* ih) { Ihandle* text = (Ihandle*)iupAttribGet(ih, "_IUP_GLTEXT_EDIT"); return text; } static void iGLTextSetEditAlignemnt(Ihandle* ih, Ihandle* text) { char value1[30], value2[30]; char* value = iupAttribGetStr(ih, "ALIGNMENT"); iupStrToStrStr(value, value1, value2, ':'); if (value1[0] == 0) strcpy(value1, "ALEFT"); IupSetStrAttribute(text, "ALIGNMENT", value1); } static void iGLTextEditShow(Ihandle* ih, int x, int y) { int pos; Ihandle* text = iGLTextGetEditHandle(ih); iGLTextSetEditAlignemnt(ih, text); IupSetStrAttribute(text, "FONT", IupGetAttribute(ih, "FONT")); /* TODO: compensate IupText internal spacing */ /* IupSetStrAttribute(text, "PADDING", iupAttribGetStr(ih, "PADDING")); */ text->currentwidth = ih->currentwidth; text->currentheight = ih->currentheight; #ifdef GL_EDITDLG iGLTextEditShowDlg(ih, text); #else text->x = ih->x; text->y = ih->y; iupClassObjectLayoutUpdate(text); IupSetAttribute(text, "VISIBLE", "YES"); IupSetAttribute(text, "ACTIVE", "YES"); #endif IupSetFocus(text); pos = IupConvertXYToPos(text, x, y); IupSetInt(text, "CARETPOS", pos); } /******************************************************************/ static int iGLTextACTION(Ihandle* ih) { char* value = IupGetAttribute(iGLTextGetEditHandle(ih), "VALUE"); int active = iupAttribGetInt(ih, "ACTIVE"); int highlight = iupAttribGetInt(ih, "HIGHLIGHT"); char* fgcolor = iupAttribGetStr(ih, "FGCOLOR"); char* bgcolor = iupAttribGetStr(ih, "BGCOLOR"); float bwidth = iupAttribGetFloat(ih, "BORDERWIDTH"); int border_width = (int)ceil(bwidth); char* bordercolor = iupAttribGetStr(ih, "BORDERCOLOR"); if (highlight) { char* hlcolor = iupAttribGetStr(ih, "HLCOLOR"); if (hlcolor) bgcolor = hlcolor; } /* draw border - can still be disabled setting bwidth=0 */ iupGLDrawRect(ih, 0, ih->currentwidth - 1, 0, ih->currentheight - 1, bwidth, bordercolor, active, 0); /* draw background */ iupGLDrawBox(ih, border_width, ih->currentwidth - 1 - border_width, border_width, ih->currentheight - 1 - border_width, bgcolor, 1); /* always active */ iupGLIconDraw(ih, border_width, border_width, ih->currentwidth - 2 * border_width, ih->currentheight - 2 * border_width, NULL, NULL, value, fgcolor, active); return IUP_DEFAULT; } static int iGLTextBUTTON_CB(Ihandle* ih, int button, int pressed, int x, int y, char* status) { if (button == IUP_BUTTON1) { iupGLSubCanvasRedraw(ih); if (!pressed) iGLTextEditShow(ih, x, y); } (void)x; (void)y; (void)status; return IUP_DEFAULT; } static int iGLTextSetValueAttrib(Ihandle* ih, const char* value) { IupSetStrAttribute(iGLTextGetEditHandle(ih), "VALUE", value); return 0; /* do not store value in hash table */ } static char* iGLTextGetValueAttrib(Ihandle* ih) { return IupGetAttribute(iGLTextGetEditHandle(ih), "VALUE"); } static char* iGLTextGetTextAttrib(Ihandle* ih) { return IupGetName(iGLTextGetEditHandle(ih)); } static char* iGLTextGetTextHandleAttrib(Ihandle* ih) { return (char*)iGLTextGetEditHandle(ih); } static int iGLTextCreateMethod(Ihandle* ih, void** params) { iGLTextEditCreate(ih); IupSetCallback(ih, "GL_ACTION", iGLTextACTION); IupSetCallback(ih, "GL_BUTTON_CB", (Icallback)iGLTextBUTTON_CB); IupSetCallback(ih, "GL_LEAVEWINDOW_CB", iupGLSubCanvasRedraw); IupSetCallback(ih, "GL_ENTERWINDOW_CB", iupGLSubCanvasRedraw); (void)params; return IUP_NOERROR; } static void iGLTextComputeNaturalSizeMethod(Ihandle* ih, int *w, int *h, int *children_expand) { int natural_w = 0, natural_h = 0, visiblecolumns = iupAttribGetInt(ih, "VISIBLECOLUMNS"); float bwidth = iupAttribGetFloat(ih, "BORDERWIDTH"); int border_width = (int)ceil(bwidth); /* Since the contents can be changed by the user, the size can not be dependent on it. */ iupGLIconGetSize(ih, NULL, "WWWWWWWWWW", &natural_w, &natural_h); /* one line height */ natural_w = (visiblecolumns*natural_w) / 10; /* compute the borders space */ *w += 2 * border_width; *h += 2 * border_width; *w = natural_w; *h = natural_h; (void)children_expand; /* unset if not a container */ } /******************************************************************************/ Iclass* iupGLTextNewClass(void) { Iclass* ic = iupClassNew(iupRegisterFindClass("glsubcanvas")); ic->name = "gltext"; ic->cons = "GLText"; ic->format = NULL; /* no parameters */ ic->nativetype = IUP_TYPEVOID; ic->childtype = IUP_CHILDNONE; ic->is_interactive = 0; /* Class functions */ ic->New = iupGLTextNewClass; ic->Create = iGLTextCreateMethod; ic->ComputeNaturalSize = iGLTextComputeNaturalSizeMethod; iupClassRegisterCallback(ic, "VALUECHANGED_CB", ""); iupClassRegisterAttribute(ic, "VALUE", iGLTextGetValueAttrib, iGLTextSetValueAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE | IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "FGCOLOR", NULL, NULL, "0 0 0", NULL, IUPAF_DEFAULT); /* inheritable */ iupClassRegisterAttribute(ic, "VISIBLECOLUMNS", NULL, NULL, IUPAF_SAMEASSYSTEM, "5", IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "TEXT", iGLTextGetTextAttrib, NULL, NULL, NULL, IUPAF_READONLY | IUPAF_IHANDLENAME | IUPAF_NOT_MAPPED | IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "TEXT_HANDLE", iGLTextGetTextHandleAttrib, NULL, NULL, NULL, IUPAF_READONLY | IUPAF_NOT_MAPPED | IUPAF_NO_INHERIT | IUPAF_IHANDLE | IUPAF_NO_STRING); /* replace default value */ iupClassRegisterAttribute(ic, "PADDING", NULL, NULL, IUPAF_SAMEASSYSTEM, "2x2", IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "CPADDING", iupBaseGetCPaddingAttrib, iupBaseSetCPaddingAttrib, NULL, NULL, IUPAF_NO_SAVE | IUPAF_NOT_MAPPED); iupClassRegisterAttribute(ic, "ALIGNMENT", NULL, NULL, IUPAF_SAMEASSYSTEM, "ALEFT:ATOP", IUPAF_NO_INHERIT); return ic; } Ihandle* IupGLText(void) { return IupCreate("gltext"); }