changeset 3205:25e264312f90

Added text stuff and updated the calls of the functions
author unexist
date Tue, 22 May 2012 23:15:36 +0200
parents 369bdd72f5e6
children 77e0c21c1426
files src/subtle/panel.c src/subtle/ruby.c src/subtle/style.c src/subtle/subtle.h src/subtle/text.c
diffstat 5 files changed, 262 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/src/subtle/panel.c	Tue May 22 23:15:06 2012 +0200
+++ b/src/subtle/panel.c	Tue May 22 23:15:36 2012 +0200
@@ -56,7 +56,7 @@
   /* Set window background and border*/
   PanelRect(drawable, x, s->separator->width, s);
 
-  subSharedTextDraw(subtle->dpy, subtle->gcs.draw,
+  subSharedDrawString(subtle->dpy, subtle->gcs.draw,
     s->font, drawable, x + STYLE_LEFT((*s)),
     s->font->y + STYLE_TOP((*s)), s->fg, s->bg,
     s->separator->string, strlen(s->separator->string));
@@ -84,7 +84,7 @@
   if(c->flags & SUB_CLIENT_MODE_FIXED)
     x += snprintf(buf + x, sizeof(buf), "%c", '!');
 
-  *width = subSharedTextWidth(subtle->dpy, subtle->styles.title.font,
+  *width = subSharedStringWidth(subtle->dpy, subtle->styles.title.font,
     buf, strlen(buf), NULL, NULL, True);
 } /* }}} */
 
@@ -169,7 +169,7 @@
 
         /* Sublet specific */
         p->sublet->time    = subSubtleTime();
-        p->sublet->text    = subSharedTextNew();
+        p->sublet->text    = subTextNew();
         p->sublet->styleid = -1;
         break; /* }}} */
       case SUB_PANEL_VIEWS: /* {{{ */
@@ -206,7 +206,7 @@
         if(p->keychain && p->keychain->keys)
           {
             /* Font offset, panel border and padding */
-            p->width = subSharedTextWidth(subtle->dpy,
+            p->width = subSharedStringWidth(subtle->dpy,
               subtle->styles.separator.font, p->keychain->keys,
               p->keychain->len, NULL, NULL, True) +
               subtle->styles.separator.padding.left +
@@ -243,7 +243,7 @@
                     PanelClientModes(c, buf, &width);
 
                     /* Font offset, panel border and padding */
-                    p->width = subSharedTextWidth(subtle->dpy,
+                    p->width = subSharedStringWidth(subtle->dpy,
                       subtle->styles.title.font, c->name,
                       /* Limit string length */
                       len > subtle->styles.clients.right ?
@@ -282,7 +282,7 @@
                   v->width = v->icon->width + STYLE_WIDTH((s));
                 else
                   {
-                    v->width = subSharedTextWidth(subtle->dpy, s.font,
+                    v->width = subSharedStringWidth(subtle->dpy, s.font,
                       v->name, strlen(v->name), NULL, NULL, True) +
                       STYLE_WIDTH((s)) + (v->icon ? v->icon->width + 3 : 0);
                   }
@@ -336,7 +336,7 @@
             icony = p->icon->height > y ? subtle->styles.separator.margin.top :
               y - p->icon->height;
 
-            subSharedTextIconDraw(subtle->dpy, subtle->gcs.draw,
+            subSharedDrawIcon(subtle->dpy, subtle->gcs.draw,
               drawable, p->x + 2 + subtle->styles.separator.padding.left, icony,
               p->icon->width, p->icon->height, subtle->styles.sublets.fg,
               subtle->styles.sublets.bg, p->icon->pixmap, p->icon->bitmap);
@@ -345,7 +345,7 @@
       case SUB_PANEL_KEYCHAIN: /* {{{ */
         if(p->keychain && p->keychain->keys)
           {
-            subSharedTextDraw(subtle->dpy, subtle->gcs.draw,
+            subSharedDrawString(subtle->dpy, subtle->gcs.draw,
               subtle->styles.separator.font, drawable,
               p->x + STYLE_LEFT(subtle->styles.separator),
               subtle->styles.separator.font->y +
@@ -362,9 +362,9 @@
             PanelRect(drawable, p->x, p->width, s);
 
             /* Render text parts */
-            subSharedTextRender(subtle->dpy, subtle->gcs.draw, s->font,
+            subTextRender(p->sublet->text, s->font, subtle->gcs.draw,
               drawable, p->x + STYLE_LEFT((*s)), s->font->y +
-              STYLE_TOP((*s)), s->fg, s->icon, s->bg, p->sublet->text);
+              STYLE_TOP((*s)), s->fg, s->icon, s->bg);
           }
         break; /* }}} */
       case SUB_PANEL_TITLE: /* {{{ */
@@ -391,12 +391,12 @@
                 y   = subtle->styles.title.font->y +
                   STYLE_TOP(subtle->styles.title);
 
-                subSharedTextDraw(subtle->dpy, subtle->gcs.draw,
+                subSharedDrawString(subtle->dpy, subtle->gcs.draw,
                   subtle->styles.title.font, drawable, x, y,
                   subtle->styles.title.fg, subtle->styles.title.bg,
                   buf, strlen(buf));
 
-                subSharedTextDraw(subtle->dpy, subtle->gcs.draw,
+                subSharedDrawString(subtle->dpy, subtle->gcs.draw,
                   subtle->styles.title.font, drawable, x + width, y,
                   subtle->styles.title.fg, subtle->styles.title.bg, c->name,
                   /* Limit string length */
@@ -439,7 +439,7 @@
                     icony = v->icon->height > y ? s.margin.top :
                       y - v->icon->height;
 
-                    subSharedTextIconDraw(subtle->dpy, subtle->gcs.draw,
+                    subSharedDrawIcon(subtle->dpy, subtle->gcs.draw,
                       drawable, vx + x, icony, v->icon->width,
                       v->icon->height, s.icon, s.bg, v->icon->pixmap,
                       v->icon->bitmap);
@@ -449,7 +449,7 @@
                   {
                     if(v->flags & SUB_VIEW_ICON) x += v->icon->width + 3;
 
-                    subSharedTextDraw(subtle->dpy, subtle->gcs.draw,
+                    subSharedDrawString(subtle->dpy, subtle->gcs.draw,
                       s.font, drawable, vx + x, s.font->y +
                       STYLE_TOP((s)), s.fg, s.bg, v->name, strlen(v->name));
                   }
@@ -747,7 +747,7 @@
                 printf("Unloaded sublet (%s)\n", p->sublet->name);
                 free(p->sublet->name);
               }
-            if(p->sublet->text) subSharedTextFree(p->sublet->text);
+            if(p->sublet->text) subTextKill(p->sublet->text);
 
             free(p->sublet);
           }
--- a/src/subtle/ruby.c	Tue May 22 23:15:06 2012 +0200
+++ b/src/subtle/ruby.c	Tue May 22 23:15:36 2012 +0200
@@ -3019,9 +3019,9 @@
           if(s->styles && (style = subArrayGet(s->styles, p->sublet->styleid)))
               s = style;
 
-          p->sublet->width = subSharedTextParse(subtle->dpy,
-            subtle->styles.sublets.font, p->sublet->text,
-            RSTRING_PTR(value)) + STYLE_WIDTH((*s));
+          p->sublet->width = subTextParse(p->sublet->text,
+            subtle->styles.sublets.font, RSTRING_PTR(value)) +
+            STYLE_WIDTH((*s));
         }
       else rb_raise(rb_eArgError, "Unknown value type");
     }
@@ -3123,9 +3123,9 @@
               p->sublet->styleid = FIX2INT(value);
             }
 
-          p->sublet->width = subSharedTextParse(subtle->dpy,
-            subtle->styles.sublets.font, p->sublet->text,
-            RSTRING_PTR(value)) + STYLE_WIDTH((*s));
+          p->sublet->width = subTextParse(p->sublet->text,
+            subtle->styles.sublets.font, RSTRING_PTR(value)) +
+            STYLE_WIDTH((*s));
         }
       else rb_raise(rb_eArgError, "Unknown value type");
     }
--- a/src/subtle/style.c	Tue May 22 23:15:06 2012 +0200
+++ b/src/subtle/style.c	Tue May 22 23:15:36 2012 +0200
@@ -60,7 +60,7 @@
       /* Update separator width after font */
       if(s1->separator)
         {
-          s1->separator->width = subSharedTextWidth(subtle->dpy,
+          s1->separator->width = subSharedStringWidth(subtle->dpy,
             s1->font, s1->separator->string,
             strlen(s1->separator->string), NULL, NULL, True);
 
--- a/src/subtle/subtle.h	Tue May 22 23:15:06 2012 +0200
+++ b/src/subtle/subtle.h	Tue May 22 23:15:36 2012 +0200
@@ -360,6 +360,11 @@
 #define SUB_TRAY_CLOSE                (1L << 12)                  ///< Send close message
 #define SUB_TRAY_UNMAP                (1L << 11)                  ///< Ignore unmaps
 
+/* Text flags */
+#define SUB_TEXT_EMPTY                (1L << 0)                   ///< Empty text
+#define SUB_TEXT_BITMAP               (1L << 1)                   ///< Text bitmap
+#define SUB_TEXT_PIXMAP               (1L << 2)                   ///< Text pixmap
+
 /* View flags */
 #define SUB_VIEW_ICON                 (1L << 10)                  ///< View icon
 #define SUB_VIEW_ICON_ONLY            (1L << 11)                  ///< Icon only
@@ -727,6 +732,20 @@
   struct subarray_t *matcher;                                     ///< Tag matcher
 } SubTag; /* }}} */
 
+typedef struct subtextitem_t /* {{{ */
+{
+  int             flags, width, height;                           ///< Text flags, width, height
+  long            color;                                          ///< Text color
+
+  union subdata_t data;                                           ///< Text data
+} SubTextItem; /* }}} */
+
+typedef struct subtext_t /* {{{ */
+{
+  struct subtextitem_t **items;                                   ///< Item text items
+  int                  flags, nitems, width;                      ///< Item flags, count, width
+} SubText; /* }}} */
+
 typedef struct subtray_t /* {{{ */
 {
   FLAGS  flags;                                                   ///< Tray flags
@@ -922,6 +941,14 @@
 void subTagKill(SubTag *t);                                       ///< Delete tag
 /* }}} */
 
+/* text.c {{{ */
+SubText *subTextNew(void);                                         ///< Create text
+int subTextParse(SubText *t, SubFont *f, char *text);             ///< Parse string
+void subTextRender(SubText *t, SubFont *f, GC gc, Window win,
+  int x, int y, long fg, long icon, long bg);                     ///< Render text
+void subTextKill(SubText *t);                                     ///< Delete text
+/* }}} */
+
 /* tray.c {{{ */
 SubTray *subTrayNew(Window win);                                  ///< Create tray
 void subTrayConfigure(SubTray *t);                                ///< Configure tray
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/subtle/text.c	Tue May 22 23:15:36 2012 +0200
@@ -0,0 +1,213 @@
+
+ /**
+  * @package subtle
+  *
+  * @file Text functions
+  * @copyright (c) 2005-2012 Christoph Kappel <unexist@subforge.org>
+  * @version $Id$
+  *
+  * This program can be distributed under the terms of the GNU GPLv2.
+  * See the file COPYING for details.
+  **/
+
+#include "subtle.h"
+
+ /** subTextNew {{{
+  * @brief Create new text
+  **/
+
+SubText *
+subTextNew(void)
+{
+  return TEXT(subSharedMemoryAlloc(1, sizeof(SubText)));
+} /* }}} */
+
+ /** subTextParse {{{
+  * @brief Parse a string and store it in given text
+  * @param]inout]  t     A #SubText
+  * @param[inout]  f     A #SubFont
+  * @param[in]     text  Text to parse
+  * @return Returns the length of the text in chars
+  **/
+
+int
+subTextParse(SubText *t,
+  SubFont *f,
+  char *text)
+{
+  int i = 0, left = 0, right = 0;
+  char *tok = NULL;
+  long color = -1, pixmap = 0;
+  SubTextItem *item = NULL;
+
+  assert(f && t);
+
+  t->width = 0;
+
+  /* Split and iterate over tokens */
+  while((tok = strsep(&text, SEPARATOR)))
+    {
+      if('#' == *tok) color = strtol(tok + 1, NULL, 0); ///< Color
+      else if('\0' != *tok) ///< Text or icon
+        {
+          /* Re-use items to save alloc cycles */
+          if(i < t->nitems && (item = ITEM(t->items[i])))
+            {
+              if(!(item->flags & (SUB_TEXT_BITMAP|SUB_TEXT_PIXMAP)) &&
+                  item->data.string)
+                free(item->data.string);
+
+              item->flags &= ~(SUB_TEXT_EMPTY|SUB_TEXT_BITMAP|SUB_TEXT_PIXMAP);
+            }
+          else if((item = ITEM(subSharedMemoryAlloc(1, sizeof(SubTextItem)))))
+            {
+              /* Add icon to array */
+              t->items = (SubTextItem **)subSharedMemoryRealloc(t->items,
+                (t->nitems + 1) * sizeof(SubTextItem *));
+              t->items[(t->nitems)++] = item;
+            }
+
+          /* Get geometry of bitmap/pixmap */
+          if(('!' == *tok || '&' == *tok) &&
+              (pixmap = strtol(tok + 1, NULL, 0)))
+            {
+              XRectangle geometry = { 0 };
+
+              subSharedPropertyGeometry(subtle->dpy, pixmap, &geometry);
+
+              item->flags    |= ('!' == *tok ? SUB_TEXT_BITMAP :
+                SUB_TEXT_PIXMAP);
+              item->data.num  = pixmap;
+              item->width     = geometry.width;
+              item->height    = geometry.height;
+
+              /* Add spacing and check if icon is first */
+              t->width += item->width + (0 == i ? 3 : 6);
+
+              item->color = color;
+            }
+          else ///< Ordinary text
+            {
+              item->data.string = strdup(tok);
+              item->width       = subSharedStringWidth(subtle->dpy, f, tok,
+                strlen(tok), &left, &right, False);
+
+              /* Remove left bearing from first text item */
+              t->width += item->width - (0 == i ? left : 0);
+
+              item->color = color;
+            }
+
+          i++;
+        }
+    }
+
+  /* Mark other items a clean */
+  for(; i < t->nitems; i++)
+    ITEM(t->items[i])->flags |= SUB_TEXT_EMPTY;
+
+  /* Fix spacing of last item */
+  if(item)
+    {
+      if(item->flags & (SUB_TEXT_BITMAP|SUB_TEXT_PIXMAP))
+        t->width -= 2;
+      else
+        {
+          t->width    -= right;
+          item->width -= right;
+        }
+    }
+
+  return t->width;
+} /* }}} */
+
+ /** subTextRender {{{
+  * @brief Render text on window at given position
+  * @param[inout]  t     A #SubText
+  * @param[inout]  f     A #SubFont
+  * @param[in]     gc    A #GC
+  * @param[in]     win   Window to draw on
+  * @param[in]     x     X position
+  * @param]in]     y     Y position
+  * @param[in]     fg    Foreground color
+  * @param[in]     icon  Icon color
+  * @param[in]     bg    Background color
+  **/
+
+void
+subTextRender(SubText *t,
+  SubFont *f,
+  GC gc,
+  Window win,
+  int x,
+  int y,
+  long fg,
+  long icon,
+  long bg)
+{
+  int i, width = x;
+
+  assert(t);
+
+  /* Render text items */
+  for(i = 0; i < t->nitems; i++)
+    {
+      SubTextItem *item = ITEM(t->items[i]);
+
+      if(item->flags & SUB_TEXT_EMPTY) ///< Empty text
+        {
+          break; ///< Break loop
+        }
+      else if(item->flags & (SUB_TEXT_BITMAP|SUB_TEXT_PIXMAP)) ///< Icons
+        {
+          int icony = 0, dx = (0 == i) ? 0 : 3; ///< Add spacing when icon isn't first
+
+          icony = item->height > f->height ?
+            y - f->y - ((item->height - f->height) / 2): y - item->height;
+
+          subSharedDrawIcon(subtle->dpy, gc, win, width + dx, icony,
+            item->width, item->height, (-1 == item->color) ? icon : item->color,
+            bg, (Pixmap)item->data.num, (item->flags & SUB_TEXT_BITMAP));
+
+          /* Add spacing when icon isn't last */
+          width += item->width + dx + (i != t->nitems - 1 ? 3 : 0);
+        }
+      else ///< Text
+        {
+          subSharedDrawString(subtle->dpy, gc, f, win, width, y,
+            (-1 == item->color) ? fg : item->color, bg, 
+            item->data.string, strlen(item->data.string));
+
+          width += item->width;
+        }
+    }
+} /* }}} */
+
+ /** subTextKill {{{
+  * @brief Delete text
+  * @param[in]  t  A #SubText
+  **/
+
+void
+subTextKill(SubText *t)
+{
+  int i;
+
+  assert(t);
+
+  for(i = 0; i < t->nitems; i++)
+    {
+      SubTextItem *item = (SubTextItem *)t->items[i];
+
+      if(!(item->flags & (SUB_TEXT_BITMAP|SUB_TEXT_PIXMAP)) &&
+          item->data.string)
+        free(item->data.string);
+
+      free(t->items[i]);
+    }
+
+  free(t->items);
+  free(t);
+} /* }}} */
+
+// vim:ts=2:bs=2:sw=2:et:fdm=marker