iup-stack/iup/srcglcontrols/iup_glframe.c

333 lines
10 KiB
C
Raw Permalink Normal View History

2023-02-20 16:44:45 +00:00
/** \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);
}