Blame graph.c

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