231 lines
4.6 KiB
C
231 lines
4.6 KiB
C
|
|
#include "WINGsP.h"
|
|
|
|
typedef struct W_Frame {
|
|
W_Class widgetClass;
|
|
W_View *view;
|
|
|
|
char *caption;
|
|
WMColor *textColor;
|
|
|
|
struct {
|
|
WMReliefType relief:4;
|
|
WMTitlePosition titlePosition:4;
|
|
} flags;
|
|
} Frame;
|
|
|
|
#define DEFAULT_RELIEF WRGroove
|
|
#define DEFAULT_TITLE_POSITION WTPAtTop
|
|
#define DEFAULT_WIDTH 40
|
|
#define DEFAULT_HEIGHT 40
|
|
|
|
static void destroyFrame(Frame * fPtr);
|
|
static void paintFrame(Frame * fPtr);
|
|
static void repaintFrame(Frame * fPtr);
|
|
|
|
void WMSetFrameTitlePosition(WMFrame * fPtr, WMTitlePosition position)
|
|
{
|
|
fPtr->flags.titlePosition = position;
|
|
|
|
if (fPtr->view->flags.realized) {
|
|
repaintFrame(fPtr);
|
|
}
|
|
}
|
|
|
|
void WMSetFrameRelief(WMFrame * fPtr, WMReliefType relief)
|
|
{
|
|
fPtr->flags.relief = relief;
|
|
|
|
if (fPtr->view->flags.realized) {
|
|
repaintFrame(fPtr);
|
|
}
|
|
}
|
|
|
|
void WMSetFrameTitle(WMFrame * fPtr, const char *title)
|
|
{
|
|
if (fPtr->caption)
|
|
wfree(fPtr->caption);
|
|
|
|
if (title)
|
|
fPtr->caption = wstrdup(title);
|
|
else
|
|
fPtr->caption = NULL;
|
|
|
|
if (fPtr->view->flags.realized) {
|
|
repaintFrame(fPtr);
|
|
}
|
|
}
|
|
|
|
static void repaintFrame(Frame * fPtr)
|
|
{
|
|
W_View *view = fPtr->view;
|
|
W_Screen *scrPtr = view->screen;
|
|
const W_RenderBackend *R = scrPtr->renderBackend;
|
|
void *rctx = scrPtr->renderBackendCtx;
|
|
|
|
R->fill_rect(rctx, (WMDrawable)view->window, view->backColor,
|
|
0, 0, view->size.width, view->size.height);
|
|
paintFrame(fPtr);
|
|
}
|
|
|
|
static void paintFrame(Frame * fPtr)
|
|
{
|
|
W_View *view = fPtr->view;
|
|
W_Screen *scrPtr = view->screen;
|
|
WMFont *font = scrPtr->normalFont;
|
|
int tx, ty, tw, th, tlen;
|
|
int fy, fh;
|
|
Bool drawTitle;
|
|
|
|
if (fPtr->caption != NULL) {
|
|
th = WMFontHeight(font);
|
|
tlen = strlen(fPtr->caption);
|
|
} else {
|
|
th = 0;
|
|
tlen = 0;
|
|
}
|
|
|
|
switch (fPtr->flags.titlePosition) {
|
|
case WTPAboveTop:
|
|
ty = 0;
|
|
fy = th + 4;
|
|
fh = view->size.height - fy;
|
|
break;
|
|
|
|
case WTPAtTop:
|
|
ty = 0;
|
|
fy = th / 2;
|
|
fh = view->size.height - fy;
|
|
break;
|
|
|
|
case WTPBelowTop:
|
|
ty = 4;
|
|
fy = 0;
|
|
fh = view->size.height;
|
|
break;
|
|
|
|
case WTPAboveBottom:
|
|
ty = view->size.height - th - 4;
|
|
fy = 0;
|
|
fh = view->size.height;
|
|
break;
|
|
|
|
case WTPAtBottom:
|
|
ty = view->size.height - th;
|
|
fy = 0;
|
|
fh = view->size.height - th / 2;
|
|
break;
|
|
|
|
case WTPBelowBottom:
|
|
ty = view->size.height - th;
|
|
fy = 0;
|
|
fh = view->size.height - th - 4;
|
|
break;
|
|
|
|
default:
|
|
ty = 0;
|
|
fy = 0;
|
|
fh = view->size.height;
|
|
}
|
|
|
|
if (tlen > 0 && fPtr->flags.titlePosition != WTPNoTitle) {
|
|
tw = WMWidthOfString(font, fPtr->caption, tlen);
|
|
|
|
tx = (view->size.width - tw) / 2;
|
|
|
|
drawTitle = True;
|
|
} else {
|
|
tw = tx = 0;
|
|
drawTitle = False;
|
|
}
|
|
|
|
W_DrawReliefWithGC(scrPtr, (WMDrawable)view->window, 0, fy, view->size.width, fh,
|
|
fPtr->flags.relief, scrPtr->black, scrPtr->darkGray,
|
|
scrPtr->gray, scrPtr->white);
|
|
|
|
if (drawTitle) {
|
|
/* can't draw AA text over and over again because it gets messed */
|
|
/* // TODO create the dbl buffer pixmap when create/set frame title */
|
|
if (scrPtr->antialiasedText) {
|
|
const W_RenderBackend *R = scrPtr->renderBackend;
|
|
void *rctx = scrPtr->renderBackendCtx;
|
|
WMDrawable d;
|
|
|
|
d = R->pixmap_create(rctx, tw, th, scrPtr->depth);
|
|
R->fill_rect(rctx, d, view->backColor, 0, 0, tw, th);
|
|
|
|
WMDrawString(scrPtr, d, fPtr->textColor ? fPtr->textColor : scrPtr->black, font, 0, 0, fPtr->caption, tlen);
|
|
R->pixmap_copy(rctx, d, (WMDrawable)view->window, 0, 0, tw, th, tx, ty);
|
|
R->pixmap_free(rctx, d);
|
|
} else {
|
|
WMDrawString(scrPtr, (WMDrawable)view->window, scrPtr->black, font, tx, ty, fPtr->caption, tlen);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void handleEvents(WMEvent * event, void *data)
|
|
{
|
|
Frame *fPtr = (Frame *) data;
|
|
|
|
CHECK_CLASS(data, WC_Frame);
|
|
|
|
switch (event->type) {
|
|
case WME_EXPOSE:
|
|
if (event->u.expose.count == 0)
|
|
paintFrame(fPtr);
|
|
break;
|
|
|
|
case WME_DESTROY:
|
|
destroyFrame(fPtr);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void WMSetFrameTitleColor(WMFrame *fPtr, WMColor *color)
|
|
{
|
|
if (fPtr->textColor)
|
|
WMReleaseColor(fPtr->textColor);
|
|
fPtr->textColor = WMRetainColor(color);
|
|
|
|
if (fPtr->view->flags.realized) {
|
|
repaintFrame(fPtr);
|
|
}
|
|
}
|
|
|
|
WMFrame *WMCreateFrame(WMWidget * parent)
|
|
{
|
|
Frame *fPtr;
|
|
|
|
fPtr = wmalloc(sizeof(Frame));
|
|
|
|
fPtr->widgetClass = WC_Frame;
|
|
|
|
fPtr->view = W_CreateView(W_VIEW(parent));
|
|
if (!fPtr->view) {
|
|
wfree(fPtr);
|
|
return NULL;
|
|
}
|
|
fPtr->view->self = fPtr;
|
|
fPtr->textColor = WMRetainColor(fPtr->view->screen->black);
|
|
|
|
WMCreateEventHandler(fPtr->view, ExposureMask | StructureNotifyMask, handleEvents, fPtr);
|
|
|
|
fPtr->flags.relief = DEFAULT_RELIEF;
|
|
fPtr->flags.titlePosition = DEFAULT_TITLE_POSITION;
|
|
|
|
WMResizeWidget(fPtr, DEFAULT_WIDTH, DEFAULT_HEIGHT);
|
|
|
|
return fPtr;
|
|
}
|
|
|
|
static void destroyFrame(Frame * fPtr)
|
|
{
|
|
if (fPtr->textColor)
|
|
WMReleaseColor(fPtr->textColor);
|
|
|
|
if (fPtr->caption)
|
|
wfree(fPtr->caption);
|
|
|
|
wfree(fPtr);
|
|
}
|