|
|
452870 |
|
|
|
452870 |
#include "app.h"
|
|
|
452870 |
|
|
|
452870 |
|
|
|
452870 |
|
|
|
452870 |
int graphInit(Graph *g, App *app) {
|
|
|
452870 |
LOGDBG("graph: init");
|
|
|
452870 |
|
|
|
dbe1a1 |
CLEARFROM(g, app);
|
|
|
452870 |
g->app = app;
|
|
|
452870 |
|
|
|
dbe1a1 |
enum {
|
|
|
37122c |
F = 0xffffu, // full
|
|
|
37122c |
B = 0x9000u, // bright
|
|
|
37122c |
D = 0x7000u, // dark
|
|
|
37122c |
Q = 0x4000u }; // quart
|
|
|
dbe1a1 |
static const XRenderColor renderColors[GC_COUNT] = {
|
|
|
dbe1a1 |
{ 0, 0, Q, F }, // window
|
|
|
37122c |
{ 0, 0, D, F }, // inactive button
|
|
|
37122c |
{ 0, 0, B, F }, // highlighted button
|
|
|
dbe1a1 |
{ 0, 0, F, F }, // active button
|
|
|
37122c |
{ B, 0, F, F }, // active button 2
|
|
|
dbe1a1 |
{ F, F, 0, F }, // inactive text
|
|
|
37122c |
{ F, F, 0, F }, // highlighted text
|
|
|
dbe1a1 |
{ F, F, 0, F }, // active text
|
|
|
dbe1a1 |
{ F, F, 0, F } }; // active text 2
|
|
|
dbe1a1 |
|
|
|
dbe1a1 |
static const char *fonts[] = FONTS;
|
|
|
dbe1a1 |
static const int sizes[FONT_MAX_SIZES] = FONT_SIZES;
|
|
|
452870 |
|
|
|
dbe1a1 |
LOGDBG("graph: init: create XftDraw");
|
|
|
dbe1a1 |
g->draw = XftDrawCreate(
|
|
|
dbe1a1 |
g->app->dpy,
|
|
|
dbe1a1 |
g->app->win,
|
|
|
dbe1a1 |
DefaultVisual(g->app->dpy, g->app->screen),
|
|
|
dbe1a1 |
DefaultColormap(g->app->dpy, g->app->screen) );
|
|
|
dbe1a1 |
if (!g->draw)
|
|
|
dbe1a1 |
return LOGERR("graph: init: cannot create XftDraw");
|
|
|
dbe1a1 |
|
|
|
dbe1a1 |
LOGDBG("graph: init: open fonts");
|
|
|
dbe1a1 |
char buf[1024] = {};
|
|
|
dbe1a1 |
for(int i = 0; i < FONT_MAX_SIZES; ++i) {
|
|
|
dbe1a1 |
if (!sizes[i]) break;
|
|
|
dbe1a1 |
for(int j = 0; j < COUNTOF(fonts); ++j) {
|
|
|
dbe1a1 |
snprintf(buf, sizeof(buf), "%s:size=%d", fonts[j], sizes[i]);
|
|
|
dbe1a1 |
LOGDBG("graph: init: try open font [%s]", buf);
|
|
|
dbe1a1 |
g->fonts[g->fontsCnt] = XftFontOpenName(g->app->dpy, g->app->screen, buf);
|
|
|
dbe1a1 |
if (g->fonts[g->fontsCnt]) {
|
|
|
dbe1a1 |
++g->fontsCnt;
|
|
|
dbe1a1 |
break;
|
|
|
dbe1a1 |
} else {
|
|
|
dbe1a1 |
LOGDBG("graph: init: cannot open font [%s]", buf);
|
|
|
061fcf |
}
|
|
|
061fcf |
}
|
|
|
061fcf |
}
|
|
|
061fcf |
|
|
|
dbe1a1 |
if (!g->fontsCnt) {
|
|
|
dbe1a1 |
LOGERR("graph: init: cannot open any font");
|
|
|
dbe1a1 |
XftDrawDestroy(g->draw);
|
|
|
dbe1a1 |
CLEARFROM(g, app);
|
|
|
061fcf |
return 0;
|
|
|
061fcf |
}
|
|
|
dbe1a1 |
|
|
|
dbe1a1 |
LOGDBG("graph: init: allocate colors");
|
|
|
dbe1a1 |
for(int i = 0; i < GC_COUNT; ++i) {
|
|
|
dbe1a1 |
XftColorAllocValue(
|
|
|
dbe1a1 |
g->app->dpy,
|
|
|
dbe1a1 |
DefaultVisual(g->app->dpy, g->app->screen),
|
|
|
dbe1a1 |
DefaultColormap(g->app->dpy, g->app->screen),
|
|
|
dbe1a1 |
&renderColors[i],
|
|
|
dbe1a1 |
&g->colors[i] );
|
|
|
452870 |
}
|
|
|
452870 |
|
|
|
452870 |
return 1;
|
|
|
452870 |
}
|
|
|
452870 |
|
|
|
452870 |
|
|
|
452870 |
void graphDeinit(Graph *g) {
|
|
|
452870 |
LOGDBG("graph: deinit");
|
|
|
dbe1a1 |
for(int i = 0; i < GC_COUNT; ++i)
|
|
|
dbe1a1 |
XftColorFree(
|
|
|
dbe1a1 |
g->app->dpy,
|
|
|
dbe1a1 |
DefaultVisual(g->app->dpy, g->app->screen),
|
|
|
dbe1a1 |
DefaultColormap(g->app->dpy, g->app->screen),
|
|
|
dbe1a1 |
&g->colors[i] );
|
|
|
dbe1a1 |
for(int i = 0; i < g->fontsCnt; ++i)
|
|
|
dbe1a1 |
XftFontClose(g->app->dpy, g->fonts[i]);
|
|
|
dbe1a1 |
XftDrawDestroy(g->draw);
|
|
|
452870 |
}
|
|
|
452870 |
|
|
|
452870 |
|
|
|
452870 |
void graphResize(Graph *g)
|
|
|
452870 |
{ }
|
|
|
452870 |
|
|
|
452870 |
|
|
|
452870 |
void graphDrawBackgound(Graph *g, int x, int y, int w, int h) {
|
|
|
dbe1a1 |
XftDrawRect(g->draw, &g->colors[GC_WINDOW], x, y, w, h);
|
|
|
452870 |
}
|
|
|
452870 |
|
|
|
452870 |
|
|
|
37122c |
void graphDrawButton(Graph *g, int x, int y, int w, int h, int active, int highlight) {
|
|
|
dbe1a1 |
GraphStyle s = active == 1 ? GC_BUTTON_ACTIVE
|
|
|
dbe1a1 |
: active == 2 ? GC_BUTTON_ACTIVE2
|
|
|
37122c |
: highlight ? GC_BUTTON_HIGHTLIGHT
|
|
|
dbe1a1 |
: GC_BUTTON_INACTIVE;
|
|
|
dbe1a1 |
XftDrawRect(g->draw, &g->colors[s], x, y, w, h);
|
|
|
452870 |
}
|
|
|
452870 |
|
|
|
452870 |
|
|
|
452870 |
|
|
|
843e7a |
void textLayoutInit(TextLayout *tl, Graph *g, const char *text) {
|
|
|
dbe1a1 |
CLEARFROM(tl, g);
|
|
|
452870 |
tl->g = g;
|
|
|
8864eb |
|
|
|
dbe1a1 |
tl->len = text ? strlen(text) : 0;
|
|
|
dbe1a1 |
tl->text = text;
|
|
|
061fcf |
if (!tl->len)
|
|
|
061fcf |
return;
|
|
|
061fcf |
|
|
|
dbe1a1 |
for(int i = 0; i < tl->g->fontsCnt; ++i) {
|
|
|
dbe1a1 |
XGlyphInfo e = {};
|
|
|
dbe1a1 |
XftTextExtentsUtf8(g->app->dpy, g->fonts[i], (const FcChar8*)tl->text, tl->len, &e);
|
|
|
8864eb |
|
|
|
8864eb |
int asc = tl->g->fonts[i]->ascent;
|
|
|
8864eb |
int desc = tl->g->fonts[i]->descent;
|
|
|
dbe1a1 |
int w = e.width;
|
|
|
8864eb |
int minw = asc + asc/3;
|
|
|
db2d04 |
int h = asc + desc; // proper value is: asc + 2*desc
|
|
|
8864eb |
|
|
|
8864eb |
tl->sizes[i].x = e.x - w/2;
|
|
|
8864eb |
tl->sizes[i].y = asc/2;
|
|
|
dbe1a1 |
tl->sizes[i].w = w < minw ? minw : w;
|
|
|
dbe1a1 |
tl->sizes[i].h = h;
|
|
|
061fcf |
}
|
|
|
452870 |
}
|
|
|
452870 |
|
|
|
061fcf |
|
|
|
452870 |
void textLayoutDeinit(TextLayout *tl)
|
|
|
dbe1a1 |
{ CLEARFROM(tl, g); }
|
|
|
452870 |
|
|
|
061fcf |
|
|
|
37122c |
void textLayoutDraw(TextLayout *tl, int x, int y, int w, int h, int active, int highlight) {
|
|
|
061fcf |
if (!tl->len) return;
|
|
|
dbe1a1 |
GraphStyle s = active == 1 ? GC_TEXT_ACTIVE
|
|
|
dbe1a1 |
: active == 2 ? GC_TEXT_ACTIVE2
|
|
|
37122c |
: highlight ? GC_TEXT_HIGHTLIGHT
|
|
|
dbe1a1 |
: GC_TEXT_INACTIVE;
|
|
|
dbe1a1 |
|
|
|
dbe1a1 |
// find font size
|
|
|
dbe1a1 |
int i;
|
|
|
dbe1a1 |
for(i = tl->g->fontsCnt - 1; i > 0; --i)
|
|
|
dbe1a1 |
if (tl->sizes[i].w <= w && tl->sizes[i].h <= h) break;
|
|
|
dbe1a1 |
|
|
|
dbe1a1 |
XftDrawStringUtf8(
|
|
|
dbe1a1 |
tl->g->draw,
|
|
|
dbe1a1 |
&tl->g->colors[s],
|
|
|
dbe1a1 |
tl->g->fonts[i],
|
|
|
dbe1a1 |
x + tl->sizes[i].x,
|
|
|
dbe1a1 |
y + tl->sizes[i].y,
|
|
|
dbe1a1 |
(const FcChar8*)tl->text,
|
|
|
dbe1a1 |
tl->len );
|
|
|
061fcf |
}
|
|
|
061fcf |
|