Initial revision
[ssr] / StraySrc / Glass / !Glass / c / editIcon
1 /*
2 * editIcon.c
3 *
4 * Edit icon dialogue box
5 *
6 * © 1994-1998 Straylight
7 */
8
9 /*----- Licensing note ----------------------------------------------------*
10 *
11 * This file is part of Straylight's Glass.
12 *
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)
16 * any later version.
17 *
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.
22 *
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.
26 */
27
28 /*----- Header files ------------------------------------------------------*/
29
30 /*
31 * ANSI standard headers
32 */
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37
38 /*
39 * Steel headers
40 */
41
42 #define _STDAPP
43 #define _LOWLVL
44 #include "steel/Steel.h"
45
46 #include "steel/buttons.h"
47 #include "steel/fontMenu.h"
48 #include "steel/akbd.h"
49 #include "steel/bbc.h"
50 #include "steel/buffer.h"
51 #include "steel/font.h"
52
53 /*
54 * Glass headers
55 */
56
57 #include "gStruct.h"
58 #include "gMenus.h"
59 #include "gIcons.h"
60
61 #include "glass.h"
62 #include "tfile.h"
63 #include "window.h"
64 #include "intMsgs.h"
65 #include "editIcon.h"
66 #include "colSelect.h"
67 #include "indir.h"
68 #include "gPrefs.h"
69
70 /*----- Static variables --------------------------------------------------*/
71
72 static char *editIcon__panels[]=
73 {
74 "iconData",
75 "iconAppear",
76 "iconActions",
77 "iconColours",
78 "iconPos",
79 "iconSize",
80 };
81
82 /*----- Support routines --------------------------------------------------*/
83
84 #define max2(a,b) ((a)>(b) ? (a) : (b))
85 #define min2(a,b) ((a)<(b) ? (a) : (b))
86
87 /*
88 * void editIcon__setupPanel(glass_editIcon *ed)
89 *
90 * Use
91 * Sets up a panel from the icon description given.
92 *
93 * Parameters
94 * glass_editIcon *ed == the edit to handle.
95 */
96
97 static void editIcon__setupPanel(glass_editIcon *ed)
98 {
99 char *p;
100
101 switch (ed->e.panel)
102 {
103 case glass_EIDATA:
104 dbox_setfield(ed->e.pd,glass_EIDVALSTRING,"%s",ed->valid);
105 dbox_setfield(ed->e.pd,glass_EIDDATA,"%s",ed->data);
106 if (!(ed->idef.flags&3))
107 {
108 dbox_shadeicon(ed->e.pd,glass_EIDINDIR,TRUE);
109 dbox_shadeicon(ed->e.pd,glass_EIDDATA,TRUE);
110 dbox_selecticon(ed->e.pd,glass_EIDINDIR,FALSE);
111 dbox_selecticon(ed->e.pd,glass_EIDVALID,FALSE);
112 dbox_shadeicon(ed->e.pd,glass_EIDVALSTRING,TRUE);
113 dbox_shadeicon(ed->e.pd,glass_EIDVALID,TRUE);
114 dbox_shadeicon(ed->e.pd,glass_EIDINDSIZE,TRUE);
115 dbox_shadeicon(ed->e.pd,glass_EIDINDUP,TRUE);
116 dbox_shadeicon(ed->e.pd,glass_EIDINDDOWN,TRUE);
117 dbox_shadeicon(ed->e.pd,glass_EIDMINIMISE,TRUE);
118 dbox_shadeicon(ed->e.pd,glass_EIDINDPART,TRUE);
119 dbox_setfield(ed->e.pd,glass_EIDINDSIZE,"%i",12);
120 }
121 else if (ed->idef.flags & wimp_INDIRECT)
122 {
123 dbox_shadeicon(ed->e.pd,glass_EIDINDIR,FALSE);
124 dbox_shadeicon(ed->e.pd,glass_EIDDATA,FALSE);
125 dbox_selecticon(ed->e.pd,glass_EIDINDIR,TRUE);
126 dbox_selecticon(ed->e.pd,glass_EIDVALID,ed->hasValid);
127 dbox_shadeicon(ed->e.pd,glass_EIDVALSTRING,!ed->hasValid);
128 dbox_shadeicon(ed->e.pd,glass_EIDVALID,
129 !(ed->idef.flags&wimp_ITEXT));
130 dbox_shadeicon(ed->e.pd,glass_EIDINDSIZE,FALSE);
131 dbox_shadeicon(ed->e.pd,glass_EIDINDUP,FALSE);
132 dbox_shadeicon(ed->e.pd,glass_EIDINDDOWN,FALSE);
133 dbox_shadeicon(ed->e.pd,glass_EIDMINIMISE,FALSE);
134 dbox_shadeicon(ed->e.pd,glass_EIDINDPART,FALSE);
135 dbox_setfield(ed->e.pd,glass_EIDINDSIZE,"%i",ed->indLen);
136 }
137 else
138 {
139 dbox_shadeicon(ed->e.pd,glass_EIDINDIR,FALSE);
140 dbox_shadeicon(ed->e.pd,glass_EIDDATA,FALSE);
141 dbox_selecticon(ed->e.pd,glass_EIDINDIR,FALSE);
142 dbox_selecticon(ed->e.pd,glass_EIDVALID,FALSE);
143 dbox_shadeicon(ed->e.pd,glass_EIDVALSTRING,TRUE);
144 dbox_shadeicon(ed->e.pd,glass_EIDVALID,TRUE);
145 dbox_shadeicon(ed->e.pd,glass_EIDINDSIZE,TRUE);
146 dbox_shadeicon(ed->e.pd,glass_EIDINDUP,TRUE);
147 dbox_shadeicon(ed->e.pd,glass_EIDINDDOWN,TRUE);
148 dbox_shadeicon(ed->e.pd,glass_EIDMINIMISE,TRUE);
149 dbox_shadeicon(ed->e.pd,glass_EIDINDPART,TRUE);
150 dbox_setfield(ed->e.pd,glass_EIDINDSIZE,"%i",12);
151 }
152 dbox_selecticon(ed->e.pd,glass_EIDTEXT,
153 !!(ed->idef.flags&wimp_ITEXT));
154 dbox_selecticon(ed->e.pd,glass_EIDSPRITE,
155 !!(ed->idef.flags&wimp_ISPRITE));
156 break;
157 case glass_EIAPPEARANCE:
158 dbox_setfield(ed->e.pd,glass_EIAFONTNAME,"%.%s",ed->font);
159 dbox_setfield(ed->e.pd,glass_EIAFSIZEWRITE,"%i",ed->fontSize);
160 if (ed->idef.flags & wimp_ITEXT)
161 {
162 if (ed->idef.flags & wimp_IFONT)
163 {
164 dbox_selecticon(ed->e.pd,glass_EIAFONT,TRUE);
165 dbox_shadeicon(ed->e.pd,glass_EIAFONTNAME,FALSE);
166 dbox_shadeicon(ed->e.pd,glass_EIAFONTMENU,FALSE);
167 dbox_shadeicon(ed->e.pd,glass_EIAFONT,FALSE);
168 dbox_shadeicon(ed->e.pd,glass_EIAFSIZEUP,FALSE);
169 dbox_shadeicon(ed->e.pd,glass_EIAFSIZEDOWN,FALSE);
170 dbox_shadeicon(ed->e.pd,glass_EIAFSIZEWRITE,FALSE);
171 }
172 else
173 {
174 dbox_selecticon(ed->e.pd,glass_EIAFONT,FALSE);
175 dbox_shadeicon(ed->e.pd,glass_EIAFONT,FALSE);
176 dbox_shadeicon(ed->e.pd,glass_EIAFONTNAME,TRUE);
177 dbox_shadeicon(ed->e.pd,glass_EIAFONTMENU,TRUE);
178 dbox_shadeicon(ed->e.pd,glass_EIAFSIZEUP,TRUE);
179 dbox_shadeicon(ed->e.pd,glass_EIAFSIZEDOWN,TRUE);
180 dbox_shadeicon(ed->e.pd,glass_EIAFSIZEWRITE,TRUE);
181 }
182 }
183 else
184 {
185 dbox_selecticon(ed->e.pd,glass_EIAFONT,FALSE);
186 dbox_shadeicon(ed->e.pd,glass_EIAFONT,TRUE);
187 dbox_shadeicon(ed->e.pd,glass_EIAFONTNAME,TRUE);
188 dbox_shadeicon(ed->e.pd,glass_EIAFONTMENU,TRUE);
189 dbox_shadeicon(ed->e.pd,glass_EIAFSIZEUP,TRUE);
190 dbox_shadeicon(ed->e.pd,glass_EIAFSIZEDOWN,TRUE);
191 dbox_shadeicon(ed->e.pd,glass_EIAFSIZEWRITE,TRUE);
192 }
193 dbox_selecticon(ed->e.pd,glass_EIAHCENTRE,
194 !!(ed->idef.flags & wimp_IHCENTRE));
195 dbox_selecticon(ed->e.pd,glass_EIAVCENTRE,
196 !!(ed->idef.flags & wimp_IVCENTRE));
197 dbox_selecticon(ed->e.pd,glass_EIARALIGN,
198 !!(ed->idef.flags & wimp_IRJUST));
199 dbox_selecticon(ed->e.pd,glass_EIABORDER,
200 !!(ed->idef.flags & wimp_IBORDER));
201 dbox_selecticon(ed->e.pd,glass_EIAFILL,
202 !!(ed->idef.flags & wimp_IFILLED));
203 if (ed->idef.flags & wimp_ISPRITE)
204 {
205 dbox_selecticon(ed->e.pd,glass_EIAHALFSIZE,
206 !!(ed->idef.flags & wimp_IHALVESPRITE));
207 dbox_shadeicon(ed->e.pd,glass_EIAHALFSIZE,FALSE);
208 }
209 else
210 {
211 dbox_selecticon(ed->e.pd,glass_EIAHALFSIZE,FALSE);
212 dbox_shadeicon(ed->e.pd,glass_EIAHALFSIZE,TRUE);
213 }
214 dbox_selecticon(ed->e.pd,glass_EIANEEDSHELP,
215 !!(ed->idef.flags & wimp_IREDRAW));
216 break;
217 case glass_EIACTIONS:
218 p=buffer_find();
219 sprintf(p,"eiBTYPE%i",(ed->idef.flags>>12) & 0x0f);
220 dbox_setfield(ed->e.pd,glass_EIABTYPE,"%s",msgs_lookup(p));
221 dbox_setfield(ed->e.pd,glass_EIAESGWRITE,"%i",
222 (ed->idef.flags>>16) & 0x1f);
223 dbox_selecticon(ed->e.pd,glass_EIAADJUST,
224 !!(ed->idef.flags & wimp_IESG_NOC));
225 dbox_selecticon(ed->e.pd,glass_EIASELECT,
226 !!(ed->idef.flags & wimp_ISELECTED));
227 dbox_selecticon(ed->e.pd,glass_EIASHADE,
228 !!(ed->idef.flags & wimp_INOSELECT));
229 break;
230 case glass_EICOLOURS:
231 colSelect_setColourButton(ed->e.pd,glass_EICFORE,
232 (ed->idef.flags>>24) & 15);
233 colSelect_setColourButton(ed->e.pd,glass_EICBACK,
234 (ed->idef.flags>>28) & 15);
235 break;
236 case glass_EISIZE:
237 dbox_setfield(ed->e.pd,
238 glass_EIPWRITE,
239 "%i,%i",
240 ed->idef.box.x1-ed->idef.box.x0,
241 ed->idef.box.y1-ed->idef.box.y0);
242 dbox_shadeicon(ed->e.pd,glass_EIPSETSIZE,!(ed->idef.flags & 3));
243 break;
244 case glass_EIPOSITION:
245 dbox_setfield(ed->e.pd,
246 glass_EIPWRITE,
247 "%i,%i",
248 ed->idef.box.x0,
249 ed->idef.box.y0);
250 break;
251 }
252 }
253
254 /*
255 * BOOL editIcon__getSpriteSize(char *name,sprite_area *a,int *x,int *y)
256 *
257 * Use
258 * Attempts to read the size of a sprite in OS units.
259 *
260 * Returns
261 * TRUE if it really worked
262 */
263
264 static BOOL editIcon__getSpriteSize(char *name,sprite_area *a,int *x,int *y)
265 {
266 os_error *e;
267 os_regset r;
268
269 /* --- First look in the given area --- */
270
271 e=os_swivr(OS_SpriteOp,&r,40+256,a,name);
272
273 /* --- Now, OS version permitting, look in the WIMP area --- */
274
275 if (e && wimpt_getVersion()>=300)
276 e=os_swivr(Wimp_SpriteOp,&r,40,0,name);
277
278 /* --- If it worked, read out all the info and return it --- */
279
280 if (!e)
281 {
282 *x=r.r[3]<<bbc_modevar(r.r[6],bbc_XEigFactor);
283 *y=r.r[4]<<bbc_modevar(r.r[6],bbc_YEigFactor);
284 }
285
286 /* --- Return the success value --- */
287
288 return (!e);
289 }
290
291 /*
292 * void editIcon__setSize(glass_editIcon *ed)
293 *
294 * Use
295 * Reads the size of the icon correctly from the definition, assuming
296 * various things:
297 *
298 * 1. The icon isn't word-wrapped
299 * 2. Both selected and unselected versions of the sprite to use are the
300 * same size
301 * 3. Size is independent of things like button type
302 */
303
304 static void editIcon__setSize(glass_editIcon *ed)
305 {
306 int w,h;
307 int sw,sh;
308 char sname[15];
309 static int posns[]={1,1,2,2,1,1,3,2};
310 int f;
311 char *sprname;
312
313 /* --- Read the current width and height from dbox --- */
314
315 dbox_scanfield(ed->e.pd,glass_EIPWRITE,"%d,%d",&w,&h);
316
317 /* --- Find out if this is going to be easy --- */
318
319 switch (ed->idef.flags & 3)
320 {
321 /* --- No icon data -- ignore this operation --- */
322
323 case 0:
324 break;
325
326 /* --- Only text -- work it out (assuming system font size) --- */
327
328 case 1:
329 h=48;
330 w=16*(strlen(ed->data)+1);
331 break;
332
333 /* --- Only a sprite -- use the size of the sprite --- */
334
335 case 2:
336 if (!editIcon__getSpriteSize(ed->data,ed->w->t->s,&w,&h))
337 note(msgs_lookup("eiSPRGONE"),ed->data);
338 break;
339
340 /* --- Text and sprite together --- */
341
342 case 3:
343 sprname=ed->data;
344
345 if ((ed->idef.flags & 0x100) && ed->hasValid)
346 {
347 /* --- Parse the validation string to find the sprite name --- */
348
349 int state=1;
350 char *p=ed->valid;
351 char *q=sname;
352
353 for (;*p>31 && state!=3;p++)
354 {
355 switch (*p)
356 {
357 case '\\':
358 if (p[1]>31)
359 p++;
360 if (state==1)
361 state=0;
362 else if (state==2)
363 *q++=*p;
364 break;
365 case ';':
366 if (state>1)
367 {
368 *q++=0;
369 state=3;
370 }
371 else
372 state=1;
373 break;
374 case 'S':
375 case 's':
376 if (state==1)
377 state=2;
378 else if (state==2)
379 *q++=*p;
380 break;
381 case ',':
382 switch (state)
383 {
384 case 2:
385 *q++=0;
386 state++;
387 }
388 break;
389 default:
390 switch (state)
391 {
392 case 1:
393 state=0;
394 break;
395 case 2:
396 *q++=*p;
397 break;
398 }
399 break;
400 }
401 }
402
403 if (state==2)
404 {
405 *q++=0;
406 state=3;
407 }
408
409 if (state==3)
410 sprname=sname;
411 }
412
413 if (editIcon__getSpriteSize(sprname,ed->w->t->s,&sw,&sh))
414 {
415 if (ed->data[0])
416 {
417 h=48;
418 w=16*(strlen(ed->data)+1);
419
420 f=posns[(tst(ed->idef.flags,3)<<2) |
421 (tst(ed->idef.flags,4)<<1) |
422 (tst(ed->idef.flags,9)<<0)];
423
424 if (f & 2)
425 h=max2(h,sh);
426 else
427 h+=sh;
428
429 if (f & 1)
430 w=max2(w,sw);
431 else
432 w+=sw;
433 }
434 else
435 {
436 h=sh;
437 w=sw;
438 }
439 }
440 else
441 note(msgs_lookup("eiSPRGONE"),sprname);
442 break;
443 }
444
445 dbox_setfield(ed->e.pd,glass_EIPWRITE,"%i,%i",w,h);
446 }
447
448 /*
449 * void editIcon__closePanel(glass_editIcon *ed)
450 *
451 * Use
452 * Records the settings in a panel for future reference, for example when
453 * the panel is being replaced by a different one.
454 *
455 * Parameters
456 * glass_editIcon *ed == the edit box we're talking about
457 */
458
459 #define Q dbox_READSTATE
460
461 static void editIcon__closePanel(glass_editIcon *ed)
462 {
463 int esg;
464 int x,y;
465 switch (ed->e.panel)
466 {
467 case glass_EIDATA:
468 dbox_getfield(ed->e.pd,glass_EIDDATA,ed->data,256);
469 dbox_getfield(ed->e.pd,glass_EIDVALSTRING,ed->valid,256);
470 dbox_scanfield(ed->e.pd,glass_EIDINDSIZE,"%d",&ed->indLen);
471 ed->hasValid=dbox_selecticon(ed->e.pd,glass_EIDVALID,Q);
472 ed->idef.flags&=~0x00000103;
473 ed->idef.flags|=dbox_selecticon(ed->e.pd,glass_EIDTEXT,Q)<<0;
474 ed->idef.flags|=dbox_selecticon(ed->e.pd,glass_EIDSPRITE,Q)<<1;
475 ed->idef.flags|=dbox_selecticon(ed->e.pd,glass_EIDINDIR,Q)<<8;
476 break;
477 case glass_EIAPPEARANCE:
478 ed->idef.flags&=~0x00000afc;
479 dbox_scanfield(ed->e.pd,glass_EIAFSIZEWRITE,"%d",&ed->fontSize);
480 ed->idef.flags|=dbox_selecticon(ed->e.pd,glass_EIAHCENTRE,Q)<<3;
481 ed->idef.flags|=dbox_selecticon(ed->e.pd,glass_EIAVCENTRE,Q)<<4;
482 ed->idef.flags|=dbox_selecticon(ed->e.pd,glass_EIABORDER,Q)<<2;
483 ed->idef.flags|=dbox_selecticon(ed->e.pd,glass_EIAFILL,Q)<<5;
484 ed->idef.flags|=dbox_selecticon(ed->e.pd,glass_EIAFONT,Q)<<6;
485 ed->idef.flags|=dbox_selecticon(ed->e.pd,glass_EIANEEDSHELP,Q)<<7;
486 ed->idef.flags|=dbox_selecticon(ed->e.pd,glass_EIARALIGN,Q)<<9;
487 ed->idef.flags|=dbox_selecticon(ed->e.pd,glass_EIAHALFSIZE,Q)<<11;
488 break;
489 case glass_EIACTIONS:
490 ed->idef.flags&=~0x007f0400;
491 dbox_scanfield(ed->e.pd,glass_EIAESGWRITE,"%d",&esg);
492 ed->idef.flags|=esg<<16;
493 ed->idef.flags|=dbox_selecticon(ed->e.pd,glass_EIAADJUST,Q)<<10;
494 ed->idef.flags|=dbox_selecticon(ed->e.pd,glass_EIASELECT,Q)<<21;
495 ed->idef.flags|=dbox_selecticon(ed->e.pd,glass_EIASHADE,Q)<<22;
496 break;
497 case glass_EISIZE:
498 dbox_scanfield(ed->e.pd,glass_EIPWRITE,"%d,%d",&x,&y);
499 ed->idef.box.x1=ed->idef.box.x0+x;
500 ed->idef.box.y1=ed->idef.box.y0+y;
501 break;
502 case glass_EIPOSITION:
503 dbox_scanfield(ed->e.pd,glass_EIPWRITE,"%d,%d",&x,&y);
504 ed->idef.box.x1+=x-ed->idef.box.x0;
505 ed->idef.box.y1+=y-ed->idef.box.y0;
506 ed->idef.box.x0=x;
507 ed->idef.box.y0=y;
508 break;
509 }
510 }
511
512 #undef Q
513
514 /*
515 * void editIcon__setPanel(glass_editIcon *ed,dbox_field f)
516 *
517 * Use
518 * Creates a new panel based on a radio button click or some-such.
519 *
520 * Parameters
521 * glass_editIcon *ed == the edit window to change panel
522 * dbox_field f == the radio button associated with the desired panel
523 */
524
525 static void editIcon__panelHandler(dbox d,dbox_field f,void *handle);
526 static BOOL editIcon__panelRaw(dbox d,wimp_eventstr *e,void *handle);
527
528 static void editIcon__setPanel(glass_editIcon *ed,dbox_field f)
529 {
530 dbox d;
531 wimp_wstate s;
532 wimp_icon i;
533 int width,height;
534 int ox,oy;
535 wimp_w behind;
536 wimp_caretstr c;
537 BOOL ownCaret=TRUE;
538 if (f==ed->e.panel)
539 return;
540 editIcon__closePanel(ed);
541 wimpt_noerr(wimp_get_wind_state(dbox_syshandle(ed->e.d),&s));
542 wimpt_noerr(wimp_get_icon_info(dbox_syshandle(ed->e.d),
543 glass_EIPOSN,&i));
544 ox=s.o.box.x0-s.o.x;
545 oy=s.o.box.y1-s.o.y;
546 mem_useUser(indir_alloc,indir_free);
547 if (f==-1)
548 d=dbox_create("iconNowt");
549 else
550 d=dbox_create(editIcon__panels[f-glass_EIDATA]);
551 if (!d)
552 {
553 mem_useMalloc();
554 return;
555 }
556 dbox_eventHandler(d,editIcon__panelHandler,ed);
557 dbox_rawEventHandler(d,editIcon__panelRaw,ed);
558 if (ed->e.panel)
559 {
560 wimpt_noerr(wimp_get_caret_pos(&c));
561 ownCaret=(c.w==dbox_syshandle(ed->e.pd));
562 dbox_selecticon(ed->e.d,ed->e.panel,dbox_RESETSTATE);
563 wimpt_noerr(wimp_get_wind_state(dbox_syshandle(ed->e.pd),&s));
564 pane_removePane(ed->e.p,dbox_syshandle(ed->e.pd));
565 dbox_delete(ed->e.pd);
566 }
567 dbox_selecticon(ed->e.d,f,dbox_SETSTATE);
568 behind=s.o.behind;
569 wimpt_noerr(wimp_get_wind_state(dbox_syshandle(d),&s));
570 width=s.o.box.x1-s.o.box.x0;
571 height=s.o.box.y1-s.o.box.y0;
572 s.o.box.x0=i.box.x0+ox+wimpt_dx();
573 s.o.box.y0=i.box.y0+oy+wimpt_dy();
574 s.o.box.x1=s.o.box.x0+width;
575 s.o.box.y1=s.o.box.y0+height;
576 s.o.y=10000;
577 s.o.behind=behind;
578 ed->e.pd=d;
579 ed->e.panel=f;
580 editIcon__setupPanel(ed);
581 wimpt_noerr(wimp_open_wind(&s.o));
582 if (ownCaret)
583 {
584 c.w=dbox_syshandle(d);
585 c.i=-1;
586 c.x=-500000;
587 c.y=0;
588 c.height=0x02000000;
589 wimpt_noerr(wimp_set_caret_pos(&c));
590 }
591 pane_addPane(ed->e.p,dbox_syshandle(d));
592 mem_useMalloc();
593 }
594
595 /*
596 * void editIcon__recreate(glass_editIcon *ed)
597 *
598 * Use
599 * Recreates the icon from the dialogue box settings
600 *
601 * Parameters
602 * glass_editIcon *ed == info about the edit
603 */
604
605 static void editIcon__recreate(glass_editIcon *ed)
606 {
607 char *p=0;
608 char *q=0;
609 int inum;
610 int fhandle;
611 ed->w->def->i[ed->i].edit=0; /* Delink temporarily */
612 window_redrawIcon(ed->w,ed->i); /* Force redraw of old icon */
613
614 if (!(ed->idef.flags & wimp_INDIRECT))
615 {
616 ed->indLen=12;
617 ed->hasValid=FALSE;
618 }
619 if (strlen(ed->data)>=ed->indLen)
620 {
621 ed->idef.flags|=wimp_INDIRECT;
622 ed->indLen=strlen(ed->data)+1;
623 }
624 if (ed->idef.flags & wimp_INDIRECT)
625 {
626 if (p=indir_alloc(ed->indLen),!p)
627 {
628 werr(FALSE,msgs_lookup("eiNEMUI"));
629 return;
630 }
631 if (ed->hasValid && (ed->idef.flags & wimp_ITEXT))
632 {
633 if (q=indir_alloc(strlen(ed->valid)+1),!q)
634 {
635 indir_free(p);
636 werr(FALSE,msgs_lookup("eiNEMUI"));
637 return;
638 }
639 strcpy(q,ed->valid);
640 ed->w->size+=strlen(ed->valid)+1;
641 }
642 strcpy(p,ed->data);
643 ed->w->size+=ed->indLen;
644 }
645
646 if (ed->w->def->i[ed->i].i.flags & wimp_IFONT) /* Was old anti? */
647 {
648 fhandle=(ed->w->def->i[ed->i].i.flags >> 24) & 255;
649 wimpt_noerr(font_lose(fhandle));
650 ed->w->fonts[fhandle]--;
651 }
652 if (ed->idef.flags & wimp_IFONT) /* Is new icon antialiased? */
653 {
654 if (font_find(ed->font,ed->fontSize*16,ed->fontSize*16,0,0,&fhandle))
655 {
656 werr(FALSE,msgs_lookup("eiCFF"),ed->font);
657 ed->idef.flags&=~wimp_IFONT;
658 }
659 else
660 {
661 ed->w->antiAliased=TRUE;
662 ed->w->fonts[fhandle]++;
663 ed->idef.flags=(ed->idef.flags & 0x00ffffff) | (fhandle<<24);
664 }
665 }
666
667 if (ed->w->def->i[ed->i].i.flags & wimp_INDIRECT)
668 {
669 indir_free(ed->w->def->i[ed->i].i.data.indirecttext.buffer);
670 ed->w->size-=ed->w->def->i[ed->i].i.data.indirecttext.bufflen;
671 if ((ed->w->def->i[ed->i].i.flags & wimp_ITEXT) &&
672 (ed->w->def->i[ed->i].i.data.indirecttext.validstring!=(char *)-1))
673 {
674 utils_ctermToNterm(ed->w->def->i[ed->i].
675 i.data.indirecttext.validstring);
676 ed->w->size-=
677 strlen(ed->w->def->i[ed->i].i.data.indirecttext.validstring)+1;
678 indir_free(ed->w->def->i[ed->i].i.data.indirecttext.validstring);
679 }
680 }
681
682 if (p)
683 {
684 ed->idef.data.indirecttext.buffer=p;
685 ed->idef.data.indirecttext.bufflen=ed->indLen;
686 if (q)
687 ed->idef.data.indirecttext.validstring=q;
688 else if (ed->idef.flags & wimp_ITEXT)
689 ed->idef.data.indirecttext.validstring=(char *)-1;
690 else
691 ed->idef.data.indirectsprite.spritearea=ed->w->t->s;
692 }
693 else
694 memcpy(ed->idef.data.text,ed->data,12);
695
696 ed->w->def->i[ed->i].i=ed->idef;
697 dbox_scanfield(ed->e.d,glass_EINUMWRITE,"%d",&inum);
698 if (!window_renumber(ed->w,ed->i,inum))
699 dbox_setfield(ed->e.d,glass_EINUMWRITE,"%i",ed->i);
700 else
701 ed->i=inum;
702
703 window_redrawIcon(ed->w,ed->i); /* Force redraw of new icon */
704 ed->w->def->i[ed->i].edit=ed; /* Relink again */
705 tfile_markAsAltered(ed->w->t);
706 }
707
708 /*
709 * void editIcon__nextPanel(glass_editIcon *ed,int dir)
710 *
711 * Use
712 * Changes panel to the next one in the given direction. Skips shaded
713 * panels and handles everything nicely.
714 *
715 * Parameters
716 * glass_editIcon *ed == the edit dialogue box to move about in
717 * int dir == the direction (-1 for up, 1 for down)
718 */
719
720 static void editIcon__nextPanel(glass_editIcon *ed,int dir)
721 {
722 int i=ed->e.panel;
723
724 if (i==-1)
725 i=(dir==1 ? glass_EIDATA : glass_EISIZE);
726 else
727 i+=dir;
728
729 for (;i>=glass_EIDATA && i<=glass_EISIZE;i+=dir)
730 {
731 if (!dbox_shadeicon(ed->e.d,i,dbox_READSTATE))
732 {
733 editIcon__setPanel(ed,i);
734 break;
735 }
736 }
737 }
738
739 /*----- Event handlers ----------------------------------------------------*/
740
741 /*
742 * void editIcon__dboxHandler(dbox d,dbox_field f,void *handle)
743 *
744 * Use
745 * Handles any and all events directed at the dbox. Well, almost all...
746 *
747 * Parameters
748 * dbox d == the dbox handle
749 * dbox_field f == the event that happened
750 * void *handle == pointer to the dialogue box control info
751 */
752
753 static void editIcon__dboxHandler(dbox d,dbox_field f,void *handle)
754 {
755 glass_editIcon *ed=handle;
756 buttons_simpleArrow sa={0,9999,FALSE};
757
758 switch (f)
759 {
760 case dbox_CLOSE:
761 if (ed->e.pd)
762 dbox_deleteNoUpdate(ed->e.pd);
763 pane_delete(ed->e.p);
764 dbox_delete(ed->e.d);
765 ed->w->def->i[ed->i].edit=0;
766 mem_free(ed);
767 break;
768 case dbox_HELP:
769 help_startHelp();
770 help_addLine(msgs_lookup("eihEIDB"));
771 help_readFromIcon();
772 help_endHelp();
773 break;
774 case glass_EICAN:
775 dbox_clickicon(d,f);
776 if (!dbox_wasAdjustClick())
777 pane_close(ed->e.p);
778 else
779 {
780 /* --- set up for old icon --- */
781 ed->idef=ed->w->def->i[ed->i].i;
782 editIcon_readData(ed->w,ed->i);
783 dbox_setfield(ed->e.d,glass_EINUMWRITE,"%i",ed->i);
784 editIcon__setupPanel(ed);
785 }
786 dbox_unclick();
787 if (!dbox_wasAdjustClick())
788 editIcon_close(ed->w,ed->i);
789 break;
790 case glass_EIOK:
791 dbox_clickicon(d,f);
792 editIcon__closePanel(ed);
793 if (!dbox_wasAdjustClick())
794 {
795 pane_close(ed->e.p);
796 editIcon__recreate(ed);
797 dbox_unclick();
798 editIcon_close(ed->w,ed->i);
799 }
800 else
801 {
802 editIcon__recreate(ed);
803 editIcon_readData(ed->w,ed->i);
804 editIcon__setupPanel(ed);
805 dbox_unclick();
806 }
807 break;
808 case glass_EIDELETE:
809 dbox_clickicon(d,f);
810 if (gPrefs_current()->cDelIcon)
811 {
812 if (!warning(msgs_lookup("eiCDIP"),
813 msgs_lookup("eiCDI")))
814 {
815 dbox_unclick();
816 return;
817 }
818 }
819 pane_close(ed->e.p);
820 dbox_unclick();
821 window_deleteIcon(ed->w,ed->i); /* Closes the edit for us */
822 break;
823 case glass_EIDATA:
824 case glass_EIAPPEARANCE:
825 case glass_EIACTIONS:
826 case glass_EICOLOURS:
827 case glass_EIPOSITION:
828 case glass_EISIZE:
829 editIcon__setPanel(ed,f);
830 break;
831 case glass_EINUMUP:
832 buttons_arrow(d,f,d,glass_EINUMWRITE,0,+1,&sa);
833 break;
834 case glass_EINUMDOWN:
835 buttons_arrow(d,f,d,glass_EINUMWRITE,0,-1,&sa);
836 break;
837 }
838 }
839
840 /*
841 * BOOL editIcon__dboxRaw(dbox d,wimp_eventstr *e,void *handle)
842 *
843 * Use
844 * Handles open window requests and things for the main Preferences dbox.
845 *
846 * Parameters
847 * dbox d == the dbox handle
848 * wimp_eventstr *e == the event that happened
849 * void *handle == a unused pointer
850 *
851 * Returns
852 * TRUE if the event has been handled;
853 */
854
855 static BOOL editIcon__dboxRaw(dbox d,wimp_eventstr *e,void *handle)
856 {
857 BOOL handled=FALSE;
858 glass_editIcon *ed=handle;
859 glass_intMsgstr *m;
860 unused(d);
861 switch (e->e)
862 {
863 case wimp_EOPEN:
864 pane_moved(ed->e.p);
865 handled=TRUE;
866 break;
867 case wimp_EKEY:
868 switch (e->data.key.chcode)
869 {
870 case akbd_UpK+akbd_Sh:
871 editIcon__nextPanel(ed,-1);
872 handled=TRUE;
873 break;
874 case akbd_DownK+akbd_Sh:
875 editIcon__nextPanel(ed,+1);
876 handled=TRUE;
877 break;
878 }
879 break;
880 case wimp_ESEND:
881 case wimp_ESENDWANTACK:
882 switch (e->data.msg.hdr.action)
883 {
884 case wimp_MINTERNAL:
885 m=intMsgs_receive(e);
886 switch(e->data.msg.data.words[0])
887 {
888 case glass_DELETEFILE:
889 if (m->df.t==ed->w->t)
890 editIcon_close(ed->w,ed->i);
891 break;
892 case glass_DELETEWINDOW:
893 if (m->dw.w==ed->w)
894 editIcon_close(ed->w,ed->i);
895 break;
896 case glass_RENAME:
897 if (m->rn.w==ed->w)
898 dbox_setfield(ed->e.d,glass_EIWINDISP,"%s",ed->w->id);
899 break;
900 }
901 break;
902 }
903 break;
904 }
905 return (handled);
906 }
907
908 /*
909 * menu editIcon__fontMaker(void *handle)
910 *
911 * Use
912 * Sets up the font menu.
913 *
914 * Parameters
915 * void *handle == pointer to this edit
916 *
917 * Returns
918 * A menu to display
919 */
920
921 static menu editIcon__fontMaker(void *handle)
922 {
923 glass_editIcon *ed=handle;
924 menu m=fontMenu_createFontMenu(FALSE);
925 fontMenu_tickGivenName(ed->font);
926 return (m);
927 }
928
929 /*
930 * void editIcon__fontHandler(int hit[],void *handle)
931 *
932 * Use
933 * Gets the font chosen from the font menu.
934 *
935 * Parameters
936 * int hit[] == the hit string
937 * void *handle == pointer to this edit
938 */
939
940 static void editIcon__fontHandler(int hit[],void *handle)
941 {
942 glass_editIcon *ed=handle;
943 if (hit[0])
944 {
945 strcpy(ed->font,fontMenu_fontname(hit[0],hit[1]));
946 dbox_setfield(ed->e.pd,glass_EIAFONTNAME,"%.%s",ed->font);
947 }
948 }
949
950 /*
951 * void editIcon__fontHelp(int hit[],void *handle)
952 *
953 * Use
954 * Gives help on a font menu item
955 *
956 * Parameters
957 * int hit[] == the hit string
958 * void *handle == pointer to this edit
959 */
960
961 static void editIcon__fontHelp(int hit[],void *handle)
962 {
963 unused(handle);
964 if (hit[0])
965 {
966 help_startHelp();
967 help_addLine(msgs_lookup("eimhFONT"),fontMenu_fontname(hit[0],hit[1]));
968 help_endHelp();
969 }
970 }
971
972 /*
973 * menu editIcon__btypeMaker(void *handle)
974 *
975 * Use
976 * Generates and sets up a button type menu for an edit dialogue box
977 *
978 * Parameters
979 * void *handle == pointer to the edit
980 *
981 * Returns
982 * The menu to use
983 */
984
985 static menu editIcon__btypeMaker(void *handle)
986 {
987 static menu m;
988 static int ticked;
989 glass_editIcon *ed=handle;
990 int i;
991 char *buf=buffer_find();
992 if (!m)
993 {
994 m=menu_new(msgs_lookup("eiBTMT"),msgs_lookup("eiBTYPE0"));
995 for (i=1;i<=15;i++)
996 {
997 sprintf(buf,"eiBTYPE%i",i);
998 menu_extend(m,msgs_lookup(buf));
999 }
1000 }
1001 if (ticked)
1002 menu_setflags(m,ticked,FALSE,FALSE);
1003 ticked=((ed->idef.flags>>12)&0x0f)+1;
1004 menu_setflags(m,ticked,TRUE,FALSE);
1005 return (m);
1006 }
1007
1008 /*
1009 * void editIcon__btypeHandler(int hit[],void *handle)
1010 *
1011 * Use
1012 * Handles a click on the button type menu.
1013 *
1014 * Parameters
1015 * int hit[] == the mouse click info
1016 * void *handle == pointer to edit information
1017 */
1018
1019 static void editIcon__btypeHandler(int hit[],void *handle)
1020 {
1021 glass_editIcon *ed=handle;
1022 char *buf=buffer_find();
1023 if (hit[0])
1024 {
1025 ed->idef.flags&=~0x0000f000;
1026 ed->idef.flags+=(hit[0]-1)<<12;
1027 sprintf(buf,"eiBTYPE%i",hit[0]-1);
1028 dbox_setfield(ed->e.pd,glass_EIABTYPE,"%s",msgs_lookup(buf));
1029 }
1030 }
1031
1032 /*
1033 * void editIcon__colProc(dbox d,dbox_field f,int colour, void *handle)
1034 *
1035 * Use
1036 * This routine is called when a colour is selected in the colours panel.
1037 *
1038 * Parameters
1039 * dbox d == the panel's handle
1040 * dbox_field f == the colour button that has changed
1041 * int colour == the new colour for the button
1042 * void *handle == pointer to this edit
1043 */
1044
1045 static void editIcon__colProc(dbox d,dbox_field f,int colour,void *handle)
1046 {
1047 glass_editIcon *ed=handle;
1048 unused(d);
1049 switch (f)
1050 {
1051 case glass_EICFORE:
1052 ed->idef.flags=(ed->idef.flags & ~0x0f000000)+(colour<<24);
1053 break;
1054 case glass_EICBACK:
1055 ed->idef.flags=(ed->idef.flags & ~0xf0000000)+(colour<<28);
1056 break;
1057 }
1058 }
1059
1060 /*
1061 * void editIcon__btypeHelp(int hit[],void *handle)
1062 *
1063 * Use
1064 * Handles a help request for the button type menu.
1065 *
1066 * Parameters
1067 * int hit[] == the helpq info
1068 * void *handle == pointer to edit information
1069 */
1070
1071 static void editIcon__btypeHelp(int hit[],void *handle)
1072 {
1073 char *buf=buffer_find();
1074 unused(handle);
1075 if (hit[0])
1076 {
1077 help_startHelp();
1078 sprintf(buf,"eiBTYPE%i",hit[0]-1);
1079 help_addLine(msgs_lookup("eimhBTYPE"),msgs_lookup(buf));
1080 help_endHelp();
1081 }
1082 }
1083
1084 /*
1085 * void editIcon__posSizeArrows(dbox d,dbox_field f,int diff,void *handle)
1086 *
1087 * Use
1088 * Handles a click event on one of the position or size arrow buttons in
1089 * the dialogue box. See the structure definition below for a description
1090 * of the data structure required.
1091 */
1092
1093 typedef struct
1094 {
1095 BOOL xOrY;
1096 BOOL sizing;
1097 }
1098 editIcon__posSizeArrowstr;
1099
1100 static void editIcon__posSizeArrows(dbox d,
1101 dbox_field f,
1102 int diff,
1103 void *handle)
1104 {
1105 editIcon__posSizeArrowstr *s=handle;
1106 int x,y;
1107 int *v;
1108
1109 dbox_scanfield(d,f,"%d,%d",&x,&y);
1110 v=s->xOrY ? &x : &y;
1111 *v+=diff;
1112 if (s->sizing && *v<0)
1113 *v=0;
1114 dbox_setfield(d,f,"%i,%i",x,y);
1115 }
1116
1117 /*
1118 * void editIcon__panelHandler(dbox d,dbox_field f,void *handle)
1119 *
1120 * Use
1121 * Handles simple click events for the current panel in an edit dbox
1122 *
1123 * Parameters
1124 * dbox d == the panel's dbox handle
1125 * dbox_field f == the icon that was clicked
1126 * void *handle == pointer to edit information
1127 */
1128
1129 static void editIcon__panelHandler(dbox d,dbox_field f,void *handle)
1130 {
1131 glass_editIcon *ed=handle;
1132 buttons_simpleArrow sa={0,9999,FALSE};
1133 buttons_simpleArrow esga={0,31,FALSE};
1134 editIcon__posSizeArrowstr psa={0,FALSE};
1135 BOOL indon;
1136
1137 switch (f)
1138 {
1139 case dbox_CLOSE:
1140 case dbox_HELP:
1141 case glass_EIOK:
1142 case glass_EICAN:
1143 editIcon__dboxHandler(ed->e.d,f,ed);
1144 return;
1145 break;
1146 }
1147 switch (ed->e.panel)
1148 {
1149 case glass_EIDATA:
1150 switch (f)
1151 {
1152 case glass_EIDINDIR:
1153 if (dbox_selecticon(d,f,dbox_READSTATE))
1154 {
1155 if (dbox_selecticon(ed->e.pd,glass_EIDTEXT,dbox_READSTATE))
1156 {
1157 dbox_shadeicon(ed->e.pd,glass_EIDVALID,FALSE);
1158 dbox_shadeicon(ed->e.pd,
1159 glass_EIDVALSTRING,
1160 !dbox_selecticon(ed->e.pd,
1161 glass_EIDVALID,
1162 dbox_READSTATE));
1163 }
1164 dbox_shadeicon(ed->e.pd,glass_EIDINDSIZE,FALSE);
1165 dbox_shadeicon(ed->e.pd,glass_EIDINDUP,FALSE);
1166 dbox_shadeicon(ed->e.pd,glass_EIDINDDOWN,FALSE);
1167 dbox_shadeicon(ed->e.pd,glass_EIDMINIMISE,FALSE);
1168 dbox_shadeicon(ed->e.pd,glass_EIDINDPART,FALSE);
1169 }
1170 else
1171 {
1172 dbox_shadeicon(ed->e.pd,glass_EIDVALSTRING,TRUE);
1173 dbox_shadeicon(ed->e.pd,glass_EIDVALID,TRUE);
1174 dbox_shadeicon(ed->e.pd,glass_EIDINDSIZE,TRUE);
1175 dbox_shadeicon(ed->e.pd,glass_EIDINDUP,TRUE);
1176 dbox_shadeicon(ed->e.pd,glass_EIDINDDOWN,TRUE);
1177 dbox_shadeicon(ed->e.pd,glass_EIDMINIMISE,TRUE);
1178 dbox_shadeicon(ed->e.pd,glass_EIDINDPART,TRUE);
1179 }
1180 break;
1181 case glass_EIDINDUP:
1182 buttons_arrow(ed->e.pd,f,ed->e.pd,glass_EIDINDSIZE,0,+1,&sa);
1183 break;
1184 case glass_EIDINDDOWN:
1185 buttons_arrow(ed->e.pd,f,ed->e.pd,glass_EIDINDSIZE,0,-1,&sa);
1186 break;
1187 case glass_EIDVALID:
1188 dbox_shadeicon(ed->e.pd,glass_EIDVALSTRING,dbox_TOGGLESTATE);
1189 break;
1190 case glass_EIDMINIMISE:
1191 dbox_clickicon(d,f);
1192 dbox_getfield(d,glass_EIDDATA,ed->data,256);
1193 dbox_setfield(d,glass_EIDINDSIZE,"%i",strlen(ed->data)+1);
1194 dbox_unclick();
1195 break;
1196 case glass_EIDTEXT:
1197 if (dbox_selecticon(ed->e.pd,glass_EIDTEXT,dbox_READSTATE))
1198 {
1199 dbox_shadeicon(ed->e.pd,glass_EIDDATA,FALSE);
1200 dbox_shadeicon(ed->e.pd,glass_EIDINDIR,FALSE);
1201 if (dbox_selecticon(d,glass_EIDINDIR,dbox_READSTATE))
1202 {
1203 dbox_shadeicon(ed->e.pd,glass_EIDVALID,FALSE);
1204 dbox_shadeicon(ed->e.pd,glass_EIDVALSTRING,
1205 !dbox_selecticon(ed->e.pd,glass_EIDVALID,dbox_READSTATE));
1206 dbox_shadeicon(ed->e.pd,glass_EIDINDSIZE,FALSE);
1207 dbox_shadeicon(ed->e.pd,glass_EIDINDUP,FALSE);
1208 dbox_shadeicon(ed->e.pd,glass_EIDINDDOWN,FALSE);
1209 dbox_shadeicon(ed->e.pd,glass_EIDMINIMISE,FALSE);
1210 dbox_shadeicon(ed->e.pd,glass_EIDINDPART,FALSE);
1211 }
1212 else
1213 {
1214 dbox_shadeicon(ed->e.pd,glass_EIDVALID,TRUE);
1215 dbox_shadeicon(ed->e.pd,glass_EIDVALSTRING,TRUE);
1216 dbox_shadeicon(ed->e.pd,glass_EIDINDSIZE,TRUE);
1217 dbox_shadeicon(ed->e.pd,glass_EIDINDUP,TRUE);
1218 dbox_shadeicon(ed->e.pd,glass_EIDINDDOWN,TRUE);
1219 dbox_shadeicon(ed->e.pd,glass_EIDMINIMISE,TRUE);
1220 dbox_shadeicon(ed->e.pd,glass_EIDINDPART,TRUE);
1221 }
1222 dbox_shadeicon(ed->e.d,glass_EICOLOURS,
1223 !!(ed->idef.flags & wimp_IFONT));
1224 }
1225 else
1226 {
1227 dbox_shadeicon(ed->e.pd,glass_EIDVALID,TRUE);
1228 dbox_shadeicon(ed->e.pd,glass_EIDVALSTRING,TRUE);
1229 if (dbox_selecticon(d,glass_EIDSPRITE,dbox_READSTATE))
1230 {
1231 dbox_shadeicon(ed->e.pd,glass_EIDDATA,FALSE);
1232 dbox_shadeicon(ed->e.pd,glass_EIDINDIR,FALSE);
1233 indon=dbox_selecticon(d,glass_EIDINDIR,dbox_READSTATE);
1234 dbox_shadeicon(ed->e.pd,glass_EIDINDSIZE,!indon);
1235 dbox_shadeicon(ed->e.pd,glass_EIDINDUP,!indon);
1236 dbox_shadeicon(ed->e.pd,glass_EIDINDDOWN,!indon);
1237 dbox_shadeicon(ed->e.pd,glass_EIDMINIMISE,!indon);
1238 dbox_shadeicon(ed->e.pd,glass_EIDINDPART,!indon);
1239 }
1240 else
1241 {
1242 dbox_shadeicon(ed->e.pd,glass_EIDDATA,TRUE);
1243 dbox_shadeicon(ed->e.pd,glass_EIDINDSIZE,TRUE);
1244 dbox_shadeicon(ed->e.pd,glass_EIDINDUP,TRUE);
1245 dbox_shadeicon(ed->e.pd,glass_EIDINDDOWN,TRUE);
1246 dbox_shadeicon(ed->e.pd,glass_EIDINDPART,TRUE);
1247 dbox_shadeicon(ed->e.pd,glass_EIDINDIR,TRUE);
1248 dbox_shadeicon(ed->e.pd,glass_EIDMINIMISE,TRUE);
1249 }
1250 dbox_shadeicon(ed->e.d,glass_EICOLOURS,FALSE);
1251 }
1252 break;
1253 case glass_EIDSPRITE:
1254 if (dbox_selecticon(ed->e.pd,glass_EIDSPRITE,dbox_READSTATE))
1255 {
1256 dbox_shadeicon(ed->e.pd,glass_EIDDATA,FALSE);
1257 dbox_shadeicon(ed->e.pd,glass_EIDINDIR,FALSE);
1258 indon=dbox_selecticon(d,glass_EIDINDIR,dbox_READSTATE);
1259 dbox_shadeicon(ed->e.pd,glass_EIDINDSIZE,!indon);
1260 dbox_shadeicon(ed->e.pd,glass_EIDINDUP,!indon);
1261 dbox_shadeicon(ed->e.pd,glass_EIDINDDOWN,!indon);
1262 dbox_shadeicon(ed->e.pd,glass_EIDMINIMISE,!indon);
1263 dbox_shadeicon(ed->e.pd,glass_EIDINDPART,!indon);
1264 }
1265 else if (!dbox_selecticon(ed->e.pd,glass_EIDTEXT,dbox_READSTATE))
1266 {
1267 dbox_shadeicon(ed->e.pd,glass_EIDDATA,TRUE);
1268 dbox_shadeicon(ed->e.pd,glass_EIDINDIR,TRUE);
1269 dbox_shadeicon(ed->e.pd,glass_EIDINDSIZE,TRUE);
1270 dbox_shadeicon(ed->e.pd,glass_EIDINDUP,TRUE);
1271 dbox_shadeicon(ed->e.pd,glass_EIDINDDOWN,TRUE);
1272 dbox_shadeicon(ed->e.pd,glass_EIDMINIMISE,TRUE);
1273 dbox_shadeicon(ed->e.pd,glass_EIDINDPART,TRUE);
1274 }
1275 break;
1276 }
1277 break;
1278 case glass_EIAPPEARANCE:
1279 switch (f)
1280 {
1281 case glass_EIAFONT:
1282 if (dbox_selecticon(d,f,dbox_READSTATE) ||
1283 fontMenu_createFontMenu(FALSE))
1284 {
1285 dbox_selecticon(d,f,dbox_TOGGLESTATE);
1286 dbox_shadeicon(d,glass_EIAFONTNAME,dbox_TOGGLESTATE);
1287 dbox_shadeicon(d,glass_EIAFONTMENU,dbox_TOGGLESTATE);
1288 dbox_shadeicon(d,glass_EIAFSIZEUP,dbox_TOGGLESTATE);
1289 dbox_shadeicon(d,glass_EIAFSIZEDOWN,dbox_TOGGLESTATE);
1290 dbox_shadeicon(d,glass_EIAFSIZEWRITE,dbox_TOGGLESTATE);
1291 dbox_shadeicon(ed->e.d,glass_EICOLOURS,dbox_TOGGLESTATE);
1292 }
1293 break;
1294 case glass_EIAFSIZEUP:
1295 buttons_arrow(ed->e.pd,f,ed->e.pd,glass_EIAFSIZEWRITE,0,+1,&sa);
1296 break;
1297 case glass_EIAFSIZEDOWN:
1298 buttons_arrow(ed->e.pd,f,ed->e.pd,glass_EIAFSIZEWRITE,0,-1,&sa);
1299 break;
1300 }
1301 break;
1302 case glass_EIACTIONS:
1303 switch (f)
1304 {
1305 case glass_EIAESGUP:
1306 buttons_arrow(d,f,d,glass_EIAESGWRITE,0,+1,&esga);
1307 break;
1308 case glass_EIAESGDOWN:
1309 buttons_arrow(d,f,d,glass_EIAESGWRITE,0,-1,&esga);
1310 break;
1311 }
1312 break;
1313 case glass_EICOLOURS:
1314 /* Nothin' doing */
1315 break;
1316 case glass_EISIZE:
1317 psa.sizing=TRUE;
1318 /* Drop through */
1319 case glass_EIPOSITION:
1320 switch (f)
1321 {
1322 case glass_EIPUP:
1323 psa.xOrY=FALSE;
1324 buttons_arrow(d,f,d,glass_EIPWRITE,
1325 editIcon__posSizeArrows,
1326 +wimpt_dy(),
1327 &psa);
1328 break;
1329 case glass_EIPDOWN:
1330 psa.xOrY=FALSE;
1331 buttons_arrow(d,f,d,glass_EIPWRITE,
1332 editIcon__posSizeArrows,
1333 -wimpt_dy(),
1334 &psa);
1335 break;
1336 case glass_EIPLEFT:
1337 psa.xOrY=TRUE;
1338 buttons_arrow(d,f,d,glass_EIPWRITE,
1339 editIcon__posSizeArrows,
1340 -wimpt_dx(),
1341 &psa);
1342 break;
1343 case glass_EIPRIGHT:
1344 psa.xOrY=TRUE;
1345 buttons_arrow(d,f,d,glass_EIPWRITE,
1346 editIcon__posSizeArrows,
1347 +wimpt_dx(),
1348 &psa);
1349 break;
1350 case glass_EIPSETSIZE:
1351 dbox_clickicon(d,f);
1352 editIcon__setSize(ed);
1353 dbox_unclick();
1354 break;
1355 }
1356 break;
1357 }
1358 }
1359
1360 /*
1361 * BOOL editIcon__panelRaw(dbox d,wimp_eventstr *e,void *handle)
1362 *
1363 * Use
1364 * Handles the more wierd events for a particular panel.
1365 *
1366 * Parameters
1367 * dbox d == the dbox handle of the panel
1368 * wimp_eventstr *e == the event to look at
1369 * void *handle == pointer to the current edit
1370 *
1371 * Returns
1372 * TRUE if the event is dead (long live the event...)
1373 */
1374
1375 static BOOL editIcon__panelRaw(dbox d,wimp_eventstr *e,void *handle)
1376 {
1377 BOOL handled=FALSE;
1378 glass_editIcon *ed=handle;
1379 BOOL cursor=FALSE;
1380 if (e->e==wimp_EKEY)
1381 {
1382 switch (e->data.key.chcode)
1383 {
1384 case akbd_UpK+akbd_Sh:
1385 editIcon__nextPanel(ed,-1);
1386 handled=TRUE;
1387 break;
1388 case akbd_DownK+akbd_Sh:
1389 editIcon__nextPanel(ed,+1);
1390 handled=TRUE;
1391 break;
1392 }
1393 }
1394 if (!handled) switch (ed->e.panel)
1395 {
1396 case glass_EIDATA:
1397 /* Nothin' doing */
1398 break;
1399 case glass_EIAPPEARANCE:
1400 switch (e->e)
1401 {
1402 case wimp_EBUT:
1403 switch (e->data.but.m.i)
1404 {
1405 case glass_EIAFONTNAME:
1406 menu_make(editIcon__fontMaker,editIcon__fontHandler,
1407 editIcon__fontHelp,ed);
1408 handled=TRUE;
1409 break;
1410 case glass_EIAFONTMENU:
1411 dbox_clickicon(d,glass_EIAFONTMENU);
1412 menu_make(editIcon__fontMaker,editIcon__fontHandler,
1413 editIcon__fontHelp,ed);
1414 dbox_unclick();
1415 handled=TRUE;
1416 break;
1417 }
1418 break;
1419 }
1420 break;
1421 case glass_EIACTIONS:
1422 switch (e->e)
1423 {
1424 case wimp_EBUT:
1425 switch (e->data.but.m.i)
1426 {
1427 case glass_EIABTYPE:
1428 menu_make(editIcon__btypeMaker,editIcon__btypeHandler,
1429 editIcon__btypeHelp,ed);
1430 handled=TRUE;
1431 break;
1432 case glass_EIABTMENU:
1433 dbox_clickicon(d,glass_EIABTMENU);
1434 menu_make(editIcon__btypeMaker,editIcon__btypeHandler,
1435 editIcon__btypeHelp,ed);
1436 dbox_unclick();
1437 handled=TRUE;
1438 break;
1439 }
1440 break;
1441 case wimp_EKEY:
1442 switch (e->data.key.c.i)
1443 {
1444 case glass_EIAESGWRITE:
1445 switch (e->data.key.chcode)
1446 {
1447 case akbd_DownK:
1448 case akbd_UpK:
1449 case akbd_TabK:
1450 case akbd_TabK+akbd_Sh:
1451 case akbd_UpK+akbd_Ctl:
1452 case akbd_DownK+akbd_Ctl:
1453 cursor=TRUE;
1454 break;
1455 }
1456 handled=buttons_insertChar(d,e->data.key.chcode,'0','9');
1457 if (handled || cursor)
1458 buttons_arrowClick(d,glass_EIAESGWRITE,0,31,0,FALSE);
1459 break;
1460 }
1461 break;
1462 }
1463 break;
1464 case glass_EICOLOURS:
1465 switch (e->e)
1466 {
1467 case wimp_EBUT:
1468 switch (e->data.but.m.i)
1469 {
1470 case glass_EICFORE:
1471 colSelect(ed->e.pd,glass_EICFORE,e->data.but.m.bbits,
1472 msgs_lookup("eiFGC"),FALSE,
1473 editIcon__colProc,ed);
1474 break;
1475 case glass_EICBACK:
1476 colSelect(ed->e.pd,glass_EICBACK,e->data.but.m.bbits,
1477 msgs_lookup("eiBGC"),FALSE,
1478 editIcon__colProc,ed);
1479 break;
1480 }
1481 break;
1482 }
1483 break;
1484 case glass_EISIZE:
1485 case glass_EIPOSITION:
1486 /* Nothin' doin' */
1487 break;
1488 }
1489 return (FALSE);
1490 }
1491
1492 /*----- External routines -------------------------------------------------*/
1493
1494 /*
1495 * void editIcon_renumber(glass_windPointer *w,int icon,int new)
1496 *
1497 * Use
1498 * Informs an edit dialogue that an icon has been renumbered.
1499 *
1500 * Parameters
1501 * glass_windPointer *w == the window containing the icon
1502 * int icon == the icon number
1503 * int new == the new number for the icon
1504 */
1505
1506 void editIcon_renumber(glass_windPointer *w,int icon,int new)
1507 {
1508 glass_editIcon *ed=w->def->i[icon].edit;
1509 if (!ed)
1510 return;
1511 ed->i=new;
1512 dbox_setfield(ed->e.d,glass_EINUMWRITE,"%i",new);
1513 }
1514
1515 /*
1516 * void editIcon_iconMoved(glass_windPointer *w,int icon)
1517 *
1518 * Use
1519 * Informs an edit dialogue that an icon has been moved.
1520 *
1521 * Parameters
1522 * glass_windPointer *w == the window containing the icon
1523 * int icon == the icon number. This may not be the same during the edit...
1524 */
1525
1526 void editIcon_iconMoved(glass_windPointer *w,int icon)
1527 {
1528 glass_editIcon *ed=w->def->i[icon].edit;
1529 if (!ed)
1530 return;
1531 ed->idef.box=ed->w->def->i[ed->i].i.box;
1532 if (ed->e.panel==glass_EIPOSITION || ed->e.panel==glass_EISIZE)
1533 editIcon__setupPanel(ed);
1534 }
1535
1536 /*
1537 * void editIcon_readData(glass_windPointer *w,int icon)
1538 *
1539 * Use
1540 * Forces a re-read of the icon data for the given icon edit
1541 *
1542 * Parameters
1543 * glass_windPointer *w == the window containing the icon
1544 * int icon == the icon number. This may not be the same during the edit...
1545 */
1546
1547 void editIcon_readData(glass_windPointer *w,int icon)
1548 {
1549 glass_editIcon *ed=w->def->i[icon].edit;
1550 if (!ed)
1551 return;
1552 ed->idef.data=ed->w->def->i[ed->i].i.data;
1553 if (ed->idef.flags & wimp_INDIRECT)
1554 {
1555 utils_ctermToNterm(ed->idef.data.indirecttext.buffer);
1556 strcpy(ed->data,ed->idef.data.indirecttext.buffer);
1557 ed->indLen=ed->idef.data.indirecttext.bufflen;
1558 if (ed->idef.flags & wimp_ITEXT &&
1559 ed->idef.data.indirecttext.validstring!=(char *)-1)
1560 {
1561 utils_ctermToNterm(ed->idef.data.indirecttext.validstring);
1562 strcpy(ed->valid,ed->idef.data.indirecttext.validstring);
1563 ed->hasValid=TRUE;
1564 }
1565 else
1566 {
1567 ed->valid[0]=0;
1568 ed->hasValid=FALSE;
1569 }
1570 }
1571 else
1572 {
1573 ed->data[12]=0;
1574 memcpy(ed->data,ed->idef.data.text,12);
1575 utils_ctermToNterm(ed->data);
1576 ed->valid[0]=0;
1577 ed->indLen=12;
1578 }
1579 if (ed->e.panel==glass_EIDATA)
1580 editIcon__setupPanel(ed);
1581 if (ed->idef.flags & wimp_IFONT)
1582 {
1583 if (ed->e.panel==glass_EICOLOURS)
1584 editIcon__setPanel(ed,-1);
1585 dbox_shadeicon(ed->e.d,glass_EICOLOURS,TRUE);
1586 }
1587 else
1588 dbox_shadeicon(ed->e.d,glass_EICOLOURS,FALSE);
1589 }
1590
1591 /*
1592 * void editIcon_close(glass_windPointer *w,int icon)
1593 *
1594 * Use
1595 * Closes an edit window
1596 *
1597 * Parameters
1598 * glass_windPointer *w == the window containing the icon
1599 * int icon == the icon number. This may not be the same during the edit...
1600 */
1601
1602 void editIcon_close(glass_windPointer *w,int icon)
1603 {
1604 glass_editIcon *ed=w->def->i[icon].edit;
1605 if (ed)
1606 {
1607 if (ed->e.pd)
1608 dbox_deleteNoUpdate(ed->e.pd);
1609 pane_delete(ed->e.p);
1610 dbox_deleteNoUpdate(ed->e.d);
1611 ed->w->def->i[ed->i].edit=0;
1612 mem_free(ed);
1613 }
1614 }
1615
1616 /*
1617 * void editIcon(glass_windPointer *w,int icon)
1618 *
1619 * Use
1620 * Edits the given icon in a dialogue box.
1621 *
1622 * Parameters
1623 * glass_windPointer *w == the window containing the icon
1624 * int icon == the icon number. This may not be the same during the edit...
1625 */
1626
1627 void editIcon(glass_windPointer *w,int icon)
1628 {
1629 glass_editIcon *ed;
1630 os_regset r;
1631 if (w->def->i[icon].edit)
1632 {
1633 dbox_display(w->def->i[icon].edit->e.d,TRUE);
1634 pane_front(w->def->i[icon].edit->e.p);
1635 return;
1636 }
1637 mem_useUser(indir_alloc,indir_free);
1638 ed=mem_alloc(sizeof(glass_editIcon));
1639 if (!ed)
1640 {
1641 werr(FALSE,msgs_lookup("eiNEM"));
1642 mem_useMalloc();
1643 return;
1644 }
1645 if (ed->e.d=dbox_create("editIcon"),!ed->e.d)
1646 {
1647 mem_free(ed);
1648 mem_useMalloc();
1649 return;
1650 }
1651 if (ed->e.p=pane_create(dbox_syshandle(ed->e.d)),!ed->e.p)
1652 {
1653 dbox_delete(ed->e.d);
1654 mem_free(ed);
1655 mem_useMalloc();
1656 return;
1657 }
1658 mem_useMalloc();
1659 ed->w=w;
1660 ed->i=icon;
1661 ed->idef=w->def->i[icon].i;
1662 w->def->i[icon].edit=ed;
1663 ed->e.panel=0;
1664
1665 /* --- Set up icon data now --- */
1666 editIcon_readData(w,icon);
1667 if (ed->idef.flags & wimp_IFONT)
1668 {
1669 r.r[0]=ed->idef.flags >> 24;
1670 r.r[1]=(int)(ed->font);
1671 wimpt_noerr(os_swix(XFont_ReadDefn,&r));
1672 utils_ctermToNterm(ed->font);
1673 ed->fontSize=r.r[2]/16;
1674 dbox_shadeicon(ed->e.d,glass_EICOLOURS,TRUE);
1675 }
1676 else
1677 {
1678 strcpy(ed->font,"Homerton.Medium");
1679 ed->fontSize=12;
1680 dbox_shadeicon(ed->e.d,glass_EICOLOURS,FALSE);
1681 }
1682
1683 /* --- Now do handlers, and final setting up --- */
1684 dbox_setfield(ed->e.d,glass_EINUMWRITE,"%i",icon);
1685 dbox_setfield(ed->e.d,glass_EIWINDISP,"%s",w->id);
1686 dbox_eventHandler(ed->e.d,editIcon__dboxHandler,ed);
1687 dbox_rawEventHandler(ed->e.d,editIcon__dboxRaw,ed);
1688 dbox_openDisplaced(ed->e.d);
1689 editIcon__setPanel(ed,glass_EIDATA);
1690 }