Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / libs / gadtools / gadgets.c
blob92b4c447e9a8dd9d84227142877625ac4a19e46d
1 /*
2 Copyright © 1995-2010, The AROS Development Team. All rights reserved.
3 $Id$
5 GadTools gadget creation functions
6 */
8 /****************************************************************************************/
10 #include <stdio.h>
11 #include <proto/exec.h>
12 #include <exec/types.h>
13 #include <exec/libraries.h>
14 #include <exec/memory.h>
15 #include <proto/intuition.h>
16 #include <graphics/gfxmacros.h>
17 #include <intuition/intuition.h>
18 #include <intuition/classusr.h>
19 #include <intuition/gadgetclass.h>
20 #include <intuition/imageclass.h>
21 #include <intuition/screens.h>
22 #include <intuition/icclass.h>
23 #include <proto/utility.h>
24 #include <utility/tagitem.h>
25 #include <libraries/gadtools.h>
27 #if 0
28 #define SDEBUG 0
29 #define DEBUG 0
30 #endif
31 #include <aros/debug.h>
33 #include "gadtools_intern.h"
35 /****************************************************************************************/
37 #define EG(x) ((struct ExtGadget *)(x))
39 /****************************************************************************************/
41 struct Gadget *makebutton(struct GadToolsBase_intern *GadToolsBase,
42 struct TagItem stdgadtags[],
43 struct VisualInfo *vi,
44 struct TagItem *taglist)
46 struct Gadget *obj;
47 struct TagItem tags[] =
49 {GA_Disabled , FALSE },
50 {GA_Immediate , FALSE },
51 {GA_RelVerify , TRUE },
52 {TAG_MORE , (IPTR) NULL }
55 tags[0].ti_Data = GetTagData(GA_Disabled, FALSE, taglist);
56 tags[1].ti_Data = GetTagData(GA_Immediate, FALSE, taglist);
57 tags[3].ti_Data = (IPTR) stdgadtags;
59 obj = (struct Gadget *) NewObjectA(GadToolsBase->buttonclass, NULL, tags);
60 if (obj)
62 obj->GadgetType |= GTYP_GADTOOLS;
64 return obj;
67 /****************************************************************************************/
69 struct Gadget *makecheckbox(struct GadToolsBase_intern *GadToolsBase,
70 struct TagItem stdgadtags[],
71 struct VisualInfo *vi,
72 struct TagItem *taglist)
74 struct Gadget *obj;
75 struct TagItem tags[] =
77 {GA_Disabled , FALSE },
78 {GTCB_Checked , FALSE },
79 {TAG_MORE , (IPTR)NULL }
82 EnterFunc(bug("makecheckbox()\n"));
84 tags[0].ti_Data = GetTagData(GA_Disabled, FALSE, taglist);
85 tags[1].ti_Data = GetTagData(GTCB_Checked, FALSE, taglist);
86 tags[2].ti_Data = (IPTR) stdgadtags;
88 if (!GetTagData(GTCB_Scaled, FALSE, taglist)) {
89 stdgadtags[TAG_Width].ti_Data = CHECKBOX_WIDTH;
90 stdgadtags[TAG_Height].ti_Data = CHECKBOX_HEIGHT;
93 obj = (struct Gadget *) NewObjectA(GadToolsBase->checkboxclass, NULL, tags);
94 if (obj)
96 obj->GadgetType |= GTYP_GADTOOLS;
99 ReturnPtr("makecheckbox()", struct Gadget *, obj);
102 /****************************************************************************************/
104 struct Gadget *makecycle(struct GadToolsBase_intern *GadToolsBase,
105 struct TagItem stdgadtags[],
106 struct VisualInfo *vi,
107 struct TextAttr *tattr,
108 struct TagItem *taglist)
110 struct Gadget *obj;
111 struct TagItem tags[] =
113 {GA_Disabled , FALSE }, /* 0 */
114 {GTCY_Labels , FALSE }, /* 1 */
115 {GTCY_Active , 0 }, /* 2 */
116 {GA_RelVerify , TRUE }, /* 3 */
117 {GA_TextAttr , 0 }, /* 4 */
118 {TAG_MORE , (IPTR)NULL } /* 5 */
121 EnterFunc(bug("makecycle()\n"));
123 tags[0].ti_Data = GetTagData(GA_Disabled, FALSE, taglist);
124 tags[1].ti_Data = GetTagData(GTCY_Labels, FALSE, taglist);
125 tags[2].ti_Data = GetTagData(GTCY_Active, 0, taglist);
127 /* Be sure not to pass GA_TextAttr, NULL */
128 if (tattr)
129 tags[4].ti_Data = (IPTR)tattr;
130 else
131 tags[4].ti_Tag = TAG_IGNORE;
133 tags[5].ti_Data = (IPTR) stdgadtags;
135 obj = (struct Gadget *) NewObjectA(GadToolsBase->cycleclass, NULL, tags);
137 if (obj)
139 obj->GadgetType |= GTYP_GADTOOLS;
142 ReturnPtr("makecycle()", struct Gadget *, obj);
145 /****************************************************************************************/
147 struct Gadget *makemx(struct GadToolsBase_intern *GadToolsBase,
148 struct TagItem stdgadtags[],
149 struct VisualInfo *vi,
150 struct TextAttr *tattr,
151 struct TagItem *taglist)
153 struct Gadget *obj;
154 int labels = 0;
155 STRPTR *labellist;
156 struct TagItem *tag, tags[] =
158 {GA_Disabled , FALSE }, /* 0 */
159 {GTMX_Labels , (IPTR) NULL }, /* 1 */
160 {GTMX_Active , 0 }, /* 2 */
161 {GTMX_Spacing , 1 }, /* 3 */
162 {GTMX_TickHeight , MX_HEIGHT }, /* 4 */
163 {GTMX_TickLabelPlace , GV_LabelPlace_Right }, /* 5 */
164 {GA_TextAttr , 0 }, /* 6 */
165 {TAG_MORE , (IPTR) NULL } /* 7 */
168 tags[0].ti_Data = GetTagData(GA_Disabled, FALSE, taglist);
169 labellist = (STRPTR *) GetTagData(GTMX_Labels, (IPTR) NULL, taglist);
170 if (!labellist)
171 return NULL;
172 tags[1].ti_Data = (IPTR) labellist;
173 tags[2].ti_Data = GetTagData(GTMX_Active, 0, taglist);
174 tags[3].ti_Data = GetTagData(GTMX_Spacing, 1, taglist);
175 if (GetTagData(GTMX_Scaled, FALSE, taglist))
176 tags[4].ti_Data = stdgadtags[TAG_Height].ti_Data;
177 else
178 stdgadtags[TAG_Width].ti_Data = MX_WIDTH;
179 switch (stdgadtags[TAG_LabelPlace].ti_Data & 0x1f)
181 case GV_LabelPlace_Left:
182 tags[5].ti_Data = GV_LabelPlace_Left;
183 break;
184 case GV_LabelPlace_Above:
185 tags[5].ti_Data = GV_LabelPlace_Above;
186 break;
187 case GV_LabelPlace_Below:
188 tags[5].ti_Data = GV_LabelPlace_Below;
189 break;
192 /* Be sure not to pass GA_TextAttr, NULL */
193 if (tattr)
194 tags[6].ti_Data = (IPTR)tattr;
195 else
196 tags[6].ti_Tag = TAG_IGNORE;
198 tags[7].ti_Data = (IPTR) stdgadtags;
200 tag = FindTagItem(GTMX_TitlePlace, taglist);
201 if (tag)
203 switch (tag->ti_Data)
205 case PLACETEXT_LEFT:
206 stdgadtags[TAG_LabelPlace].ti_Data = GV_LabelPlace_Left;
207 break;
208 case PLACETEXT_RIGHT:
209 stdgadtags[TAG_LabelPlace].ti_Data = GV_LabelPlace_Right;
210 break;
211 case PLACETEXT_ABOVE:
212 stdgadtags[TAG_LabelPlace].ti_Data = GV_LabelPlace_Above;
213 break;
214 case PLACETEXT_BELOW:
215 stdgadtags[TAG_LabelPlace].ti_Data = GV_LabelPlace_Below;
216 break;
217 default:
218 freeitext(GadToolsBase,
219 (struct IntuiText *)stdgadtags[TAG_IText].ti_Data);
220 stdgadtags[TAG_IText].ti_Data = (IPTR)NULL;
221 break;
223 } else
225 freeitext(GadToolsBase,
226 (struct IntuiText *)stdgadtags[TAG_IText].ti_Data);
227 stdgadtags[TAG_IText].ti_Data = (IPTR)NULL;
230 while (labellist[labels])
231 labels++;
233 obj = (struct Gadget *) NewObjectA(GadToolsBase->mxclass, NULL, tags);
235 if (obj)
237 obj->GadgetType |= GTYP_GADTOOLS;
240 return obj;
243 /****************************************************************************************/
245 struct Gadget *makepalette(struct GadToolsBase_intern *GadToolsBase,
246 struct TagItem stdgadtags[],
247 struct VisualInfo *vi,
248 const struct TagItem *taglist)
250 struct Gadget *obj = NULL;
252 struct TagItem *tag, tags[] =
254 {GA_RelVerify, TRUE }, /* 0 */
255 {GA_Disabled, FALSE }, /* 1 */
256 {GTPA_Depth, 1 }, /* 2 */
257 {GTPA_Color, 0 }, /* 3 */
258 {GTPA_ColorOffset, 0 }, /* 4 */
259 {GTPA_IndicatorWidth, 0 }, /* 5 */
260 {GTPA_IndicatorHeight, 0 }, /* 6 */
261 {GTPA_NumColors, 2 }, /* 7 */
262 {GTPA_ColorTable, 0 }, /* 8 */
263 {TAG_MORE, (IPTR)NULL }
266 /* Could use GetTagData(), but this is faster */
267 while ((tag = NextTagItem((struct TagItem **)&taglist)))
269 IPTR tidata = tag->ti_Data;
271 /* Note: GTPA_NumColors overrides GTPA_Depth tag! */
273 switch (tag->ti_Tag)
275 case GA_Disabled: tags[1].ti_Data = tidata; break;
276 case GTPA_Depth: tags[2].ti_Data = tidata; tags[7].ti_Data = 1L << tidata;break;
277 case GTPA_Color: tags[3].ti_Data = tidata; break;
278 case GTPA_ColorOffset: tags[4].ti_Data = tidata; break;
279 case GTPA_IndicatorWidth: tags[5].ti_Data = tidata; break;
280 case GTPA_IndicatorHeight: tags[6].ti_Data = tidata; break;
281 case GTPA_NumColors: tags[7].ti_Data = tidata; break;
282 case GTPA_ColorTable: tags[8].ti_Data = tidata; break;
284 } /* switch() */
286 } /* while (iterate taglist) */
288 tags[9].ti_Data = (IPTR)stdgadtags;
290 obj = (struct Gadget *) NewObjectA(GadToolsBase->paletteclass, NULL, tags);
292 if (obj)
294 obj->GadgetType |= GTYP_GADTOOLS;
297 return obj;
300 /****************************************************************************************/
302 struct Gadget *maketext(struct GadToolsBase_intern *GadToolsBase,
303 struct TagItem stdgadtags[],
304 struct VisualInfo *vi,
305 struct TextAttr *tattr,
306 const struct TagItem *taglist)
308 struct Gadget *obj = NULL;
309 BOOL cliptag_found = FALSE;
311 struct TagItem *tag, tags[] =
313 {GTTX_Text , 0 },
314 {GTTX_CopyText , FALSE },
315 {GTTX_Clipped , FALSE },
316 {GTTX_Border , FALSE },
317 {GTTX_FrontPen , TEXTPEN },
318 {GTTX_BackPen , BACKGROUNDPEN },
319 {GTTX_Justification , GTJ_LEFT },
320 {GTA_Text_Format , (IPTR)"%s" },
321 {GA_TextAttr , (IPTR)NULL },
322 {GTA_GadgetKind , TEXT_KIND },
323 {TAG_MORE , (IPTR) NULL }
326 /* Could use GetTagData(), but this is faster */
327 while ((tag = NextTagItem((struct TagItem **)&taglist)))
329 IPTR tidata = tag->ti_Data;
331 switch (tag->ti_Tag)
333 case GTTX_Text: tags[0].ti_Data = tidata; break;
334 case GTTX_CopyText: tags[1].ti_Data = tidata; break;
335 case GTTX_Clipped: tags[2].ti_Data = tidata; cliptag_found = TRUE;break;
336 case GTTX_Border: tags[3].ti_Data = tidata; break;
337 case GTTX_FrontPen: tags[4].ti_Data = tidata; break;
338 case GTTX_BackPen: tags[5].ti_Data = tidata; break;
339 case GTTX_Justification: tags[6].ti_Data = tidata; break;
342 } /* while (iterate taglist) */
344 /* if GTTX_Clipped was not specified then the default value is
345 the GTTX_Border value */
347 if (!cliptag_found) tags[2].ti_Data = tags[3].ti_Data;
349 /* Be sure not to pass GA_TextAttr, NULL */
350 if (tattr)
351 tags[8].ti_Data = (IPTR)tattr;
352 else
353 tags[8].ti_Tag = TAG_IGNORE;
354 tags[10].ti_Data = (IPTR)stdgadtags;
356 obj = (struct Gadget *) NewObjectA(GadToolsBase->textclass, NULL, tags);
358 if (obj)
360 obj->GadgetType |= GTYP_GADTOOLS;
363 return (obj);
366 /****************************************************************************************/
368 struct Gadget *makenumber(struct GadToolsBase_intern *GadToolsBase,
369 struct TagItem stdgadtags[],
370 struct VisualInfo *vi,
371 struct TextAttr *tattr,
372 const struct TagItem *taglist)
374 struct Gadget *obj = NULL;
375 BOOL cliptag_found = FALSE;
377 struct TagItem *tag, tags[] =
379 {GTNM_Number , 0 },
380 {GTNM_Format , (IPTR)"%ld" },
381 {GTNM_Clipped , FALSE },
382 {GTNM_Border , FALSE },
383 {GTNM_FrontPen , TEXTPEN },
384 {GTNM_BackPen , BACKGROUNDPEN },
385 {GTNM_Justification , GTJ_CENTER },
386 {GTNM_MaxNumberLen , 100 },
387 {GA_TextAttr , (IPTR)NULL },
388 {GTA_GadgetKind , NUMBER_KIND },
389 {TAG_MORE , (IPTR) NULL }
393 /* Could use GetTagData(), but this is faster */
394 while ((tag = NextTagItem((struct TagItem **)&taglist)))
396 IPTR tidata = tag->ti_Data;
398 switch (tag->ti_Tag)
400 case GTNM_Number: tags[0].ti_Data = tidata; break;
401 case GTNM_Format: tags[1].ti_Data = tidata; break;
402 case GTNM_Clipped: tags[2].ti_Data = tidata; cliptag_found = TRUE;break;
403 case GTNM_Border: tags[3].ti_Data = tidata; break;
404 case GTNM_FrontPen: tags[4].ti_Data = tidata; break;
405 case GTNM_BackPen: tags[5].ti_Data = tidata; break;
406 case GTNM_Justification: tags[6].ti_Data = tidata; break;
407 case GTNM_MaxNumberLen: tags[7].ti_Data = tidata; break;
410 } /* while (iterate taglist) */
412 /* if GTNM_Clipped was not specified then the default value is
413 the GTNM_Border value */
415 if (!cliptag_found) tags[2].ti_Data = tags[3].ti_Data;
417 /* Be sure not to pass GA_TextAttr, NULL */
418 if (tattr)
419 tags[8].ti_Data = (IPTR)tattr;
420 else
421 tags[8].ti_Tag = TAG_IGNORE;
423 tags[10].ti_Data = (IPTR)stdgadtags;
425 obj = (struct Gadget *) NewObjectA(GadToolsBase->textclass, NULL, tags);
427 if (obj)
429 obj->GadgetType |= GTYP_GADTOOLS;
432 return (obj);
436 /****************************************************************************************/
438 /* This MUST be global, since the gadgetclass doesn't copy ICA_MAPPINGs */
439 const struct TagItem slider2level[] =
441 {GTSL_Level, GTNM_Number},
442 {TAG_DONE }
445 /****************************************************************************************/
447 struct Gadget *makeslider(struct GadToolsBase_intern *GadToolsBase,
448 struct TagItem stdgadtags[],
449 struct VisualInfo *vi,
450 struct TextAttr *tattr,
451 const struct TagItem *taglist)
454 struct TagItem *tag;
455 struct IBox bbox;
457 struct TagItem stags[] =
459 {GA_Disabled , FALSE },
460 {GA_RelVerify , TRUE }, /* Georg S.: was false */
461 {GA_Immediate , TRUE }, /* Georg S.: was false */
462 {GTSL_Min , 0 },
463 {GTSL_Max , 15 },
464 {GTSL_Level , 0 },
465 {PGA_Freedom , FREEHORIZ },
466 {PGA_Borderless , TRUE },
467 #ifdef __MORPHOS__
468 {PGA_NewLook , FALSE },
469 #else
470 {PGA_NewLook , TRUE },
471 #endif
472 {GA_Bounds , (IPTR)&bbox },
473 {GA_FollowMouse , TRUE },
474 {PGA_NotifyBehaviour, PG_BEHAVIOUR_NICE },
475 {PGA_RenderBehaviour, PG_BEHAVIOUR_NICE },
476 {TAG_MORE , (IPTR)NULL }
479 struct TagItem ltags[] =
481 {GA_Left , 0 },
482 {GA_Top , 0 },
483 {GA_Width , 0 },
484 {GA_Height , 0 },
485 {GA_TextAttr , (IPTR)tattr },
486 {GTNM_Format , (IPTR)NULL },
487 {GTNM_Justification , GTJ_LEFT },
488 {GTA_Text_DispFunc , (IPTR)NULL },
489 {GA_Next , (IPTR)NULL },
490 {GA_DrawInfo , (IPTR)NULL },
491 {GTNM_Number , 0 },
492 {GTA_GadgetKind , SLIDER_KIND },
493 {GA_Previous , (IPTR)NULL },
494 {GTA_Text_ParentGadget , 0 },
495 {TAG_DONE }
497 STRPTR lformat = NULL;
498 WORD lmaxlen = 0;
499 LONG lmaxpixellen = 0L;
500 UBYTE lplace = PLACETEXT_LEFT;
501 WORD level = 0;
503 struct Gadget *slidergad = NULL, *levelgad = NULL;
505 /* Parse tags */
506 while ((tag = NextTagItem((struct TagItem **)&taglist)))
508 IPTR tidata = tag->ti_Data;
510 switch (tag->ti_Tag)
513 /* Slider tags */
514 case GA_Disabled: stags[0].ti_Data = tidata; break;
515 case GA_RelVerify: stags[1].ti_Data = tidata; break;
516 case GA_Immediate: stags[2].ti_Data = tidata; break;
517 case GTSL_Min: stags[3].ti_Data = tidata; break;
518 case GTSL_Max: stags[4].ti_Data = tidata; break;
519 case GTSL_Level: level = stags[5].ti_Data = tidata; break;
520 case PGA_Freedom:
521 if (tidata == LORIENT_HORIZ)
522 stags[6].ti_Data = FREEHORIZ;
523 else
524 stags[6].ti_Data = FREEVERT;
525 break;
527 /* Level tags */
528 case GTSL_LevelFormat: lformat = (STRPTR)tidata; break;
529 case GTSL_MaxLevelLen: lmaxlen = (UWORD)tidata; break;
530 case GTSL_MaxPixelLen: lmaxpixellen = (ULONG)tidata; break;
531 case GTSL_LevelPlace: lplace = (UBYTE)tidata; break;
532 case GTSL_Justification: ltags[6].ti_Data = tidata; break;
533 case GTSL_DispFunc: ltags[7].ti_Data = tidata; break;
537 } /* while (iterate taglist) */
539 /* if there is a bounding box the label position
540 will be calculated based on this box and not
541 the gadget coords */
543 bbox.Left = GetTagData(GA_Left, 0, stdgadtags);
544 bbox.Top = GetTagData(GA_Top, 0, stdgadtags);
545 bbox.Width = GetTagData(GA_Width, 0, stdgadtags);
546 bbox.Height = GetTagData(GA_Height, 0, stdgadtags);
548 /* There are always GA_Left, GA_Top, GA_Width and GA_Height tags
549 thanks to creategadgeta.c! */
551 FindTagItem(GA_Left,stdgadtags)->ti_Data += BORDERPROPSPACINGX;
552 FindTagItem(GA_Top,stdgadtags)->ti_Data += BORDERPROPSPACINGY;
553 FindTagItem(GA_Width,stdgadtags)->ti_Data -= BORDERPROPSPACINGX * 2;
554 FindTagItem(GA_Height,stdgadtags)->ti_Data -= BORDERPROPSPACINGY * 2;
556 /* Create slider gadget */
557 stags[13].ti_Data = (IPTR)stdgadtags;
558 slidergad = NewObjectA(GadToolsBase->sliderclass, NULL, stags);
560 if (!slidergad)
561 return (NULL);
563 slidergad->GadgetType |= GTYP_GADTOOLS;
565 if (lformat || lmaxlen || lmaxpixellen)
567 WORD x = 0, y = 0;
568 UWORD ysize = 8;
570 struct TagItem lntags[] =
572 {ICA_TARGET, (IPTR)NULL },
573 {ICA_MAP , (IPTR)NULL },
574 {TAG_DONE }
577 /* Set some defaults */
578 if (!lformat)
579 lformat = "%ld";
580 if (!lmaxlen)
581 lmaxlen = 2;
582 if (!lmaxpixellen)
584 struct TextFont *font;
585 UWORD xsize;
587 ysize = vi->vi_dri->dri_Font->tf_YSize;
588 xsize = vi->vi_dri->dri_Font->tf_XSize;
590 if (tattr)
592 font = OpenFont(tattr);
593 if (font)
595 ysize = font->tf_YSize;
596 xsize = font->tf_XSize;
597 CloseFont(font);
599 else /* If no valid tattr */
600 ltags[4].ti_Tag = TAG_IGNORE;
602 else /* If no valid tattr */
603 ltags[4].ti_Tag = TAG_IGNORE;
605 lmaxpixellen = lmaxlen * xsize;
607 ltags[4].ti_Data = (IPTR)tattr;
609 } /* if (!lmaxpixellen) */
611 switch (lplace)
613 case PLACETEXT_LEFT:
614 x = slidergad->LeftEdge - BORDERPROPSPACINGX - lmaxpixellen - 4;
615 y = slidergad->TopEdge + (slidergad->Height - ysize) / 2 + 1;
616 break;
617 case PLACETEXT_RIGHT:
618 x = slidergad->LeftEdge + slidergad->Width + BORDERPROPSPACINGX + 5;
619 y = slidergad->TopEdge + (slidergad->Height - ysize) / 2 + 1;
620 break;
621 case PLACETEXT_ABOVE:
622 x = slidergad->LeftEdge - (lmaxpixellen - slidergad->Width) / 2;
623 y = slidergad->TopEdge - BORDERPROPSPACINGY - ysize - 2;
624 break;
625 case PLACETEXT_BELOW:
626 x = slidergad->LeftEdge - (lmaxpixellen - slidergad->Width) / 2;
627 y = slidergad->TopEdge + slidergad->Height + BORDERPROPSPACINGY + 3;
628 break;
631 /* Create the levelobj */
633 ltags[0].ti_Data = (IPTR)x;
634 ltags[1].ti_Data = (IPTR)y;
635 ltags[2].ti_Data = (IPTR)lmaxpixellen;
636 ltags[3].ti_Data = (IPTR)ysize;
637 ltags[5].ti_Data = (IPTR)lformat;
638 ltags[8].ti_Data = (IPTR)slidergad;
639 ltags[9].ti_Data = (IPTR)vi->vi_dri;
640 ltags[10].ti_Data = (IPTR)level;
641 ltags[12].ti_Data = (IPTR)GetTagData(GA_Previous, 0, stdgadtags);
642 ltags[13].ti_Data = (IPTR)slidergad;
644 levelgad = (struct Gadget *)NewObjectA(GadToolsBase->textclass, NULL, ltags);
645 if (!levelgad)
647 DisposeObject((Object *)slidergad);
648 return (NULL);
650 levelgad->GadgetType |= GTYP_GADTOOLS;
652 /* Set up a notification from the slider to the level */
653 lntags[0].ti_Data = (IPTR)levelgad;
654 lntags[1].ti_Data = (IPTR)slider2level;
655 SetAttrsA((Object *)slidergad, lntags);
657 return (levelgad);
659 } /* if (slider should have a level attached) */
661 return (slidergad);
665 /****************************************************************************************/
667 #ifdef SDEBUG
668 # undef SDEBUG
669 #endif
670 #ifdef DEBUG
671 # undef DEBUG
672 #endif
673 #define SDEBUG 0
674 #define DEBUG 0
675 #include <aros/debug.h>
677 /****************************************************************************************/
679 struct Gadget *makescroller(struct GadToolsBase_intern *GadToolsBase,
680 struct TagItem stdgadtags[],
681 struct VisualInfo *vi,
682 const struct TagItem *taglist)
684 struct Gadget *scroller = NULL,
685 *arrow_dec = NULL,
686 *arrow_inc = NULL ;
687 struct IBox bbox;
689 struct TagItem *tag, stags[] =
691 {GTSC_Top , 0 },
692 {GTSC_Total , 0 },
693 {GTSC_Visible , 2 },
694 {PGA_Freedom , FREEHORIZ },
695 {GA_Disabled , FALSE },
696 {GA_RelVerify , TRUE },
697 {GA_Immediate , TRUE },
698 {GTA_GadgetKind , SCROLLER_KIND },
699 {PGA_Borderless , TRUE },
700 #ifdef __MORPHOS__
701 {PGA_NewLook , FALSE },
702 #else
703 {PGA_NewLook , TRUE },
704 #endif
705 {GA_Bounds , (IPTR) &bbox },
706 {GA_FollowMouse , TRUE },
707 {PGA_NotifyBehaviour, PG_BEHAVIOUR_NICE },
708 {PGA_RenderBehaviour, PG_BEHAVIOUR_NICE },
709 {TAG_MORE , (IPTR)NULL }
712 struct TagItem *scr_dim_tagitem;
716 UWORD freedom = stags[3].ti_Data; /* default */
717 WORD arrowdim = 0 /* -1*/, arrowkind = SCROLLER_KIND;
718 ULONG scr_dim_tag;
720 EnterFunc(bug("makescroller(stdgadtags=%p, vi=%p, taglist = %p)\n",
721 stdgadtags, vi, taglist));
722 /* Could use GetTagData(), but this is faster */
723 while ((tag = NextTagItem((struct TagItem **)&taglist)))
725 IPTR tidata = tag->ti_Data;
727 switch (tag->ti_Tag)
729 case GTSC_Top: stags[0].ti_Data = tidata; break;
730 case GTSC_Total: stags[1].ti_Data = tidata; break;
731 case GTSC_Visible: stags[2].ti_Data = tidata; break;
732 case PGA_Freedom:
733 if (tidata == LORIENT_HORIZ)
734 freedom = stags[3].ti_Data = FREEHORIZ;
735 else
736 freedom = stags[3].ti_Data = FREEVERT;
737 break;
738 case GA_Disabled: stags[4].ti_Data = tidata; break;
739 case GA_RelVerify: stags[5].ti_Data = tidata; break;
740 case GA_Immediate: stags[6].ti_Data = tidata; break;
742 case GTSC_Arrows: arrowdim = (WORD)tidata; break;
743 case GTA_Scroller_ArrowKind: arrowkind = (WORD)tidata; break;
744 case GTA_Scroller_ScrollerKind: stags[7].ti_Data = tidata; break;
748 } /* while (iterate taglist) */
750 /* if there is a bounding box the label position
751 will be calculated based on this box and not
752 the gadget coords */
754 DEBUG_CREATESCROLLER(bug("makescroller: arrowdim %ld\n", arrowdim));
756 bbox.Left = GetTagData(GA_Left, 0, stdgadtags);
757 bbox.Top = GetTagData(GA_Top, 0, stdgadtags);
758 bbox.Width = GetTagData(GA_Width, 0, stdgadtags);
759 bbox.Height = GetTagData(GA_Height, 0, stdgadtags);
761 DEBUG_CREATESCROLLER(bug("makescroller: left %ld top %ld width %ld height %ld\n", bbox.Left, bbox.Top, bbox.Width, bbox.Height));
763 stags[14].ti_Data = (IPTR)stdgadtags;
765 /* Substract the arrow's total size from the sroller's size */
767 if (arrowdim == -1)
769 DEBUG_CREATESCROLLER(bug("makescroller: default arrowdim\n"));
770 if (freedom == FREEVERT)
772 arrowdim = GetTagData(GA_Width, 16, stdgadtags);
773 DEBUG_CREATESCROLLER(bug("makescroller: freevert arrowdim %ld\n", arrowdim));
774 } else {
775 arrowdim = GetTagData(GA_Height, 16, stdgadtags);
776 DEBUG_CREATESCROLLER(bug("makescroller: freehoriz arrowdim %ld\n", arrowdim));
778 DEBUG_CREATESCROLLER(bug("makescroller: arrowdim %ld\n", arrowdim));
781 scr_dim_tag = ((freedom == FREEVERT) ? GA_Height : GA_Width);
783 scr_dim_tagitem = FindTagItem(scr_dim_tag, stdgadtags);
784 scr_dim_tagitem->ti_Data -= 2 * arrowdim;
786 /* There are always GA_Left, GA_Top, GA_Width and GA_Height tags
787 thanks to creategadgeta.c! */
789 FindTagItem(GA_Left,stdgadtags)->ti_Data += BORDERPROPSPACINGX;
790 FindTagItem(GA_Top,stdgadtags)->ti_Data += BORDERPROPSPACINGY;
791 FindTagItem(GA_Width,stdgadtags)->ti_Data -= BORDERPROPSPACINGX * 2;
792 FindTagItem(GA_Height,stdgadtags)->ti_Data -= BORDERPROPSPACINGY * 2;
794 scroller = (struct Gadget *) NewObjectA(GadToolsBase->scrollerclass, NULL, stags);
796 if (!scroller)
797 return (NULL);
799 scroller->GadgetType |= GTYP_GADTOOLS;
801 DEBUG_CREATESCROLLER(bug("makescroller: scroller gadget 0x%lx scroller Width %ld Height %ld\n",scroller,scroller->Width,scroller->Height));
802 DEBUG_CREATESCROLLER(bug("makescroller: scroller nextgadget 0x%lx\n",scroller->NextGadget));
804 if (arrowdim) /* Scroller has arrows ? */
806 struct TagItem atags[] =
808 {GA_Left , 0 },
809 {GA_Top , 0 },
810 {GA_Width , 0 },
811 {GA_Height , 0 },
812 {GTA_Arrow_Type , 0 },
813 {GA_DrawInfo , (IPTR)NULL },
814 {GA_Next , (IPTR)NULL },
815 {GTA_Arrow_Scroller , (IPTR)NULL },
816 {GA_RelVerify , TRUE },
817 {GA_Immediate , TRUE },
818 {GA_ID , 0 },
819 {GTA_GadgetKind , arrowkind },
820 {GA_Previous , (IPTR)NULL },
821 {TAG_DONE }
823 struct TagItem tellscrollertags[] =
825 {GTA_Scroller_Arrow1, 0 },
826 {GTA_Scroller_Arrow2, 0 },
827 {TAG_DONE }
830 atags[5].ti_Data = (IPTR)vi->vi_dri; /* Set GA_DrawInfo */
831 atags[6].ti_Data = (IPTR)scroller; /* Set GA_Previous */
832 atags[7].ti_Data = (IPTR)scroller; /* Set GTA_Arrow_Scroller */
833 atags[12].ti_Data = (IPTR)GetTagData(GA_Previous, 0, stdgadtags);
835 /* These must be the same as for scroller */
836 atags[10].ti_Data = (IPTR)GetTagData(GA_ID, 0, stdgadtags);
838 if (freedom == FREEVERT)
840 DEBUG_CREATESCROLLER(bug("makescroller: Freedom=FREEVERT\n"));
841 atags[0].ti_Data = scroller->LeftEdge - BORDERPROPSPACINGX;
842 atags[1].ti_Data = scroller->TopEdge + BORDERPROPSPACINGY + scroller->Height;
843 atags[2].ti_Data = scroller->Width + BORDERPROPSPACINGX * 2;
844 atags[3].ti_Data = arrowdim;
845 atags[4].ti_Data = UPIMAGE;
847 DEBUG_CREATESCROLLER(bug("makescroller: Width %ld Height %ld\n",atags[2].ti_Data,atags[3].ti_Data));
849 arrow_dec = NewObjectA(GadToolsBase->arrowclass, NULL, atags);
850 if (!arrow_dec)
851 goto failure;
853 arrow_dec->GadgetType |= GTYP_GADTOOLS;
855 DEBUG_CREATESCROLLER(bug("makescroller: arrow_dec gadget 0x%lx\n",arrow_dec));
856 DEBUG_CREATESCROLLER(bug("makescroller: arrow_dec nextgadget 0x%lx\n",arrow_dec->NextGadget));
858 atags[1].ti_Data += arrowdim;
859 atags[4].ti_Data = DOWNIMAGE;
860 atags[6].ti_Data = (IPTR)arrow_dec;
862 arrow_inc = NewObjectA(GadToolsBase->arrowclass, NULL, atags);
863 if (!arrow_inc)
864 goto failure;
866 arrow_inc->GadgetType |= GTYP_GADTOOLS;
868 DEBUG_CREATESCROLLER(bug("makescroller: arrow_inc gadget 0x%lx\n",arrow_inc));
869 DEBUG_CREATESCROLLER(bug("makescroller: arrow_inc nextgadget 0x%lx\n",arrow_inc->NextGadget));
872 else
874 DEBUG_CREATESCROLLER(bug("makescroller: Freedom=FREEHORIZ\n"));
876 atags[0].ti_Data = scroller->LeftEdge + scroller->Width + BORDERPROPSPACINGX;
877 atags[1].ti_Data = scroller->TopEdge - BORDERPROPSPACINGY;
878 atags[2].ti_Data = arrowdim;
879 atags[3].ti_Data = scroller->Height + BORDERPROPSPACINGY * 2;
880 atags[4].ti_Data = LEFTIMAGE;
882 DEBUG_CREATESCROLLER(bug("makescroller: Width %ld Height %ld\n",atags[3].ti_Data,atags[2].ti_Data));
884 arrow_dec = NewObjectA(GadToolsBase->arrowclass, NULL, atags);
885 if (!arrow_dec)
886 goto failure;
888 arrow_dec->GadgetType |= GTYP_GADTOOLS;
890 DEBUG_CREATESCROLLER(bug("makescroller: arrow_dec gadget 0x%lx\n",arrow_dec));
892 atags[0].ti_Data += arrowdim;
893 atags[4].ti_Data = RIGHTIMAGE;
894 atags[6].ti_Data = (IPTR)arrow_dec;
896 arrow_inc = NewObjectA(GadToolsBase->arrowclass, NULL, atags);
897 if (!arrow_inc)
898 goto failure;
900 arrow_inc->GadgetType |= GTYP_GADTOOLS;
902 DEBUG_CREATESCROLLER(bug("makescroller: arrow_inc gadget 0x%lx\n",arrow_inc));
904 } /* if (scroller is FREEVERT or FREEHORIZ) */
906 tellscrollertags[0].ti_Data = (IPTR)arrow_dec;
907 tellscrollertags[1].ti_Data = (IPTR)arrow_inc;
909 DEBUG_CREATESCROLLER(bug("makescroller: tell scroller about arrows\n"));
910 SetAttrsA(scroller, tellscrollertags);
912 ReturnPtr ("makescroller", struct Gadget *, arrow_inc);
914 } /* if (scroller should have arrows attached) */
916 ReturnPtr ("makescroller", struct Gadget *, scroller);
918 failure:
919 if (scroller)
920 DisposeObject((Object *)scroller);
922 if (arrow_dec)
923 DisposeObject((Object *)arrow_dec);
925 if (arrow_inc)
926 DisposeObject((Object *)arrow_inc);
928 ReturnPtr("makescroller", struct Gadget *, NULL);
931 /****************************************************************************************/
933 struct Gadget *makestring(struct GadToolsBase_intern *GadToolsBase,
934 struct TagItem stdgadtags[],
935 struct VisualInfo *vi,
936 struct TextAttr *tattr,
937 const struct TagItem *taglist)
939 struct Gadget *obj = NULL;
940 struct IBox bbox;
942 struct TagItem *tag, tags[] =
944 {GA_Disabled , FALSE }, /* 0 */
945 {GA_Immediate , FALSE }, /* 1 */
946 {GA_RelVerify , TRUE }, /* 2 */
947 {GA_TabCycle , TRUE }, /* 3 */
948 {GTST_String , (IPTR)NULL }, /* 4 */
949 {GTST_MaxChars , 64UL }, /* 5 */
950 {GTST_EditHook , (IPTR)NULL }, /* 6 */
951 {STRINGA_ExitHelp , FALSE }, /* 7 */
952 {STRINGA_Justification , GACT_STRINGLEFT }, /* 8 */
953 {STRINGA_ReplaceMode , FALSE }, /* 9 */
954 {GA_TextAttr , (IPTR)NULL }, /* 10 */
955 {GTA_GadgetKind , STRING_KIND }, /* 11 */
956 {GA_Bounds , (IPTR)&bbox }, /* 12 */
957 {TAG_MORE , (IPTR)NULL } /* 13 */
961 /* Could use GetTagData(), but this is faster */
962 while ((tag = NextTagItem((struct TagItem **)&taglist)))
964 IPTR tidata = tag->ti_Data;
966 switch (tag->ti_Tag)
968 case GA_Disabled: tags[0].ti_Data = tidata; break;
969 case GA_Immediate: tags[1].ti_Data = tidata; break;
970 case GA_RelVerify: tags[2].ti_Data = tidata; break;
971 case GA_TabCycle: tags[3].ti_Data = tidata; break;
972 case GTST_String: tags[4].ti_Data = tidata; break;
973 case GTST_MaxChars: tags[5].ti_Data = tidata; break;
974 case GTST_EditHook: tags[6].ti_Data = tidata; break;
975 case STRINGA_ExitHelp: tags[7].ti_Data = tidata; break;
976 case STRINGA_Justification: tags[8].ti_Data = tidata; break;
977 case STRINGA_ReplaceMode: tags[9].ti_Data = tidata; break;
980 } /* while (iterate taglist) */
982 if (tattr) /* Text Attr supplied ? */
983 tags[10].ti_Data = (IPTR)tattr;
984 else
985 tags[10].ti_Tag = TAG_IGNORE; /* Don't pass GA_TextAttr, NULL */
987 /* if there is a bounding box the label position
988 will be calculated based on this box and not
989 the gadget coords */
991 bbox.Left = GetTagData(GA_Left, 0, stdgadtags);
992 bbox.Top = GetTagData(GA_Top, 0, stdgadtags);
993 bbox.Width = GetTagData(GA_Width, 0, stdgadtags);
994 bbox.Height = GetTagData(GA_Height, 0, stdgadtags);
996 /* There are always GA_Left, GA_Top, GA_Width and GA_Height tags
997 thanks to creategadgeta.c! */
999 FindTagItem(GA_Left,stdgadtags)->ti_Data += BORDERSTRINGSPACINGX;
1000 FindTagItem(GA_Top,stdgadtags)->ti_Data += BORDERSTRINGSPACINGY;
1001 FindTagItem(GA_Width,stdgadtags)->ti_Data -= BORDERSTRINGSPACINGX * 2;
1002 FindTagItem(GA_Height,stdgadtags)->ti_Data -= BORDERSTRINGSPACINGY * 2;
1004 tags[13].ti_Data = (IPTR)stdgadtags;
1006 obj = (struct Gadget *) NewObjectA(GadToolsBase->stringclass, NULL, tags);
1008 if (obj)
1010 obj->GadgetType |= GTYP_GADTOOLS;
1012 return (obj);
1015 /****************************************************************************************/
1017 struct Gadget *makeinteger(struct GadToolsBase_intern *GadToolsBase,
1018 struct TagItem stdgadtags[],
1019 struct VisualInfo *vi,
1020 struct TextAttr *tattr,
1021 const struct TagItem *taglist)
1023 struct Gadget *obj = NULL;
1024 struct IBox bbox;
1026 struct TagItem *tag, tags[] =
1028 {GA_Disabled , FALSE }, /* 0 */
1029 {GA_Immediate , FALSE }, /* 1 */
1030 {GA_RelVerify , TRUE }, /* 2 */
1031 {GA_TabCycle , TRUE }, /* 3 */
1032 {GTIN_Number , 0L }, /* 4 */
1033 {GTIN_MaxChars , 10L }, /* 5 */
1034 {GTIN_EditHook , (IPTR)NULL }, /* 6 */
1035 {STRINGA_ExitHelp , FALSE }, /* 7 */
1036 {STRINGA_Justification , GACT_STRINGLEFT }, /* 8 */
1037 {STRINGA_ReplaceMode , FALSE }, /* 9 */
1038 {GA_TextAttr , (IPTR)NULL }, /* 10 */
1039 {GTA_GadgetKind , INTEGER_KIND }, /* 11 */
1040 {GA_Bounds , (IPTR)&bbox }, /* 12 */
1041 {TAG_MORE , (IPTR)NULL } /* 13 */
1045 /* Could use GetTagData(), but this is faster */
1046 while ((tag = NextTagItem((struct TagItem **)&taglist)))
1048 IPTR tidata = tag->ti_Data;
1050 switch (tag->ti_Tag)
1052 case GA_Disabled: tags[0].ti_Data = tidata; break;
1053 case GA_Immediate: tags[1].ti_Data = tidata; break;
1054 case GA_RelVerify: tags[2].ti_Data = tidata; break;
1055 case GA_TabCycle: tags[3].ti_Data = tidata; break;
1056 case GTIN_Number: tags[4].ti_Data = tidata; break;
1057 case GTIN_MaxChars: tags[5].ti_Data = tidata; break;
1058 case GTIN_EditHook: tags[6].ti_Data = tidata; break;
1059 case STRINGA_ExitHelp: tags[7].ti_Data = tidata; break;
1060 case STRINGA_Justification: tags[8].ti_Data = tidata; break;
1061 case STRINGA_ReplaceMode: tags[9].ti_Data = tidata; break;
1064 } /* while (iterate taglist) */
1066 if (tattr) /* Text Attr supplied ? */
1067 tags[10].ti_Data = (IPTR)tattr;
1068 else
1069 tags[10].ti_Tag = TAG_IGNORE; /* Don't pass GA_TextAttr, NULL */
1071 /* if there is a bounding box the label position
1072 will be calculated based on this box and not
1073 the gadget coords */
1075 bbox.Left = GetTagData(GA_Left, 0, stdgadtags);
1076 bbox.Top = GetTagData(GA_Top, 0, stdgadtags);
1077 bbox.Width = GetTagData(GA_Width, 0, stdgadtags);
1078 bbox.Height = GetTagData(GA_Height, 0, stdgadtags);
1080 /* There are always GA_Left, GA_Top, GA_Width and GA_Height tags
1081 thanks to creategadgeta.c! */
1083 FindTagItem(GA_Left,stdgadtags)->ti_Data += BORDERSTRINGSPACINGX;
1084 FindTagItem(GA_Top,stdgadtags)->ti_Data += BORDERSTRINGSPACINGY;
1085 FindTagItem(GA_Width,stdgadtags)->ti_Data -= BORDERSTRINGSPACINGX * 2;
1086 FindTagItem(GA_Height,stdgadtags)->ti_Data -= BORDERSTRINGSPACINGY * 2;
1088 tags[13].ti_Data = (IPTR)stdgadtags;
1090 obj = (struct Gadget *) NewObjectA(GadToolsBase->stringclass, NULL, tags);
1091 if (obj)
1093 obj->GadgetType |= GTYP_GADTOOLS;
1095 return (obj);
1099 /****************************************************************************************/
1101 const struct TagItem scroller2lv[] =
1103 {PGA_Top , GTLV_Top},
1104 {TAG_DONE , }
1107 /****************************************************************************************/
1109 /* Spacing between scroller and listview */
1110 #define SCROLLER_SPACING 2
1112 /****************************************************************************************/
1114 struct Gadget *makelistview(struct GadToolsBase_intern *GadToolsBase,
1115 struct TagItem stdgadtags[],
1116 struct VisualInfo *vi,
1117 struct TextAttr *tattr,
1118 const struct TagItem *taglist)
1120 struct Gadget *lvgad = NULL, *showselgad = LV_SHOWSELECTED_NONE;
1121 struct Gadget *scrollergad;
1122 struct IBox bbox;
1125 WORD scroller_width = 16; /* default */
1127 struct TagItem *lv_width_tag, *lv_height_tag;
1128 WORD lv_width, lv_height;
1129 #if CORRECT_LISTVIEWHEIGHT
1130 WORD viewheight, totalitemheight = 0;
1131 #endif
1132 WORD ysize;
1134 struct TagItem *tag, lvtags[] =
1136 {GA_Disabled , FALSE }, /* 0 */
1137 {GTLV_Top , 0L }, /* 1 */
1138 {GTLV_MakeVisible , 0L }, /* 2 */
1139 {GTLV_Labels , (IPTR)NULL }, /* 3 */
1140 {GTLV_Selected , ~0L }, /* 4 */
1141 {GTLV_ItemHeight , 0L }, /* 5 */
1142 {GTLV_CallBack , (IPTR)NULL }, /* 6 */
1143 {GTLV_MaxPen , 0L }, /* 7 */
1144 {GTLV_ReadOnly , 0L }, /* 8 */
1145 {LAYOUTA_Spacing , 0L }, /* 9 */
1146 {GA_TextAttr , (IPTR)NULL }, /* 10 */
1147 {GA_RelVerify , TRUE }, /* 11 */
1148 {GA_Bounds , (IPTR)&bbox }, /* 12 */
1149 {GTLV_ShowSelected , (IPTR)showselgad }, /* 13 */
1150 {TAG_MORE , (IPTR)NULL } /* 14 */
1153 EnterFunc(bug("makelistview()\n"));
1155 /* Could use GetTagData(), but this is faster */
1156 while ((tag = NextTagItem((struct TagItem **)&taglist)))
1158 IPTR tidata = tag->ti_Data;
1160 switch (tag->ti_Tag)
1162 case GA_Disabled: lvtags[0].ti_Data = tidata; break;
1163 case GTLV_Top: lvtags[1].ti_Data = tidata; break;
1164 case GTLV_MakeVisible: lvtags[2].ti_Data = tidata; break;
1165 case GTLV_Labels: lvtags[3].ti_Data = tidata; break;
1166 case GTLV_Selected: lvtags[4].ti_Data = tidata; break;
1167 case GTLV_ItemHeight: lvtags[5].ti_Data = tidata; break;
1168 case GTLV_CallBack: lvtags[6].ti_Data = tidata; break;
1169 case GTLV_MaxPen: lvtags[7].ti_Data = tidata; break;
1170 case GTLV_ReadOnly: lvtags[8].ti_Data = tidata; break;
1171 case LAYOUTA_Spacing: lvtags[9].ti_Data = tidata; break;
1173 case GTLV_ShowSelected:
1174 showselgad = (struct Gadget *)tidata;
1175 lvtags[13].ti_Data = (IPTR)showselgad;
1176 break;
1178 case GTLV_ScrollWidth: scroller_width = (UWORD)tidata;
1181 } /* while (iterate taglist) */
1183 /* if there is a bounding box the label position
1184 will be calculated based on this box and not
1185 the gadget coords */
1187 bbox.Left = GetTagData(GA_Left, 0, stdgadtags);
1188 bbox.Top = GetTagData(GA_Top, 0, stdgadtags);
1189 bbox.Width = GetTagData(GA_Width, 0, stdgadtags);
1190 bbox.Height = GetTagData(GA_Height, 0, stdgadtags);
1192 /* Callback supplied ? */
1193 if (!lvtags[6].ti_Data)
1194 lvtags[6].ti_Tag = TAG_IGNORE; /* Don't pass GTLV_Callback, NULL */
1196 if (tattr) /* Text Attr supplied ? */
1198 lvtags[10].ti_Data = (IPTR)tattr;
1199 ysize = tattr->ta_YSize;
1201 else
1203 lvtags[10].ti_Tag = TAG_IGNORE; /* Don't pass GA_TextAttr, NULL */
1205 ysize = vi->vi_dri->dri_Font->tf_YSize;
1208 /* If not set allready, set ItemHeight */
1209 if (lvtags[5].ti_Data == 0)
1210 lvtags[5].ti_Data = ysize;
1212 /* If not set allready, set Spacing */
1213 if (lvtags[9].ti_Data == 0)
1214 lvtags[9].ti_Data = LV_DEF_INTERNAL_SPACING;
1216 DEBUG_CREATELISTVIEW(bug("makelistview: item ysize %ld\n", ysize));
1218 /* Find the dimension specific tags */
1219 lv_width_tag = FindTagItem(GA_Width, stdgadtags);
1220 lv_height_tag = FindTagItem(GA_Height, stdgadtags);
1222 lv_width = (WORD)lv_width_tag->ti_Data;
1223 lv_height = (WORD)lv_height_tag->ti_Data;
1226 /* Adjust the listview width according to scroller width + some spacing */
1227 lv_width -= (scroller_width + SCROLLER_SPACING);
1229 /* Adjust the listview height according to showsel gadget height */
1230 if ((showselgad) && (showselgad != LV_SHOWSELECTED_NONE))
1232 /* The showselected string gadget must have the same width as the
1233 listview gadget, otherwise fail (AmigaOS does the same). Fail
1234 also if the showselected string gadget is too high*/
1236 if ((EG(showselgad)->BoundsWidth != bbox.Width) ||
1237 (EG(showselgad)->BoundsHeight >= lv_height))
1239 ReturnPtr ("makelistview", struct Gadget *, NULL);
1242 /* the showselected string gadget shrinks the height of the listview */
1244 lv_height -= EG(showselgad)->BoundsHeight;
1246 /* the showselected string gadget will get its position automatically
1247 fixed to be under the listview gadget */
1249 EG(showselgad)->BoundsLeftEdge = bbox.Left;
1250 EG(showselgad)->BoundsTopEdge = bbox.Top + lv_height;
1251 EG(showselgad)->LeftEdge = EG(showselgad)->BoundsLeftEdge + BORDERSTRINGSPACINGX;
1252 EG(showselgad)->TopEdge = EG(showselgad)->BoundsTopEdge + BORDERSTRINGSPACINGY;
1254 D(bug("makelistview: Showselected gadget specified"));
1258 #if CORRECT_LISTVIEWHEIGHT
1259 /* GTLV_ItemHeight + LAYOUTA_Spacing */
1260 totalitemheight = lvtags[5].ti_Data + lvtags[9].ti_Data;
1262 /* stegerg: I think it looks better without this adjustment. Think of
1263 GTLV_ShowSelected and aligning with other gadgets */
1265 /* Adjust listview height so that an exact number of items fits in it */
1266 viewheight = lv_height - (2 * LV_BORDER_Y);
1267 lv_height -= (viewheight % totalitemheight);
1269 #endif
1271 /* Reinsert the modified dimension attrs into the listview taglist */
1273 D(bug("makelistview: Dimension passed to listview: w=%d, h=%d\n", lv_width, lv_height));
1275 lv_width_tag->ti_Data = (IPTR)lv_width;
1276 lv_height_tag->ti_Data = (IPTR)lv_height;
1278 lvtags[14].ti_Data = (IPTR)stdgadtags;
1280 D(bug("makelistview: Listview class opened\n"));
1281 lvgad = (struct Gadget *)NewObjectA(GadToolsBase->listviewclass, NULL, lvtags);
1282 if (lvgad)
1284 struct TagItem scr_stdtags[] =
1286 {GA_Left , 0L },
1287 {GA_Top , 0L },
1288 {GA_Width , 0L },
1289 {GA_Height , 0L },
1290 {GA_Next , (IPTR)NULL },
1291 {GA_ID , 0L },
1292 {GA_DrawInfo, (IPTR)NULL },
1293 {GA_Previous, (IPTR)NULL },
1294 {TAG_DONE }
1297 struct TagItem scr_specialtags[] =
1299 /* The listview will initialize the scrollers top, visible & total,
1300 ** in its GM_LAYOUT method
1302 {GTSC_Arrows , scroller_width },
1303 {PGA_Freedom , LORIENT_VERT },
1304 {GTA_Scroller_ArrowKind , LISTVIEW_KIND },
1305 {GTA_Scroller_ScrollerKind , LISTVIEW_KIND },
1306 {TAG_DONE }
1309 lvgad->GadgetType |= GTYP_GADTOOLS;
1311 D(bug("makelistview: Listview gadget created: %p\n", lvgad));
1312 D(bug("makelistview: scroller_width %ld\n",scroller_width));
1314 /* Create a scroller object to use with the listviev */
1315 scr_stdtags[0].ti_Data = lvgad->LeftEdge + lvgad->Width - 1 + SCROLLER_SPACING;
1316 scr_stdtags[1].ti_Data = lvgad->TopEdge;
1317 scr_stdtags[2].ti_Data = scroller_width;
1318 scr_stdtags[3].ti_Data = lvgad->Height;
1319 scr_stdtags[4].ti_Data = (IPTR)lvgad;
1320 scr_stdtags[5].ti_Data = lvgad->GadgetID;
1321 scr_stdtags[6].ti_Data = (IPTR)vi->vi_dri;
1322 scr_stdtags[7].ti_Data = (IPTR)GetTagData(GA_Previous, 0, stdgadtags);
1324 scrollergad = makescroller(GadToolsBase, scr_stdtags, vi, scr_specialtags);
1325 if (scrollergad)
1327 struct TagItem lvset_tags[] =
1329 {GTA_Listview_Scroller, (IPTR)NULL },
1330 {TAG_DONE, }
1332 struct TagItem scrnotify_tags[] =
1334 {ICA_TARGET , (IPTR)NULL },
1335 {ICA_MAP , (IPTR)NULL },
1336 {TAG_DONE }
1338 struct Gadget *prop_of_scrollergad;
1340 D(bug("makelistview: Scroller gadget created: %p\n", scrollergad));
1342 /* the scrollergadget is a multigadget gadget: arrowinc->arrowdec->prop */
1343 /* FIXME: This relies on scroller gadget to always contain arrow gadgets
1344 * If this ever changes the line below must be updated.
1346 prop_of_scrollergad = scrollergad->NextGadget->NextGadget;
1348 scrollergad->Activation &= ~GACT_FOLLOWMOUSE;
1350 /* Tell the listview about the scroller and the showselgad */
1351 DEBUG_CREATELISTVIEW(bug("makelistview: tell listview about scroller\n"));
1352 lvset_tags[0].ti_Data = (IPTR)prop_of_scrollergad;
1353 SetAttrsA((Object *)lvgad, lvset_tags);
1355 /* Tell the scroller to notify the listview when its PGA_Top attribute changes */
1356 DEBUG_CREATELISTVIEW(bug("makelistview: tell scroller about notification\n"));
1357 scrnotify_tags[0].ti_Data = (IPTR)lvgad;
1358 scrnotify_tags[1].ti_Data = (IPTR)scroller2lv;
1360 SetAttrsA((Object *)prop_of_scrollergad, scrnotify_tags);
1362 ReturnPtr ("makelistview", struct Gadget *, scrollergad);
1365 DisposeObject(lvgad);
1367 } /* if (lvgad created) */
1369 ReturnPtr ("makelistview", struct Gadget *, NULL);
1372 /****************************************************************************************/
1374 struct Gadget *makegeneric(struct GadToolsBase_intern *GadToolsBase,
1375 struct TagItem stdgadtags[],
1376 struct VisualInfo *vi,
1377 struct TextAttr *tattr,
1378 struct TagItem *taglist)
1380 struct GT_GenericGadget *gad;
1381 struct Gadget *prevgad;
1383 gad = AllocMem(sizeof(struct GT_GenericGadget), MEMF_PUBLIC | MEMF_CLEAR);
1384 if (gad)
1386 gad->gad.LeftEdge = stdgadtags[TAG_Left].ti_Data;
1387 gad->gad.TopEdge = stdgadtags[TAG_Top].ti_Data;
1388 gad->gad.Width = stdgadtags[TAG_Width].ti_Data;
1389 gad->gad.Height = stdgadtags[TAG_Height].ti_Data;
1390 gad->gad.Flags = GFLG_EXTENDED;
1391 gad->gad.Activation = 0;
1392 gad->gad.GadgetType = GTYP_GADTOOLS;
1393 gad->gad.GadgetRender = NULL;
1394 gad->gad.SelectRender = NULL;
1395 gad->gad.GadgetText = (struct IntuiText *)stdgadtags[TAG_IText].ti_Data;
1396 gad->gad.MutualExclude = 0;
1397 gad->gad.SpecialInfo = NULL;
1398 gad->gad.GadgetID = stdgadtags[TAG_ID].ti_Data;
1399 gad->gad.UserData = (APTR)stdgadtags[TAG_UserData].ti_Data;
1400 gad->gad.MoreFlags = GMORE_BOUNDS | GMORE_GADGETHELP;
1401 gad->gad.BoundsLeftEdge = stdgadtags[TAG_Left].ti_Data;
1402 gad->gad.BoundsTopEdge = stdgadtags[TAG_Top].ti_Data;
1403 gad->gad.BoundsWidth = stdgadtags[TAG_Width].ti_Data;
1404 gad->gad.BoundsHeight = stdgadtags[TAG_Height].ti_Data;
1405 gad->magic = GENERIC_MAGIC;
1406 gad->magic2 = GENERIC_MAGIC2;
1407 gad->itext = (struct IntuiText *)stdgadtags[TAG_IText].ti_Data;
1409 prevgad = (struct Gadget *)stdgadtags[TAG_Previous].ti_Data;
1410 prevgad->NextGadget = (struct Gadget *)gad;
1413 ReturnPtr ("makegeneric", struct Gadget *, (struct Gadget *)gad);
1416 /****************************************************************************************/