4 * Manipulation of template windows
6 * © 1994-1998 Straylight
9 /*----- Licensing note ----------------------------------------------------*
11 * This file is part of Straylight's Glass.
13 * Glass is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2, or (at your option)
18 * Glass is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with Glass. If not, write to the Free Software Foundation,
25 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28 /*----- Header files ------------------------------------------------------*/
31 * ANSI standard headers
44 #include "steel/Steel.h"
46 #include "steel/flex.h"
62 /*----- Main code ---------------------------------------------------------*/
65 * wimp_w window__recreate(glass_windPointer *w)
68 * Recreates a window, getting all the fiddly bits right.
71 * glass_windPointer *w == the window
74 * The window handle, or 0 for failure
77 wimp_w window__recreate(glass_windPointer *w)
83 /* --- Update all the sprite areas for the title bar and icons --- */
85 icf=w->def->desc.w.titleflags;
86 if ((icf & wimp_INDIRECT) && (icf & wimp_ISPRITE) && !(icf & wimp_ITEXT))
87 w->def->desc.w.title.indirectsprite.spritearea=w->t->s;
88 for (i=0;i<w->def->desc.w.nicons;i++)
90 icf=w->def->i[i].i.flags;
91 if ((icf & wimp_INDIRECT) && (icf & wimp_ISPRITE) && !(icf & wimp_ITEXT))
92 w->def->i[i].i.data.indirectsprite.spritearea=w->t->s;
95 /* --- If we're in test mode, allocate space for all the icons --- */
103 if (!flex_alloc((flex_ptr)&wp,
105 w->def->desc.w.nicons*sizeof(wimp_icon)))
108 /* --- Copy the window data across from our main structure --- */
111 ip=(wimp_icon *)(wp+1);
112 for (i=0;i<w->def->desc.w.nicons;i++)
113 ip[i]=w->def->i[i].i;
114 wp->spritearea=w->t->s;
116 /* --- Mangle the flags a little --- */
118 wp->flags&=~wimp_WPANE; /* Strange things occur if we don't... */
119 wp->flags&=~wimp_BACK_WINDOW; /* Don't let Pinboard hide my windows */
120 wp->flags&=~wimp_HOT_KEYS; /* Don't grab hot keys -- no use for them */
122 /* --- Bodge the window extent --- *
124 * Since the visible area can now `stretch' the window extent, we may
125 * need to bodge the extent for a bit
128 wp->ex.x1=max2(wp->ex.x1,wp->scx+wp->box.x1-wp->box.x0);
129 wp->ex.y0=min2(wp->ex.y0,wp->scy-wp->box.y1+wp->box.y0);
132 /* --- Try to create the window --- */
134 if (wimpt_complain(wimp_create_wind(wp,&wh)))
136 flex_free((flex_ptr)&wp);
139 flex_free((flex_ptr)&wp);
141 /* --- Bodge for WimpExtension being buggy --- *
143 * WimpExtension doesn't accept NULL-terminated strings for all its
144 * validation strings, so we have to go through them all and return-
145 * terminate them :-(. Hopefully we won't have to do this when
146 * WimpExtension II is ready.
149 #ifndef window__WimpExtension_works_with_null_terminated_strings
150 for (i=0;i<w->def->desc.w.nicons;i++)
152 if ( (w->def->i[i].i.flags & wimp_INDIRECT) &&
153 (w->def->i[i].i.flags & wimp_ITEXT) &&
154 (w->def->i[i].i.data.indirecttext.validstring!=(char *)-1) )
157 for (j=w->def->i[i].i.data.indirecttext.validstring;*j>=32;j++)
168 /* --- We're creating the window for editing -- don't make icons --- */
175 wdef.ex.x1=max2(wdef.ex.x1,wdef.scx+wdef.box.x1-wdef.box.x0);
176 wdef.ex.y0=min2(wdef.ex.y0,wdef.scy-wdef.box.y1+wdef.box.y0);
179 wdef.nicons=0; /* We draw the icons ourselves */
180 wdef.spritearea=w->t->s; /* Set up sprite area */
181 wdef.workflags=wimp_BCLICKDRAGDOUBLE<<12;
182 wdef.flags|=wimp_WMOVEABLE; /* Make window movable (Acorn karnt spel) */
183 wdef.flags&=~wimp_REDRAW_OK; /* We need to draw the icons! */
184 wdef.flags&=~wimp_WPANE; /* Show the highlight on the actual window*/
185 wdef.flags&=~wimp_BACK_WINDOW; /* Let it come to the front nicely */
186 wdef.flags&=~wimp_HOT_KEYS; /* Don't grab hot keys -- no use for them */
187 if (wimpt_complain(wimp_create_wind(&wdef,&wh)))
188 return(0); /* Don't be too unhappy if it failed */
191 win_activeinc(); /* Pointless convention, but there you go */
196 * void window__nudgeScroll(glass_windPointer *w,int x,int y)
199 * Scrolls the window a bit, by adding the x and y values given to the
200 * scroll offsets of the window. The values are multiplied up to give a
201 * sensible sized scroll.
204 * glass_windPointer *w == the window to scroll
205 * int x == the x scroll offset to add
206 * int y == the y scroll offset to add
209 void window__nudgeScroll(glass_windPointer *w,int x,int y)
213 /* --- Scroll the window --- */
215 wimpt_noerr(wimp_get_wind_state(w->h,&s));
218 wimpt_noerr(wimp_open_wind(&s.o));
219 wimpt_noerr(wimp_get_wind_state(w->h,&s));
221 /* --- Write the new scroll values back to the window block --- */
223 if (s.o.x!=w->def->desc.w.scx || s.o.y!=w->def->desc.w.scy)
225 w->def->desc.w.scx=s.o.x;
226 w->def->desc.w.scy=s.o.y;
227 if (!w->t->alts) /* Moving the window alters the template */
228 tfile_markAsAltered(w->t); /* But only if not already altered */
229 editWindow_windowMoved(w);
234 * void window_hasBeenDeleted(glass_windPointer *w)
237 * Informs the window system that a window is about to be deleted.
240 * glass_windPointer *w == the window that bites the dust
243 void window_hasBeenDeleted(glass_windPointer *w)
245 if (window_selectionOwner()==w)
246 window__gainSelection(0);
247 if (window__menuOwner()==w)
248 window__updateMenu(0);
251 win_removeIdleClaimer(window__winIdles,w);
252 window__setPtrShape(window__SELECT);
257 * void window_recreate(glass_windPointer *w)
260 * Recreates a window after editing. Nothing happens if the window is not
261 * open already. If an error occurs, the open window is removed and left
265 * glass_windPointer *w == the window to recreate
268 void window_recreate(glass_windPointer *w)
274 wimpt_noerr(wimp_get_wind_state(w->h,&s));
275 wimpt_noerr(wimp_delete_wind(w->h));
276 win_register_event_handler(w->h,0,0);
278 if (wnd=window__recreate(w),!wnd)
280 win_register_event_handler(wnd,window__events,w);
283 wimpt_noerr(wimp_open_wind(&s.o));
284 window_updateToolbar();
288 * void window_close(glass_windPointer *w)
291 * Closes the specified window.
294 * glass_windPointer *w == the window wot we 'ave to close
297 void window_close(glass_windPointer *w)
304 wimpt_noerr(wimp_close_wind(w->h)); /* Closed, guv'nor */
305 if (window_selectionOwner()==w)
306 window__gainSelection(0);
311 for (i=0;i<w->def->desc.w.nicons;i++)
313 wimpt_noerr(wimp_get_icon_info(w->h,i,&icn));
314 if (memcmp(&icn,&w->def->i[i].i,sizeof(wimp_icon)))
316 tfile_markAsAltered(w->t);
326 win_removeIdleClaimer(window__winIdles,w);
327 window__setPtrShape(window__SELECT);
329 win_register_event_handler(w->h,0,0); /* Window won't need this now */
330 wimpt_noerr(wimp_delete_wind(w->h)); /* Delete the window */
331 w->h=0; /* Make sure nobody does anything stupid */
333 if (window__menuOwner()==w)
334 window__updateMenu(0);
338 * void window_open(glass_windPointer *w,BOOL test)
341 * Opens the specified window. If the window is off-screen, it is moved
342 * back. This routine also registers all handlers required for editing the
343 * window etc. If the window is already open, it is brought to the front.
346 * glass_windPointer *w == pointer to basic window information.
347 * BOOL test == open in test mode or not
350 void window_open(glass_windPointer *w,BOOL test)
355 /* --- Create the window if it doesn't exist yet --- */
359 /* --- Allow tfile to set the test flag --- */
367 /* --- Unselect all the window's icons and guides --- */
369 for (i=0;i<w->def->desc.w.nicons;i++)
371 w->def->i[i].selected=FALSE;
372 w->def->i[i].copied=FALSE;
375 for (i=0;i<glass_GUIDELIMIT;i++)
376 w->guide[i].selected=FALSE;
382 /* --- Finally, create the window and attach the event handler --- */
384 if (w->h=window__recreate(w),!w->h)
388 win_register_event_handler(w->h,window__testEvents,w);
391 win_register_event_handler(w->h,window__events,w);
393 /* --- Now we can open the window --- */
395 wimpt_noerr(wimp_get_wind_state(w->h,&s));
396 s.o.behind=-1; /* Open the window on top of the screen */
397 win_adjustBox(&s.o); /* Make sure it goes on the screen! */
398 wimpt_noerr(wimp_open_wind(&s.o)); /* Go! */
399 wimpt_noerr(wimp_get_wind_state(w->h,&s)); /* Find out where it went */
400 w->def->desc.w.box=s.o.box;
401 w->def->desc.w.scx=s.o.x;
402 w->def->desc.w.scy=s.o.y;
403 w->def->desc.w.behind=s.o.behind;
404 editWindow_windowMoved(w);
405 if (window_selectionOwner()==w)
406 window_updateToolbar();