/* * wToolbars.c * * Handling of the tool and info bars * * © 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/interface.h" #include "steel/sculptrix.h" #include "steel/buttons.h" #include "steel/caretPtr.h" #include "steel/flex.h" #include "steel/akbd.h" #include "steel/coords.h" #include "steel/pointer.h" #include "steel/bbc.h" #include "steel/colourtran.h" #include "steel/font.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 "intMsgs.h" #include "toolbox.h" #include "editIcon.h" #include "editWin.h" #include "indir.h" #include "align.h" #include "iconData.h" #include "tearEdit.h" /*----- Private variables -------------------------------------------------*/ static dbox window__toolbar; /* Dialogue box handle for the tool bar */ static dbox window__infobar; /* Dialogue box handle for the info bar */ static window__infoWidth; /* The natural width of the info bar */ static window__infoMax; /* The maximum width of the info bar */ static int window__toolX=98; static int window__toolY=912; static int window__infoX=234; static int window__infoY=260; /*----- Main code ---------------------------------------------------------*/ /* * void window__setToolBarPositions(wimp_openstr *o) * * Use * Displays the tool and info bars according to current settings etc. * * Parameters * wimp_openstr *o == the position of the selection owner window, or 0. * This is updated to put the window somewhere nice without flicker. */ void window__setToolBarPositions(wimp_openstr *o) { wimp_wstate s; wimp_wstate t; wimp_redrawstr r; int width; int height; int tgap,bgap,lgap,rgap; glass_windPointer *w=window_selectionOwner(); /* --- More WindowManager cunningness --- * * * When you click on the scroll arrows, the Wimp decides it'd be a good * plan to ask you to open the window behind *itself*. This gets nobbled * here, and so the whole window frame flickes disgustingly. We bodge. * We also try to do absolutely nothing if the window isn't going anywhere. */ if (o && !wimpt_justChangedMode() && (o->behind==o->w || (!memcmp(&o->box,&w->def->desc.w.box,sizeof(wimp_box)) && o->behind==w->def->desc.w.behind))) { wimpt_noerr(wimp_open_wind(o)); return; } wimpt_noerr(wimp_get_wind_state(w->h,&t)); r.w=t.o.w; wimpt_noerr(wimp_getwindowoutline(&r)); lgap=t.o.box.x0-r.box.x0; rgap=r.box.x1-t.o.box.x1; tgap=r.box.y1-t.o.box.y1; bgap=t.o.box.y0-r.box.y0; if (o) { t.o=*o; if (o->behind==-2) { wimpt_noerr(wimp_open_wind(o)); wimpt_noerr(wimp_get_wind_state(w->h,&t)); } } if (window__infobar && !gPrefs_current()->iFloating) { if (t.o.behind==dbox_syshandle(window__infobar)) { wimpt_noerr(wimp_get_wind_state(dbox_syshandle(window__infobar),&s)); t.o.behind=s.o.behind; } } if (window__toolbar && !gPrefs_current()->tFloating) { if (t.o.behind==dbox_syshandle(window__toolbar)) { wimpt_noerr(wimp_get_wind_state(dbox_syshandle(window__toolbar),&s)); t.o.behind=s.o.behind; } } if (t.flags & wimp_WCLICK_TOGGLE && o) { wimpt_noerr(wimp_open_wind(o)); wimpt_noerr(wimp_get_wind_state(w->h,&t)); } if (window__toolbar) { wimpt_noerr(wimp_get_wind_state(dbox_syshandle(window__toolbar),&s)); width=s.o.box.x1-s.o.box.x0; height=s.o.box.y1-s.o.box.y0; if (!gPrefs_current()->tFloating) { if (gPrefs_current()->tLeft) s.o.box.x0=gPrefs_current()->tPosn.x-width+t.o.box.x0-lgap; else s.o.box.x0=gPrefs_current()->tPosn.x-width+t.o.box.x1+rgap; s.o.box.x1=s.o.box.x0+width; s.o.box.y1=gPrefs_current()->tPosn.y+t.o.box.y1+tgap-wimpt_dy(); s.o.box.y0=s.o.box.y1-height; window__toolX=s.o.box.x1; window__toolY=s.o.box.y1; s.o.behind=t.o.behind; t.o.behind=s.o.w; } else { s.o.box.x0=window__toolX-width; s.o.box.x1=s.o.box.x0+width; s.o.box.y1=window__toolY; s.o.box.y0=s.o.box.y1-height; } win_adjustBox(&s.o); wimpt_noerr(wimp_open_wind(&s.o)); } if (window__infobar) { wimpt_noerr(wimp_get_wind_state(dbox_syshandle(window__infobar),&s)); height=s.o.box.y1-s.o.box.y0; width=(w->renumber ? window__infoMax : window__infoWidth); if (!gPrefs_current()->iFloating) { s.o.box.x0=gPrefs_current()->iPosn.x+t.o.box.x0-lgap+wimpt_dx(); s.o.box.x1=s.o.box.x0+width; if (gPrefs_current()->iUnder) s.o.box.y1=gPrefs_current()->iPosn.y+t.o.box.y0-bgap; else s.o.box.y1=gPrefs_current()->iPosn.y+t.o.box.y1+tgap; s.o.box.y0=s.o.box.y1-height; window__infoX=s.o.box.x0; window__infoY=s.o.box.y1; s.o.behind=t.o.behind; t.o.behind=s.o.w; } else { s.o.box.x0=window__infoX; s.o.box.x1=s.o.box.x0+width; s.o.box.y1=window__infoY; s.o.box.y0=s.o.box.y1-height; } win_adjustBox(&s.o); wimpt_noerr(wimp_open_wind(&s.o)); } if (o) { o->behind=t.o.behind; wimpt_noerr(wimp_open_wind(o)); } } /* * void window__updateInfoBar(void) * * Use * Updates the settings on the info bar. If a setting hasn't changed, then * it isn't updated (reducing flicker). * * Parameters * BOOL force == whether to force an update of everything. */ void window__updateInfoBar(BOOL force) { static int ox=-1; static int oy=-1; static glass_windPointer *ow; static int oi=-2; static int orenum=-1; int x,y; int ni; glass_windPointer *wso=window_selectionOwner(); wimp_mousestr m; unused(orenum); if (force) { ox=-1; oy=-1; ow=0; oi=-2; orenum=-1; } if (!window__infobar) return; if (wso!=ow) dbox_setfield(window__infobar,glass_IBWIND,"%s",wso->id); ow=wso; wimpt_noerr(wimp_get_point_info(&m)); x=ow->def->desc.w.box.x0-ow->def->desc.w.scx; y=ow->def->desc.w.box.y1-ow->def->desc.w.scy; m.x-=x; m.y-=y; if (m.w!=ow->h || m.i<-1) { m.x=-3; m.y=-3; } if (m.x!=ox) { switch (m.x) { case -3: dbox_setfield(window__infobar,glass_IBX,""); break; default: dbox_setfield(window__infobar,glass_IBX,"%i",m.x); break; } } if (m.y!=oy) { switch (m.y) { case -3: dbox_setfield(window__infobar,glass_IBY,""); break; default: dbox_setfield(window__infobar,glass_IBY,"%i",m.y); break; } } ox=m.x; oy=m.y; if (m.x==-3) ni=-3; #ifndef glass_DEMO else if (wso->testMode) ni=m.i; #endif else { ni=window__pointerInfo(ow,-1,FALSE); if (ni & window__ZONEMASK) ni=-1; } if (ni!=oi) { switch (ni) { case -3: dbox_setfield(window__infobar,glass_IBICON,""); break; case -1: dbox_setfield(window__infobar,glass_IBICON,msgs_lookup("wdBACKG")); break; default: dbox_setfield(window__infobar,glass_IBICON,"%i",ni); break; } oi=ni; } } /* * BOOL window__toolRaw(dbox d,wimp_eventstr *e,void *handle) * * Use * Handles odd events for tool and info boxes (mainly moves - getting the * positioning right, updating the preferences entries and so on). * * Parameters * dbox d == the dialogue box handle * wimp_eventstr *e == the event that happened * void *handle == a pointer (ignored) * * Returns * TRUE if the event has been processed. */ static BOOL window__toolRaw(dbox d,wimp_eventstr *e,void *handle) { BOOL handled=FALSE; wimp_wstate s; wimp_wstate t; wimp_redrawstr r; int tgap,bgap,lgap,rgap; BOOL more; glass_windPointer *wso=window_selectionOwner(); unused(handle); switch (e->e) { case wimp_EREDRAW: if (d==window__infobar) { r.w=e->data.o.w; wimpt_noerr(wimp_redraw_wind(&r,&more)); while (more) { wimp_setcolour(0x81); bbc_clg(); sculptrix_redrawWindow(&r); wimpt_noerr(wimp_get_rectangle(&r,&more)); } handled=TRUE; } break; case wimp_EOPEN: if (wimpt_justChangedMode()) /* We've already moved them with the */ { /* main window, so the WIMP just messes */ handled=TRUE; /* it all up */ break; } win_adjustBox(&e->data.o); wimpt_noerr(wimp_get_wind_state(wso->h,&s)); r.w=s.o.w; wimpt_noerr(wimp_getwindowoutline(&r)); lgap=s.o.box.x0-r.box.x0; rgap=r.box.x1-s.o.box.x1; tgap=r.box.y1-s.o.box.y1; bgap=s.o.box.y0-r.box.y0; wimpt_noerr(wimp_get_wind_state(e->data.o.w,&t)); if (d==window__toolbar) { if (!gPrefs_current()->tFloating) { gPrefs_current()->tLeft=abs(e->data.o.box.x1-s.o.box.x0)< abs(e->data.o.box.x0-s.o.box.x1); if (gPrefs_current()->tLeft) gPrefs_current()->tPosn.x=e->data.o.box.x1-s.o.box.x0+lgap; else gPrefs_current()->tPosn.x=e->data.o.box.x1-s.o.box.x1-rgap; gPrefs_current()->tPosn.y=e->data.o.box.y1-s.o.box.y1-tgap+ wimpt_dy(); e->data.o.behind=t.o.behind; } window__toolX=e->data.o.box.x1; window__toolY=e->data.o.box.y1; } else if (d==window__infobar) { if (!gPrefs_current()->iFloating) { gPrefs_current()->iUnder=abs(e->data.o.box.y1-s.o.box.y0)< abs(e->data.o.box.y0-s.o.box.y1); gPrefs_current()->iPosn.x=e->data.o.box.x0-s.o.box.x0; if (gPrefs_current()->iUnder) gPrefs_current()->iPosn.y=e->data.o.box.y1-s.o.box.y0+bgap; else gPrefs_current()->iPosn.y=e->data.o.box.y1-s.o.box.y1-tgap; e->data.o.behind=t.o.behind; } window__infoX=e->data.o.box.x0; window__infoY=e->data.o.box.y1; } wimpt_noerr(wimp_open_wind(&e->data.o)); handled=TRUE; break; } return (handled); } /* * void window__infoEvents(dbox d,dbox_field f,void *handle) * * Use * Handles events on the info bar. * * Parameters * dbox d == the dialogue box handle * dbox_field f == the event that happened * void *handle == a pointer (ignored) */ static void window__infoEvents(dbox d,dbox_field f,void *handle) { wimp_dragstr dr; #ifndef glass_DEMO glass_windPointer *wso=window_selectionOwner(); #endif unused(handle); switch (f) { case glass_IBDRAG: dr.window=dbox_syshandle(d); dr.type=wimp_MOVE_WIND; wimp_drag_box(&dr); break; #ifndef glass_DEMO case glass_IBEDIT: if (wso->testMode) window__simMenu(wso,glass_TWMISC,glass_TWMTEST); break; case glass_IBTEST: if (!wso->testMode) window__simMenu(wso,glass_TWMISC,glass_TWMTEST); break; #endif case dbox_HELP: help_startHelp(); help_addLine(msgs_lookup("wdhIB")); help_readFromIcon(); help_endHelp(); break; } } /* * void window__toolEvents(dbox d,dbox_field f,void *handle) * * Use * Handles events on the tool bar. * * Parameters * dbox d == the dialogue box handle * dbox_field f == the event that happened * void *handle == a pointer (ignored) */ static void window__toolEvents(dbox d,dbox_field f,void *handle) { wimp_dragstr dr; glass_windPointer *wso=window_selectionOwner(); static int hit1[]= { 0, glass_TWMISC, glass_TWICON, glass_TWSELECT, glass_TWSELECT, glass_TWMISC, glass_TWSELECT, glass_TWSELECT, }; static int hit2[]= { 0, glass_TWMCLOSE, glass_TWINEW, glass_TWSDEL, glass_TWSCOPY, glass_TWMEDITWIN, glass_TWSEDIT, glass_TWSORDER, }; unused(handle); switch (f) { case glass_TBDRAG: dr.window=dbox_syshandle(d); dr.type=wimp_MOVE_WIND; wimp_drag_box(&dr); break; case dbox_HELP: help_startHelp(); help_addLine(msgs_lookup("wdhTB")); help_readFromIcon(); help_endHelp(); break; default: if (f>=0 && f<=(sizeof(hit1)/sizeof(int))) { dbox_clickicon(d,f); window__simMenu(wso,hit1[f],hit2[f]); dbox_unclick(); } break; } } /* * void window_updateToolbar(void) * * Use * Updates the display of toolbars as necessary in line with new * Preferences settings. It is assumed that Preferences is intelligent * enough to only call this if something actually needs to be done! */ void window_updateToolbar(void) { glass_windPointer *wso=window_selectionOwner(); if (!wso) /* Nothing doing if no current window */ return; if (gPrefs_current()->tDisplay) { if (!window__toolbar) { window__toolbar=dbox_create("toolbar"); if (window__toolbar) { dbox_eventHandler(window__toolbar,window__toolEvents,0); dbox_rawEventHandler(window__toolbar,window__toolRaw,0); } } } else { if (window__toolbar) dbox_delete(window__toolbar); window__toolbar=0; } if (gPrefs_current()->iDisplay) { if (!window__infobar) { window__infobar=dbox_create("infobar"); if (window__infobar) { dbox_eventHandler(window__infobar,window__infoEvents,0); dbox_rawEventHandler(window__infobar,window__toolRaw,0); #ifdef glass_DEMO dbox_shadeicon(window__infobar,glass_IBEDIT,TRUE); dbox_shadeicon(window__infobar,glass_IBTEST,TRUE); dbox_selecticon(window__infobar,glass_IBEDIT,TRUE); dbox_selecticon(window__infobar,glass_IBTEST,FALSE); #else dbox_selecticon(window__infobar,glass_IBEDIT,!wso->testMode); dbox_selecticon(window__infobar, glass_IBTEST,wso->testMode); dbox_shadeicon(window__infobar,glass_IBEDIT,wso->renumber); dbox_shadeicon(window__infobar,glass_IBTEST,wso->renumber); #endif if (wso->renumber) { dbox_setfield(window__infobar, glass_IBRENUM,"%i", window__lowestSelected(wso)); } } } window__updateInfoBar(TRUE); } else { if (window__infobar) dbox_delete(window__infobar); window__infobar=0; } window__setToolBarPositions(0); } /* * void window__toggleRenumber(glass_windPointer *w) * * Use * Updates the info bar after entering or leaving renumber-mode. w is * the currently selected window. */ void window__toggleRenumber(glass_windPointer *w) { if (window__infobar) { if (w->renumber) { dbox_setfield(window__infobar, glass_IBRENUM, "%i", window__lowestSelected(w)); } #ifndef glass_DEMO dbox_shadeicon(window__infobar,glass_IBEDIT,w->renumber); dbox_shadeicon(window__infobar,glass_IBTEST,w->renumber); #else dbox_shadeicon(window__infobar,glass_IBEDIT,TRUE); dbox_shadeicon(window__infobar,glass_IBTEST,TRUE); #endif window__setToolBarPositions(0); } } /* * void window__toggleTest(glass_windPointer *w) * * Use * Updates the info bar after entering or leaving test-mode. w is the * currently selected window. */ #ifndef glass_DEMO void window__toggleTest(glass_windPointer *w) { if (window__infobar) { dbox_selecticon(window__infobar,glass_IBEDIT,!w->testMode); dbox_selecticon(window__infobar,glass_IBTEST,w->testMode); } } #endif /* * void window__updateInfoName(char *newname) * * Use * Updates the name in the info bar */ void window__updateInfoName(char *newname) { if (window__infobar) dbox_setfield(window__infobar,glass_IBWIND,"%s",newname); } /* * void window__nextRenumber(glass_windPointer *w) * * Use * Updates the next renumber icon number display. */ void window__nextRenumber(glass_windPointer *w) { if (window__infobar) { dbox_setfield(window__infobar,glass_IBRENUM,"%i", window__lowestSelected(w)); } } /* * void window__moveToolbars(glass_windPointer *w) * * Use * Moves the toolbars and attaches them to a new window * * Parameters * glass_windPointer *w == the window to attach the bars to */ void window__moveToolbars(glass_windPointer *w) { if (w) { if (!window__toolbar && gPrefs_current()->tDisplay) { window__toolbar=dbox_create("toolbar"); if (window__toolbar) { dbox_eventHandler(window__toolbar,window__toolEvents,0); dbox_rawEventHandler(window__toolbar,window__toolRaw,0); } } if (!window__infobar && gPrefs_current()->iDisplay) { window__infobar=dbox_create("infobar"); if (window__infobar) { dbox_eventHandler(window__infobar,window__infoEvents,0); dbox_rawEventHandler(window__infobar,window__toolRaw,0); } } window__updateInfoBar(TRUE); window__setToolBarPositions(0); if (window__infobar) { #ifdef glass_DEMO dbox_shadeicon(window__infobar,glass_IBEDIT,TRUE); dbox_shadeicon(window__infobar,glass_IBTEST,TRUE); dbox_selecticon(window__infobar,glass_IBEDIT,TRUE); dbox_selecticon(window__infobar,glass_IBTEST,FALSE); #else dbox_selecticon(window__infobar,glass_IBEDIT,!w->testMode); dbox_selecticon(window__infobar,glass_IBTEST,w->testMode); dbox_shadeicon(window__infobar,glass_IBEDIT,w->renumber); dbox_shadeicon(window__infobar,glass_IBTEST,w->renumber); #endif if (w->renumber) { dbox_setfield(window__infobar, glass_IBRENUM, "%i", window__lowestSelected(w)); } } } else { if (window__toolbar) dbox_delete(window__toolbar); if (window__infobar) dbox_delete(window__infobar); window__toolbar=0; window__infobar=0; } } /* * void window__tbarInit(void) * * Use * Initialises the toolbar system */ void window__tbarInit(void) { wimp_wind *wdef; wdef=&template_find("infobar")->window; window__infoWidth=wdef->box.x1-wdef->box.x0; window__infoMax=wdef->ex.x1-wdef->ex.x0; }