*
* 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
- * 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>
#include <ioncore/global.h>
#include <ioncore/common.h>
#include <ioncore/gr.h>
+#include <ioncore/gr-util.h>
#include "brush.h"
#include "font.h"
#include "private.h"
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)
-{
- DEColourGroup *cg=debrush_get_current_colour_group(brush);
- 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,
GrBorderLine 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;
+
+#define ISSET(S, A) ((S)!=NULL && gr_stylespec_isset(S, A))
+
+
+GR_DEFATTR(dragged);
+GR_DEFATTR(tagged);
+GR_DEFATTR(submenu);
+GR_DEFATTR(numbered);
+GR_DEFATTR(tabnumber);
+
+
+static void ensure_attrs()
+{
+ GR_ALLOCATTR_BEGIN;
+ GR_ALLOCATTR(dragged);
+ GR_ALLOCATTR(tagged);
+ GR_ALLOCATTR(submenu);
+ GR_ALLOCATTR(numbered);
+ GR_ALLOCATTR(tabnumber);
+ GR_ALLOCATTR_END;
+}
+
+
+static int get_ty(const WRectangle *g, const GrBorderWidths *bdw,
+ const GrFontExtents *fnte)
+{
+ return (g->y+bdw->top+fnte->baseline
+ +(g->h-bdw->top-bdw->bottom-fnte->max_height)/2);
+}
void debrush_tab_extras(DEBrush *brush, const WRectangle *g,
- DEColourGroup *cg, GrBorderWidths *bdw,
- GrFontExtents *fnte,
+ DEColourGroup *cg, const GrBorderWidths *bdw,
+ const GrFontExtents *fnte,
const GrStyleSpec *a1,
const GrStyleSpec *a2,
- bool pre)
+ bool pre, int index)
{
DEStyle *d=brush->d;
GC tmp;
*/
static bool swapped=FALSE;
- ENSURE_INITSPEC(dragged_spec, "dragged");
- ENSURE_INITSPEC(tagged_spec, "tagged");
+ ensure_attrs();
if(pre){
- if(!MATCHES2(dragged_spec, a1, a2))
- return;
-
- tmp=d->normal_gc;
- d->normal_gc=d->stipple_gc;
- d->stipple_gc=tmp;
- swapped=TRUE;
- XClearArea(ioncore_g.dpy, brush->win, g->x, g->y, g->w, g->h, False);
+ if(ISSET(a2, GR_ATTR(dragged)) || ISSET(a1, GR_ATTR(dragged))){
+ tmp=d->normal_gc;
+ d->normal_gc=d->stipple_gc;
+ d->stipple_gc=tmp;
+ swapped=TRUE;
+ XClearArea(ioncore_g.dpy, brush->win, g->x, g->y, g->w, g->h, False);
+ }
return;
}
- if(MATCHES2(tagged_spec, a1, a2)){
+
+ if((ISSET(a1, GR_ATTR(numbered)) || ISSET(a2, GR_ATTR(numbered)))
+ && index>=0){
+
+ DEColourGroup *cg;
+ GrStyleSpec tmp;
+
+ gr_stylespec_init(&tmp);
+ gr_stylespec_append(&tmp, a2);
+ gr_stylespec_set(&tmp, GR_ATTR(tabnumber));
+
+ cg=debrush_get_colour_group2(brush, a1, &tmp);
+
+ gr_stylespec_unalloc(&tmp);
+
+ if(cg!=NULL){
+ char *s=NULL;
+
+ libtu_asprintf(&s, "[%d]", index+1);
+
+ if(s!=NULL){
+ int l=strlen(s);
+ uint w=debrush_get_text_width(brush, s, l);
+ if(w < g->w-bdw->right-bdw->left){
+ int ty=get_ty(g, bdw, fnte);
+ int tx=(d->textalign==DEALIGN_RIGHT
+ ? g->x+bdw->left
+ : g->x+g->w-bdw->right-w);
+ debrush_do_draw_string(brush, tx, ty, s, l, TRUE, cg);
+ }
+ free(s);
+ }
+ }
+ }
+
+ if(ISSET(a2, GR_ATTR(tagged)) || ISSET(a1, GR_ATTR(tagged))){
XSetForeground(ioncore_g.dpy, d->copy_gc, cg->fg);
copy_masked(brush, d->tag_pixmap, brush->win, 0, 0,
g->x+g->w-bdw->right-d->tag_pixmap_w,
g->y+bdw->top);
}
-
+
if(swapped){
tmp=d->normal_gc;
d->normal_gc=d->stipple_gc;
void debrush_menuentry_extras(DEBrush *brush,
const WRectangle *g,
DEColourGroup *cg,
- GrBorderWidths *bdw,
- GrFontExtents *fnte,
+ const GrBorderWidths *bdw,
+ const GrFontExtents *fnte,
const GrStyleSpec *a1,
const GrStyleSpec *a2,
- bool pre)
+ bool pre, int index)
{
int tx, ty;
if(pre)
return;
- ENSURE_INITSPEC(submenu_spec, "submenu");
+ ensure_attrs();
- if(!MATCHES2(submenu_spec, a1, a2))
- return;
-
- ty=(g->y+bdw->top+fnte->baseline
- +(g->h-bdw->top-bdw->bottom-fnte->max_height)/2);
- tx=g->x+g->w-bdw->right;
+ if(ISSET(a2, GR_ATTR(submenu)) || ISSET(a1, GR_ATTR(submenu))){
+ ty=get_ty(g, bdw, fnte);
+ tx=g->x+g->w-bdw->right;
- debrush_do_draw_string(brush, tx, ty, DE_SUB_IND, DE_SUB_IND_LEN,
- FALSE, cg);
+ debrush_do_draw_string(brush, tx, ty, DE_SUB_IND, DE_SUB_IND_LEN,
+ FALSE, cg);
+ }
}
DEColourGroup *cg,
bool needfill,
const GrStyleSpec *a1,
- const GrStyleSpec *a2)
+ const GrStyleSpec *a2,
+ int index)
{
uint len;
GrBorderWidths bdw;
grbrush_get_font_extents(&(brush->grbrush), &fnte);
if(brush->extras_fn!=NULL)
- brush->extras_fn(brush, geom, cg, &bdw, &fnte, a1, a2, TRUE);
+ brush->extras_fn(brush, geom, cg, &bdw, &fnte, a1, a2, TRUE, index);
debrush_do_draw_box(brush, geom, cg, needfill);
tx=geom->x+bdw.left;
}
- ty=(geom->y+bdw.top+fnte.baseline
- +(geom->h-bdw.top-bdw.bottom-fnte.max_height)/2);
+ ty=get_ty(geom, &bdw, &fnte);
debrush_do_draw_string(brush, tx, ty, text, len, FALSE, cg);
}while(0);
if(brush->extras_fn!=NULL)
- brush->extras_fn(brush, geom, cg, &bdw, &fnte, a1, a2, FALSE);
+ brush->extras_fn(brush, geom, cg, &bdw, &fnte, a1, a2, FALSE, index);
}
if(cg!=NULL){
debrush_do_draw_textbox(brush, geom, text, cg, needfill,
- attr, NULL);
+ attr, NULL, -1);
}
}
if(cg!=NULL){
debrush_do_draw_textbox(brush, &g, elem[i].text, cg, needfill,
- common_attrib, &elem[i].attr);
+ common_attrib, &elem[i].attr, i);
}
if(i==n-1)