home *** CD-ROM | disk | FTP | other *** search
- /* Wimp commands for tcl */
- /* (c) C.T.Stretch */
- /* Sat,25 Jun 1994 */
-
- #include "h.WInt"
- #include "h.osbyte"
-
- #define MENUFLAGS wimp_ICON_TEXT|wimp_ICON_INDIRECTED|wimp_ICON_FILLED|\
- (wimp_COLOUR_BLACK<<wimp_ICON_FG_COLOUR_SHIFT)
-
- #define TCLMENU(x) ((tcl_menu*)((x)+1)-1)
-
- #define TRACEFLAGS (TCL_TRACE_WRITES|TCL_GLOBAL_ONLY)
-
- static tcl_menu *thismenu,*iconbar_menu;
- static int iconbar_y;
-
-
- /*
- * menu_free --
- *
- * Release the memory used by a menu.
- * Remove all the variable traces.
- * Called recursively for submenus.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- */
-
- extern void menu_free(tcl_menu *m)
- { wimp_menu_entry *wme;
- char **p;
- trace *s,*t;
- int i;
- if(m==menu_NONE) return;
- wme=m->menu.entries;
- p=m->action;
- for(i=0;i<m->n;i++)
- { ckfree(*p);
- if(wme->sub_menu!=wimp_NO_SUB_MENU&&
- !(wme->menu_flags&wimp_MENU_GIVE_WARNING))
- menu_free(TCLMENU(wme->sub_menu));
- wme++;p++;
- }
- for(t=m->traces;t;)
- { s=t->next;
- Tcl_UntraceVar2(w_Interp,t->var,t->tag,TRACEFLAGS,t->proc,t->cd);
- ckfree(t->var);ckfree(t->tag);
- ckfree(t);
- t=s;
- }
- ckfree(m->action);
- ckfree(m);
- }
-
- /*
- * tick --
- *
- * Called as a trace procedure if the variable holding the tick
- * status of a menu item is changed.
- *
- *
- * Results:
- * None.
- *
- * Side effects:
- * Adjusts the tick bit in the menu.
- *
- */
-
- static char *tick(ClientData d,Tcl_Interp *interp,char *n1,char *n2,int flags)
- { char *v=Tcl_GetVar2(interp,n1,n2,flags&TCL_GLOBAL_ONLY);
- bits *b=(bits*)d;
- if(!strcmp(v,"0")) (*b)&=~wimp_MENU_TICKED;
- else (*b)|=wimp_MENU_TICKED;
- return 0;
- }
-
- /*
- * grey --
- *
- *
- * Called as a trace procedure if the variable holding the grey
- * status of a menu item is changed.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Adjusts the grey bit in the menu.
- *
- */
-
- static char *grey(ClientData d,Tcl_Interp *interp,char *n1,char *n2,int flags)
- { char *v=Tcl_GetVar2(interp,n1,n2,flags&TCL_GLOBAL_ONLY);
- bits *b=(bits*)d;
- if(!strcmp(v,"0")) (*b)&=~wimp_ICON_SHADED;
- else (*b)|=wimp_ICON_SHADED;
- return 0;
- }
-
- /*
- * menu_open --
- *
- * Opens a menu in response to a menu button click.
- *
- *
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- */
-
- void menu_open(void)
- { int y=block.pointer.pos.y;
- if(block.pointer.w==wimp_ICON_BAR)
- { y=iconbar_y;thismenu=iconbar_menu;
- substr['w'-'a']="bar";
- }
- else
- { y=block.pointer.pos.y;
- thismenu=diagram_menu();
- if(thismenu==menu_NONE) return;
- if(!thismenu)
- { thismenu=document_menu();
- if(thismenu==menu_NONE) return;
- }
- }
- if(thismenu) wimp_create_menu(&(thismenu->menu),block.pointer.pos.x-64,y);
- }
-
- /*
- * menu_select --
- *
- * Called after a menu selection. Runs the associated script.
- * Re-opens the menu if adjust was used.
- *
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- */
-
- void menu_select(void)
- { int i;
- tcl_menu *tm=thismenu;
- wimp_menu *wm;
- wimp_pointer wp;
- if(block.selection.items[0]>=0) for(i=0;i<7;i++)
- { int j=block.selection.items[i];
- if(block.selection.items[i+1]<0)
- { if(tm->action[j]) checkEval(tm->action[j],"menu action");
- break;
- }
- if(j<0||j>=tm->n) break;
- wm=tm->menu.entries[j].sub_menu;
- tm=TCLMENU(wm);
- }
- wimp_get_pointer_info(&wp);
- if(wp.buttons==wimp_CLICK_ADJUST)
- wimp_create_menu(&(thismenu->menu),wp.pos.x,wp.pos.y);
- }
-
- /*
- * menu_make --
- *
- * Constructs a menu from a menu description
- * Called recursively for submenus.
- *
- *
- * Results:
- * Returns a tcl_menu or 0 for a bad description.
- *
- * Side effects:
- * None.
- *
- */
-
- tcl_menu *menu_make(char *desc,char *tag)
- { int width=12,nitems,i;
- char **items;
- char *name;
- wimp_menu *wm;
- tcl_menu *tm;
- char *tg;
- if(Tcl_SplitList(w_Interp,desc,&nitems,&items))
- return wrong0("Bad list ",desc);
- nitems--;
- if(nitems<1) return wrong0("Menu with no items ",desc);
- tm=ckalloc(sizeof(tcl_menu)+(nitems-1)*sizeof(wimp_menu_entry));
- tm->action=ckalloc(nitems*sizeof(char*));
- tm->n=nitems;
- tm->traces=0;
- wm=&(tm->menu);
- for(i=0;i<nitems;i++)
- { int nparts,j;
- char **parts;
- wimp_menu_entry *wme;
- if(Tcl_SplitList(w_Interp,items[i+1],&nparts,&parts))
- return wrong0("Bad list ",items[i+1]);
- if(nparts<1) return wrong0("Bad menu item ",desc);
- wme=&(wm->entries[i]);
- wme->menu_flags=0;
- wme->sub_menu=wimp_NO_SUB_MENU;
- wme->icon_flags=MENUFLAGS;
- tm->action[i]=0;
- name=scopy(parts[0]);
- wme->data.indirected_text.text=name;
- wme->data.indirected_text.validation=0;
- wme->data.indirected_text.size=strlen(name);
- tg=0;
- for(j=1;j<nparts;j++)
- { if(!strcmp(parts[j],"-tag"))
- { tg=tag;
- continue;
- }
- if(j==nparts-1) return wrong0("Odd menu component ",parts[j]);
- if(!strcmp(parts[j],"-click"))
- { tm->action[i]=scopy(parts[++j]);
- continue;
- }
- if(!strcmp(parts[j],"-tick"))
- { int n=strlen(parts[++j]);
- char *s;
- trace *t=ckcalloc(sizeof(trace));
- if(tg) n+=2+strlen(tg);
- tm->action[i]=ckalloc(2*n+15);
- if(tg) sprintf(tm->action[i],"set %s(%s) [expr !$%s(%s)]",
- parts[j],tg,parts[j],tg);
- else sprintf(tm->action[i],"set %s [expr !$%s]",parts[j],parts[j]);
- s=Tcl_GetVar2(w_Interp,parts[j],tg,TCL_GLOBAL_ONLY);
- if(s)
- { if(strcmp(s,"0")!=0) wme->menu_flags|=wimp_MENU_TICKED;
- }
- else Tcl_SetVar2(w_Interp,parts[j],tg,"0",TCL_GLOBAL_ONLY);
- t->next=tm->traces;
- tm->traces=t;
- t->var=scopy(parts[j]);
- if(tg) t->tag=scopy(tg);
- t->proc=tick;
- t->cd=(ClientData)&(wme->menu_flags);
- Tcl_TraceVar2(w_Interp,parts[j],tg,TRACEFLAGS,tick,t->cd);
- continue;
- }
- if(!strcmp(parts[j],"-grey"))
- { char *s;
- trace *t=ckcalloc(sizeof(trace));
- s=Tcl_GetVar2(w_Interp,parts[++j],tg,TCL_GLOBAL_ONLY);
- if(s&&(strcmp(s,"0")!=0)) wme->icon_flags|=wimp_ICON_SHADED;
- t->next=tm->traces;
- tm->traces=t;
- t->var=scopy(parts[j]);
- if(tg) t->tag=scopy(tg);
- t->proc=grey;
- t->cd=(ClientData)&(wme->icon_flags);
- Tcl_TraceVar2(w_Interp,parts[j],tg,TRACEFLAGS,grey,t->cd);
- continue;
- }
- if(!strcmp(parts[j],"-sub"))
- { tcl_menu *tsm=menu_make(parts[++j],tag);
- if(!tsm) return 0;
- wme->sub_menu=&(tsm->menu);
- continue;
- }
- if(!strcmp(parts[j],"-dbox"))
- { wimp_menu *wm=box_find(parts[++j]);
- if(!wm) return wrong0("Unknown dbox ",parts[j]);
- wme->sub_menu=wm;
- wme->menu_flags|=wimp_MENU_GIVE_WARNING;
- continue;
- }
- return wrong0("Odd menu component ",parts[j]);
- }
- ckfree(parts);
- }
- wm->entries[0].menu_flags|=wimp_MENU_TITLE_INDIRECTED;
- wm->entries[nitems-1].menu_flags|=wimp_MENU_LAST;
- wm->title_data.indirected_text.text=scopy(items[0]);
- wm->title_fg=wimp_COLOUR_BLACK;
- wm->title_bg=wimp_COLOUR_LIGHT_GREY;
- wm->work_fg=wimp_COLOUR_BLACK;
- wm->work_bg=wimp_COLOUR_WHITE;
- wm->width=width*16;
- wm->height=44;
- wm->gap=0;
- return tm;
- }
-
- /*
- * menu_bar --
- *
- * Finds the height to open the iconbar menu.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Sets iconbar_y and iconbar_menu.
- *
- */
-
- void menu_bar(tcl_menu *wm)
- { wimp_menu_entry *wme=wm->menu.entries;
- iconbar_y=140;
- for(;!(wme->menu_flags&wimp_MENU_LAST);wme++) iconbar_y+=44;
- iconbar_menu=wm;
- }
-
-