/* * wMenus.c * * Handling the Template Window Menu * * © 1994-1998 Straylight */ /*----- Licensing note ----------------------------------------------------* * * This file is part of Straylight's Glass. * * Glass is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * Glass is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Glass. If not, write to the Free Software Foundation, * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /*----- Header files ------------------------------------------------------*/ /* * ANSI standard headers */ #include #include #include /* * Steel headers */ #define _STDAPP #define _LOWLVL #include "steel/Steel.h" #include "steel/buttons.h" #include "steel/choices.h" #include "steel/bbc.h" #include "steel/buffer.h" #include "steel/tearoff.h" /* * Glass headers */ #include "gStruct.h" #include "gMenus.h" #include "gIcons.h" #include "glass.h" #include "gPrefs.h" #include "tfile.h" #include "window.h" #include "_window.h" #include "editIcon.h" #include "editWin.h" #include "align.h" #include "iconData.h" #include "tearEdit.h" /*----- Private data ------------------------------------------------------*/ static int window__menuX; /* x-position of pointer on menu click */ static int window__menuY; /* y-position of pointer on menu click */ static int window__newIcons; /* Number of new icon types defined */ static glass_windPointer* window__menuWin; /* Which window owns the menu */ static tearoff window__mRoot; /* Root of menu structure */ static tearoff window__mMisc; /* Misc submenu */ static tearoff window__mSelect; /* Select submenu */ static tearoff window__mButton; /* Button type submenu */ static tearoff window__mIcon; /* Icon submenu */ static tearoff window__mCreate; /* Icon types submenu */ static tearoff window__mGuide; /* Guides submenu */ /*----- Main code ---------------------------------------------------------*/ /* * glass_windPointer *window__menuOwner(void) * * Use * Returns which window currently owns the menu. * * Returns * A pointer to the window's anchor block. */ glass_windPointer *window__menuOwner(void) { return (window__menuWin); } /* * void window__doTable(unsigned short *p,int s,unsigned int f,tearoff t) * * Use * Updates a tearoff menu using the given table. * * Parameters * unsigned short *p == pointer to shade flags table * int s == number of items in table * unsigned int f == which flags to use to mask with * tearoff t == which tearoff menu to play with */ static void window__doTable(const unsigned short *p, int s,unsigned int f,tearoff t) { unsigned int *tbl=(unsigned int *)p; int i; unsigned int w; for (i=0;i>16 : *tbl++); tearoff_shadeItem(t,i+1,(w & f)!=0); } } /* * void window__updateMenu(glass_windPointer *w) * * Use * Updates the menu attached to the main window. * * Parameters * glass_windPointer *w == pointer to owning menu */ void window__updateMenu(glass_windPointer *w) { int i; unsigned int sflags; int gflags; glass_windPointer *wso=window_selectionOwner(); /* --- Redesign --- * * * Based on the Sapphire idea, we define a number of shade flags, * and a big table which says which items need to be shaded when. * * The table is carefully organised so as not to give clues about how * to implement test mode. This isn't important. */ #define s_all (1<<15) #define s_guide (1<<0 | s_all) #define s_gsel (1<<1 | s_all) #define s_sel (1<<2 | s_all) #define s_icon (1<<3 | s_all) #define s_ren (1<<4 | s_all) #define s_copy (1<<5 | s_all) #define s_grid (1<<6 | s_all) #ifndef glass_DEMO #define s_test (1<<7 | s_all) #else #define s_test (s_all) #endif #define s_qs (s_test | s_ren) #define s_s (s_sel | s_qs) /* --- Shading table --- * * * Each entry packed into a single byte. This is quite good, for C ;-) */ const static unsigned short root[]= { s_all, s_all, s_test, s_qs, s_qs, s_qs, s_qs }; const static unsigned short misc[]= { s_all, s_qs, s_ren, s_qs, s_qs, s_all }; const static unsigned short select[]= { s_icon|s_qs, s_s, s_qs|s_copy, s_s, s_sel|s_test, s_s, s_s, s_s, s_s, s_s|s_grid, s_s, s_s, s_s}; const static unsigned short icon[]= { s_qs, s_qs, s_qs }; const static unsigned short guide[]= { s_qs|s_guide, s_qs|s_gsel, s_qs|s_gsel, s_qs, s_qs }; /* --- Build the mask word --- */ if (!w) sflags=s_all; else { sflags=0; /* --- Work out guide status --- */ gflags=0; for (i=0;iguide[i].active) gflags|=1; if (w->guide[i].selected) gflags|=2; } /* --- Now set flags appropriately --- */ if (!(gflags & 1)) sflags|=s_guide & ~s_all; if (!(gflags & 2)) sflags|=s_gsel & ~s_all; if (!w->selno) sflags|=s_sel & ~s_all; if (!w->def->desc.w.nicons) sflags|=s_icon & ~s_all; if (w->renumber) sflags|=s_ren & ~s_all; if (!wso || !wso->selno) sflags|=s_copy & ~s_all; if (!w->gridLock) sflags|=s_grid & ~s_all; #ifndef glass_DEMO if (w->testMode) sflags|=s_test & ~s_all; #endif } /* --- Now shade all the items --- */ window__doTable(root,sizeof(root)/2,sflags,window__mRoot); window__doTable(misc,sizeof(misc)/2,sflags,window__mMisc); window__doTable(select,sizeof(select)/2,sflags,window__mSelect); window__doTable(icon,sizeof(icon)/2,sflags,window__mIcon); window__doTable(guide,sizeof(guide)/2,sflags,window__mGuide); for (i=0;i<16;i++) tearoff_shadeItem(window__mButton,i+1,(s_s & sflags)!=0); for (i=0;itestMode); #endif tearoff_selectItem(window__mSelect,glass_TWSORDER,w && w->renumber); /* --- That's it, then --- * * * We need to remember which window all of this applies to so that the * user doesn't get all confused. */ window__menuWin=w; } /* * void window__gridBox(glass_windPointer *w) * * Use * Displays and processes a grid dialogue box */ static void window__gridBox(glass_windPointer *w) { dbox d; dbox_field f; buttons_simpleArrow sa={0,999,FALSE}; wimp_redrawstr r; BOOL shade; BOOL done=FALSE; wimp_wstate s; if (d=dbox_create("grid"),!d) return; dbox_selecticon(d,glass_GDISP,w->gridShow); dbox_selecticon(d,glass_GLOCK,w->gridLock); dbox_setfield(d,glass_GWWRITE,"%i",w->gridx); dbox_setfield(d,glass_GHWRITE,"%i",w->gridy); shade=!(w->gridShow || w->gridLock); dbox_shadeicon(d,glass_GWUP,shade); dbox_shadeicon(d,glass_GWDOWN,shade); dbox_shadeicon(d,glass_GWWRITE,shade); dbox_shadeicon(d,glass_GHUP,shade); dbox_shadeicon(d,glass_GHDOWN,shade); dbox_shadeicon(d,glass_GHWRITE,shade); dbox_display(d,dbox_MENU_OVERPTR); done=FALSE; while (!done) { switch (f=dbox_fillin(d),f) { case dbox_CLOSE: done=TRUE; break; case glass_GOK: dbox_clickicon(d,glass_GOK); w->gridShow=dbox_selecticon(d,glass_GDISP,dbox_READSTATE); w->gridLock=dbox_selecticon(d,glass_GLOCK,dbox_READSTATE); dbox_scanfield(d,glass_GWWRITE,"%d",&w->gridx); dbox_scanfield(d,glass_GHWRITE,"%d",&w->gridy); wimpt_noerr(wimp_get_wind_state(w->h,&s)); r.w=w->h; r.box.x0=s.o.x; r.box.x1=r.box.x0+s.o.box.x1-s.o.box.x0; r.box.y1=s.o.y; r.box.y0=r.box.y1+s.o.box.y0-s.o.box.y1; wimpt_noerr(wimp_force_redraw(&r)); window__updateMenu(w); if (!dbox_wasAdjustClick()) dbox_hide(d); dbox_unclick(); if (!dbox_wasAdjustClick()) done=TRUE; break; case glass_GDISP: case glass_GLOCK: shade=!(dbox_selecticon(d,glass_GDISP,dbox_READSTATE) || dbox_selecticon(d,glass_GLOCK,dbox_READSTATE)); dbox_shadeicon(d,glass_GWUP,shade); dbox_shadeicon(d,glass_GWDOWN,shade); dbox_shadeicon(d,glass_GWWRITE,shade); dbox_shadeicon(d,glass_GHUP,shade); dbox_shadeicon(d,glass_GHDOWN,shade); dbox_shadeicon(d,glass_GHWRITE,shade); break; case glass_GWUP: buttons_arrow(d,f,d,glass_GWWRITE,0,+1,&sa); break; case glass_GWDOWN: buttons_arrow(d,f,d,glass_GWWRITE,0,-1,&sa); break; case glass_GHUP: buttons_arrow(d,f,d,glass_GHWRITE,0,+1,&sa); break; case glass_GHDOWN: buttons_arrow(d,f,d,glass_GHWRITE,0,-1,&sa); break; } } dbox_delete(d); } /* * void window__thHelp(char *prefix,int hit) * * Use * Does help for a tearoff menu. * * Parameters * char *prefix == pointer to prefix string * int hit == which item */ static void window__thHelp(char *prefix,int hit) { char *p=buffer_find(); sprintf(p,"%s%i",prefix,hit); help_startHelp(); help_addLine(msgs_lookup(p)); help_endHelp(); } /* * void window__mhRoot(tearoff_message m,int hit,void *handle) * * Use * Handles events on the root menu * * Parameters * tearoff_message m == what happened * int hit == what item it happened to * void *handle == nothing interesting */ static void window__mhRoot(tearoff_message m,int hit,void *handle) { glass_windPointer *w=handle ? handle : window__menuWin; unused(handle); switch (m) { case tearoff_HELP: window__thHelp("wmhRT",hit); break; case tearoff_SELECTION: case tearoff_SUBMENU: switch (hit) { case glass_TWSAVE: if (w) tfile_saveWindow(w); break; case glass_TWEDIT: tearEdit_open(); break; case glass_TWGRID: #ifndef glass_DEMO if (w && !w->renumber && !w->testMode) window__gridBox(w); #else if (w && !w->renumber) window__gridBox(w); #endif break; } break; } } /* * void window__mhMisc(tearoff_message m,int hit,void *handle) * * Use * Handles events on the misc submenu * * Parameters * tearoff_message m == what happened * int hit == what item it happened to * void *handle == nothing interesting */ static void window__mhMisc(tearoff_message m,int hit,void *handle) { glass_windPointer *w=handle ? handle : window__menuWin; int i; int stop; BOOL checked; BOOL done; int xoff,yoff; wimp_box b; #ifndef glass_DEMO wimp_wstate s; wimp_caretstr c; wimp_icon icn; wimp_w whand; glass_windPointer *wso=window_selectionOwner(); #endif unused(handle); switch (m) { case tearoff_HELP: window__thHelp("wmhMSC",hit); break; case tearoff_SELECTION: case tearoff_SUBMENU: switch (hit) { case glass_TWMINFO: if (w) tfile_windowInfo(w); break; case glass_TWMEDITWIN: editWindow(w); break; #ifndef glass_DEMO case glass_TWMTEST: checked=!gPrefs_current()->cTest; if (w->edit) { if (!checked) { if (!warning(msgs_lookup("wdTCEP"),msgs_lookup("wdTCE"))) return; checked=TRUE; } editWindow_close(w); } for (i=0;idef->desc.w.nicons;i++) { if (w->def->i[i].edit) { if (!checked) { if (!warning(msgs_lookup("wdTCEP"),msgs_lookup("wdTCE"))) return; checked=TRUE; } editIcon_close(w,i); } } if (w->testMode) /* Are we coming out of test mode? */ { for (i=0;idef->desc.w.nicons;i++) { wimpt_noerr(wimp_get_icon_info(w->h,i,&icn)); if (memcmp(&icn,&w->def->i[i].i,sizeof(wimp_icon))) { tfile_markAsAltered(w->t); w->def->i[i].i=icn; } } } w->testMode=!w->testMode; if (whand=window__recreate(w),!whand) { w->testMode=!w->testMode; return; } wimpt_noerr(wimp_get_wind_state(w->h,&s)); if (w->ownPointer) { win_removeIdleClaimer(window__winIdles,w); window__setPtrShape(window__SELECT); } wimpt_noerr(wimp_close_wind(w->h)); /* Closed, guv'nor */ win_register_event_handler(w->h,0,0); /* Won't need this now */ wimpt_noerr(wimp_delete_wind(w->h)); /* Delete the window */ w->h=whand; win_register_event_handler(w->h, w->testMode ? window__testEvents : window__events,w); s.o.w=w->h; if (w==wso) window__toggleTest(w); wimpt_noerr(wimp_open_wind(&s.o)); if (w==wso) { window__setToolBarPositions(0); if (w->testMode) { if (window__selectedIcon()!=-1) tearEdit_update(0,-1); } else { c.w=w->h; c.i=-1; c.x=w->def->desc.w.ex.x0-50; c.y=0; c.height=0x02000000; c.index=-1; wimpt_noerr(wimp_set_caret_pos(&c)); tearEdit_update(w,window__selectedIcon()); } } window__updateMenu(w); /* --- Our good mate the Window Manager --- * * * Because the RISC OS 3 Window Manager is about as braindead as * it's possible to get without being written by Microsoft, it * decides that it would be a simply super idea to move our window * back on the screen at this point, screwing up the cached window * position. */ wimpt_noerr(wimp_get_wind_state(w->h,&s)); if (memcmp(&s.o.box,&w->def->desc.w,24)) { w->def->desc.w.box=s.o.box; w->def->desc.w.scx=s.o.x; w->def->desc.w.scy=s.o.y; if (!w->t->alts) tfile_markAsAltered(w->t); } break; #endif case glass_TWMREMDEL: stop=w->def->desc.w.nicons-1; done=FALSE; for (i=0;i<=stop;i++) { if (w->def->i[i].i.flags & wimp_IDELETED) { window_renumber(w,i--,stop--); done=TRUE; } } if (done) { window__removeTrailingDeleted(w); tfile_markAsAltered(w->t); } break; case glass_TWMBRINGBK: for (i=0;idef->desc.w.nicons;i++) { window_boundingBox(w,i,&b); xoff=yoff=0; if (b.x0def->desc.w.ex.x0) xoff=w->def->desc.w.ex.x0-b.x0; if (b.x1>w->def->desc.w.ex.x1) xoff=w->def->desc.w.ex.x1-b.x1; if (b.y0def->desc.w.ex.y0) yoff=w->def->desc.w.ex.y0-b.y0; if (b.y1>w->def->desc.w.ex.y1) yoff=w->def->desc.w.ex.y1-b.y1; if (xoff || yoff) { b.x0+=xoff; b.x1+=xoff; b.y0+=yoff; b.y1+=yoff; window_setBox(w,i,&b); tfile_markAsAltered(w->t); } } break; case glass_TWMCLOSE: event_clear_current_menu(); window_close(w); break; } break; } } /* * void window__mhSelect(tearoff_message m,int hit,void *handle) * * Use * Handles events on the select submenu * * Parameters * tearoff_message m == what happened * int hit == what item it happened to * void *handle == nothing interesting */ static void window__mhSelect(tearoff_message m,int hit,void *handle) { glass_windPointer *w=handle ? handle : window__menuWin; int i; BOOL stop; BOOL checked; wimp_box b; int xoff,yoff; unused(handle); switch (m) { case tearoff_HELP: window__thHelp("wmhSEL",hit); break; case tearoff_SELECTION: case tearoff_SUBMENU: switch (hit) { case glass_TWSALL: window__gainSelection(w); for (i=0;idef->desc.w.nicons;i++) window__select(w,i,TRUE); window__updateMenu(w); break; case glass_TWSCLR: window__gainSelection(w); for (i=0;idef->desc.w.nicons;i++) window__select(w,i,FALSE); window__updateMenu(w); break; case glass_TWSCOPY: window__copyIcons(w); window__updateMenu(w); break; case glass_TWSDEL: if (gPrefs_current()->cDelIcon) { if (!warning(msgs_lookup("wdCDIP"),msgs_lookup("wdCDI"))) return; } i=0; while (idef->desc.w.nicons) { if (w->def->i[i].selected) window_deleteIcon(w,i); else i++; } window__updateMenu(w); break; case glass_TWSFRONT: stop=w->def->desc.w.nicons-1; for (i=0;i<=stop;i++) { if (w->def->i[i].selected) { window_renumber(w,i,w->def->desc.w.nicons-1); i--; stop--; } } tfile_markAsAltered(w->t); break; case glass_TWSRAISE: if (w->def->i[w->def->desc.w.nicons - 1].selected) { bbc_vdu(7); break; } for (i=w->def->desc.w.nicons - 1; i >= 0; i--) { if (w->def->i[i].selected) window_renumber(w, i, i + 1); } tfile_markAsAltered(w->t); break; case glass_TWSLOWER: if (w->def->i[0].selected) { bbc_vdu(7); break; } for (i = 0; i < w->def->desc.w.nicons ;i++) { if (w->def->i[i].selected) window_renumber(w, i, i - 1); } tfile_markAsAltered(w->t); break; case glass_TWSBACK: stop=0; for (i=w->def->desc.w.nicons-1;i>=stop;i--) { if (w->def->i[i].selected) { window_renumber(w,i,0); i++; stop++; } } tfile_markAsAltered(w->t); break; case glass_TWSORDER: checked=!gPrefs_current()->cTest; if (w->edit) { if (!checked) { if (!warning(msgs_lookup("wdTCRP"),msgs_lookup("wdTCR"))) return; checked=TRUE; } editWindow_close(w); } for (i=0;idef->desc.w.nicons;i++) { if (w->def->i[i].edit) { if (!checked) { if (!warning(msgs_lookup("wdTCRP"),msgs_lookup("wdTCR"))) return; checked=TRUE; } editIcon_close(w,i); } } window__renumber(w,!w->renumber); window__updateMenu(w); break; case glass_TWSPULL: for (i=0;idef->desc.w.nicons;i++) { if (w->def->i[i].selected) { window_boundingBox(w,i,&b); xoff=b.x1-b.x0; yoff=b.y1-b.y0; window__align(w,&b.x0,&b.y1); b.x1=b.x0+xoff; b.y0=b.y1-yoff; window_setBox(w,i,&b); tfile_markAsAltered(w->t); } } break; case glass_TWSALIGN: align(); break; case glass_TWSEDIT: for (i=0;idef->desc.w.nicons;i++) { if (w->def->i[i].selected) editIcon(w,i); } break; } break; } } /* * void window__mhButton(tearoff_message m,int hit,void *handle) * * Use * Handles events on the foo submenu * * Parameters * tearoff_message m == what happened * int hit == what item it happened to * void *handle == nothing interesting */ static void window__mhButton(tearoff_message m,int hit,void *handle) { glass_windPointer *w=handle ? handle : window__menuWin; int i; unused(handle); switch (m) { case tearoff_HELP: window__thHelp("wmhBUT",hit); break; case tearoff_SELECTION: case tearoff_SUBMENU: if (hit) { for (i=0;idef->desc.w.nicons;i++) { if (w->def->i[i].selected) { w->def->i[i].i.flags&=~0x0000f000; w->def->i[i].i.flags|=(hit-1)<<12; tfile_markAsAltered(w->t); } } } break; } } /* * void window__newIcon(int which,glass_windPointer *w) * * Use * Creates a new icon in the window. * * Parameters * int which == which icon type to use * glass_windPointer *w == the window to build it in */ static void window__newIcon(int which,glass_windPointer *w) { int i; wimp_wind *wdef; wimp_icon *idef; wimp_box b; int xoff,yoff; const static wimp_icon defidef={0,0,200,48,0x0f00603f,""}; if (i=window__createIcon(w),i==-1) return; wdef=&template_find("default")->window; idef=(wimp_icon *)(wdef+1); switch (wdef->nicons) { case 0: w->def->i[i].i=defidef; break; default: w->def->i[i].i=idef[which]; break; } if (!iconData_handleFont(w,&w->def->i[i].i.flags)) werr(FALSE,msgs_lookup("wdFERCI")); if (!iconData_processIcon(w,i,0,TRUE,0)) { werr(FALSE,msgs_lookup("wdNEMCI")); w->def->i[i].i.flags&=~wimp_INDIRECT; window_deleteIcon(w,i); return; } window_boundingBox(w,i,&b); xoff=window__menuX-b.x0; yoff=window__menuY-b.y1; if (w->gridLock) window__align(w,&xoff,&yoff); w->def->i[i].i.box.x0+=xoff; w->def->i[i].i.box.x1+=xoff; w->def->i[i].i.box.y0+=yoff; w->def->i[i].i.box.y1+=yoff; window_redrawIcon(w,i); tfile_markAsAltered(w->t); window__menuX+=w->gridx; window__menuY-=w->gridy; } /* * void window__mhIcon(tearoff_message m,int hit,void *handle) * * Use * Handles events on the icon submenu * * Parameters * tearoff_message m == what happened * int hit == what item it happened to * void *handle == nothing interesting */ static void window__mhIcon(tearoff_message m,int hit,void *handle) { glass_windPointer *w=handle ? handle : window__menuWin; unused(handle); switch (m) { case tearoff_HELP: window__thHelp("wmhICN",hit); break; case tearoff_SELECTION: case tearoff_SUBMENU: switch (hit) { case glass_TWINEW: window__newIcon(0,w); window__updateMenu(w); break; case glass_TWIPAL: window__showPalette(); break; case glass_TWIGRAB: window_grab(window__grabIcon,w); break; } break; } } /* * void window__mhCreate(tearoff_message m,int hit,void *handle) * * Use * Handles events on the new icon submenu * * Parameters * tearoff_message m == what happened * int hit == what item it happened to * void *handle == nothing interesting */ static void window__mhCreate(tearoff_message m,int hit,void *handle) { glass_windPointer *w=handle ? handle : window__menuWin; unused(handle); if (!w) { bbc_vdu(7); return; } switch (m) { case tearoff_HELP: help_startHelp(); help_addLine(msgs_lookup("wmhNI")); help_endHelp(); break; case tearoff_SELECTION: case tearoff_SUBMENU: if (hit) { window__newIcon(hit-1,w); window__updateMenu(w); } break; } } /* * void window__mhGuide(tearoff_message m,int hit,void *handle) * * Use * Handles events on the guide submenu * * Parameters * tearoff_message m == what happened * int hit == what item it happened to * void *handle == nothing interesting */ static void window__mhGuide(tearoff_message m,int hit,void *handle) { glass_windPointer *w=handle ? handle : window__menuWin; int i; unused(handle); switch (m) { case tearoff_HELP: window__thHelp("wmhGD",hit); break; case tearoff_SELECTION: case tearoff_SUBMENU: switch (hit) { case glass_TWGSELALL: window__gainSelection(w); for (i=0;iguide[i].active && !w->guide[i].selected) { w->guide[i].selected=TRUE; window__redrawGuide(w,i); } } window__updateMenu(w); break; case glass_TWGCLRSEL: for (i=0;iguide[i].active && w->guide[i].selected) { w->guide[i].selected=FALSE; window__redrawGuide(w,i); } } window__updateMenu(w); break; case glass_TWGHORIZ: for (i=0;iguide[i].active) { w->guide[i].active=TRUE; w->guide[i].horiz=TRUE; w->guide[i].coord=window__menuY; w->guide[i].selected=FALSE; window__redrawGuide(w,i); window__menuY-=w->gridy; break; } } if (i==glass_GUIDELIMIT) note(msgs_lookup("wdTMG"),glass_GUIDELIMIT); window__updateMenu(w); break; case glass_TWGVERT: for (i=0;iguide[i].active) { w->guide[i].active=TRUE; w->guide[i].horiz=FALSE; w->guide[i].coord=window__menuX; w->guide[i].selected=FALSE; window__redrawGuide(w,i); window__menuX+=w->gridx; break; } } if (i==glass_GUIDELIMIT) note(msgs_lookup("wdTMG"),glass_GUIDELIMIT); window__updateMenu(w); break; case glass_TWGDEL: for (i=0;iguide[i].active && w->guide[i].selected) { w->guide[i].active=w->guide[i].selected=FALSE; window__redrawGuide(w,i); } } window__updateMenu(w); break; } break; } } /* * void window__simMenu(glass_windPointer *w,int hit1,int hit2) * * Use * Simulates a menu hit on the specified item. Gives a beep if the item * is unavailable. Otherwise, the hit is sent to the current selection * owner. [fixed to allow which window is used rather than only the * selection owner, 1 November 1993] * * Use * glass_windPointer *w == the window in which to simulate the event * int hit1 == first hit in the sequence * int hit2 == second hit in the sequence */ void window__simMenu(glass_windPointer *w,int hit1,int hit2) { /* --- A bit of a hack(tm) --- * * * The old Wimp-menu based code used to simulate menu events to try to * do key shortcuts and the button bar. We try to emulate the old * behaviour, although the implementation is a /little/ different. The * old code used to peek about in the menu blocks to find submenus. * We can't do this any more, because the tearoff structure is hidden, * so we keep a big table of our own to help us find our way around. * Actually, this makes the code /much/ smaller. */ const static struct { tearoff_selectProc p; tearoff *t; } table[]={ window__mhRoot, &window__mRoot, /* Funny entry for root menu */ window__mhMisc, &window__mMisc, 0, 0, window__mhSelect, &window__mSelect, window__mhIcon, &window__mIcon, 0, 0, window__mhButton, &window__mButton }; if (!hit2) hit2=hit1; if (table[hit1].t && !tearoff_isShaded(*table[hit1].t,hit2)) table[hit1].p(tearoff_SELECTION,hit2,w); else bbc_vdu(7); } /* * void window__showMenu(int x,int y,glass_windPointer *w) * * Use * Displays the Template Window Menu * * Parameters * int x,int y == the (window) position to display the menu * glass_windPointer *w == the window to display the menu for */ void window__showMenu(int x,int y,glass_windPointer *w) { window__menuX=x; window__menuY=y; window__updateMenu(w); tearoff_displayMenu(window__mRoot,w); } /* * void window__menuInit(void) * * Use * Initialises the create icon menu */ void window__menuInit(void) { wimp_wind *wdef; wimp_icon *idef; int i; char *p; char buff[15]; /* --- First set up the create menu --- */ template_readfile(choices_name("Defaults.Templates",FALSE)); wdef=&template_find("default")->window; idef=(wimp_icon *)(wdef+1); window__newIcons=wdef->nicons; switch (wdef->nicons) { case 0: case 1: break; default: for (i=0;inicons;i++) { if (idef[i].flags & wimp_INDIRECT) { p=idef[i].data.indirecttext.buffer; utils_ctermToNterm(p); if (*p=='`') p++; if (window__mCreate) window__mCreate=tearoff_extendMenu(window__mCreate,p); else window__mCreate=tearoff_create(msgs_lookup("wdCRTMT"), p,TRUE,window__mhCreate,800,0); if (p[-1]=='`') { p[-1]=0; idef[i].data.indirecttext.bufflen=1; } } else { memcpy(buff,idef[i].data.text,12); utils_ctermToNterm(buff); buff[12]=0; p=buff; if (*p=='`') p++; if (window__mCreate) window__mCreate=tearoff_extendMenu(window__mCreate,p); else window__mCreate=tearoff_create(msgs_lookup("wdCRTMT"), p,TRUE,window__mhCreate,800,0); if (p[-1]=='`') p[-1]=0; } } break; } /* --- Create the main menu tree --- */ window__mRoot=tearoff_create(msgs_lookup("wdWMT"), msgs_lookup("wdWM"), TRUE,window__mhRoot,0,0); window__mMisc=tearoff_create(msgs_lookup("wdMISCMT"), msgs_lookup("wdMISCM"), FALSE,window__mhMisc,0,0); window__mSelect=tearoff_create(msgs_lookup("wdSELMT"), msgs_lookup("wdSELM"), TRUE,window__mhSelect,0,0); window__mIcon=tearoff_create(msgs_lookup("wdICNMT"), msgs_lookup("wdICNM"), FALSE,window__mhIcon,0,0); window__mGuide=tearoff_create(msgs_lookup("wdGDEMT"), msgs_lookup("wdGDEM"), TRUE,window__mhGuide,0,0); window__mButton=tearoff_create(msgs_lookup("eiBTMT"), msgs_lookup("eiBTYPE0"), FALSE, window__mhButton, 0, 0); p=buffer_find(); for (i=1;i<=15;i++) { sprintf(p,"eiBTYPE%i",i); window__mButton=tearoff_extendMenu(window__mButton,msgs_lookup(p)); } tearoff_attachSubMenu(window__mRoot,glass_TWMISC,window__mMisc); tearoff_attachSubMenu(window__mRoot,glass_TWSELECT,window__mSelect); tearoff_attachSubMenu(window__mRoot,glass_TWICON,window__mIcon); tearoff_attachSubMenu(window__mRoot,glass_TWGDE,window__mGuide); tearoff_attachSubMenu(window__mSelect,glass_TWSBTYPE,window__mButton); if (window__mCreate) tearoff_attachSubMenu(window__mIcon,glass_TWINEW,window__mCreate); }