333 lines
10 KiB
C
333 lines
10 KiB
C
|
/** \file
|
||
|
* \brief GLFrame Control.
|
||
|
*
|
||
|
* See Copyright Notice in "iup.h"
|
||
|
*/
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <math.h>
|
||
|
|
||
|
#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_glcontrols.h"
|
||
|
#include "iup_gldraw.h"
|
||
|
#include "iup_glicon.h"
|
||
|
#include "iup_glsubcanvas.h"
|
||
|
|
||
|
|
||
|
static int iGLFrameACTION(Ihandle* ih)
|
||
|
{
|
||
|
char *image = iupAttribGet(ih, "IMAGE");
|
||
|
char* title = iupAttribGet(ih, "TITLE");
|
||
|
char* bordercolor = iupAttribGetStr(ih, "FRAMECOLOR");
|
||
|
float bwidth = iupAttribGetFloat(ih, "FRAMEWIDTH");
|
||
|
int border_width = (int)ceil(bwidth);
|
||
|
int active = iupAttribGetInt(ih, "ACTIVE");
|
||
|
|
||
|
if (image || title)
|
||
|
{
|
||
|
char* fgcolor = iupAttribGetStr(ih, "FORECOLOR");
|
||
|
int off = iupAttribGetInt(ih, "TITLEOFFSET");
|
||
|
int title_box = iupAttribGetInt(ih, "TITLEBOX");
|
||
|
int w = 0, h = 0;
|
||
|
iupGLIconGetSize(ih, image, title, &w, &h);
|
||
|
if (w > ih->currentwidth - 2 * border_width)
|
||
|
w = ih->currentwidth - 2 * border_width;
|
||
|
|
||
|
if (title_box)
|
||
|
{
|
||
|
char* bgimage = iupAttribGet(ih, "TITLEBACKIMAGE");
|
||
|
|
||
|
/* draw border */
|
||
|
iupGLDrawRect(ih, 0, ih->currentwidth - 1, 0, ih->currentheight - 1, bwidth, bordercolor, 1, 0);
|
||
|
|
||
|
/* draw box */
|
||
|
if (bgimage)
|
||
|
iupGLDrawIconImageZoom(ih, border_width, ih->currentwidth - 1 - border_width,
|
||
|
border_width, border_width + h - 1,
|
||
|
"TITLEBACKIMAGE", bgimage, active);
|
||
|
else
|
||
|
iupGLDrawBox(ih, border_width, ih->currentwidth-1 - border_width,
|
||
|
border_width, border_width + h - 1,
|
||
|
bordercolor, 1); /* always active */
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
/* draw frame border */
|
||
|
iupGLDrawFrameRect(ih, 0, ih->currentwidth - 1, 0, ih->currentheight - 1, bwidth, bordercolor, 1, off, w, h);
|
||
|
}
|
||
|
|
||
|
iupGLIconDraw(ih, off, 0, w, h, "IMAGE", image, title, fgcolor, active);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
/* draw background */
|
||
|
char* bgcolor = iupAttribGetStr(ih, "BACKCOLOR");
|
||
|
char* bgimage = iupAttribGet(ih, "BACKIMAGE");
|
||
|
|
||
|
if (bgimage)
|
||
|
iupGLDrawIconImageZoom(ih, border_width, ih->currentwidth - 1 - border_width,
|
||
|
border_width, ih->currentheight - 1 - border_width,
|
||
|
"BACKIMAGE", bgimage, active);
|
||
|
else
|
||
|
iupGLDrawBox(ih, border_width, ih->currentwidth - 1 - border_width,
|
||
|
border_width, ih->currentheight - 1 - border_width,
|
||
|
bgcolor, 1); /* always active */
|
||
|
|
||
|
/* draw border - after background because of the round rect */
|
||
|
iupGLDrawRect(ih, 0, ih->currentwidth - 1, 0, ih->currentheight - 1, bwidth, bordercolor, 1, 1);
|
||
|
}
|
||
|
|
||
|
return IUP_DEFAULT;
|
||
|
}
|
||
|
|
||
|
static int iGLFrameBUTTON_CB(Ihandle* ih, int button, int pressed, int x, int y, char* status)
|
||
|
{
|
||
|
/* Only called when MOVEABLE=Yes */
|
||
|
|
||
|
if (button == IUP_BUTTON1 && pressed)
|
||
|
iupGLSubCanvasStartMoving(ih, x, y);
|
||
|
|
||
|
(void)status;
|
||
|
return IUP_DEFAULT;
|
||
|
}
|
||
|
|
||
|
static int iGLFrameMOTION_CB(Ihandle* ih, int x, int y, char* status)
|
||
|
{
|
||
|
int pressed = iupAttribGetInt(ih, "PRESSED");
|
||
|
|
||
|
/* Only called when MOVEABLE=Yes */
|
||
|
|
||
|
if (pressed)
|
||
|
iupGLSubCanvasMove(ih, x, y);
|
||
|
|
||
|
(void)status;
|
||
|
return IUP_DEFAULT;
|
||
|
}
|
||
|
|
||
|
static void iGLFrameGetDecorOffset(Ihandle* ih, int *dx, int *dy)
|
||
|
{
|
||
|
char* image = iupAttribGet(ih, "IMAGE");
|
||
|
char* title = iupAttribGet(ih, "TITLE");
|
||
|
float bwidth = iupAttribGetFloat(ih, "FRAMEWIDTH");
|
||
|
int border_width = (int)ceil(bwidth);
|
||
|
*dx = border_width;
|
||
|
*dy = border_width;
|
||
|
|
||
|
if (image || title)
|
||
|
{
|
||
|
int w = 0, h = 0;
|
||
|
iupGLIconGetSize(ih, image, title, &w, &h);
|
||
|
|
||
|
(*dy) += h;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void iGLFrameGetDecorSize(Ihandle* ih, int *width, int *height, int* title_width)
|
||
|
{
|
||
|
char* image = iupAttribGet(ih, "IMAGE");
|
||
|
char* title = iupAttribGet(ih, "TITLE");
|
||
|
float bwidth = iupAttribGetFloat(ih, "FRAMEWIDTH");
|
||
|
int border_width = (int)ceil(bwidth);
|
||
|
|
||
|
*width = 2 * border_width;
|
||
|
*height = 2 * border_width;
|
||
|
if (title_width)
|
||
|
*title_width = 0;
|
||
|
|
||
|
if (image || title)
|
||
|
{
|
||
|
int w = 0,
|
||
|
h = 0;
|
||
|
iupGLIconGetSize(ih, image, title, &w, &h);
|
||
|
|
||
|
(*height) += h;
|
||
|
if (title_width)
|
||
|
*title_width = w;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static char* iGLFrameGetClientSizeAttrib(Ihandle* ih)
|
||
|
{
|
||
|
int width, height, decorwidth, decorheight;
|
||
|
width = ih->currentwidth;
|
||
|
height = ih->currentheight;
|
||
|
iGLFrameGetDecorSize(ih, &decorwidth, &decorheight, NULL);
|
||
|
width -= decorwidth;
|
||
|
height -= decorheight;
|
||
|
if (width < 0) width = 0;
|
||
|
if (height < 0) height = 0;
|
||
|
return iupStrReturnIntInt(width, height, 'x');
|
||
|
}
|
||
|
|
||
|
static char* iGLFrameGetClipMinAttrib(Ihandle* ih)
|
||
|
{
|
||
|
int x, y;
|
||
|
iGLFrameGetDecorOffset(ih, &x, &y);
|
||
|
return iupStrReturnIntInt(x, y, 'x');
|
||
|
}
|
||
|
|
||
|
static int iGLFrameSetMoveableAttrib(Ihandle* ih, const char* value)
|
||
|
{
|
||
|
Ihandle* gl_parent = (Ihandle*)iupAttribGet(ih, "_IUP_GLCANVAS_PARENT");
|
||
|
/* only a direct child of the canvasbox can be moved */
|
||
|
if (iupStrBoolean(value) && ih->parent == gl_parent)
|
||
|
{
|
||
|
IupSetCallback(ih, "GL_BUTTON_CB", (Icallback)iGLFrameBUTTON_CB);
|
||
|
IupSetCallback(ih, "GL_MOTION_CB", (Icallback)iGLFrameMOTION_CB);
|
||
|
return 1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
IupSetCallback(ih, "GL_BUTTON_CB", NULL);
|
||
|
IupSetCallback(ih, "GL_MOTION_CB", NULL);
|
||
|
iupAttribSet(ih, "MOVEABLE", "NO");
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void iGLFrameComputeNaturalSizeMethod(Ihandle* ih, int *w, int *h, int *children_expand)
|
||
|
{
|
||
|
int decorwidth, decorheight, title_width;
|
||
|
Ihandle* child = ih->firstchild;
|
||
|
|
||
|
iGLFrameGetDecorSize(ih, &decorwidth, &decorheight, &title_width);
|
||
|
*w = decorwidth;
|
||
|
*h = decorheight;
|
||
|
|
||
|
if (child)
|
||
|
{
|
||
|
/* update child natural size first */
|
||
|
iupBaseComputeNaturalSize(child);
|
||
|
|
||
|
*children_expand = child->expand;
|
||
|
*w += iupMAX(child->naturalwidth, title_width); /* make room for title always */
|
||
|
*h += child->naturalheight;
|
||
|
}
|
||
|
else
|
||
|
*w += title_width;
|
||
|
}
|
||
|
|
||
|
static void iGLFrameSetChildrenCurrentSizeMethod(Ihandle* ih, int shrink)
|
||
|
{
|
||
|
if (ih->firstchild)
|
||
|
{
|
||
|
int width, height, decorwidth, decorheight;
|
||
|
|
||
|
iGLFrameGetDecorSize(ih, &decorwidth, &decorheight, NULL);
|
||
|
|
||
|
width = ih->currentwidth - decorwidth;
|
||
|
height = ih->currentheight - decorheight;
|
||
|
if (width < 0) width = 0;
|
||
|
if (height < 0) height = 0;
|
||
|
|
||
|
iupBaseSetCurrentSize(ih->firstchild, width, height, shrink);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void iGLFrameSetChildrenPositionMethod(Ihandle* ih, int x, int y)
|
||
|
{
|
||
|
if (ih->firstchild)
|
||
|
{
|
||
|
int dx, dy;
|
||
|
iGLFrameGetDecorOffset(ih, &dx, &dy);
|
||
|
|
||
|
iupBaseSetPosition(ih->firstchild, x + dx, y + dy);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static int iGLFrameCreateMethod(Ihandle* ih, void** params)
|
||
|
{
|
||
|
if (params)
|
||
|
{
|
||
|
Ihandle** iparams = (Ihandle**)params;
|
||
|
if (*iparams)
|
||
|
IupAppend(ih, *iparams);
|
||
|
}
|
||
|
|
||
|
IupSetCallback(ih, "GL_ACTION", iGLFrameACTION);
|
||
|
|
||
|
return IUP_NOERROR;
|
||
|
}
|
||
|
|
||
|
|
||
|
/******************************************************************************/
|
||
|
|
||
|
|
||
|
Iclass* iupGLFrameNewClass(void)
|
||
|
{
|
||
|
Iclass* ic = iupClassNew(iupRegisterFindClass("glsubcanvas"));
|
||
|
|
||
|
ic->name = "glframe";
|
||
|
ic->cons = "GLFrame";
|
||
|
ic->format = "h"; /* one Ihandle* */
|
||
|
ic->nativetype = IUP_TYPEVOID;
|
||
|
ic->childtype = IUP_CHILDMANY+1; /* 1 child */
|
||
|
ic->is_interactive = 0;
|
||
|
|
||
|
/* Class functions */
|
||
|
ic->New = iupGLFrameNewClass;
|
||
|
ic->Create = iGLFrameCreateMethod;
|
||
|
|
||
|
ic->ComputeNaturalSize = iGLFrameComputeNaturalSizeMethod;
|
||
|
ic->SetChildrenCurrentSize = iGLFrameSetChildrenCurrentSizeMethod;
|
||
|
ic->SetChildrenPosition = iGLFrameSetChildrenPositionMethod;
|
||
|
|
||
|
iupClassRegisterCallback(ic, "MOVE_CB", "ii");
|
||
|
|
||
|
/* Base Container */
|
||
|
iupClassRegisterAttribute(ic, "EXPAND", iupBaseContainerGetExpandAttrib, NULL, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED | IUPAF_NO_INHERIT);
|
||
|
iupClassRegisterAttribute(ic, "CLIENTSIZE", iGLFrameGetClientSizeAttrib, NULL, NULL, NULL, IUPAF_READONLY | IUPAF_NOT_MAPPED | IUPAF_NO_INHERIT);
|
||
|
iupClassRegisterAttribute(ic, "CLIENTOFFSET", iupBaseGetClientOffsetAttrib, NULL, NULL, NULL, IUPAF_READONLY | IUPAF_NOT_MAPPED | IUPAF_NO_INHERIT);
|
||
|
|
||
|
/* Visual */
|
||
|
/* NOTICE: avoid defining inheritable attributes for containers */
|
||
|
|
||
|
iupGLIconRegisterAttrib(ic);
|
||
|
|
||
|
iupClassRegisterAttribute(ic, "CLIP_MIN", iGLFrameGetClipMinAttrib, NULL, NULL, NULL, IUPAF_READONLY | IUPAF_NOT_MAPPED | IUPAF_NO_INHERIT);
|
||
|
|
||
|
iupClassRegisterAttribute(ic, "IMAGE", NULL, NULL, NULL, NULL, IUPAF_IHANDLENAME | IUPAF_NO_DEFAULTVALUE | IUPAF_NO_INHERIT);
|
||
|
iupClassRegisterAttribute(ic, "IMAGEPRESS", NULL, NULL, NULL, NULL, IUPAF_IHANDLENAME | IUPAF_NO_DEFAULTVALUE | IUPAF_NO_INHERIT);
|
||
|
iupClassRegisterAttribute(ic, "IMAGEHIGHLIGHT", NULL, NULL, NULL, NULL, IUPAF_IHANDLENAME | IUPAF_NO_DEFAULTVALUE | IUPAF_NO_INHERIT);
|
||
|
iupClassRegisterAttribute(ic, "IMAGEINACTIVE", NULL, NULL, NULL, NULL, IUPAF_IHANDLENAME | IUPAF_NO_DEFAULTVALUE | IUPAF_NO_INHERIT);
|
||
|
|
||
|
iupClassRegisterAttribute(ic, "FORECOLOR", NULL, NULL, IUPAF_SAMEASSYSTEM, "0 0 0", IUPAF_NO_INHERIT);
|
||
|
iupClassRegisterAttribute(ic, "TITLE", NULL, NULL, NULL, NULL, IUPAF_NO_DEFAULTVALUE | IUPAF_NO_INHERIT);
|
||
|
iupClassRegisterAttribute(ic, "TITLEOFFSET", NULL, NULL, IUPAF_SAMEASSYSTEM, "5", IUPAF_NO_INHERIT);
|
||
|
iupClassRegisterAttribute(ic, "TITLEBOX", NULL, NULL, NULL, NULL, IUPAF_NO_INHERIT);
|
||
|
iupClassRegisterAttribute(ic, "TITLEBACKIMAGE", NULL, NULL, NULL, NULL, IUPAF_IHANDLENAME | IUPAF_NO_INHERIT);
|
||
|
iupClassRegisterAttribute(ic, "TITLEBACKIMAGEINACTIVE", NULL, NULL, NULL, NULL, IUPAF_IHANDLENAME | IUPAF_NO_INHERIT);
|
||
|
|
||
|
iupClassRegisterAttribute(ic, "FRAMECOLOR", NULL, NULL, IUPAF_SAMEASSYSTEM, "50 150 255", IUPAF_NO_INHERIT);
|
||
|
iupClassRegisterAttribute(ic, "FRAMEWIDTH", NULL, NULL, IUPAF_SAMEASSYSTEM, "1", IUPAF_NO_INHERIT);
|
||
|
|
||
|
iupClassRegisterAttribute(ic, "BACKIMAGE", NULL, NULL, NULL, NULL, IUPAF_IHANDLENAME | IUPAF_NO_INHERIT);
|
||
|
iupClassRegisterAttribute(ic, "BACKIMAGEINACTIVE", NULL, NULL, NULL, NULL, IUPAF_IHANDLENAME | IUPAF_NO_INHERIT);
|
||
|
iupClassRegisterAttribute(ic, "BACKCOLOR", NULL, NULL, NULL, NULL, IUPAF_NO_INHERIT);
|
||
|
|
||
|
iupClassRegisterAttribute(ic, "MOVEABLE", NULL, iGLFrameSetMoveableAttrib, NULL, NULL, IUPAF_NOT_MAPPED | IUPAF_NO_INHERIT);
|
||
|
iupClassRegisterAttribute(ic, "MOVETOTOP", NULL, NULL, NULL, NULL, IUPAF_NOT_MAPPED | IUPAF_NO_INHERIT);
|
||
|
|
||
|
/* replace default value */
|
||
|
iupClassRegisterAttribute(ic, "PADDING", NULL, NULL, IUPAF_SAMEASSYSTEM, "2x0", IUPAF_NO_INHERIT);
|
||
|
|
||
|
return ic;
|
||
|
}
|
||
|
|
||
|
Ihandle* IupGLFrame(Ihandle* child)
|
||
|
{
|
||
|
void *children[2];
|
||
|
children[0] = (void*)child;
|
||
|
children[1] = NULL;
|
||
|
return IupCreatev("glframe", children);
|
||
|
}
|