/* * wWindows.c * * Manipulation of template windows * * © 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/flex.h" /* * Glass headers */ #include "gStruct.h" #include "gMenus.h" #include "gIcons.h" #include "glass.h" #include "tfile.h" #include "window.h" #include "_window.h" #include "editWin.h" /*----- Main code ---------------------------------------------------------*/ /* * wimp_w window__recreate(glass_windPointer *w) * * Use * Recreates a window, getting all the fiddly bits right. * * Parameters * glass_windPointer *w == the window * * Returns * The window handle, or 0 for failure */ wimp_w window__recreate(glass_windPointer *w) { wimp_iconflags icf; wimp_w wh; int i; /* --- Update all the sprite areas for the title bar and icons --- */ icf=w->def->desc.w.titleflags; if ((icf & wimp_INDIRECT) && (icf & wimp_ISPRITE) && !(icf & wimp_ITEXT)) w->def->desc.w.title.indirectsprite.spritearea=w->t->s; for (i=0;idef->desc.w.nicons;i++) { icf=w->def->i[i].i.flags; if ((icf & wimp_INDIRECT) && (icf & wimp_ISPRITE) && !(icf & wimp_ITEXT)) w->def->i[i].i.data.indirectsprite.spritearea=w->t->s; } /* --- If we're in test mode, allocate space for all the icons --- */ #ifndef glass_DEMO if (w->testMode) { wimp_wind *wp; wimp_icon *ip; if (!flex_alloc((flex_ptr)&wp, sizeof(wimp_wind)+ w->def->desc.w.nicons*sizeof(wimp_icon))) return (0); /* --- Copy the window data across from our main structure --- */ *wp=w->def->desc.w; ip=(wimp_icon *)(wp+1); for (i=0;idef->desc.w.nicons;i++) ip[i]=w->def->i[i].i; wp->spritearea=w->t->s; /* --- Mangle the flags a little --- */ wp->flags&=~wimp_WPANE; /* Strange things occur if we don't... */ wp->flags&=~wimp_BACK_WINDOW; /* Don't let Pinboard hide my windows */ wp->flags&=~wimp_HOT_KEYS; /* Don't grab hot keys -- no use for them */ /* --- Bodge the window extent --- * * * Since the visible area can now `stretch' the window extent, we may * need to bodge the extent for a bit */ wp->ex.x1=max2(wp->ex.x1,wp->scx+wp->box.x1-wp->box.x0); wp->ex.y0=min2(wp->ex.y0,wp->scy-wp->box.y1+wp->box.y0); w->tex=wp->ex; /* --- Try to create the window --- */ if (wimpt_complain(wimp_create_wind(wp,&wh))) { flex_free((flex_ptr)&wp); return (0); } flex_free((flex_ptr)&wp); /* --- Bodge for WimpExtension being buggy --- * * * WimpExtension doesn't accept NULL-terminated strings for all its * validation strings, so we have to go through them all and return- * terminate them :-(. Hopefully we won't have to do this when * WimpExtension II is ready. */ #ifndef window__WimpExtension_works_with_null_terminated_strings for (i=0;idef->desc.w.nicons;i++) { if ( (w->def->i[i].i.flags & wimp_INDIRECT) && (w->def->i[i].i.flags & wimp_ITEXT) && (w->def->i[i].i.data.indirecttext.validstring!=(char *)-1) ) { char *j; for (j=w->def->i[i].i.data.indirecttext.validstring;*j>=32;j++) /* thing */; *j=0x0d; } } #endif } else #endif /* --- We're creating the window for editing -- don't make icons --- */ { wimp_wind wdef; wdef=w->def->desc.w; wdef.ex.x1=max2(wdef.ex.x1,wdef.scx+wdef.box.x1-wdef.box.x0); wdef.ex.y0=min2(wdef.ex.y0,wdef.scy-wdef.box.y1+wdef.box.y0); w->tex=wdef.ex; wdef.nicons=0; /* We draw the icons ourselves */ wdef.spritearea=w->t->s; /* Set up sprite area */ wdef.workflags=wimp_BCLICKDRAGDOUBLE<<12; wdef.flags|=wimp_WMOVEABLE; /* Make window movable (Acorn karnt spel) */ wdef.flags&=~wimp_REDRAW_OK; /* We need to draw the icons! */ wdef.flags&=~wimp_WPANE; /* Show the highlight on the actual window*/ wdef.flags&=~wimp_BACK_WINDOW; /* Let it come to the front nicely */ wdef.flags&=~wimp_HOT_KEYS; /* Don't grab hot keys -- no use for them */ if (wimpt_complain(wimp_create_wind(&wdef,&wh))) return(0); /* Don't be too unhappy if it failed */ } win_activeinc(); /* Pointless convention, but there you go */ return (wh); } /* * void window__nudgeScroll(glass_windPointer *w,int x,int y) * * Use * Scrolls the window a bit, by adding the x and y values given to the * scroll offsets of the window. The values are multiplied up to give a * sensible sized scroll. * * Parameters * glass_windPointer *w == the window to scroll * int x == the x scroll offset to add * int y == the y scroll offset to add */ void window__nudgeScroll(glass_windPointer *w,int x,int y) { wimp_wstate s; /* --- Scroll the window --- */ wimpt_noerr(wimp_get_wind_state(w->h,&s)); s.o.x+=x*32; s.o.y+=y*32; wimpt_noerr(wimp_open_wind(&s.o)); wimpt_noerr(wimp_get_wind_state(w->h,&s)); /* --- Write the new scroll values back to the window block --- */ if (s.o.x!=w->def->desc.w.scx || s.o.y!=w->def->desc.w.scy) { w->def->desc.w.scx=s.o.x; w->def->desc.w.scy=s.o.y; if (!w->t->alts) /* Moving the window alters the template */ tfile_markAsAltered(w->t); /* But only if not already altered */ editWindow_windowMoved(w); } } /* * void window_hasBeenDeleted(glass_windPointer *w) * * Use * Informs the window system that a window is about to be deleted. * * Parameters * glass_windPointer *w == the window that bites the dust */ void window_hasBeenDeleted(glass_windPointer *w) { if (window_selectionOwner()==w) window__gainSelection(0); if (window__menuOwner()==w) window__updateMenu(0); if (w->ownPointer) { win_removeIdleClaimer(window__winIdles,w); window__setPtrShape(window__SELECT); } } /* * void window_recreate(glass_windPointer *w) * * Use * Recreates a window after editing. Nothing happens if the window is not * open already. If an error occurs, the open window is removed and left * that way. * * Parameters * glass_windPointer *w == the window to recreate */ void window_recreate(glass_windPointer *w) { wimp_wstate s; wimp_w wnd; if (!w->h) return; wimpt_noerr(wimp_get_wind_state(w->h,&s)); wimpt_noerr(wimp_delete_wind(w->h)); win_register_event_handler(w->h,0,0); win_activedec(); if (wnd=window__recreate(w),!wnd) return; win_register_event_handler(wnd,window__events,w); w->h=wnd; s.o.w=w->h; wimpt_noerr(wimp_open_wind(&s.o)); window_updateToolbar(); } /* * void window_close(glass_windPointer *w) * * Use * Closes the specified window. * * Parameters * glass_windPointer *w == the window wot we 'ave to close */ void window_close(glass_windPointer *w) { #ifndef glass_DEMO int i; wimp_icon icn; #endif wimpt_noerr(wimp_close_wind(w->h)); /* Closed, guv'nor */ if (window_selectionOwner()==w) window__gainSelection(0); #ifndef glass_DEMO if (w->testMode) { 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; } } } else #endif if (w->ownPointer) { win_removeIdleClaimer(window__winIdles,w); window__setPtrShape(window__SELECT); } win_register_event_handler(w->h,0,0); /* Window won't need this now */ wimpt_noerr(wimp_delete_wind(w->h)); /* Delete the window */ w->h=0; /* Make sure nobody does anything stupid */ if (window__menuOwner()==w) window__updateMenu(0); } /* * void window_open(glass_windPointer *w,BOOL test) * * Use * Opens the specified window. If the window is off-screen, it is moved * back. This routine also registers all handlers required for editing the * window etc. If the window is already open, it is brought to the front. * * Parameters * glass_windPointer *w == pointer to basic window information. * BOOL test == open in test mode or not */ void window_open(glass_windPointer *w,BOOL test) { wimp_wstate s; int i; /* --- Create the window if it doesn't exist yet --- */ if (!w->h) { /* --- Allow tfile to set the test flag --- */ #ifndef glass_DEMO w->testMode=test; #else unused(test); #endif /* --- Unselect all the window's icons and guides --- */ for (i=0;idef->desc.w.nicons;i++) { w->def->i[i].selected=FALSE; w->def->i[i].copied=FALSE; } for (i=0;iguide[i].selected=FALSE; w->lastClicked=-1; w->selno=0; w->ownPointer=FALSE; w->renumber=FALSE; /* --- Finally, create the window and attach the event handler --- */ if (w->h=window__recreate(w),!w->h) return; #ifndef glass_DEMO if (test) win_register_event_handler(w->h,window__testEvents,w); else #endif win_register_event_handler(w->h,window__events,w); } /* --- Now we can open the window --- */ wimpt_noerr(wimp_get_wind_state(w->h,&s)); s.o.behind=-1; /* Open the window on top of the screen */ win_adjustBox(&s.o); /* Make sure it goes on the screen! */ wimpt_noerr(wimp_open_wind(&s.o)); /* Go! */ wimpt_noerr(wimp_get_wind_state(w->h,&s)); /* Find out where it went */ w->def->desc.w.box=s.o.box; w->def->desc.w.scx=s.o.x; w->def->desc.w.scy=s.o.y; w->def->desc.w.behind=s.o.behind; editWindow_windowMoved(w); if (window_selectionOwner()==w) window_updateToolbar(); }