corrections to check for existing files.
[AROS-Contrib.git] / dopus / Library / gui.c
blob8282897fdc79df80877d827c31d2e8dd7163ab1c
1 /*
3 Directory Opus 4
4 Original GPL release version 4.12
5 Copyright 1993-2000 Jonathan Potter
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 All users of Directory Opus 4 (including versions distributed
22 under the GPL) are entitled to upgrade to the latest version of
23 Directory Opus version 5 at a reduced price. Please see
24 http://www.gpsoft.com.au for more information.
26 The release of Directory Opus 4 under the GPL in NO WAY affects
27 the existing commercial status of Directory Opus 5.
31 #define PROTO_DOPUS_H
32 #include <dopus/dopusbase.h>
33 #include "dopuslib.h"
35 const UWORD ditherdata[] = { 0x8888,0x2222 };
37 #define isinside(x,y,x1,y1,x2,y2) (x>=x1 && x<=x2 && y>=y1 && y<=y2)
39 int __regargs makeusstring(char *from,char *to,int *uspos,int size)
41 int len,c;
43 *uspos=-1;
44 for (c=0,len=0;len<size;c++) {
45 if (!from[c]) break;
46 else if (from[c]=='_' && *uspos==-1) *uspos=len;
47 else to[len++]=from[c];
49 to[len]=0;
50 return(len);
53 void __regargs ShowRMBGadName(struct RastPort *rp,struct RMBGadget *gad,int a)
55 struct RMBGadgetText *text;
56 int len,l,uspos,old;
57 char buf[100];
59 if ((text=&gad->txt[a])) {
60 old=rp->DrawMode;
61 SetDrMd(rp,JAM2);
62 SetAPen(rp,text->bg);
63 RectFill(rp,gad->x+text->x,gad->y+text->y,gad->x+text->x+text->w-1,gad->y+text->y+text->h-1);
64 SetAPen(rp,text->fg);
65 SetBPen(rp,text->bg);
66 if (text->text) {
67 len=makeusstring(text->text,buf,&uspos,99);
68 while ((l=TextLength(rp,buf,len))>text->w) {
69 if ((--len)==0) break;
71 buf[len]=0;
72 DoUScoreText(rp,buf,gad->x+text->x+((text->w-l)/2),
73 gad->y+text->y+((text->h-rp->Font->tf_YSize)/2)+rp->Font->tf_Baseline,uspos);
75 SetDrMd(rp,old);
79 void __regargs HighlightRMBGad(struct RastPort *rp,struct RMBGadget *gad,int state)
81 if (gad->flags&RGF_ALTBORD) DrawBorder(rp,gad->high_bord[state],gad->x,gad->y);
82 else {
83 int old;
85 old=rp->DrawMode;
86 SetDrMd(rp,COMPLEMENT);
87 RectFill(rp,gad->x,gad->y,gad->x+gad->w-1,gad->y+gad->h-1);
88 SetDrMd(rp,old);
92 void __saveds GhostGadget(register struct Gadget *gad __asm("a0"), register struct RastPort *rp __asm("a1"), register int xoff __asm("d0"), register int yoff __asm("d1"))
94 ULONG old_drmd = GetDrMd(rp);
96 SetDrMd(rp,COMPLEMENT);
97 SetAfPt(rp,ditherdata,1);
98 RectFill(rp,gad->LeftEdge+xoff,gad->TopEdge+yoff,
99 gad->LeftEdge+gad->Width-1-xoff,
100 gad->TopEdge+gad->Height-1-yoff);
101 SetAfPt(rp,NULL,0);
102 SetDrMd(rp,old_drmd);
105 void __saveds HiliteGad(register struct Gadget *gad __asm("a0"), register struct RastPort *rp __asm("a1"))
108 moveq.l #0,d4
109 move.b 28(a1),d4
111 UBYTE old_drmd = GetDrMd(rp);
112 D(bug("HiliteGad()\n"));
114 move.l a0,a2
115 move.l a1,a3
116 moveq.l #2,d0
117 move.l db_GfxBase(a6),a6
118 jsr _LVOSetDrMd(a6)
120 SetDrMd(rp,COMPLEMENT);
122 move.l a3,a1
123 moveq.l #0,d0
124 moveq.l #0,d1
125 move.w 4(a2),d0
126 move.w 6(a2),d1
127 move.l d0,d2
128 add.w 8(a2),d2
129 subq.w #1,d2
130 move.l d1,d3
131 add.w 10(a2),d3
132 subq.w #1,d3
133 jsr _LVORectFill(a6)
135 RectFill(rp,gad->LeftEdge,gad->TopEdge,gad->LeftEdge+gad->Width-1,gad->TopEdge+gad->Height-1);
137 move.l a3,a1
138 move.l d4,d0
139 jsr _LVOSetDrMd(a6)
141 SetDrMd(rp,old_drmd);
145 void __saveds ActivateStrGad(register struct Gadget *gad __asm("a0"), register struct Window *win __asm("a1"))
147 struct StringInfo *si;
149 D(bug("ActivateStrGad()\n"));
150 if (gad->Flags & GFLG_DISABLED) return;
152 si = (struct StringInfo *)(gad->SpecialInfo);
154 si->BufferPos = (gad->Activation & GACT_STRINGRIGHT) ? 0 : strlen(si->Buffer);
156 RefreshGList(gad,win,NULL,1);
157 ActivateGadget(gad,win,NULL);
160 void __saveds RefreshStrGad(register struct Gadget *gad __asm("a0"), register struct Window *win __asm("a1"))
162 ((struct StringInfo *)(gad->SpecialInfo))->BufferPos=0;
164 D(bug("RefreshStrGad()\n"));
165 gad->Flags |= GFLG_GADGHNONE;
166 RefreshGList(gad,win,NULL,1);
167 gad->Flags &= ~GFLG_GADGHNONE;
170 void __saveds DisableGadget(register struct Gadget *gad __asm("a0"), register struct RastPort *rp __asm("a1"), register int xoff __asm("d0"), register int yoff __asm("d1"))
172 if (gad->Flags & GFLG_DISABLED) return;
174 gad->Flags |= GFLG_DISABLED;
175 GhostGadget(gad,rp,xoff,yoff);
178 void __saveds EnableGadget(register struct Gadget *gad __asm("a0"), register struct RastPort *rp __asm("a1"), register int xoff __asm("d0"), register int yoff __asm("d1"))
180 if (gad->Flags & GFLG_DISABLED)
182 gad->Flags &= ~GFLG_DISABLED;
183 GhostGadget(gad,rp,xoff,yoff);
187 int __saveds DoAddGadgets(register struct Window *win __asm("a0"), register struct Gadget *firstgad __asm("a1"), register char **text __asm("a2"), register int count __asm("d0"), register int fg __asm("d1"), register int bg __asm("d2"), register int add __asm("d3"))
189 int num=0,realcount=0,of,ob,a,x,y,b,c,up,xp,yp,bl,len,offset;
190 char buf[80];
191 struct RastPort *rp;
192 struct Gadget *gad;
194 rp=win->RPort; gad=firstgad;
195 of=rp->FgPen; ob=rp->BgPen;
196 x=rp->Font->tf_XSize; y=rp->Font->tf_YSize; bl=rp->Font->tf_Baseline;
198 while (gad && num<count) {
199 while (text && text[realcount] && text[realcount]!=(char *)-1 &&
200 !text[realcount][0]) ++realcount;
201 if (text && !text[realcount]) text=NULL;
203 if (gad->GadgetType==GTYP_STRGADGET) {
204 Do3DStringBox(rp,
205 gad->LeftEdge-(gad->MutualExclude*2),gad->TopEdge-gad->MutualExclude,
206 gad->Width+(gad->MutualExclude*4),gad->Height+(gad->MutualExclude*2),
207 fg,bg);
209 else if (gad->GadgetType==GTYP_PROPGADGET) {
210 Do3DBox(rp,
211 gad->LeftEdge-2,gad->TopEdge-1,
212 gad->Width+4,gad->Height+2,
213 fg,bg);
215 else if (gad->MutualExclude==GAD_CYCLE) {
216 Do3DCycleBox(rp,
217 gad->LeftEdge+2,gad->TopEdge+1,
218 gad->Width-4,gad->Height-2,
219 fg,bg);
221 else if (gad->MutualExclude==GAD_CHECK) {
222 Do3DBox(rp,
223 gad->LeftEdge+2,gad->TopEdge+1,
224 22,9,
225 fg,bg);
227 else if (gad->MutualExclude!=GAD_NONE && gad->MutualExclude!=GAD_RADIO) {
228 Do3DBox(rp,
229 gad->LeftEdge+2,gad->TopEdge+1,
230 gad->Width-4,gad->Height-2,
231 fg,bg);
234 SetAPen(rp,of);
235 SetBPen(rp,ob);
237 if (text && text[realcount] && text[realcount]!=(char *)-1 &&
238 text[realcount][0]) {
239 a=strlen(text[realcount]);
240 up=-1;
241 for (b=0,c=0;b<a;b++) {
242 if (text[realcount][b]=='_' && up==-1) up=c;
243 else buf[c++]=text[realcount][b];
245 buf[c]=0;
246 if (up>-1) --a;
247 len=TextLength(rp,text[realcount],a);
249 if (gad->GadgetType==GTYP_STRGADGET ||
250 (gad->GadgetType==GTYP_PROPGADGET && !(((struct PropInfo *)gad->SpecialInfo)->Flags&FREEHORIZ)) ||
251 gad->MutualExclude==GAD_GLASS ||
252 gad->MutualExclude==GAD_CYCLE) {
254 if (gad->GadgetType==GTYP_STRGADGET) offset=gad->MutualExclude;
255 else offset=0;
257 xp=gad->LeftEdge-(offset*2)-(len+x);
258 yp=gad->TopEdge+((gad->Height+(offset*2)-y)/2)+bl-offset;
260 else if (gad->GadgetType==GTYP_PROPGADGET) {
261 xp=gad->LeftEdge+((gad->Width-len)/2);
262 yp=gad->TopEdge-(y*2)+bl;
264 else {
265 switch (gad->MutualExclude) {
266 case GAD_CHECK:
267 xp=gad->LeftEdge+36;
268 break;
269 case GAD_RADIO:
270 xp=gad->LeftEdge+gad->Width+8;
271 break;
272 default:
273 xp=gad->LeftEdge+((gad->Width-len)/2);
274 break;
276 yp=gad->TopEdge+((((gad->MutualExclude==GAD_CHECK)?12:gad->Height)-y)/2)+bl;
279 DoUScoreText(rp,buf,xp,yp,up);
282 if (gad->GadgetType==GTYP_BOOLGADGET &&
283 gad->MutualExclude!=GAD_CHECK &&
284 gad->MutualExclude!=GAD_RADIO &&
285 gad->Activation&GACT_TOGGLESELECT &&
286 gad->Flags&GFLG_SELECTED) HiliteGad(gad,rp);
288 gad=gad->NextGadget;
289 ++num;
290 ++realcount;
292 if (add) {
293 AddGList(win,firstgad,-1,realcount,NULL);
294 gad=firstgad;
295 for (a=0;a<realcount && gad;a++) {
296 if (gad->GadgetType!=GTYP_PROPGADGET) {
297 if (gad->GadgetType==GTYP_STRGADGET ||
298 gad->MutualExclude==GAD_RADIO ||
299 (gad->GadgetType==GTYP_BOOLGADGET && gad->MutualExclude==GAD_CHECK &&
300 gad->Activation&GACT_TOGGLESELECT && gad->Flags&GFLG_SELECTED))
301 RefreshGList(gad,win,NULL,1);
303 gad=gad->NextGadget;
306 return(realcount);
309 int __saveds DoDoRMBGadget(register struct RMBGadget *gad __asm("a0"), register struct Window *window __asm("a1"))
311 ULONG class;
312 UWORD code;
313 BOOL inside;
314 struct RastPort *rp;
315 int x,y,x1,y1,ret=-1;
316 ULONG idcmpflags,windowflags;
317 struct IntuiMessage *Msg;
318 struct Gadget dummy_gadget;
320 x=window->MouseX; y=window->MouseY;
321 while (gad) {
322 if (gad->w>0 && gad->h>0) {
323 x1=gad->x+gad->w-1; y1=gad->y+gad->h-1;
324 if (isinside(x,y,gad->x,gad->y,x1,y1)) break;
326 gad=gad->next;
328 if (!gad) return(-1);
329 rp=window->RPort;
331 idcmpflags=window->IDCMPFlags;
332 ModifyIDCMP(window,IDCMP_MOUSEBUTTONS|IDCMP_MOUSEMOVE|IDCMP_INACTIVEWINDOW);
334 windowflags=window->Flags;
335 window->Flags|=WFLG_REPORTMOUSE;
337 if (isinside(x,y,gad->x,gad->y,x1,y1)) {
338 if (gad->flags&RGF_ALTTEXT) ShowRMBGadName(rp,gad,1);
339 HighlightRMBGad(rp,gad,1);
340 inside=TRUE;
342 else inside=FALSE;
344 dummy_gadget.LeftEdge=0;
345 dummy_gadget.TopEdge=0;
346 dummy_gadget.Width=window->Width;
347 dummy_gadget.Height=window->Height;
348 dummy_gadget.Flags=GFLG_GADGHNONE;
349 dummy_gadget.Activation=GACT_IMMEDIATE;
350 dummy_gadget.GadgetType=GTYP_BOOLGADGET;
351 dummy_gadget.GadgetRender=NULL;
352 dummy_gadget.SelectRender=NULL;
353 dummy_gadget.GadgetText=NULL;
354 AddGList(window,&dummy_gadget,0,1,NULL);
356 FOREVER {
357 while (Msg=(struct IntuiMessage *)GetMsg(window->UserPort)) {
358 class=Msg->Class;
359 code=Msg->Code;
360 x=Msg->MouseX;
361 y=Msg->MouseY;
362 ReplyMsg((struct Message *)Msg);
364 if (class==IDCMP_INACTIVEWINDOW) goto end_rmb;
365 if (class==IDCMP_MOUSEBUTTONS && code==MENUUP) {
366 if (inside) ret=gad->id;
367 goto end_rmb;
369 if (class==IDCMP_MOUSEMOVE) {
370 if (!(isinside(x,y,gad->x,gad->y,x1,y1))) {
371 if (inside) {
372 HighlightRMBGad(rp,gad,0);
373 if (gad->flags&RGF_ALTTEXT) ShowRMBGadName(rp,gad,0);
374 inside=FALSE;
377 else {
378 if (!inside) {
379 if (gad->flags&RGF_ALTTEXT) ShowRMBGadName(rp,gad,1);
380 HighlightRMBGad(rp,gad,1);
381 inside=TRUE;
386 Wait(1<<window->UserPort->mp_SigBit);
388 end_rmb:
389 if (inside) {
390 HighlightRMBGad(rp,gad,0);
391 if (gad->flags&RGF_ALTTEXT) ShowRMBGadName(rp,gad,0);
393 RemoveGList(window,&dummy_gadget,1);
394 ModifyIDCMP(window,idcmpflags);
395 window->Flags=windowflags;
396 return(ret);
399 void __saveds DoDoCycleGadget(register struct Gadget *gad __asm("a0"), register struct Window *window __asm("a1"), register char **choices __asm("a2"), register int select __asm("d0"))
401 int op,a;
402 struct RastPort *rp;
404 rp=window->RPort;
405 op=rp->FgPen;
406 SetAPen(rp,rp->BgPen);
407 RectFill(rp,gad->LeftEdge+22,gad->TopEdge+1,
408 gad->LeftEdge+gad->Width-3,gad->TopEdge+gad->Height-2);
409 SetAPen(rp,op);
410 if (choices && choices[select]) {
411 Move(rp,gad->LeftEdge+20+((gad->Width-22-((a=strlen(choices[select]))*rp->Font->tf_XSize))/2),
412 gad->TopEdge+rp->Font->tf_Baseline+((gad->Height-rp->Font->tf_YSize)/2));
413 Text(rp,choices[select],a);
417 void __saveds DoUScoreText(register struct RastPort *rp __asm("a0"),
418 register char *buf __asm("a1"),
419 register int xp __asm("d0"),
420 register int yp __asm("d1"),
421 register int up __asm("d2"))
423 int a,x,x1,y1;
425 Move(rp,xp,yp); Text(rp,buf,(a=strlen(buf)));
426 x1 = rp->cp_x;
427 y1 = rp->cp_y;
428 if (up>-1 && up<a) {
429 x=TextLength(rp,buf,up);
430 Move(rp,xp+x,yp+2);
431 Draw(rp,rp->cp_x+(TextLength(rp,&buf[up],1))-1,rp->cp_y);
433 Move(rp,x1,y1);