Logo Search packages:      
Sourcecode: ion3 version File versions  Download package

statusbar.c

/*
 * ion/mod_statusbar/statusbar.c
 *
 * Copyright (c) Tuomo Valkonen 1999-2006. 
 *
 * 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.
 */

#include <string.h>

#include <libtu/objp.h>
#include <libtu/minmax.h>
#include <libtu/objlist.h>
#include <libtu/misc.h>
#include <ioncore/common.h>
#include <ioncore/global.h>
#include <ioncore/window.h>
#include <ioncore/binding.h>
#include <ioncore/regbind.h>
#include <ioncore/event.h>
#include <ioncore/resize.h>
#include <ioncore/gr.h>
#include <ioncore/names.h>
#include <ioncore/strings.h>
#include <ioncore/basicpholder.h>
#include <ioncore/sizehint.h>

#include "statusbar.h"
#include "main.h"
#include "draw.h"


static void statusbar_set_elems(WStatusBar *sb, ExtlTab t);
static void statusbar_free_elems(WStatusBar *sb);
static void statusbar_update_natural_size(WStatusBar *p);
static void statusbar_arrange_systray(WStatusBar *p);
static int statusbar_systray_x(WStatusBar *p);
static void statusbar_rearrange(WStatusBar *sb, bool rs);
static void do_calc_systray_w(WStatusBar *p, WSBElem *el);
static void statusbar_calc_systray_w(WStatusBar *p);


static WStatusBar *statusbars=NULL;


/*{{{ Init/deinit */


bool statusbar_init(WStatusBar *p, WWindow *parent, const WFitParams *fp)
{
    if(!window_init(&(p->wwin), parent, fp))
        return FALSE;

    region_register((WRegion*)p);

    p->brush=NULL;
    p->elems=NULL;
    p->nelems=0;
    p->natural_w=1;
    p->natural_h=1;
    p->filleridx=-1;
    p->sb_next=NULL;
    p->sb_prev=NULL;
    p->traywins=NULL;
    p->systray_enabled=TRUE;
    
    statusbar_updategr(p);

    if(p->brush==NULL){
        window_deinit(&(p->wwin));
        return FALSE;
    }
    
    window_select_input(&(p->wwin), IONCORE_EVENTMASK_NORMAL);

    region_add_bindmap((WRegion*)p, mod_statusbar_statusbar_bindmap);
    
    ((WRegion*)p)->flags|=REGION_SKIP_FOCUS;

    LINK_ITEM(statusbars, p, sb_next, sb_prev);
    
    return TRUE;
}



WStatusBar *create_statusbar(WWindow *parent, const WFitParams *fp)
{
    CREATEOBJ_IMPL(WStatusBar, statusbar, (p, parent, fp));
}


void statusbar_deinit(WStatusBar *p)
{
    UNLINK_ITEM(statusbars, p, sb_next, sb_prev);

    statusbar_free_elems(p);
    
    if(p->brush!=NULL){
        grbrush_release(p->brush);
        p->brush=NULL;
    }
    
    window_deinit(&(p->wwin));
}


/*}}}*/


/*{{{ Content stuff */

static void init_sbelem(WSBElem *el)
{
    el->type=WSBELEM_NONE;
    el->meter=NULL;
    el->text_w=0;
    el->text=NULL;
    el->max_w=0;
    el->tmpl=NULL;
    el->attr=NULL;
    el->stretch=0;
    el->align=WSBELEM_ALIGN_CENTER;
    el->zeropad=0;
    el->x=0;
    el->traywins=NULL;
}


static WSBElem *get_sbelems(ExtlTab t, int *nret, int *filleridxret)
{
    int i, n=extl_table_get_n(t);
    WSBElem *el;
    int systrayidx=-1;
    
    *nret=0;
    *filleridxret=-1;
    
    if(n<=0)
        return NULL;
    
    el=ALLOC_N(WSBElem, n); 
    
    if(el==NULL)
        return NULL;
    
    for(i=0; i<n; i++){
        ExtlTab tt;
        
        init_sbelem(&el[i]);

        if(extl_table_geti_t(t, i+1, &tt)){
            if(extl_table_gets_i(tt, "type", &(el[i].type))){
                if(el[i].type==WSBELEM_TEXT || el[i].type==WSBELEM_STRETCH){
                    extl_table_gets_s(tt, "text", &(el[i].text));
                }else if(el[i].type==WSBELEM_METER){
                    extl_table_gets_s(tt, "meter", &(el[i].meter));
                    extl_table_gets_s(tt, "tmpl", &(el[i].tmpl));
                    extl_table_gets_i(tt, "align", &(el[i].align));
                    extl_table_gets_i(tt, "zeropad", &(el[i].zeropad));
                    el[i].zeropad=maxof(el[i].zeropad, 0);
                }else if(el[i].type==WSBELEM_SYSTRAY){
                    extl_table_gets_s(tt, "meter", &(el[i].meter));
                    extl_table_gets_i(tt, "align", &(el[i].align));
                    if(el[i].meter==NULL || strcmp(el[i].meter, "systray")==0)
                        systrayidx=i;
                }else if(el[i].type==WSBELEM_FILLER){
                    *filleridxret=i;
                }
            }
            extl_unref_table(tt);
        }
    }
    
    if(systrayidx==-1){
        WSBElem *el2=REALLOC_N(el, WSBElem, n, n+1);
        if(el2!=NULL){
            el=el2;
            init_sbelem(&el[n]);
            el[n].type=WSBELEM_SYSTRAY;
            n++;
        }
    }
    
    *nret=n;
    
    return el;
}
    

static void free_sbelems(WSBElem *el, int n)
{
    int i;
    
    for(i=0; i<n; i++){
        if(el[i].text!=NULL)
            free(el[i].text);
        if(el[i].meter!=NULL)
            free(el[i].meter);
        if(el[i].tmpl!=NULL)
            free(el[i].tmpl);
        if(el[i].attr!=NULL)
            free(el[i].attr);
        if(el[i].traywins!=NULL)
            objlist_clear(&el[i].traywins);
    }
    
    free(el);
}


static void statusbar_set_elems(WStatusBar *sb, ExtlTab t)
{
    statusbar_free_elems(sb);
    
    sb->elems=get_sbelems(t, &(sb->nelems), &(sb->filleridx));
}


static void statusbar_free_elems(WStatusBar *sb)
{
    if(sb->elems!=NULL){
        free_sbelems(sb->elems, sb->nelems);
        sb->elems=NULL;
        sb->nelems=0;
        sb->filleridx=-1;
    }
}


/*}}}*/



/*{{{ Size stuff */


static void statusbar_resize(WStatusBar *p)
{
    int rqflags=REGION_RQGEOM_WEAK_X|REGION_RQGEOM_WEAK_Y;
    WRectangle g;
    
    g.w=p->natural_w;
    g.h=p->natural_h;
    g.x=REGION_GEOM(p).x;
    g.y=REGION_GEOM(p).y;

    if(g.w!=REGION_GEOM(p).w || g.h!=REGION_GEOM(p).h)
        region_rqgeom((WRegion*)p, rqflags, &g, NULL);
}


static void calc_elem_w(WStatusBar *p, WSBElem *el, GrBrush *brush)
{
    const char *str;

    if(el->type==WSBELEM_SYSTRAY){
        do_calc_systray_w(p, el);
        return;
    }
    
    if(brush==NULL){
        el->text_w=0;
        return;
    }
    
    if(el->type==WSBELEM_METER){
        str=(el->text!=NULL ? el->text : STATUSBAR_NX_STR);
        el->text_w=grbrush_get_text_width(brush, str, strlen(str));
        str=el->tmpl;
        el->max_w=maxof((str!=NULL
                         ? grbrush_get_text_width(brush, str, strlen(str))
                         : 0),
                        el->text_w);
    }else{
        str=el->text;
        el->text_w=(str!=NULL
                    ? grbrush_get_text_width(brush, str, strlen(str))
                    : 0);
        el->max_w=el->text_w;
    }
}


static void statusbar_calc_widths(WStatusBar *sb)
{
    int i;
    
    for(i=0; i<sb->nelems; i++)
        calc_elem_w(sb, &(sb->elems[i]), sb->brush);
}


static void statusbar_do_update_natural_size(WStatusBar *p)
{
    GrBorderWidths bdw;
    GrFontExtents fnte;
    WRegion *reg;
    ObjListIterTmp tmp;
    int totw=0, stmh=0;
    int i;

    if(p->brush==NULL){
        bdw.left=0; bdw.right=0;
        bdw.top=0; bdw.bottom=0;
        fnte.max_height=4;
    }else{
        grbrush_get_border_widths(p->brush, &bdw);
        grbrush_get_font_extents(p->brush, &fnte);
    }
    
    for(i=0; i<p->nelems; i++)
        totw+=p->elems[i].max_w;
        
    FOR_ALL_ON_OBJLIST(WRegion*, reg, p->traywins, tmp){
        stmh=maxof(stmh, REGION_GEOM(reg).h);
    }
    
    p->natural_w=bdw.left+totw+bdw.right;
    p->natural_h=maxof(stmh, fnte.max_height)+bdw.top+bdw.bottom;
}


void statusbar_size_hints(WStatusBar *p, XSizeHints *h)
{
    h->flags=PMaxSize|PMinSize;
    h->min_width=p->natural_w;
    h->min_height=p->natural_h;
    h->max_width=p->natural_w;
    h->max_height=p->natural_h;
}


/*}}}*/


/*{{{ Systray */


static WSBElem *statusbar_associate_systray(WStatusBar *sb, WRegion *reg)
{
    WClientWin *cwin=OBJ_CAST(reg, WClientWin);
    WSBElem *el=NULL, *fbel=NULL;
    char *name=NULL;
    int i;
    
    if(cwin!=NULL)
        extl_table_gets_s(cwin->proptab, "statusbar", &name);
    
    for(i=0; i<sb->nelems; i++){
        if(sb->elems[i].type!=WSBELEM_SYSTRAY)
            continue;
        if(sb->elems[i].meter==NULL){
            fbel=&sb->elems[i];
            continue;
        }
        if(name!=NULL && strcmp(sb->elems[i].meter, name)==0){
            el=&sb->elems[i];
            break;
        }
        if(strcmp(sb->elems[i].meter, "systray")==0)
            fbel=&sb->elems[i];
    }
    
    if(name!=NULL)
        free(name);
        
    if(el==NULL)
        el=fbel;
    
    if(fbel==NULL)
        return NULL;
    
    objlist_insert_last(&el->traywins, (Obj*)reg);
    
    return el;
}


static WSBElem *statusbar_unassociate_systray(WStatusBar *sb, WRegion *reg)
{
    int i;
    
    for(i=0; i<sb->nelems; i++){
        if(objlist_remove(&(sb->elems[i].traywins), (Obj*)reg))
            return &sb->elems[i];
    }
    
    return NULL;
}

    

static void do_calc_systray_w(WStatusBar *p, WSBElem *el)
{
    WRegion *reg;
    ObjListIterTmp tmp;
    int padding=0;
    int w=-padding;
    
    FOR_ALL_ON_OBJLIST(WRegion*, reg, el->traywins, tmp){
        w=w+REGION_GEOM(reg).w+padding;
    }
    
    el->text_w=maxof(0, w);
    el->max_w=el->text_w; /* for now */
}


static void statusbar_calc_systray_w(WStatusBar *p)
{
    int i;
    
    for(i=0; i<p->nelems; i++){
        if(p->elems[i].type==WSBELEM_SYSTRAY)
            do_calc_systray_w(p, &p->elems[i]);
    }
}


static void statusbar_arrange_systray(WStatusBar *p)
{
    WRegion *reg;
    ObjListIterTmp tmp;
    GrBorderWidths bdw;
    int padding=0, ymiddle;
    int i, x;
    
    if(p->brush!=NULL){
        grbrush_get_border_widths(p->brush, &bdw);
    }else{
        bdw.top=0;
        bdw.bottom=0;
    }
    
    ymiddle=bdw.top+(REGION_GEOM(p).h-bdw.top-bdw.bottom)/2;
    
    for(i=0; i<p->nelems; i++){
        WSBElem *el=&p->elems[i];
        if(el->type!=WSBELEM_SYSTRAY)
            continue;
        x=el->x;
        FOR_ALL_ON_OBJLIST(WRegion*, reg, el->traywins, tmp){
            WRectangle g=REGION_GEOM(reg);
            g.x=x;
            g.y=ymiddle-g.h/2;
            region_fit(reg, &g, REGION_FIT_EXACT);
            x=x+g.w+padding;
        }
    }
}


static void systray_adjust_size(WRegion *reg, WRectangle *g)
{
    XSizeHints hints;
    
    region_size_hints(reg, &hints);

    g->h=CF_STATUSBAR_SYSTRAY_HEIGHT;
    
    xsizehints_correct(&hints, &g->w, &g->h, TRUE);
}



static WRegion *statusbar_attach_simple(WStatusBar *sb,
                                        WRegionAttachHandler *handler,
                                        void *handlerparams)
{
    WRegion *reg;
    WFitParams fp;
    WSBElem *el;
    
    fp.g.x=0;
    fp.g.y=0;
    fp.mode=REGION_FIT_WHATEVER|REGION_FIT_BOUNDS;

    reg=handler((WWindow*)sb, &fp, handlerparams);
    
    if(reg==NULL)
        return NULL;
    
    if(!objlist_insert_last(&sb->traywins, (Obj*)reg)){
        /* TODO: failure handling */
        return NULL;
    }
    
    el=statusbar_associate_systray(sb, reg);
    if(el==NULL){
        /* TODO: failure handling */
        objlist_remove(&sb->traywins, (Obj*)reg);
        return NULL;
    }

    fp.g=REGION_GEOM(reg);
    fp.mode=REGION_FIT_EXACT;
    systray_adjust_size(reg, &fp.g);
    
    region_fitrep(reg, NULL, &fp);
    
    do_calc_systray_w(sb, el);

    region_set_manager(reg, (WRegion*)sb);
    
    statusbar_rearrange(sb, TRUE);
    
    if(REGION_IS_MAPPED(sb))
        region_map(reg);
    
    return reg;
}


static WPHolder *statusbar_prepare_manage(WStatusBar *sb, 
                                          const WClientWin *cwin,
                                          const WManageParams *param,
                                          int redir)
{
    if(redir==MANAGE_REDIR_STRICT_YES)
        return NULL;
    
    return (WPHolder*)create_basicpholder((WRegion*)sb, 
                                          ((WRegionDoAttachFnSimple*)
                                           statusbar_attach_simple));
}


static void statusbar_managed_remove(WStatusBar *sb, WRegion *reg)
{
    WSBElem *el;
        
    objlist_remove(&sb->traywins, (Obj*)reg);
    region_unset_manager(reg, (WRegion*)sb);
    
    el=statusbar_unassociate_systray(sb, reg);
    if(el!=NULL && ioncore_g.opmode!=IONCORE_OPMODE_DEINIT){
        do_calc_systray_w(sb, el);
        statusbar_rearrange(sb, TRUE);
    }
}


static void statusbar_managed_rqgeom(WStatusBar *sb, WRegion *reg, int flags,
                                     const WRectangle *geom, 
                                     WRectangle *geomret)
{
    WRectangle g;
    
    g.x=REGION_GEOM(reg).x;
    g.y=REGION_GEOM(reg).y;
    g.w=geom->w;
    g.h=geom->h;

    systray_adjust_size(reg, &g);

    if(flags&REGION_RQGEOM_TRYONLY){
        if(geomret!=NULL)
            *geomret=g;
        return;
    }
    
    region_fit(reg, &g, REGION_FIT_EXACT);
    
    statusbar_calc_systray_w(sb);
    statusbar_rearrange(sb, TRUE);
    
    if(geomret!=NULL)
        *geomret=REGION_GEOM(reg);
    
}


void statusbar_map(WStatusBar *sb)
{
    WRegion *reg;
    ObjListIterTmp tmp;
    
    window_map((WWindow*)sb);
    
    FOR_ALL_ON_OBJLIST(WRegion*, reg, sb->traywins, tmp)
        region_map(reg);
}


void statusbar_unmap(WStatusBar *sb)
{
    WRegion *reg;
    ObjListIterTmp tmp;
    
    window_unmap((WWindow*)sb);
    
    FOR_ALL_ON_OBJLIST(WRegion*, reg, sb->traywins, tmp)
        region_unmap(reg);
}


bool statusbar_fitrep(WStatusBar *sb, WWindow *par, const WFitParams *fp)
{
    bool wchg=(REGION_GEOM(sb).w!=fp->g.w);
    bool hchg=(REGION_GEOM(sb).h!=fp->g.h);
    
    window_do_fitrep(&(sb->wwin), par, &(fp->g));
    
    if(wchg || hchg){
        statusbar_calculate_xs(sb);
        statusbar_arrange_systray(sb);
        statusbar_draw(sb, TRUE);
    }
    
    return TRUE;
}


WPHolder *statusbar_prepare_manage_transient(WStatusBar *sb, 
                                             const WClientWin *cwin,
                                             const WManageParams *param,
                                             int unused)
{
    WRegion *mgr=REGION_MANAGER(sb);
    
    if(mgr==NULL)
        mgr=(WRegion*)region_screen_of((WRegion*)sb);
    
    if(mgr!=NULL)
        return region_prepare_manage(mgr, cwin, param, 
                                     MANAGE_REDIR_PREFER_NO);
    else
        return NULL;
}

    

/*}}}*/


/*{{{ Exports */


static ExtlFn parse_template_fn;
static bool parse_template_fn_set=FALSE;


EXTL_EXPORT
void mod_statusbar__set_template_parser(ExtlFn fn)
{
    if(parse_template_fn_set)
        extl_unref_fn(parse_template_fn);
    parse_template_fn=extl_ref_fn(fn);
    parse_template_fn_set=TRUE;
}


/*EXTL_DOC
 * Set statusbar template.
 */
EXTL_EXPORT_MEMBER
void statusbar_set_template(WStatusBar *sb, const char *tmpl)
{
    ExtlTab t=extl_table_none();
    bool ok=FALSE;
    
    if(parse_template_fn_set){
        extl_protect(NULL);
        ok=extl_call(parse_template_fn, "s", "t", tmpl, &t);
        extl_unprotect(NULL);
    }

    if(ok)
        statusbar_set_template_table(sb, t);
}


/*EXTL_DOC
 * Set statusbar template as table.
 */
EXTL_EXPORT_MEMBER
void statusbar_set_template_table(WStatusBar *sb, ExtlTab t)
{
    WRegion *reg;
    ObjListIterTmp tmp;
    
    statusbar_set_elems(sb, t);

    FOR_ALL_ON_OBJLIST(WRegion*, reg, sb->traywins, tmp){
        statusbar_associate_systray(sb, reg);
    }
    
    statusbar_calc_widths(sb);
    statusbar_rearrange(sb, FALSE);
}


/*EXTL_DOC
 * Get statusbar template as table.
 */
EXTL_EXPORT_MEMBER
ExtlTab statusbar_get_template_table(WStatusBar *sb)
{
    int count = sb->nelems;
    int i;

    ExtlTab t = extl_create_table();

    for(i=0; i<count; i++){
        ExtlTab tt = extl_create_table();
        
        extl_table_sets_i(tt, "type", sb->elems[i].type);
        extl_table_sets_s(tt, "text", sb->elems[i].text);
        extl_table_sets_s(tt, "meter", sb->elems[i].meter);
        extl_table_sets_s(tt, "tmpl", sb->elems[i].tmpl);
        extl_table_sets_i(tt, "align", sb->elems[i].align);
        extl_table_sets_i(tt, "zeropad", sb->elems[i].zeropad);

        extl_table_seti_t(t, (i+1), tt);
        extl_unref_table(tt);
    }

    return t;
}


static void reset_stretch(WStatusBar *sb)
{
    int i;
    
    for(i=0; i<sb->nelems; i++)
        sb->elems[i].stretch=0;
}


static void positive_stretch(WStatusBar *sb)
{
    int i;
    
    for(i=0; i<sb->nelems; i++)
        sb->elems[i].stretch=maxof(0, sb->elems[i].stretch);
}


static void spread_stretch(WStatusBar *sb)
{
    int i, j, k;
    int diff;
    WSBElem *el, *lel, *rel;
    const char *str;
    
    for(i=0; i<sb->nelems; i++){
        el=&(sb->elems[i]);

        if(el->type!=WSBELEM_METER && el->type!=WSBELEM_SYSTRAY)
            continue;
        
        diff=el->max_w-el->text_w;
        
        lel=NULL;
        rel=NULL;
        
        if(el->align!=WSBELEM_ALIGN_RIGHT){
            for(j=i+1; j<sb->nelems; j++){
                if(sb->elems[j].type==WSBELEM_STRETCH){
                    rel=&(sb->elems[j]);
                    break;
                }
            }
        }
        
        if(el->align!=WSBELEM_ALIGN_LEFT){
            for(k=i-1; k>=0; k--){
                if(sb->elems[k].type==WSBELEM_STRETCH){
                    lel=&(sb->elems[k]);
                    break;
                }
            }
        }
        
        if(rel!=NULL && lel!=NULL){
            int l=diff/2;
            int r=diff-l;
            lel->stretch+=l;
            rel->stretch+=r;
        }else if(lel!=NULL){
            lel->stretch+=diff;
        }else if(rel!=NULL){
            rel->stretch+=diff;
        }
    }
}


static void statusbar_rearrange(WStatusBar *sb, bool rs)
{
    if(rs){
        statusbar_do_update_natural_size(sb);
        statusbar_resize(sb);
    }

    reset_stretch(sb);
    spread_stretch(sb);
    positive_stretch(sb);
    statusbar_calculate_xs(sb);
    
    if(rs)
        statusbar_arrange_systray(sb);
}



/*EXTL_DOC
 * Set statusbar template.
 */
EXTL_EXPORT_MEMBER
void statusbar_update(WStatusBar *sb, ExtlTab t)
{
    int i;
    WSBElem *el;
    bool grow=FALSE;
    
    if(sb->brush==NULL)
        return;
    
    for(i=0; i<sb->nelems; i++){
        el=&(sb->elems[i]);
        
        if(el->type!=WSBELEM_METER)
            continue;
        
        if(el->text!=NULL){
            free(el->text);
            el->text=NULL;
        }

        if(el->attr!=NULL){
            free(el->attr);
            el->attr=NULL;
        }
        
        if(el->meter!=NULL){
            const char *str;
            char *attrnm;
            
            extl_table_gets_s(t, el->meter, &(el->text));
            
            if(el->text==NULL){
                str=STATUSBAR_NX_STR;
            }else{
                /* Zero-pad */
                int l=strlen(el->text);
                int ml=str_len(el->text);
                int diff=el->zeropad-ml;
                if(diff>0){
                    char *tmp=ALLOC_N(char, l+diff+1);
                    if(tmp!=NULL){
                        memset(tmp, '0', diff);
                        memcpy(tmp+diff, el->text, l+1);
                        free(el->text);
                        el->text=tmp;
                    }
                }
                str=el->text;
            }
            
            el->text_w=grbrush_get_text_width(sb->brush, str, strlen(str));
            
            if(el->text_w>el->max_w){
                el->max_w=el->text_w;
                grow=TRUE;
            }
            
            attrnm=scat(el->meter, "_hint");
            if(attrnm!=NULL){
                extl_table_gets_s(t, attrnm, &(el->attr));
                free(attrnm);
            }
        }
    }

    statusbar_rearrange(sb, grow);
    
    window_draw((WWindow*)sb, FALSE);
}


/*}}}*/


/*{{{ Updategr */


void statusbar_updategr(WStatusBar *p)
{
    GrBrush *nbrush;
    
    nbrush=gr_get_brush(p->wwin.win, region_rootwin_of((WRegion*)p),
                        "stdisp-statusbar");
    if(nbrush==NULL)
        return;
    
    if(p->brush!=NULL)
        grbrush_release(p->brush);
    
    p->brush=nbrush;

    statusbar_calc_widths(p);
    statusbar_rearrange(p, TRUE);
    
    window_draw(&(p->wwin), TRUE);
}


/*}}}*/


/*{{{ Misc */


int statusbar_orientation(WStatusBar *sb)
{
    return REGION_ORIENTATION_HORIZONTAL;
}


/*EXTL_DOC
 * Returns a list of all statusbars.
 */
EXTL_EXPORT
ExtlTab mod_statusbar_statusbars()
{
    ExtlTab t=extl_create_table();
    WStatusBar *sb;
    int i=1;
    
    for(sb=statusbars; sb!=NULL; sb=sb->sb_next){
        extl_table_seti_o(t, i, (Obj*)sb);
    }
    
    return t;
}


WStatusBar *mod_statusbar_find_suitable(WClientWin *cwin,
                                        const WManageParams *param)
{
    WStatusBar *sb;

    for(sb=statusbars; sb!=NULL; sb=sb->sb_next){
        /*if(!sb->is_auto)
            continue;*/
        if(!sb->systray_enabled)
            continue;
        if(!region_same_rootwin((WRegion*)sb, (WRegion*)cwin))
            continue;
        break;
    }

    return sb;
}


bool statusbar_set_systray(WStatusBar *sb, int sp)
{
    bool set=sb->systray_enabled;
    bool nset=libtu_do_setparam(sp, set);
    
    sb->systray_enabled=nset;
    
    return nset;
}


/*EXTL_DOC
 * Enable or disable use of \var{sb} as systray.
 * The parameter \var{how} can be one of (set/unset/toggle). 
 * Resulting state is returned.
 */
EXTL_EXPORT_AS(WStatusBar, set_systray)
bool statusbar_set_systray_extl(WStatusBar *sb, const char *how)
{
    return statusbar_set_systray(sb, libtu_string_to_setparam(how));
}


/*EXTL_DOC
 * Is \var{sb} used as a systray?
 */
EXTL_EXPORT_MEMBER
bool statusbar_is_systray_extl(WStatusBar *sb)
{
    return sb->systray_enabled;
}


/*}}}*/


/*{{{ Load */


WRegion *statusbar_load(WWindow *par, const WFitParams *fp, ExtlTab tab)
{
    WStatusBar *sb=create_statusbar(par, fp);

    if(sb!=NULL){
        char *tmpl=NULL;
        ExtlTab t=extl_table_none();
        if(extl_table_gets_s(tab, "template", &tmpl)){
            statusbar_set_template(sb, tmpl);
            free(tmpl);
        }else if(extl_table_gets_t(tab, "template_table", &t)){
            statusbar_set_template_table(sb, t);
            extl_unref_table(t);
        }else{
            const char *tmpl=TR("[ %date || load: %load ] %filler%systray");
            statusbar_set_template(sb, tmpl);
        }
        
        extl_table_gets_b(tab, "systray", &sb->systray_enabled);
    }
    
    return (WRegion*)sb;
}


/*}}}*/


/*{{{ Dynamic function table and class implementation */


static DynFunTab statusbar_dynfuntab[]={
    {window_draw, statusbar_draw},
    {region_updategr, statusbar_updategr},
    {region_size_hints, statusbar_size_hints},
    {(DynFun*)region_orientation, (DynFun*)statusbar_orientation},

    {region_managed_rqgeom, statusbar_managed_rqgeom},
    {(DynFun*)region_prepare_manage, (DynFun*)statusbar_prepare_manage},
    {region_managed_remove, statusbar_managed_remove},
    
    {(DynFun*)region_prepare_manage_transient, 
     (DynFun*)statusbar_prepare_manage_transient},
    
    {region_map, statusbar_map},
    {region_unmap, statusbar_unmap},
    
    {(DynFun*)region_fitrep,
     (DynFun*)statusbar_fitrep},
    
    END_DYNFUNTAB
};


EXTL_EXPORT
IMPLCLASS(WStatusBar, WWindow, statusbar_deinit, statusbar_dynfuntab);

    
/*}}}*/


Generated by  Doxygen 1.6.0   Back to index