]> git.decadent.org.uk Git - ion3.git/blobdiff - de/brush.c
Imported Upstream version 20090110
[ion3.git] / de / brush.c
index a0576a6b139145800cbb6b52dd87ab6dae1d92ed..c2b5a4f46b3570e064b251dc6b2bcaff9400f475 100644 (file)
@@ -1,12 +1,9 @@
 /*
  * ion/de/brush.c
  *
- * Copyright (c) Tuomo Valkonen 1999-2006
+ * Copyright (c) Tuomo Valkonen 1999-2009
  *
- * Ion is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
+ * See the included file LICENSE for details.
  */
 
 #include <string.h>
 /*{{{ Brush creation and releasing */
 
 
+#define MATCHES(S, A) (gr_stylespec_score(&(S), A)>0)
+#define MATCHES2(S, A1, A2) (gr_stylespec_score2(&(S), A1, A2)>0)
+
+#define ENSURE_INITSPEC(S, NM) \
+    if((S).attrs==NULL) gr_stylespec_load(&(S), NM);
+
+
+static GrStyleSpec tabframe_spec=GR_STYLESPEC_INIT;
+static GrStyleSpec tabinfo_spec=GR_STYLESPEC_INIT;
+static GrStyleSpec tabmenuentry_spec=GR_STYLESPEC_INIT;
+
+
 bool debrush_init(DEBrush *brush, Window win,
-                  const char *stylename, DEStyle *style)
+                  const GrStyleSpec *spec, DEStyle *style)
 {
+    GrStyleSpec tmp;
+    
     brush->d=style;
     brush->extras_fn=NULL;
     brush->indicator_w=0;
     brush->win=win;
     brush->clip_set=FALSE;
     
+    gr_stylespec_init(&brush->current_attr);
+    
     style->usecount++;
 
     if(!grbrush_init(&(brush->grbrush))){
@@ -45,11 +58,15 @@ bool debrush_init(DEBrush *brush, Window win,
         return FALSE;
     }
     
-    if(MATCHES("tab-frame", stylename) || MATCHES("tab-info", stylename)){
+    ENSURE_INITSPEC(tabframe_spec, "tab-frame");
+    ENSURE_INITSPEC(tabinfo_spec, "tab-info");
+    ENSURE_INITSPEC(tabmenuentry_spec, "tab-menuentry");
+    
+    if(MATCHES(tabframe_spec, spec) || MATCHES(tabinfo_spec, spec)){
         brush->extras_fn=debrush_tab_extras;
         if(!style->tabbrush_data_ok)
             destyle_create_tab_gcs(style);
-    }else if(MATCHES("tab-menuentry", stylename)){
+    }else if(MATCHES(tabmenuentry_spec, spec)){
         brush->extras_fn=debrush_menuentry_extras;
         brush->indicator_w=grbrush_get_text_width((GrBrush*)brush, 
                                                   DE_SUB_IND, 
@@ -60,22 +77,32 @@ bool debrush_init(DEBrush *brush, Window win,
 }
 
 
-DEBrush *create_debrush(Window win, const char *stylename, DEStyle *style)
+DEBrush *create_debrush(Window win, const GrStyleSpec *spec, DEStyle *style)
 {
-    CREATEOBJ_IMPL(DEBrush, debrush, (p, win, stylename, style));
+    CREATEOBJ_IMPL(DEBrush, debrush, (p, win, spec, style));
 }
 
 
 static DEBrush *do_get_brush(Window win, WRootWin *rootwin, 
                              const char *stylename, bool slave)
 {
-    DEStyle *style=de_get_style(rootwin, stylename);
+    DEStyle *style;
     DEBrush *brush;
+    GrStyleSpec spec;
+    
+    if(!gr_stylespec_load(&spec, stylename))
+        return NULL;
+    
+    style=de_get_style(rootwin, &spec);
     
-    if(style==NULL)
+    if(style==NULL){
+        gr_stylespec_unalloc(&spec);
         return NULL;
+    }
     
-    brush=create_debrush(win, stylename, style);
+    brush=create_debrush(win, &spec, style);
+
+    gr_stylespec_unalloc(&spec);
     
     /* Set background colour */
     if(brush!=NULL && !slave){
@@ -104,6 +131,7 @@ void debrush_deinit(DEBrush *brush)
 {
     destyle_unref(brush->d);
     brush->d=NULL;
+    gr_stylespec_unalloc(&brush->current_attr);
     grbrush_deinit(&(brush->grbrush));
 }
 
@@ -117,6 +145,40 @@ void debrush_release(DEBrush *brush)
 /*}}}*/
 
 
+/*{{{ Attributes */
+
+
+void debrush_init_attr(DEBrush *brush, const GrStyleSpec *spec)
+{
+    gr_stylespec_unalloc(&brush->current_attr);
+
+    if(spec!=NULL)
+        gr_stylespec_append(&brush->current_attr, spec);
+}
+
+    
+void debrush_set_attr(DEBrush *brush, GrAttr attr)
+{
+    gr_stylespec_set(&brush->current_attr, attr);
+}
+
+
+void debrush_unset_attr(DEBrush *brush, GrAttr attr)
+{
+    gr_stylespec_unset(&brush->current_attr, attr);
+}
+
+
+GrStyleSpec *debrush_get_current_attr(DEBrush *brush)
+{
+    return &brush->current_attr;
+}
+
+
+/*}}}*/
+
+
+
 /*{{{ Border widths and extra information */
 
 
@@ -124,31 +186,49 @@ void debrush_get_border_widths(DEBrush *brush, GrBorderWidths *bdw)
 {
     DEStyle *style=brush->d;
     DEBorder *bd=&(style->border);
-    uint tmp;
+    uint tmp=0;
+    uint tbf=1, lrf=1;
+    uint pad=bd->pad;
+    uint spc=style->spacing;
     
+    switch(bd->sides){
+    case DEBORDER_TB:
+        lrf=0;
+        break;
+    case DEBORDER_LR:
+        tbf=0;
+        break;
+    }
+    
+    /* Ridge/groove styles use 'padding' for the spacing between the
+     * 'highlight' and 'shadow' portions of the border, and 'spacing'
+     * between the border and contents. Inlaid style also uses 'spacing'
+     * between the contents and the border, and padding as its outer
+     * component. Elevated style does not use spacing.
+     */
     switch(bd->style){
     case DEBORDER_RIDGE:
     case DEBORDER_GROOVE:
-        tmp=bd->sh+bd->hl+bd->pad;
-        bdw->top=tmp; bdw->bottom=tmp; bdw->left=tmp; bdw->right=tmp;
+        tmp=bd->sh+bd->hl+pad;
+        bdw->top=tbf*tmp+spc; bdw->bottom=tbf*tmp+spc; 
+        bdw->left=lrf*tmp+spc; bdw->right=lrf*tmp+spc;
         break;
     case DEBORDER_INLAID:
-        tmp=bd->sh+bd->pad; bdw->top=tmp; bdw->left=tmp;
-        tmp=bd->hl+bd->pad; bdw->bottom=tmp; bdw->right=tmp;
+        tmp=bd->sh+pad; bdw->top=tbf*tmp+spc; bdw->left=lrf*tmp+spc;
+        tmp=bd->hl+pad; bdw->bottom=tbf*tmp+spc; bdw->right=lrf*tmp+spc;
         break;
     case DEBORDER_ELEVATED:
     default:
-        tmp=bd->hl+bd->pad; bdw->top=tmp; bdw->left=tmp;
-        tmp=bd->sh+bd->pad; bdw->bottom=tmp; bdw->right=tmp;
+        tmp=bd->hl; bdw->top=tbf*tmp+pad; bdw->left=lrf*tmp+pad;
+        tmp=bd->sh; bdw->bottom=tbf*tmp+pad; bdw->right=lrf*tmp+pad;
         break;
     }
     
+    bdw->right+=brush->indicator_w;
+
     bdw->tb_ileft=bdw->left;
     bdw->tb_iright=bdw->right;
     bdw->spacing=style->spacing;
-    
-    bdw->right+=brush->indicator_w;
-    bdw->tb_iright+=brush->indicator_w;
 }
 
 
@@ -156,7 +236,7 @@ bool debrush_get_extra(DEBrush *brush, const char *key, char type, void *data)
 {
     DEStyle *style=brush->d;
     while(style!=NULL){
-        if(extl_table_get(style->data_table, 's', type, key, data))
+        if(extl_table_get(style->extras_table, 's', type, key, data))
             return TRUE;
         style=style->based_on;
     }
@@ -190,6 +270,9 @@ static DynFunTab debrush_dynfuntab[]={
     {(DynFun*)grbrush_get_slave, (DynFun*)debrush_get_slave},
     {grbrush_begin, debrush_begin},
     {grbrush_end, debrush_end},
+    {grbrush_init_attr, debrush_init_attr},
+    {grbrush_set_attr, debrush_set_attr},
+    {grbrush_unset_attr, debrush_unset_attr},
     END_DYNFUNTAB
 };