2 * ion/mod_statusbar/statusbar.c
4 * Copyright (c) Tuomo Valkonen 1999-2009.
6 * See the included file LICENSE for details.
12 #include <libtu/objp.h>
13 #include <libtu/minmax.h>
14 #include <libtu/ptrlist.h>
15 #include <libtu/misc.h>
16 #include <ioncore/common.h>
17 #include <ioncore/global.h>
18 #include <ioncore/window.h>
19 #include <ioncore/binding.h>
20 #include <ioncore/regbind.h>
21 #include <ioncore/event.h>
22 #include <ioncore/resize.h>
23 #include <ioncore/gr.h>
24 #include <ioncore/gr-util.h>
25 #include <ioncore/names.h>
26 #include <ioncore/strings.h>
27 #include <ioncore/basicpholder.h>
28 #include <ioncore/sizehint.h>
30 #include "statusbar.h"
35 static void statusbar_set_elems(WStatusBar
*sb
, ExtlTab t
);
36 static void statusbar_free_elems(WStatusBar
*sb
);
37 static void statusbar_update_natural_size(WStatusBar
*p
);
38 static void statusbar_arrange_systray(WStatusBar
*p
);
39 static int statusbar_systray_x(WStatusBar
*p
);
40 static void statusbar_rearrange(WStatusBar
*sb
, bool rs
);
41 static void do_calc_systray_w(WStatusBar
*p
, WSBElem
*el
);
42 static void statusbar_calc_systray_w(WStatusBar
*p
);
44 static WStatusBar
*statusbars
=NULL
;
50 bool statusbar_init(WStatusBar
*p
, WWindow
*parent
, const WFitParams
*fp
)
52 if(!window_init(&(p
->wwin
), parent
, fp
, "WStatusBar"))
64 p
->systray_enabled
=TRUE
;
66 statusbar_updategr(p
);
69 window_deinit(&(p
->wwin
));
73 window_select_input(&(p
->wwin
), IONCORE_EVENTMASK_NORMAL
);
75 region_register((WRegion
*)p
);
77 region_add_bindmap((WRegion
*)p
, mod_statusbar_statusbar_bindmap
);
79 LINK_ITEM(statusbars
, p
, sb_next
, sb_prev
);
86 WStatusBar
*create_statusbar(WWindow
*parent
, const WFitParams
*fp
)
88 CREATEOBJ_IMPL(WStatusBar
, statusbar
, (p
, parent
, fp
));
92 void statusbar_deinit(WStatusBar
*p
)
94 UNLINK_ITEM(statusbars
, p
, sb_next
, sb_prev
);
96 statusbar_free_elems(p
);
99 grbrush_release(p
->brush
);
103 window_deinit(&(p
->wwin
));
110 /*{{{ Content stuff */
113 static void init_sbelem(WSBElem
*el
)
115 el
->type
=WSBELEM_NONE
;
120 el
->meter
=STRINGID_NONE
;
121 el
->attr
=STRINGID_NONE
;
123 el
->align
=WSBELEM_ALIGN_CENTER
;
130 static bool gets_stringstore(ExtlTab t
, const char *str
, StringId
*id
)
134 if(extl_table_gets_s(t
, str
, &s
)){
135 *id
=stringstore_alloc(s
);
137 return (*id
!=STRINGID_NONE
);
144 static WSBElem
*get_sbelems(ExtlTab t
, int *nret
, int *filleridxret
)
146 int i
, n
=extl_table_get_n(t
);
156 el
=ALLOC_N(WSBElem
, n
);
166 if(extl_table_geti_t(t
, i
+1, &tt
)){
167 if(extl_table_gets_i(tt
, "type", &(el
[i
].type
))){
168 if(el
[i
].type
==WSBELEM_TEXT
|| el
[i
].type
==WSBELEM_STRETCH
){
169 extl_table_gets_s(tt
, "text", &(el
[i
].text
));
170 }else if(el
[i
].type
==WSBELEM_METER
){
171 gets_stringstore(tt
, "meter", &(el
[i
].meter
));
172 extl_table_gets_s(tt
, "tmpl", &(el
[i
].tmpl
));
173 extl_table_gets_i(tt
, "align", &(el
[i
].align
));
174 extl_table_gets_i(tt
, "zeropad", &(el
[i
].zeropad
));
175 el
[i
].zeropad
=maxof(el
[i
].zeropad
, 0);
176 }else if(el
[i
].type
==WSBELEM_SYSTRAY
){
179 gets_stringstore(tt
, "meter", &(el
[i
].meter
));
180 extl_table_gets_i(tt
, "align", &(el
[i
].align
));
182 tmp
=stringstore_get(el
[i
].meter
);
184 if(tmp
==NULL
|| strcmp(tmp
, "systray")==0)
186 }else if(el
[i
].type
==WSBELEM_FILLER
){
190 extl_unref_table(tt
);
195 WSBElem
*el2
=REALLOC_N(el
, WSBElem
, n
, n
+1);
199 el
[n
].type
=WSBELEM_SYSTRAY
;
210 static void free_sbelems(WSBElem
*el
, int n
)
219 if(el
[i
].meter
!=STRINGID_NONE
)
220 stringstore_free(el
[i
].meter
);
221 if(el
[i
].attr
!=STRINGID_NONE
)
222 stringstore_free(el
[i
].attr
);
223 if(el
[i
].traywins
!=NULL
)
224 ptrlist_clear(&el
[i
].traywins
);
231 static void statusbar_set_elems(WStatusBar
*sb
, ExtlTab t
)
233 statusbar_free_elems(sb
);
235 sb
->elems
=get_sbelems(t
, &(sb
->nelems
), &(sb
->filleridx
));
239 static void statusbar_free_elems(WStatusBar
*sb
)
242 free_sbelems(sb
->elems
, sb
->nelems
);
257 static void statusbar_resize(WStatusBar
*p
)
259 WRQGeomParams rq
=RQGEOMPARAMS_INIT
;
261 rq
.flags
=REGION_RQGEOM_WEAK_X
|REGION_RQGEOM_WEAK_Y
;
263 rq
.geom
.w
=p
->natural_w
;
264 rq
.geom
.h
=p
->natural_h
;
265 rq
.geom
.x
=REGION_GEOM(p
).x
;
266 rq
.geom
.y
=REGION_GEOM(p
).y
;
268 if(rectangle_compare(&rq
.geom
, ®ION_GEOM(p
))!=RECTANGLE_SAME
)
269 region_rqgeom((WRegion
*)p
, &rq
, NULL
);
273 static void calc_elem_w(WStatusBar
*p
, WSBElem
*el
, GrBrush
*brush
)
277 if(el
->type
==WSBELEM_SYSTRAY
){
278 do_calc_systray_w(p
, el
);
287 if(el
->type
==WSBELEM_METER
){
288 str
=(el
->text
!=NULL
? el
->text
: STATUSBAR_NX_STR
);
289 el
->text_w
=grbrush_get_text_width(brush
, str
, strlen(str
));
291 el
->max_w
=maxof((str
!=NULL
292 ? grbrush_get_text_width(brush
, str
, strlen(str
))
297 el
->text_w
=(str
!=NULL
298 ? grbrush_get_text_width(brush
, str
, strlen(str
))
300 el
->max_w
=el
->text_w
;
305 static void statusbar_calc_widths(WStatusBar
*sb
)
309 for(i
=0; i
<sb
->nelems
; i
++)
310 calc_elem_w(sb
, &(sb
->elems
[i
]), sb
->brush
);
314 static void statusbar_do_update_natural_size(WStatusBar
*p
)
324 bdw
.left
=0; bdw
.right
=0;
325 bdw
.top
=0; bdw
.bottom
=0;
328 grbrush_get_border_widths(p
->brush
, &bdw
);
329 grbrush_get_font_extents(p
->brush
, &fnte
);
332 for(i
=0; i
<p
->nelems
; i
++)
333 totw
+=p
->elems
[i
].max_w
;
335 FOR_ALL_ON_PTRLIST(WRegion
*, reg
, p
->traywins
, tmp
){
336 stmh
=maxof(stmh
, REGION_GEOM(reg
).h
);
339 p
->natural_w
=bdw
.left
+totw
+bdw
.right
;
340 p
->natural_h
=maxof(stmh
, fnte
.max_height
)+bdw
.top
+bdw
.bottom
;
344 void statusbar_size_hints(WStatusBar
*p
, WSizeHints
*h
)
347 h
->min_width
=p
->natural_w
;
348 h
->min_height
=p
->natural_h
;
351 h
->max_width
=INT_MAX
;/*p->natural_w;*/
352 h
->max_height
=p
->natural_h
;
362 static WSBElem
*statusbar_associate_systray(WStatusBar
*sb
, WRegion
*reg
)
364 WClientWin
*cwin
=OBJ_CAST(reg
, WClientWin
);
365 WSBElem
*el
=NULL
, *fbel
=NULL
;
370 extl_table_gets_s(cwin
->proptab
, "statusbar", &name
);
372 for(i
=0; i
<sb
->nelems
; i
++){
375 if(sb
->elems
[i
].type
!=WSBELEM_SYSTRAY
)
378 meter
=stringstore_get(sb
->elems
[i
].meter
);
384 if(name
!=NULL
&& strcmp(meter
, name
)==0){
388 if(strcmp(meter
, "systray")==0)
401 ptrlist_insert_last(&el
->traywins
, (Obj
*)reg
);
407 static WSBElem
*statusbar_unassociate_systray(WStatusBar
*sb
, WRegion
*reg
)
411 for(i
=0; i
<sb
->nelems
; i
++){
412 if(ptrlist_remove(&(sb
->elems
[i
].traywins
), (Obj
*)reg
))
413 return &sb
->elems
[i
];
421 static void do_calc_systray_w(WStatusBar
*p
, WSBElem
*el
)
428 FOR_ALL_ON_PTRLIST(WRegion
*, reg
, el
->traywins
, tmp
){
429 w
=w
+REGION_GEOM(reg
).w
+padding
;
432 el
->text_w
=maxof(0, w
);
433 el
->max_w
=el
->text_w
; /* for now */
437 static void statusbar_calc_systray_w(WStatusBar
*p
)
441 for(i
=0; i
<p
->nelems
; i
++){
442 if(p
->elems
[i
].type
==WSBELEM_SYSTRAY
)
443 do_calc_systray_w(p
, &p
->elems
[i
]);
448 static void statusbar_arrange_systray(WStatusBar
*p
)
453 int padding
=0, ymiddle
;
457 grbrush_get_border_widths(p
->brush
, &bdw
);
463 ymiddle
=bdw
.top
+(REGION_GEOM(p
).h
-bdw
.top
-bdw
.bottom
)/2;
465 for(i
=0; i
<p
->nelems
; i
++){
466 WSBElem
*el
=&p
->elems
[i
];
467 if(el
->type
!=WSBELEM_SYSTRAY
)
470 FOR_ALL_ON_PTRLIST(WRegion
*, reg
, el
->traywins
, tmp
){
471 WRectangle g
=REGION_GEOM(reg
);
474 region_fit(reg
, &g
, REGION_FIT_EXACT
);
481 static void systray_adjust_size(WRegion
*reg
, WRectangle
*g
)
483 g
->h
=CF_STATUSBAR_SYSTRAY_HEIGHT
;
485 region_size_hints_correct(reg
, &g
->w
, &g
->h
, TRUE
);
490 static WRegion
*statusbar_do_attach_final(WStatusBar
*sb
,
497 if(!ptrlist_insert_last(&sb
->traywins
, (Obj
*)reg
))
500 el
=statusbar_associate_systray(sb
, reg
);
502 ptrlist_remove(&sb
->traywins
, (Obj
*)reg
);
506 fp
.g
=REGION_GEOM(reg
);
507 fp
.mode
=REGION_FIT_EXACT
;
508 systray_adjust_size(reg
, &fp
.g
);
510 region_fitrep(reg
, NULL
, &fp
);
512 do_calc_systray_w(sb
, el
);
514 region_set_manager(reg
, (WRegion
*)sb
);
516 statusbar_rearrange(sb
, TRUE
);
518 if(REGION_IS_MAPPED(sb
))
525 static WRegion
*statusbar_do_attach(WStatusBar
*sb
, WRegionAttachData
*data
)
531 fp
.g
.h
=CF_STATUSBAR_SYSTRAY_HEIGHT
;
532 fp
.g
.w
=CF_STATUSBAR_SYSTRAY_HEIGHT
;
533 fp
.mode
=REGION_FIT_WHATEVER
|REGION_FIT_BOUNDS
;
535 return region_attach_helper((WRegion
*)sb
, (WWindow
*)sb
, &fp
,
536 (WRegionDoAttachFn
*)statusbar_do_attach_final
,
541 static WRegion
*statusbar_attach_ph(WStatusBar
*sb
, int flags
,
542 WRegionAttachData
*data
)
544 return statusbar_do_attach(sb
, data
);
548 static WPHolder
*statusbar_prepare_manage(WStatusBar
*sb
,
549 const WClientWin
*cwin
,
550 const WManageParams
*param
,
553 if(!MANAGE_PRIORITY_OK(priority
, MANAGE_PRIORITY_LOW
))
556 return (WPHolder
*)create_basicpholder((WRegion
*)sb
,
557 ((WBasicPHolderHandler
*)
558 statusbar_attach_ph
));
562 static void statusbar_managed_remove(WStatusBar
*sb
, WRegion
*reg
)
566 ptrlist_remove(&sb
->traywins
, (Obj
*)reg
);
568 el
=statusbar_unassociate_systray(sb
, reg
);
570 region_unset_manager(reg
, (WRegion
*)sb
);
572 if(el
!=NULL
&& ioncore_g
.opmode
!=IONCORE_OPMODE_DEINIT
){
573 do_calc_systray_w(sb
, el
);
574 statusbar_rearrange(sb
, TRUE
);
579 static void statusbar_managed_rqgeom(WStatusBar
*sb
, WRegion
*reg
,
580 const WRQGeomParams
*rq
,
585 g
.x
=REGION_GEOM(reg
).x
;
586 g
.y
=REGION_GEOM(reg
).y
;
590 systray_adjust_size(reg
, &g
);
592 if(rq
->flags
®ION_RQGEOM_TRYONLY
){
598 region_fit(reg
, &g
, REGION_FIT_EXACT
);
600 statusbar_calc_systray_w(sb
);
601 statusbar_rearrange(sb
, TRUE
);
604 *geomret
=REGION_GEOM(reg
);
609 void statusbar_map(WStatusBar
*sb
)
614 window_map((WWindow
*)sb
);
616 FOR_ALL_ON_PTRLIST(WRegion
*, reg
, sb
->traywins
, tmp
)
621 void statusbar_unmap(WStatusBar
*sb
)
626 window_unmap((WWindow
*)sb
);
628 FOR_ALL_ON_PTRLIST(WRegion
*, reg
, sb
->traywins
, tmp
)
633 bool statusbar_fitrep(WStatusBar
*sb
, WWindow
*par
, const WFitParams
*fp
)
635 bool wchg
=(REGION_GEOM(sb
).w
!=fp
->g
.w
);
636 bool hchg
=(REGION_GEOM(sb
).h
!=fp
->g
.h
);
638 if(!window_fitrep(&(sb
->wwin
), par
, fp
))
642 statusbar_calculate_xs(sb
);
643 statusbar_arrange_systray(sb
);
644 statusbar_draw(sb
, TRUE
);
651 WPHolder
*statusbar_prepare_manage_transient(WStatusBar
*sb
,
652 const WClientWin
*cwin
,
653 const WManageParams
*param
,
656 WRegion
*mgr
=REGION_MANAGER(sb
);
659 mgr
=(WRegion
*)region_screen_of((WRegion
*)sb
);
662 return region_prepare_manage(mgr
, cwin
, param
,
663 MANAGE_PRIORITY_NONE
);
676 static ExtlFn parse_template_fn
;
677 static bool parse_template_fn_set
=FALSE
;
681 void mod_statusbar__set_template_parser(ExtlFn fn
)
683 if(parse_template_fn_set
)
684 extl_unref_fn(parse_template_fn
);
685 parse_template_fn
=extl_ref_fn(fn
);
686 parse_template_fn_set
=TRUE
;
691 * Set statusbar template.
694 void statusbar_set_template(WStatusBar
*sb
, const char *tmpl
)
696 ExtlTab t
=extl_table_none();
699 if(parse_template_fn_set
){
701 ok
=extl_call(parse_template_fn
, "s", "t", tmpl
, &t
);
702 extl_unprotect(NULL
);
706 statusbar_set_template_table(sb
, t
);
711 * Set statusbar template as table.
714 void statusbar_set_template_table(WStatusBar
*sb
, ExtlTab t
)
719 statusbar_set_elems(sb
, t
);
721 FOR_ALL_ON_PTRLIST(WRegion
*, reg
, sb
->traywins
, tmp
){
722 statusbar_associate_systray(sb
, reg
);
725 statusbar_calc_widths(sb
);
726 statusbar_rearrange(sb
, FALSE
);
731 * Get statusbar template as table.
734 ExtlTab
statusbar_get_template_table(WStatusBar
*sb
)
736 int count
= sb
->nelems
;
739 ExtlTab t
= extl_create_table();
741 for(i
=0; i
<count
; i
++){
742 ExtlTab tt
= extl_create_table();
744 extl_table_sets_i(tt
, "type", sb
->elems
[i
].type
);
745 extl_table_sets_s(tt
, "text", sb
->elems
[i
].text
);
746 extl_table_sets_s(tt
, "meter", stringstore_get(sb
->elems
[i
].meter
));
747 extl_table_sets_s(tt
, "tmpl", sb
->elems
[i
].tmpl
);
748 extl_table_sets_i(tt
, "align", sb
->elems
[i
].align
);
749 extl_table_sets_i(tt
, "zeropad", sb
->elems
[i
].zeropad
);
751 extl_table_seti_t(t
, (i
+1), tt
);
752 extl_unref_table(tt
);
759 static void reset_stretch(WStatusBar
*sb
)
763 for(i
=0; i
<sb
->nelems
; i
++)
764 sb
->elems
[i
].stretch
=0;
768 static void positive_stretch(WStatusBar
*sb
)
772 for(i
=0; i
<sb
->nelems
; i
++)
773 sb
->elems
[i
].stretch
=maxof(0, sb
->elems
[i
].stretch
);
777 static void spread_stretch(WStatusBar
*sb
)
781 WSBElem
*el
, *lel
, *rel
;
784 for(i
=0; i
<sb
->nelems
; i
++){
787 if(el
->type
!=WSBELEM_METER
&& el
->type
!=WSBELEM_SYSTRAY
)
790 diff
=el
->max_w
-el
->text_w
;
795 if(el
->align
!=WSBELEM_ALIGN_RIGHT
){
796 for(j
=i
+1; j
<sb
->nelems
; j
++){
797 if(sb
->elems
[j
].type
==WSBELEM_STRETCH
){
804 if(el
->align
!=WSBELEM_ALIGN_LEFT
){
805 for(k
=i
-1; k
>=0; k
--){
806 if(sb
->elems
[k
].type
==WSBELEM_STRETCH
){
813 if(rel
!=NULL
&& lel
!=NULL
){
827 static void statusbar_rearrange(WStatusBar
*sb
, bool rs
)
830 int onw
=sb
->natural_w
;
831 int onh
=sb
->natural_h
;
833 statusbar_do_update_natural_size(sb
);
835 if( (sb
->natural_h
>onh
&& REGION_GEOM(sb
).h
>=onh
)
836 || (sb
->natural_h
<onh
&& REGION_GEOM(sb
).h
<=onh
)
837 || (sb
->natural_w
>onw
&& REGION_GEOM(sb
).w
>=onw
)
838 || (sb
->natural_w
<onw
&& REGION_GEOM(sb
).w
<=onw
)){
840 statusbar_resize(sb
);
846 positive_stretch(sb
);
847 statusbar_calculate_xs(sb
);
850 statusbar_arrange_systray(sb
);
856 * Set statusbar template.
859 void statusbar_update(WStatusBar
*sb
, ExtlTab t
)
868 for(i
=0; i
<sb
->nelems
; i
++){
873 if(el
->type
!=WSBELEM_METER
)
881 if(el
->attr
!=GRATTR_NONE
){
882 stringstore_free(el
->attr
);
883 el
->attr
=GRATTR_NONE
;
886 meter
=stringstore_get(el
->meter
);
892 extl_table_gets_s(t
, meter
, &(el
->text
));
895 str
=STATUSBAR_NX_STR
;
898 int l
=strlen(el
->text
);
899 int ml
=str_len(el
->text
);
900 int diff
=el
->zeropad
-ml
;
902 char *tmp
=ALLOC_N(char, l
+diff
+1);
904 memset(tmp
, '0', diff
);
905 memcpy(tmp
+diff
, el
->text
, l
+1);
913 if(el
->tmpl
!=NULL
&& el
->text
!=NULL
){
914 char *tmp
=grbrush_make_label(sb
->brush
, el
->text
, el
->max_w
);
922 el
->text_w
=grbrush_get_text_width(sb
->brush
, str
, strlen(str
));
924 if(el
->text_w
>el
->max_w
&& el
->tmpl
==NULL
){
925 el
->max_w
=el
->text_w
;
929 attrnm
=scat(meter
, "_hint");
932 if(extl_table_gets_s(t
, attrnm
, &s
)){
933 el
->attr
=stringstore_alloc(s
);
941 statusbar_rearrange(sb
, grow
);
943 window_draw((WWindow
*)sb
, FALSE
);
953 void statusbar_updategr(WStatusBar
*p
)
957 nbrush
=gr_get_brush(p
->wwin
.win
, region_rootwin_of((WRegion
*)p
),
963 grbrush_release(p
->brush
);
967 statusbar_calc_widths(p
);
968 statusbar_rearrange(p
, TRUE
);
970 window_draw(&(p
->wwin
), TRUE
);
980 int statusbar_orientation(WStatusBar
*sb
)
982 return REGION_ORIENTATION_HORIZONTAL
;
987 * Returns a list of all statusbars.
990 ExtlTab
mod_statusbar_statusbars()
992 ExtlTab t
=extl_create_table();
996 for(sb
=statusbars
; sb
!=NULL
; sb
=sb
->sb_next
){
997 extl_table_seti_o(t
, i
, (Obj
*)sb
);
1005 WStatusBar
*mod_statusbar_find_suitable(WClientWin
*cwin
,
1006 const WManageParams
*param
)
1010 for(sb
=statusbars
; sb
!=NULL
; sb
=sb
->sb_next
){
1013 if(!sb
->systray_enabled
)
1015 if(!region_same_rootwin((WRegion
*)sb
, (WRegion
*)cwin
))
1024 bool statusbar_set_systray(WStatusBar
*sb
, int sp
)
1026 bool set
=sb
->systray_enabled
;
1027 bool nset
=libtu_do_setparam(sp
, set
);
1029 sb
->systray_enabled
=nset
;
1036 * Enable or disable use of \var{sb} as systray.
1037 * The parameter \var{how} can be one of
1038 * \codestr{set}, \codestr{unset}, or \codestr{toggle}.
1039 * Resulting state is returned.
1041 EXTL_EXPORT_AS(WStatusBar
, set_systray
)
1042 bool statusbar_set_systray_extl(WStatusBar
*sb
, const char *how
)
1044 return statusbar_set_systray(sb
, libtu_string_to_setparam(how
));
1049 * Is \var{sb} used as a systray?
1051 EXTL_EXPORT_AS(WStatusBar
, is_systray
)
1052 bool statusbar_is_systray_extl(WStatusBar
*sb
)
1054 return sb
->systray_enabled
;
1064 WRegion
*statusbar_load(WWindow
*par
, const WFitParams
*fp
, ExtlTab tab
)
1066 WStatusBar
*sb
=create_statusbar(par
, fp
);
1070 ExtlTab t
=extl_table_none();
1071 if(extl_table_gets_s(tab
, "template", &tmpl
)){
1072 statusbar_set_template(sb
, tmpl
);
1074 }else if(extl_table_gets_t(tab
, "template_table", &t
)){
1075 statusbar_set_template_table(sb
, t
);
1076 extl_unref_table(t
);
1078 const char *tmpl
=TR("[ %date || load: %load ] %filler%systray");
1079 statusbar_set_template(sb
, tmpl
);
1082 extl_table_gets_b(tab
, "systray", &sb
->systray_enabled
);
1085 return (WRegion
*)sb
;
1092 /*{{{ Dynamic function table and class implementation */
1095 static DynFunTab statusbar_dynfuntab
[]={
1096 {window_draw
, statusbar_draw
},
1097 {region_updategr
, statusbar_updategr
},
1098 {region_size_hints
, statusbar_size_hints
},
1099 {(DynFun
*)region_orientation
, (DynFun
*)statusbar_orientation
},
1101 {region_managed_rqgeom
, statusbar_managed_rqgeom
},
1102 {(DynFun
*)region_prepare_manage
, (DynFun
*)statusbar_prepare_manage
},
1103 {region_managed_remove
, statusbar_managed_remove
},
1105 {(DynFun
*)region_prepare_manage_transient
,
1106 (DynFun
*)statusbar_prepare_manage_transient
},
1108 {region_map
, statusbar_map
},
1109 {region_unmap
, statusbar_unmap
},
1111 {(DynFun
*)region_fitrep
,
1112 (DynFun
*)statusbar_fitrep
},
1119 IMPLCLASS(WStatusBar
, WWindow
, statusbar_deinit
, statusbar_dynfuntab
);