4 * proper icon bar mangement (multiple icons, etc.)
6 * © 1993-1998 Straylight
9 /*----- Licensing note ----------------------------------------------------*
11 * This file is part of Straylight's Steel library.
13 * Steel 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 * Steel 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 Steel. If not, write to the Free Software Foundation,
25 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
46 extern void _dllEntry(ibicon__events)(wimp_eventstr *e,void *handle);
47 extern menu _dllEntry(ibicon__menumaker)(void *handle);
48 extern void _dllEntry(ibicon__menuhandler)(int hits[],void *handle);
49 extern void _dllEntry(ibicon__menuhelphandler)(int hits[],void *handle);
52 typedef struct ibicon__ibiconstr
54 struct ibicon__ibiconstr *next;
55 struct ibicon__ibiconstr *prev;
60 event_menu_maker maker;
61 menu_selectProc menusel;
62 menu_helpProc menuhelp;
64 ibicon_handler handler;
66 ibicon_rawHandler raw;
71 static ibicon ibicon__anchor;
72 static BOOL ibicon__eventHandler; /* Do we have an event handler? */
73 static ibicon ibicon__menuicon; /* The last icon to open a menu */
74 static int ibicon__priority; /* Icon priorities (RISC OS 3) */
77 * os_error *ibicon__spriteOp
86 * Does an OS_SpriteOp call. It's designed for calls that return more than
90 * int op == the operation number to perform
91 * sprite_area *a == the sprite area to do the op on. May be 1 for the
92 * WIMP area or 0 for the system area
93 * char *name == the name of the sprite
94 * os_regset *r == a regiser set to return inforation in
97 * An error block if anything went wrong
100 static os_error *ibicon__spriteOp
110 swinum=XWimp_SpriteOp;
120 return (os_swix(swinum,r));
124 * void ibicon__spriteSize(char *name,sprite_area *a,wimp_box *b,BOOL centre)
127 * Returns the size of the sprite specified. If requested, it also
128 * centres the result given within a 68 OS unit vertical area.
131 * char *name == the name of the sprite of which to return the size
132 * sprite_area *a == the sprite area (same conventions as above)
133 * wimp_box *b == a box structure to fill in
134 * BOOL centre == whether to centre the icon vertically
137 static void ibicon__spriteSize
148 wimpt_noerr(ibicon__spriteOp(40,a,name,&r));
149 b->x1=r.r[3]<<bbc_modevar(r.r[6],bbc_XEigFactor);
150 height=r.r[4]<<bbc_modevar(r.r[6],bbc_YEigFactor);
153 b->y0=(68-height)>>1;
164 * ibicon ibicon_find(wimp_i icon)
167 * Return the ibicon handle of an icon.
170 * wimp_i icon == the icon to find
173 ibicon ibicon_find(wimp_i icon)
176 for (i=ibicon__anchor;i;i=i->next)
187 * wimp_i ibicon_syshandle(ibicon i)
190 * Returns the low-level WIMP handle for the icon concerned.
193 * ibicon i == the icon whose handle is desired
196 * The WIMP icon handle for the icon
199 wimp_i ibicon_syshandle(ibicon i)
205 * void ibicon__menuhandler(int hit[],void *handle)
208 * Handles clicks on icon bar menus. It acts an event_menu_proc and passes
209 * the information on the relevant icon.
212 * int hit[] == the hit string to be processed.
213 * void *handle == not worth the effort of worrying about
216 _dll_static void ibicon__menuhandler(int hit[],void *handle)
219 if (ibicon__menuicon)
221 if (ibicon__menuicon->menusel)
222 (ibicon__menuicon->menusel)(hit,ibicon__menuicon->menuHandle);
227 * void ibicon__menuhelphandler(int hit[],void *handle)
230 * Handles help request for icon bar menus. It acts a menu_helpProc or
231 * whatever and passes the information on the relevant icon.
234 * int hit[] == the hit string to be processed.
235 * void *handle == not worth the effort of worrying about
238 _dll_static void ibicon__menuhelphandler(int hit[],void *handle)
241 if (ibicon__menuicon)
243 if (ibicon__menuicon->menuhelp)
244 (ibicon__menuicon->menuhelp)(hit,ibicon__menuicon->menuHandle);
249 * menu ibicon__menumaker(void *handle)
252 * Handles menus and things for the icon bar. Acts as an event_menu_maker
253 * and passes the request on to the icon concerned.
256 * void *handle == nothing worth worrying about
259 * The menu to display
262 _dll_static menu ibicon__menumaker(void *handle)
264 wimp_eventstr *e=wimpt_last_event();
267 ibicon__menuicon=ibicon_find(e->data.but.m.i);
268 if (ibicon__menuicon)
270 if (ibicon__menuicon->mnu)
271 return (ibicon__menuicon->mnu);
272 else if (ibicon__menuicon->maker)
273 return ((ibicon__menuicon->maker)(ibicon__menuicon->menuHandle));
275 return (0); /* menu is dead - icon disappeared */
279 * void ibicon__events(wimp_eventstr *e,void *handle)
282 * Event handler installed for both win_ICONBAR and win_ICONBARLOAD.
285 * wimp_eventstr *e == the event
286 * void *handle == nothing interesting
289 _dll_static void ibicon__events(wimp_eventstr *e,void *handle)
293 ibicon_eventType type=ibicon_NOTHING;
299 switch (e->data.but.m.bbits)
302 type=ibicon_LEFTCLICK;
305 type=ibicon_RIGHTCLICK;
310 case wimp_ESENDWANTACK:
311 switch (e->data.msg.hdr.action)
315 icn=e->data.msg.data.datasave.i;
319 icn=e->data.msg.data.dataload.i;
321 case wimp_MHELPREQUEST:
323 icn=e->data.msg.data.helprequest.m.i;
327 if (i=ibicon_find(icn),!i)
331 if ((i->raw)(i,e,i->rawHandle))
334 if (type!=ibicon_NOTHING)
337 (i->handler)(i,type,i->handle);
342 * void ibicon_setPriority(int priority)
345 * Sets the priority with which to create icons under RISC OS 3.
348 * int priority == the new setting
351 void ibicon_setPriority(int priority)
353 ibicon__priority=priority;
357 * ibicon ibicon_create
361 * sprite_area *sprarea,
367 * Creates an icon in the icon bar. Where is up to you. Specify a
368 * sprite-only icon by passing 0 for text. Use the macros to define where
369 * and what area you want the sprite from.
372 * int where == what part of the icon bar you want to put the icon in.
373 * Macros are defined for the RISC OS 2 possibilities. Wait for the
374 * RISC OS 3 macros, or just pass a window handle.
375 * char *spritename == the name of the sprite to display
376 * sprite_area *sprarea == the area from which the sprite area comes. Use
377 * the macros provided for odd things like the WIMP area. If you have
378 * text as well, then this will be ignored anyway.
379 * char *text == the text for the icon. May be a NULL pointer, for no
381 * int maxtext == the max length the text entry can be. If 0 then the
382 * length of the text given will be used.
385 * A handle to the icon if successful, or 0 if not.
392 sprite_area *sprarea,
398 ibicon new=mem_alloc(sizeof(ibicon__ibiconstr));
402 werr(FALSE,msgs_lookup("ibicnNEM:Not enough memory for icon."));
405 if (!ibicon__eventHandler)
407 win_register_event_handler(win_ICONBAR,_dllEntry(ibicon__events),0);
408 win_register_event_handler(win_ICONBARLOAD,_dllEntry(ibicon__events),0);
412 _dllEntry(ibicon__menumaker),
413 _dllEntry(ibicon__menuhandler),
414 _dllEntry(ibicon__menuhelphandler),
417 ibicon__eventHandler=TRUE;
422 maxtext=strlen(text);
423 if (new->data=mem_alloc(maxtext+1),!new->data)
426 werr(FALSE,msgs_lookup("ibicnNEM:Not enough memory for icon."));
429 if (new->valid=mem_alloc(15),!new->valid)
433 werr(FALSE,msgs_lookup("ibicnNEM:Not enough memory for icon."));
436 strcpy(new->data,text);
437 sprintf(new->valid,"S%s",spritename);
438 i.i.data.indirecttext.buffer=new->data;
439 i.i.data.indirecttext.validstring=new->valid;
440 i.i.data.indirecttext.bufflen=maxtext+1;
441 ibicon__spriteSize(spritename,sprarea,&i.i.box,FALSE);
444 if (i.i.box.x1<16*maxtext)
445 i.i.box.x1=16*maxtext;
449 if (new->data=mem_alloc(15),!new->data)
452 werr(FALSE,msgs_lookup("ibicnNEM:Not enough memory for icon."));
455 strcpy(new->data,spritename);
457 i.i.data.indirectsprite.name=new->data;
458 i.i.data.indirectsprite.spritearea=(void *)sprarea;
459 i.i.data.indirectsprite.nameisname=TRUE;
460 ibicon__spriteSize(spritename,sprarea,&i.i.box,TRUE);
464 case ibicon_LEFTSEARCHLEFT:
465 case ibicon_LEFTSEARCHRIGHT:
466 if (wimpt_getVersion()<300)
469 case ibicon_RIGHTSEARCHLEFT:
470 case ibicon_RIGHTSEARCHRIGHT:
471 if (wimpt_getVersion()<300)
479 (text ? wimp_ITEXT : 0) |
481 (text ? 0 : wimp_IVCENTRE) |
483 wimp_IBTYPE * wimp_BCLICKDEBOUNCE |
487 wimpt_noerr(_swix(XWimp_CreateIcon,_inr(0,1)+_out(0),
488 ibicon__priority,(int)&i,
491 for (c=(ibicon)&ibicon__anchor;c->next;c=c->next)
493 if (c->next->icon>new->icon)
518 * void ibicon_changeSprite(ibicon i,char *newsprite)
521 * Chnage the sprite displayed in an icon
524 * ibicon i == the icon to change
525 * char *newsprite == the new name
528 void ibicon_changeSprite(ibicon i,char *newsprite)
531 sprintf(i->valid,"S%s",newsprite);
533 strcpy(i->data,newsprite);
534 wimpt_noerr(wimp_set_icon_state(-2,i->icon,0,0));
538 * void ibicon_changeText(ibicon i,char *newtext)
541 * Change the text of an icon.
544 * ibicon i == the icon to change
545 * char *text == the new text to display
548 void ibicon_changeText(ibicon i,char *newtext)
551 strcpy(i->data,newtext);
553 werr(TRUE,msgs_lookup("ibicnCCT:(ibicon_changeText, caller fault): "
554 "Attempt to write text to sprite-only ibicon."));
555 wimpt_noerr(wimp_set_icon_state(-2,i->icon,0,0));
559 * void ibicon_attachMenu
563 * menu_selectProc sel,
564 * menu_helpProc help,
569 * Attaches a menu to an icon in the icon bar
572 * ibicon i == the icon to attach to
573 * menu m == the menu to attach
574 * menu_selectProc sel == a handler function for the menu
575 * menu_helpProc help == a help processor for the menu
576 * void *handle == a handle passed to the handler
579 void ibicon_attachMenu
592 i->menuHandle=handle;
596 * void ibicon_attachMenuMaker
599 * event_menu_maker m,
600 * menu_selectProc sel,
601 * menu_helpProc help,
606 * Attaches a menu maker to an icon in the icon bar
609 * ibicon i == the icon to attach to
610 * event_menu_maker m == the menu maker to attach
611 * menu_selectProc sel == a handler function for the menu
612 * menu_helpProc help == a help processor for the menu
613 * void *handle == a handle passed to the handler
616 void ibicon_attachMenuMaker
629 i->menuHandle=handle;
633 * void ibicon_removeIcon(ibicon i)
636 * Removes an icon totally from the icon bar.
639 * ibicon i == the icon to vape
642 void ibicon_removeIcon(ibicon i)
644 wimpt_noerr(wimp_delete_icon(-2,i->icon));
646 i->prev->next=i->next;
648 ibicon__anchor=i->next;
650 i->next->prev=i->prev;
656 * void ibicon_eventHandler(ibicon i,ibicon_handler p,void *handle)
659 * Attaches the handler to an icon.
662 * ibicon i == the icon to attach
663 * ibicon_handler p == the handler
664 * void *handle == a pointer to pass to the handler
667 void ibicon_eventHandler(ibicon i,ibicon_handler p,void *handle)
674 * void ibicon_rawEventHandler(ibicon i,ibicon_rawHandler p,void *handle)
677 * Attaches a raw event handler. This can 'vet' events before ibicon gets
678 * it mucky mits on them.
681 * ibicon i == the icon to attach
682 * ibicon_rawHandler p == the handler
683 * void *handle == a pointer to pass to the handler
686 void ibicon_rawEventHandler(ibicon i,ibicon_rawHandler p,void *handle)