X-Git-Url: https://git.decadent.org.uk/gitweb/?a=blobdiff_plain;f=mod_menu%2Fmenu.c;h=c87dc590ccb99f5693f52d19c545dad9c828f5a1;hb=ae4260bb64817c11f9a7140324cd3e3ba113e297;hp=b8ec9cfa446984102770562de2ba244c45ccd5eb;hpb=8366314611bf30a0f31d25bf5f5023186fa87692;p=ion3.git diff --git a/mod_menu/menu.c b/mod_menu/menu.c index b8ec9cf..c87dc59 100644 --- a/mod_menu/menu.c +++ b/mod_menu/menu.c @@ -1,12 +1,9 @@ /* * ion/mod_menu/menu.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 - * 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 @@ -28,6 +25,10 @@ #include #include #include +#include +#include +#include +#include #include "menu.h" #include "main.h" @@ -85,22 +86,35 @@ static void get_inner_geom(WMenu *menu, WRectangle *geom) } +GR_DEFATTR(active); +GR_DEFATTR(inactive); +GR_DEFATTR(selected); +GR_DEFATTR(unselected); +GR_DEFATTR(normal); +GR_DEFATTR(submenu); + + +static void init_attr() +{ + GR_ALLOCATTR_BEGIN; + GR_ALLOCATTR(active); + GR_ALLOCATTR(inactive); + GR_ALLOCATTR(selected); + GR_ALLOCATTR(unselected); + GR_ALLOCATTR(normal); + GR_ALLOCATTR(submenu); + GR_ALLOCATTR_END; +} + + static void menu_draw_entry(WMenu *menu, int i, const WRectangle *igeom, bool complete) { WRectangle geom; - int a; - - static const char *attrs[]={ - "active-selected-normal", - "active-selected-submenu", - "active-unselected-normal", - "active-unselected-submenu", - "inactive-selected-normal", - "inactive-selected-submenu", - "inactive-unselected-normal", - "inactive-unselected-submenu", - }; + GrAttr sa, aa; + + aa=(REGION_IS_ACTIVE(menu) ? GR_ATTR(active) : GR_ATTR(inactive)); + sa=(menu->selected_entry==i ? GR_ATTR(selected) : GR_ATTR(unselected)); if(menu->entry_brush==NULL) return; @@ -109,14 +123,15 @@ static void menu_draw_entry(WMenu *menu, int i, const WRectangle *igeom, geom.h=menu->entry_h; geom.y+=(i-menu->first_entry)*(menu->entry_h+menu->entry_spacing); - a=((REGION_IS_ACTIVE(menu) ? 0 : 4) - |(menu->selected_entry==i ? 0 : 2) - |(menu->entries[i].flags&WMENUENTRY_SUBMENU ? 1 : 0)); - - grbrush_begin(menu->entry_brush, &geom, GRBRUSH_AMEND); + grbrush_begin(menu->entry_brush, &geom, GRBRUSH_AMEND|GRBRUSH_KEEP_ATTR); + + grbrush_init_attr(menu->entry_brush, &menu->entries[i].attr); + + grbrush_set_attr(menu->entry_brush, aa); + grbrush_set_attr(menu->entry_brush, sa); grbrush_draw_textbox(menu->entry_brush, &geom, menu->entries[i].title, - attrs[a], complete); + complete); grbrush_end(menu->entry_brush); } @@ -126,10 +141,10 @@ void menu_draw_entries(WMenu *menu, bool complete) { WRectangle igeom; int i, mx; - + if(menu->entry_brush==NULL) return; - + get_inner_geom(menu, &igeom); mx=menu->first_entry+menu->vis_entries; @@ -142,8 +157,8 @@ void menu_draw_entries(WMenu *menu, bool complete) void menu_draw(WMenu *menu, bool complete) { + GrAttr aa=(REGION_IS_ACTIVE(menu) ? GR_ATTR(active) : GR_ATTR(inactive)); WRectangle geom; - const char *substyle=(REGION_IS_ACTIVE(menu) ? "active" : "inactive"); if(menu->brush==NULL) return; @@ -153,7 +168,9 @@ void menu_draw(WMenu *menu, bool complete) grbrush_begin(menu->brush, &geom, (complete ? 0 : GRBRUSH_NO_CLEAR_OK)); - grbrush_draw_border(menu->brush, &geom, substyle); + grbrush_set_attr(menu->brush, aa); + + grbrush_draw_border(menu->brush, &geom); menu_draw_entries(menu, FALSE); @@ -373,6 +390,26 @@ bool menu_fitrep(WMenu *menu, WWindow *par, const WFitParams *fp) } +void menu_size_hints(WMenu *menu, WSizeHints *hints_ret) +{ + int n=menu->n_entries; + int w=menu->max_entry_w; + int h=menu->entry_h*n + menu->entry_spacing*maxof(0, n-1); + + if(menu->brush!=NULL){ + GrBorderWidths bdw; + grbrush_get_border_widths(menu->brush, &bdw); + + w+=bdw.left+bdw.right; + h+=bdw.top+bdw.bottom; + } + + hints_ret->min_set=TRUE; + hints_ret->min_width=w; + hints_ret->min_height=h; +} + + /*}}}*/ @@ -491,9 +528,8 @@ static void menu_release_gr(WMenu *menu) static WMenuEntry *preprocess_menu(ExtlTab tab, int *n_entries) { - ExtlTab entry, sub; - ExtlFn fn; WMenuEntry *entries; + ExtlTab entry; int i, n; n=extl_table_get_n(tab); @@ -506,17 +542,40 @@ static WMenuEntry *preprocess_menu(ExtlTab tab, int *n_entries) if(entries==NULL) return NULL; - + + init_attr(); + /* Initialise entries and check submenus */ for(i=1; i<=n; i++){ - entries[i-1].title=NULL; - entries[i-1].flags=0; - if(extl_table_getis(tab, i, "submenu_fn", 'f', &fn)){ - entries[i-1].flags|=WMENUENTRY_SUBMENU; - extl_unref_fn(fn); - }else if(extl_table_getis(tab, i, "submenu", 't', &sub)){ - entries[i-1].flags|=WMENUENTRY_SUBMENU; - extl_unref_table(sub); + WMenuEntry *ent=&entries[i-1]; + + ent->title=NULL; + ent->flags=0; + + gr_stylespec_init(&ent->attr); + + if(extl_table_geti_t(tab, i, &entry)){ + char *attr; + ExtlTab sub; + ExtlFn fn; + + if(extl_table_gets_s(entry, "attr", &attr)){ + gr_stylespec_load_(&ent->attr, attr, TRUE); + free(attr); + } + + if(extl_table_gets_f(entry, "submenu_fn", &fn)){ + ent->flags|=WMENUENTRY_SUBMENU; + extl_unref_fn(fn); + }else if(extl_table_gets_t(entry, "submenu", &sub)){ + ent->flags|=WMENUENTRY_SUBMENU; + extl_unref_table(sub); + } + + if(ent->flags&WMENUENTRY_SUBMENU) + gr_stylespec_set(&ent->attr, GR_ATTR(submenu)); + + extl_unref_table(entry); } } @@ -524,6 +583,8 @@ static WMenuEntry *preprocess_menu(ExtlTab tab, int *n_entries) } +static void deinit_entries(WMenu *menu); + bool menu_init(WMenu *menu, WWindow *par, const WFitParams *fp, const WMenuCreateParams *params) @@ -542,12 +603,13 @@ bool menu_init(WMenu *menu, WWindow *par, const WFitParams *fp, menu->handler=extl_ref_fn(params->handler); menu->pmenu_mode=params->pmenu_mode; menu->big_mode=params->big_mode; - + /*menu->cycle_bindmap=NULL;*/ + menu->last_fp=*fp; - if(params->pmenu_mode) + if(params->pmenu_mode){ menu->selected_entry=-1; - else{ + }else{ menu->selected_entry=params->initial-1; if(menu->selected_entry<0) menu->selected_entry=0; @@ -575,7 +637,9 @@ bool menu_init(WMenu *menu, WWindow *par, const WFitParams *fp, if(!menu_init_gr(menu, region_rootwin_of((WRegion*)par), win)) goto fail2; - + + init_attr(); + menu_firstfit(menu, params->submenu_mode, &(params->refg)); window_select_input(&(menu->win), IONCORE_EVENTMASK_NORMAL); @@ -591,7 +655,7 @@ fail2: fail: extl_unref_table(menu->tab); extl_unref_fn(menu->handler); - free(menu->entries); + deinit_entries(menu); return FALSE; } @@ -603,24 +667,37 @@ WMenu *create_menu(WWindow *par, const WFitParams *fp, } - -void menu_deinit(WMenu *menu) +static void deinit_entries(WMenu *menu) { int i; + for(i=0; in_entries; i++){ + gr_stylespec_unalloc(&menu->entries[i].attr); + if(menu->entries[i].title!=NULL) + free(menu->entries[i].title); + } + + free(menu->entries); +} + + +void menu_deinit(WMenu *menu) +{ menu_typeahead_clear(menu); if(menu->submenu!=NULL) destroy_obj((Obj*)menu->submenu); + /*if(menu->cycle_bindmap!=NULL) + bindmap_destroy(menu->cycle_bindmap);*/ + extl_unref_table(menu->tab); extl_unref_fn(menu->handler); - for(i=0; in_entries; i++) - free(menu->entries[i].title); - free(menu->entries); + deinit_entries(menu); menu_release_gr(menu); + window_deinit((WWindow*)menu); } @@ -891,10 +968,10 @@ static void menu_do_finish(WMenu *menu) ok=extl_table_geti_t(menu->tab, menu->selected_entry+1, &tab); - if(region_manager_allows_destroying((WRegion*)head)) - destroy_obj((Obj*)head); - else if(head->submenu!=NULL) - destroy_obj((Obj*)head->submenu); + if(!region_rqdispose((WRegion*)head)){ + if(head->submenu!=NULL) + destroy_obj((Obj*)head->submenu); + } if(ok) extl_call(handler, "t", NULL, tab); @@ -930,8 +1007,7 @@ void menu_finish(WMenu *menu) EXTL_EXPORT_MEMBER void menu_cancel(WMenu *menu) { - if(region_manager_allows_destroying((WRegion*)menu)) - mainloop_defer_destroy((Obj*)menu); + region_defer_rqdispose((WRegion*)menu); } @@ -1362,6 +1438,7 @@ static DynFunTab menu_dynfuntab[]={ {window_insstr, menu_insstr}, {region_restack, menu_restack}, {region_stacking, menu_stacking}, + {region_size_hints, menu_size_hints}, END_DYNFUNTAB };