1
0
mirror of https://github.com/gryf/wmaker.git synced 2025-12-18 12:00:31 +01:00
Files
wmaker/WINGs/wframe.c
David Maciejak 3b298e8964 WINGs: add function to set the color of the frame title
This patch adds a function used to set the color of the frame title
2014-06-15 19:45:20 +01:00

261 lines
5.1 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;
XClearWindow(scrPtr->display, view->window);
paintFrame(fPtr);
}
static void paintFrame(Frame * fPtr)
{
W_View *view = fPtr->view;
W_Screen *scrPtr = view->screen;
WMFont *font = scrPtr->normalFont;
Display *display = scrPtr->display;
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;
}
{
XRectangle rect;
Region region, tmp;
GC gc[4];
int i;
region = XCreateRegion();
rect.x = 0;
rect.y = 0;
rect.width = view->size.width;
rect.height = view->size.height;
XUnionRectWithRegion(&rect, region, region);
if (drawTitle) {
tmp = XCreateRegion();
rect.x = tx;
rect.y = ty;
rect.width = tw;
rect.height = th;
XUnionRectWithRegion(&rect, tmp, tmp);
XSubtractRegion(region, tmp, region);
XDestroyRegion(tmp);
}
gc[0] = WMColorGC(scrPtr->black);
gc[1] = WMColorGC(scrPtr->darkGray);
gc[2] = WMColorGC(scrPtr->gray);
gc[3] = WMColorGC(scrPtr->white);
for (i = 0; i < 4; i++) {
XSetRegion(display, gc[i], region);
}
XDestroyRegion(region);
W_DrawReliefWithGC(scrPtr, view->window, 0, fy, view->size.width, fh,
fPtr->flags.relief, gc[0], gc[1], gc[2], gc[3]);
for (i = 0; i < 4; i++) {
XSetClipMask(display, gc[i], None);
}
}
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) {
Drawable d;
d = XCreatePixmap(display, view->window, tw, th, scrPtr->depth);
XFillRectangle(display, d, WMColorGC(view->backColor), 0, 0, tw, th);
WMDrawString(scrPtr, d, fPtr->textColor ? fPtr->textColor : scrPtr->black, font, 0, 0, fPtr->caption, tlen);
XCopyArea(display, d, view->window, scrPtr->copyGC, 0, 0, tw, th, tx, ty);
XFreePixmap(display, d);
} else {
WMDrawString(scrPtr, view->window, scrPtr->black, font, tx, ty, fPtr->caption, tlen);
}
}
}
static void handleEvents(XEvent * event, void *data)
{
Frame *fPtr = (Frame *) data;
CHECK_CLASS(data, WC_Frame);
switch (event->type) {
case Expose:
if (event->xexpose.count == 0)
paintFrame(fPtr);
break;
case DestroyNotify:
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->caption)
wfree(fPtr->caption);
wfree(fPtr);
}