/*
* ion/de/draw.c
*
- * Copyright (c) Tuomo Valkonen 1999-2006.
+ * Copyright (c) Tuomo Valkonen 1999-2007.
*
* 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
static DEColourGroup *destyle_get_colour_group2(DEStyle *style,
- const char *attr_p1,
- const char *attr_p2)
+ const GrStyleSpec *a1,
+ const GrStyleSpec *a2)
{
int i, score, maxscore=0;
DEColourGroup *maxg=&(style->cgrp);
while(style!=NULL){
for(i=0; i<style->n_extra_cgrps; i++){
- score=gr_stylespec_score2(style->extra_cgrps[i].spec,
- attr_p1, attr_p2);
+ score=gr_stylespec_score2(&style->extra_cgrps[i].spec, a1, a2);
+
if(score>maxscore){
maxg=&(style->extra_cgrps[i]);
maxscore=score;
DEColourGroup *debrush_get_colour_group2(DEBrush *brush,
- const char *attr_p1,
- const char *attr_p2)
+ const GrStyleSpec *a1,
+ const GrStyleSpec *a2)
{
- return destyle_get_colour_group2(brush->d, attr_p1, attr_p2);
+ return destyle_get_colour_group2(brush->d, a1, a2);
}
-DEColourGroup *debrush_get_colour_group(DEBrush *brush, const char *attr)
+DEColourGroup *debrush_get_colour_group(DEBrush *brush, const GrStyleSpec *attr)
{
return destyle_get_colour_group2(brush->d, attr, NULL);
}
+DEColourGroup *debrush_get_current_colour_group(DEBrush *brush)
+{
+ return debrush_get_colour_group(brush, debrush_get_current_attr(brush));
+}
+
+
/*}}}*/
b=0;
for(i=0; i<br; i++){
- points[0].x=x+w-i; points[0].y=y+b;
- points[1].x=x+w-i; points[1].y=y+h-i;
+ points[0].x=x+w-i; points[0].y=y+b;
+ points[1].x=x+w-i; points[1].y=y+h-i;
points[2].x=x+a; points[2].y=y+h-i;
if(a<tl)
}
-void debrush_do_draw_border(DEBrush *brush, WRectangle geom,
- DEColourGroup *cg)
-{
- DEBorder *bd=&(brush->d->border);
- GC gc=brush->d->normal_gc;
- Window win=brush->win;
-
- switch(bd->style){
- case DEBORDER_RIDGE:
- draw_border(win, gc, &geom, bd->hl, bd->sh, cg->hl, cg->sh);
- case DEBORDER_INLAID:
- draw_border(win, gc, &geom, bd->pad, bd->pad, cg->pad, cg->pad);
- draw_border(win, gc, &geom, bd->sh, bd->hl, cg->sh, cg->hl);
- break;
- case DEBORDER_GROOVE:
- draw_border(win, gc, &geom, bd->sh, bd->hl, cg->sh, cg->hl);
- draw_border(win, gc, &geom, bd->pad, bd->pad, cg->pad, cg->pad);
- draw_border(win, gc, &geom, bd->hl, bd->sh, cg->hl, cg->sh);
- break;
- case DEBORDER_ELEVATED:
- default:
- draw_border(win, gc, &geom, bd->hl, bd->sh, cg->hl, cg->sh);
- draw_border(win, gc, &geom, bd->pad, bd->pad, cg->pad, cg->pad);
- break;
- }
-}
-
-
-void debrush_draw_border(DEBrush *brush,
- const WRectangle *geom,
- const char *attrib)
-{
- DEColourGroup *cg=debrush_get_colour_group(brush, attrib);
- if(cg!=NULL)
- debrush_do_draw_border(brush, *geom, cg);
-}
-
-
static void draw_borderline(Window win, GC gc, WRectangle *geom,
uint tl, uint br, DEColour tlc, DEColour brc,
GrBorderLine line)
{
- if(line==GR_BORDERLINE_LEFT && geom->h>0){
+ if(line==GR_BORDERLINE_LEFT && geom->h>0 && tl>0){
XSetForeground(ioncore_g.dpy, gc, tlc);
- XDrawRectangle(ioncore_g.dpy, win, gc, geom->x, geom->y, tl, geom->h);
+ XSetBackground(ioncore_g.dpy, gc, tlc);
+ XFillRectangle(ioncore_g.dpy, win, gc, geom->x, geom->y, tl, geom->h);
geom->x+=tl;
- }else if(line==GR_BORDERLINE_TOP && geom->w>0){
+ }else if(line==GR_BORDERLINE_TOP && geom->w>0 && tl>0){
XSetForeground(ioncore_g.dpy, gc, tlc);
- XDrawRectangle(ioncore_g.dpy, win, gc, geom->x, geom->y, geom->w, tl);
+ XSetBackground(ioncore_g.dpy, gc, tlc);
+ XFillRectangle(ioncore_g.dpy, win, gc, geom->x, geom->y, geom->w, tl);
geom->y+=tl;
- }else if(line==GR_BORDERLINE_RIGHT && geom->h>0){
+ }else if(line==GR_BORDERLINE_RIGHT && geom->h>0 && br>0){
XSetForeground(ioncore_g.dpy, gc, brc);
- XDrawRectangle(ioncore_g.dpy, win, gc, geom->x+geom->w-1-br, geom->y, br, geom->h);
+ XSetBackground(ioncore_g.dpy, gc, brc);
+ XFillRectangle(ioncore_g.dpy, win, gc, geom->x+geom->w-br, geom->y, br, geom->h);
geom->w-=br;
- }else if(line==GR_BORDERLINE_BOTTOM && geom->w>0){
+ }else if(line==GR_BORDERLINE_BOTTOM && geom->w>0 && br>0){
XSetForeground(ioncore_g.dpy, gc, brc);
- XDrawRectangle(ioncore_g.dpy, win, gc, geom->x, geom->y+geom->h-1-br, geom->w, br);
+ XSetBackground(ioncore_g.dpy, gc, brc);
+ XFillRectangle(ioncore_g.dpy, win, gc, geom->x, geom->y+geom->h-br, geom->w, br);
geom->h-=br;
}
}
}
+void debrush_do_draw_padline(DEBrush *brush, WRectangle geom,
+ DEColourGroup *cg, GrBorderLine line)
+{
+ DEBorder *bd=&(brush->d->border);
+ GC gc=brush->d->normal_gc;
+ Window win=brush->win;
+
+ draw_borderline(win, gc, &geom, bd->pad, bd->pad, cg->pad, cg->pad, line);
+}
+
+
void debrush_draw_borderline(DEBrush *brush, const WRectangle *geom,
- const char *attrib, GrBorderLine line)
+ GrBorderLine line)
{
- DEColourGroup *cg=debrush_get_colour_group(brush, attrib);
+ DEColourGroup *cg=debrush_get_current_colour_group(brush);
if(cg!=NULL)
debrush_do_draw_borderline(brush, *geom, cg, line);
}
+static void debrush_do_do_draw_border(DEBrush *brush, WRectangle geom,
+ DEColourGroup *cg)
+{
+ DEBorder *bd=&(brush->d->border);
+ GC gc=brush->d->normal_gc;
+ Window win=brush->win;
+
+ switch(bd->style){
+ case DEBORDER_RIDGE:
+ draw_border(win, gc, &geom, bd->hl, bd->sh, cg->hl, cg->sh);
+ case DEBORDER_INLAID:
+ draw_border(win, gc, &geom, bd->pad, bd->pad, cg->pad, cg->pad);
+ draw_border(win, gc, &geom, bd->sh, bd->hl, cg->sh, cg->hl);
+ break;
+ case DEBORDER_GROOVE:
+ draw_border(win, gc, &geom, bd->sh, bd->hl, cg->sh, cg->hl);
+ draw_border(win, gc, &geom, bd->pad, bd->pad, cg->pad, cg->pad);
+ draw_border(win, gc, &geom, bd->hl, bd->sh, cg->hl, cg->sh);
+ break;
+ case DEBORDER_ELEVATED:
+ default:
+ draw_border(win, gc, &geom, bd->hl, bd->sh, cg->hl, cg->sh);
+ draw_border(win, gc, &geom, bd->pad, bd->pad, cg->pad, cg->pad);
+ break;
+ }
+}
+
+
+void debrush_do_draw_border(DEBrush *brush, WRectangle geom,
+ DEColourGroup *cg)
+{
+ DEBorder *bd=&(brush->d->border);
+
+ switch(bd->sides){
+ case DEBORDER_ALL:
+ debrush_do_do_draw_border(brush, geom, cg);
+ break;
+ case DEBORDER_TB:
+ debrush_do_draw_padline(brush, geom, cg, GR_BORDERLINE_LEFT);
+ debrush_do_draw_padline(brush, geom, cg, GR_BORDERLINE_RIGHT);
+ debrush_do_draw_borderline(brush, geom, cg, GR_BORDERLINE_TOP);
+ debrush_do_draw_borderline(brush, geom, cg, GR_BORDERLINE_BOTTOM);
+ break;
+ case DEBORDER_LR:
+ debrush_do_draw_padline(brush, geom, cg, GR_BORDERLINE_TOP);
+ debrush_do_draw_padline(brush, geom, cg, GR_BORDERLINE_BOTTOM);
+ debrush_do_draw_borderline(brush, geom, cg, GR_BORDERLINE_LEFT);
+ debrush_do_draw_borderline(brush, geom, cg, GR_BORDERLINE_RIGHT);
+ break;
+ }
+}
+
+
+void debrush_draw_border(DEBrush *brush,
+ const WRectangle *geom)
+{
+ DEColourGroup *cg=debrush_get_current_colour_group(brush);
+ if(cg!=NULL)
+ debrush_do_draw_border(brush, *geom, cg);
+}
+
+
/*}}}*/
}
+static GrStyleSpec dragged_spec=GR_STYLESPEC_INIT;
+static GrStyleSpec tagged_spec=GR_STYLESPEC_INIT;
+static GrStyleSpec submenu_spec=GR_STYLESPEC_INIT;
+
+
void debrush_tab_extras(DEBrush *brush, const WRectangle *g,
DEColourGroup *cg, GrBorderWidths *bdw,
GrFontExtents *fnte,
- const char *a1, const char *a2,
+ const GrStyleSpec *a1,
+ const GrStyleSpec *a2,
bool pre)
{
DEStyle *d=brush->d;
* with shared GC:s.
*/
static bool swapped=FALSE;
+
+ ENSURE_INITSPEC(dragged_spec, "dragged");
+ ENSURE_INITSPEC(tagged_spec, "tagged");
if(pre){
- if(!MATCHES2("*-*-*-dragged", a1, a2))
+ if(!MATCHES2(dragged_spec, a1, a2))
return;
tmp=d->normal_gc;
return;
}
- if(MATCHES2("*-*-tagged", a1, a2)){
+ if(MATCHES2(tagged_spec, a1, a2)){
XSetForeground(ioncore_g.dpy, d->copy_gc, cg->fg);
copy_masked(brush, d->tag_pixmap, brush->win, 0, 0,
}
-void debrush_menuentry_extras(DEBrush *brush, const WRectangle *g,
- DEColourGroup *cg, GrBorderWidths *bdw,
+void debrush_menuentry_extras(DEBrush *brush,
+ const WRectangle *g,
+ DEColourGroup *cg,
+ GrBorderWidths *bdw,
GrFontExtents *fnte,
- const char *a1, const char *a2,
+ const GrStyleSpec *a1,
+ const GrStyleSpec *a2,
bool pre)
{
int tx, ty;
if(pre)
return;
- if(!MATCHES2("*-*-submenu", a1, a2))
+ ENSURE_INITSPEC(submenu_spec, "submenu");
+
+ if(!MATCHES2(submenu_spec, a1, a2))
return;
ty=(g->y+bdw->top+fnte->baseline
}
-static void debrush_do_draw_textbox(DEBrush *brush, const WRectangle *geom,
- const char *text, DEColourGroup *cg,
+static void debrush_do_draw_textbox(DEBrush *brush,
+ const WRectangle *geom,
+ const char *text,
+ DEColourGroup *cg,
bool needfill,
- const char *a1, const char *a2)
+ const GrStyleSpec *a1,
+ const GrStyleSpec *a2)
{
uint len;
GrBorderWidths bdw;
void debrush_draw_textbox(DEBrush *brush, const WRectangle *geom,
- const char *text, const char *attr,
- bool needfill)
+ const char *text, bool needfill)
{
+ GrStyleSpec *attr=debrush_get_current_attr(brush);
DEColourGroup *cg=debrush_get_colour_group(brush, attr);
+
if(cg!=NULL){
debrush_do_draw_textbox(brush, geom, text, cg, needfill,
attr, NULL);
void debrush_draw_textboxes(DEBrush *brush, const WRectangle *geom,
int n, const GrTextElem *elem,
- bool needfill, const char *common_attrib)
+ bool needfill)
{
+ GrStyleSpec *common_attrib;
WRectangle g=*geom;
DEColourGroup *cg;
GrBorderWidths bdw;
int i;
+ common_attrib=debrush_get_current_attr(brush);
+
grbrush_get_border_widths(&(brush->grbrush), &bdw);
- for(i=0; i<n; i++){
+ for(i=0; ; i++){
g.w=bdw.left+elem[i].iw+bdw.right;
- cg=debrush_get_colour_group2(brush, common_attrib, elem[i].attr);
+ cg=debrush_get_colour_group2(brush, common_attrib, &elem[i].attr);
if(cg!=NULL){
debrush_do_draw_textbox(brush, &g, elem[i].text, cg, needfill,
- common_attrib, elem[i].attr);
+ common_attrib, &elem[i].attr);
}
+ if(i==n-1)
+ break;
+
g.x+=g.w;
if(bdw.spacing>0 && needfill){
XClearArea(ioncore_g.dpy, brush->win, g.x, g.y,
}
-void debrush_fill_area(DEBrush *brush, const WRectangle *geom, const char *attr)
+void debrush_fill_area(DEBrush *brush, const WRectangle *geom)
{
- DEColourGroup *cg=debrush_get_colour_group(brush, attr);
+ DEColourGroup *cg=debrush_get_current_colour_group(brush);
GC gc=brush->d->normal_gc;
if(cg==NULL)
void debrush_begin(DEBrush *brush, const WRectangle *geom, int flags)
{
+
if(flags&GRBRUSH_AMEND)
flags|=GRBRUSH_NO_CLEAR_OK;
+ if(!(flags&GRBRUSH_KEEP_ATTR))
+ debrush_init_attr(brush, NULL);
+
if(!(flags&GRBRUSH_NO_CLEAR_OK))
debrush_clear_area(brush, geom);