add casts to zune macros to silence some warnings
[tangerine.git] / workbench / libs / gadtools / gadgets.c
blobfd274357b671ecf9602f321f28f2a0c3b598453e
1 /*
2 Copyright © 1995-2005, 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 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(&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 struct TagItem *taglist)
308 struct Gadget *obj = NULL;
309 Class *cl;
310 BOOL cliptag_found = FALSE;
312 struct TagItem *tag, tags[] =
314 {GTTX_Text , 0 },
315 {GTTX_CopyText , FALSE },
316 {GTTX_Clipped , FALSE },
317 {GTTX_Border , FALSE },
318 {GTTX_FrontPen , TEXTPEN },
319 {GTTX_BackPen , BACKGROUNDPEN },
320 {GTTX_Justification , GTJ_LEFT },
321 {GTA_Text_Format , (IPTR)"%s" },
322 {GA_TextAttr , (IPTR)NULL },
323 {GTA_GadgetKind , TEXT_KIND },
324 {TAG_MORE , (IPTR) NULL }
327 /* Could use GetTagData(), but this is faster */
328 while ((tag = NextTagItem(&taglist)))
330 IPTR tidata = tag->ti_Data;
332 switch (tag->ti_Tag)
334 case GTTX_Text: tags[0].ti_Data = tidata; break;
335 case GTTX_CopyText: tags[1].ti_Data = tidata; break;
336 case GTTX_Clipped: tags[2].ti_Data = tidata; cliptag_found = TRUE;break;
337 case GTTX_Border: tags[3].ti_Data = tidata; break;
338 case GTTX_FrontPen: tags[4].ti_Data = tidata; break;
339 case GTTX_BackPen: tags[5].ti_Data = tidata; break;
340 case GTTX_Justification: tags[6].ti_Data = tidata; break;
343 } /* while (iterate taglist) */
345 /* if GTTX_Clipped was not specified then the default value is
346 the GTTX_Border value */
348 if (!cliptag_found) tags[2].ti_Data = tags[3].ti_Data;
350 /* Be sure not to pass GA_TextAttr, NULL */
351 if (tattr)
352 tags[8].ti_Data = (IPTR)tattr;
353 else
354 tags[8].ti_Tag = TAG_IGNORE;
355 tags[10].ti_Data = (IPTR)stdgadtags;
357 obj = (struct Gadget *) NewObjectA(GadToolsBase->textclass, NULL, tags);
359 if (obj)
361 obj->GadgetType |= GTYP_GADTOOLS;
364 return (obj);
367 /****************************************************************************************/
369 struct Gadget *makenumber(struct GadToolsBase_intern *GadToolsBase,
370 struct TagItem stdgadtags[],
371 struct VisualInfo *vi,
372 struct TextAttr *tattr,
373 struct TagItem *taglist)
375 struct Gadget *obj = NULL;
376 Class *cl;
377 BOOL cliptag_found = FALSE;
379 struct TagItem *tag, tags[] =
381 {GTNM_Number , 0 },
382 {GTNM_Format , (IPTR)"%ld" },
383 {GTNM_Clipped , FALSE },
384 {GTNM_Border , FALSE },
385 {GTNM_FrontPen , TEXTPEN },
386 {GTNM_BackPen , BACKGROUNDPEN },
387 {GTNM_Justification , GTJ_CENTER },
388 {GTNM_MaxNumberLen , 100 },
389 {GA_TextAttr , (IPTR)NULL },
390 {GTA_GadgetKind , NUMBER_KIND },
391 {TAG_MORE , (IPTR) NULL }
395 /* Could use GetTagData(), but this is faster */
396 while ((tag = NextTagItem(&taglist)))
398 IPTR tidata = tag->ti_Data;
400 switch (tag->ti_Tag)
402 case GTNM_Number: tags[0].ti_Data = tidata; break;
403 case GTNM_Format: tags[1].ti_Data = tidata; break;
404 case GTNM_Clipped: tags[2].ti_Data = tidata; cliptag_found = TRUE;break;
405 case GTNM_Border: tags[3].ti_Data = tidata; break;
406 case GTNM_FrontPen: tags[4].ti_Data = tidata; break;
407 case GTNM_BackPen: tags[5].ti_Data = tidata; break;
408 case GTNM_Justification: tags[6].ti_Data = tidata; break;
409 case GTNM_MaxNumberLen: tags[7].ti_Data = tidata; break;
412 } /* while (iterate taglist) */
414 /* if GTNM_Clipped was not specified then the default value is
415 the GTNM_Border value */
417 if (!cliptag_found) tags[2].ti_Data = tags[3].ti_Data;
419 /* Be sure not to pass GA_TextAttr, NULL */
420 if (tattr)
421 tags[8].ti_Data = (IPTR)tattr;
422 else
423 tags[8].ti_Tag = TAG_IGNORE;
425 tags[10].ti_Data = (IPTR)stdgadtags;
427 obj = (struct Gadget *) NewObjectA(GadToolsBase->textclass, NULL, tags);
429 if (obj)
431 obj->GadgetType |= GTYP_GADTOOLS;
434 return (obj);
438 /****************************************************************************************/
440 /* This MUST be global, since the gadgetclass doesn't copy ICA_MAPPINGs */
441 const struct TagItem slider2level[] =
443 {GTSL_Level, GTNM_Number},
444 {TAG_DONE }
447 /****************************************************************************************/
449 struct Gadget *makeslider(struct GadToolsBase_intern *GadToolsBase,
450 struct TagItem stdgadtags[],
451 struct VisualInfo *vi,
452 struct TextAttr *tattr,
453 struct TagItem *taglist)
456 struct TagItem *tag;
457 struct IBox bbox;
459 struct TagItem stags[] =
461 {GA_Disabled , FALSE },
462 {GA_RelVerify , TRUE }, /* Georg S.: was false */
463 {GA_Immediate , TRUE }, /* Georg S.: was false */
464 {GTSL_Min , 0 },
465 {GTSL_Max , 15 },
466 {GTSL_Level , 0 },
467 {PGA_Freedom , FREEHORIZ },
468 {PGA_Borderless , TRUE },
469 #ifdef __MORPHOS__
470 {PGA_NewLook , FALSE },
471 #else
472 {PGA_NewLook , TRUE },
473 #endif
474 {GA_Bounds , (IPTR)&bbox },
475 {GA_FollowMouse , TRUE },
476 {PGA_NotifyBehaviour, PG_BEHAVIOUR_NICE },
477 {PGA_RenderBehaviour, PG_BEHAVIOUR_NICE },
478 {TAG_MORE , (IPTR)NULL }
481 struct TagItem ltags[] =
483 {GA_Left , 0 },
484 {GA_Top , 0 },
485 {GA_Width , 0 },
486 {GA_Height , 0 },
487 {GA_TextAttr , (IPTR)tattr },
488 {GTNM_Format , (IPTR)NULL },
489 {GTNM_Justification , GTJ_LEFT },
490 {GTA_Text_DispFunc , (IPTR)NULL },
491 {GA_Next , (IPTR)NULL },
492 {GA_DrawInfo , (IPTR)NULL },
493 {GTNM_Number , 0 },
494 {GTA_GadgetKind , SLIDER_KIND },
495 {GA_Previous , (IPTR)NULL },
496 {TAG_DONE }
498 STRPTR lformat = NULL;
499 WORD lmaxlen = 0;
500 LONG lmaxpixellen = 0L;
501 UBYTE lplace = PLACETEXT_LEFT;
502 WORD level = 0;
504 struct Gadget *slidergad = NULL, *levelgad = NULL;
506 /* Parse tags */
507 while ((tag = NextTagItem(&taglist)))
509 IPTR tidata = tag->ti_Data;
511 switch (tag->ti_Tag)
514 /* Slider tags */
515 case GA_Disabled: stags[0].ti_Data = tidata; break;
516 case GA_RelVerify: stags[1].ti_Data = tidata; break;
517 case GA_Immediate: stags[2].ti_Data = tidata; break;
518 case GTSL_Min: stags[3].ti_Data = tidata; break;
519 case GTSL_Max: stags[4].ti_Data = tidata; break;
520 case GTSL_Level: level = stags[5].ti_Data = tidata; break;
521 case PGA_Freedom:
522 if (tidata == LORIENT_HORIZ)
523 stags[6].ti_Data = FREEHORIZ;
524 else
525 stags[6].ti_Data = FREEVERT;
526 break;
528 /* Level tags */
529 case GTSL_LevelFormat: lformat = (STRPTR)tidata; break;
530 case GTSL_MaxLevelLen: lmaxlen = (UWORD)tidata; break;
531 case GTSL_MaxPixelLen: lmaxpixellen = (ULONG)tidata; break;
532 case GTSL_LevelPlace: lplace = (UBYTE)tidata; break;
533 case GTSL_Justification: ltags[6].ti_Data = tidata; break;
534 case GTSL_DispFunc: ltags[7].ti_Data = tidata; break;
538 } /* while (iterate taglist) */
540 /* if there is a bounding box the label position
541 will be calculated based on this box and not
542 the gadget coords */
544 bbox.Left = GetTagData(GA_Left, 0, stdgadtags);
545 bbox.Top = GetTagData(GA_Top, 0, stdgadtags);
546 bbox.Width = GetTagData(GA_Width, 0, stdgadtags);
547 bbox.Height = GetTagData(GA_Height, 0, stdgadtags);
549 /* There are always GA_Left, GA_Top, GA_Width and GA_Height tags
550 thanks to creategadgeta.c! */
552 FindTagItem(GA_Left,stdgadtags)->ti_Data += BORDERPROPSPACINGX;
553 FindTagItem(GA_Top,stdgadtags)->ti_Data += BORDERPROPSPACINGY;
554 FindTagItem(GA_Width,stdgadtags)->ti_Data -= BORDERPROPSPACINGX * 2;
555 FindTagItem(GA_Height,stdgadtags)->ti_Data -= BORDERPROPSPACINGY * 2;
557 /* Create slider gadget */
558 stags[13].ti_Data = (IPTR)stdgadtags;
559 slidergad = NewObjectA(GadToolsBase->sliderclass, NULL, stags);
561 if (!slidergad)
562 return (NULL);
564 slidergad->GadgetType |= GTYP_GADTOOLS;
566 if (lformat || lmaxlen || lmaxpixellen)
568 WORD x = 0, y = 0;
569 UWORD ysize = 8;
570 Class *textcl;
572 struct TagItem lntags[] =
574 {ICA_TARGET, (IPTR)NULL },
575 {ICA_MAP , (IPTR)NULL },
576 {TAG_DONE }
579 /* Set some defaults */
580 if (!lformat)
581 lformat = "%ld";
582 if (!lmaxlen)
583 lmaxlen = 2;
584 if (!lmaxpixellen)
586 struct TextFont *font;
587 UWORD xsize;
589 ysize = vi->vi_dri->dri_Font->tf_YSize;
590 xsize = vi->vi_dri->dri_Font->tf_XSize;
592 if (tattr)
594 font = OpenFont(tattr);
595 if (font)
597 ysize = font->tf_YSize;
598 xsize = font->tf_XSize;
599 CloseFont(font);
601 else /* If no valid tattr */
602 ltags[4].ti_Tag = TAG_IGNORE;
604 else /* If no valid tattr */
605 ltags[4].ti_Tag = TAG_IGNORE;
607 lmaxpixellen = lmaxlen * xsize;
609 ltags[4].ti_Data = (ULONG)tattr;
611 } /* if (!lmaxpixellen) */
613 switch (lplace)
615 case PLACETEXT_LEFT:
616 x = slidergad->LeftEdge - BORDERPROPSPACINGX - lmaxpixellen - 4;
617 y = slidergad->TopEdge + (slidergad->Height - ysize) / 2 + 1;
618 break;
619 case PLACETEXT_RIGHT:
620 x = slidergad->LeftEdge + slidergad->Width + BORDERPROPSPACINGX + 5;
621 y = slidergad->TopEdge + (slidergad->Height - ysize) / 2 + 1;
622 break;
623 case PLACETEXT_ABOVE:
624 x = slidergad->LeftEdge - (lmaxpixellen - slidergad->Width) / 2;
625 y = slidergad->TopEdge - BORDERPROPSPACINGY - ysize - 2;
626 break;
627 case PLACETEXT_BELOW:
628 x = slidergad->LeftEdge - (lmaxpixellen - slidergad->Width) / 2;
629 y = slidergad->TopEdge + slidergad->Height + BORDERPROPSPACINGY + 3;
630 break;
633 /* Create the levelobj */
635 ltags[0].ti_Data = (IPTR)x;
636 ltags[1].ti_Data = (IPTR)y;
637 ltags[2].ti_Data = (IPTR)lmaxpixellen;
638 ltags[3].ti_Data = (IPTR)ysize;
639 ltags[5].ti_Data = (IPTR)lformat;
640 ltags[8].ti_Data = (IPTR)slidergad;
641 ltags[9].ti_Data = (IPTR)vi->vi_dri;
642 ltags[10].ti_Data = (IPTR)level;
643 ltags[12].ti_Data = (IPTR)GetTagData(GA_Previous, 0, stdgadtags);
645 levelgad = (struct Gadget *)NewObjectA(GadToolsBase->textclass, NULL, ltags);
646 if (!levelgad)
648 DisposeObject((Object *)slidergad);
649 return (NULL);
651 levelgad->GadgetType |= GTYP_GADTOOLS;
653 /* Set up a notification from the slider to the level */
654 lntags[0].ti_Data = (IPTR)levelgad;
655 lntags[1].ti_Data = (IPTR)slider2level;
656 SetAttrsA((Object *)slidergad, lntags);
658 return (levelgad);
660 } /* if (slider should have a level attached) */
662 return (slidergad);
666 /****************************************************************************************/
668 #ifdef SDEBUG
669 # undef SDEBUG
670 #endif
671 #ifdef DEBUG
672 # undef DEBUG
673 #endif
674 #define SDEBUG 0
675 #define DEBUG 0
676 #include <aros/debug.h>
678 /****************************************************************************************/
680 struct Gadget *makescroller(struct GadToolsBase_intern *GadToolsBase,
681 struct TagItem stdgadtags[],
682 struct VisualInfo *vi,
683 struct TagItem *taglist)
685 struct Gadget *scroller = NULL,
686 *arrow_dec = NULL,
687 *arrow_inc = NULL ;
688 struct IBox bbox;
690 struct TagItem *tag, stags[] =
692 {GTSC_Top , 0 },
693 {GTSC_Total , 0 },
694 {GTSC_Visible , 2 },
695 {PGA_Freedom , FREEHORIZ },
696 {GA_Disabled , FALSE },
697 {GA_RelVerify , TRUE },
698 {GA_Immediate , TRUE },
699 {GTA_GadgetKind , SCROLLER_KIND },
700 {PGA_Borderless , TRUE },
701 #ifdef __MORPHOS__
702 {PGA_NewLook , FALSE },
703 #else
704 {PGA_NewLook , TRUE },
705 #endif
706 {GA_Bounds , (IPTR) &bbox },
707 {GA_FollowMouse , TRUE },
708 {PGA_NotifyBehaviour, PG_BEHAVIOUR_NICE },
709 {PGA_RenderBehaviour, PG_BEHAVIOUR_NICE },
710 {TAG_MORE , (IPTR)NULL }
713 struct TagItem *scr_dim_tagitem;
717 UWORD freedom = stags[3].ti_Data; /* default */
718 WORD arrowdim = 0 /* -1*/, arrowkind = SCROLLER_KIND;
719 BOOL relverify, immediate;
720 ULONG scr_dim_tag;
722 EnterFunc(bug("makescroller(stdgadtags=%p, vi=%p, taglist = %p)\n",
723 stdgadtags, vi, taglist));
724 /* Could use GetTagData(), but this is faster */
725 while ((tag = NextTagItem(&taglist)))
727 IPTR tidata = tag->ti_Data;
729 switch (tag->ti_Tag)
731 case GTSC_Top: stags[0].ti_Data = tidata; break;
732 case GTSC_Total: stags[1].ti_Data = tidata; break;
733 case GTSC_Visible: stags[2].ti_Data = tidata; break;
734 case PGA_Freedom:
735 if (tidata == LORIENT_HORIZ)
736 freedom = stags[3].ti_Data = FREEHORIZ;
737 else
738 freedom = stags[3].ti_Data = FREEVERT;
739 break;
740 case GA_Disabled: stags[4].ti_Data = tidata; break;
741 case GA_RelVerify: relverify = stags[5].ti_Data = tidata; break;
742 case GA_Immediate: immediate = stags[6].ti_Data = tidata; break;
744 case GTSC_Arrows: arrowdim = (WORD)tidata; break;
745 case GTA_Scroller_ArrowKind: arrowkind = (WORD)tidata; break;
746 case GTA_Scroller_ScrollerKind: stags[7].ti_Data = tidata; break;
750 } /* while (iterate taglist) */
752 /* if there is a bounding box the label position
753 will be calculated based on this box and not
754 the gadget coords */
756 DEBUG_CREATESCROLLER(bug("makescroller: arrowdim %ld\n", arrowdim));
758 bbox.Left = GetTagData(GA_Left, 0, stdgadtags);
759 bbox.Top = GetTagData(GA_Top, 0, stdgadtags);
760 bbox.Width = GetTagData(GA_Width, 0, stdgadtags);
761 bbox.Height = GetTagData(GA_Height, 0, stdgadtags);
763 DEBUG_CREATESCROLLER(bug("makescroller: left %ld top %ld width %ld height %ld\n", bbox.Left, bbox.Top, bbox.Width, bbox.Height));
765 stags[14].ti_Data = (IPTR)stdgadtags;
767 /* Substract the arrow's total size from the sroller's size */
769 if (arrowdim == -1)
771 DEBUG_CREATESCROLLER(bug("makescroller: default arrowdim\n"));
772 if (freedom == FREEVERT)
774 arrowdim = GetTagData(GA_Width, 16, stdgadtags);
775 DEBUG_CREATESCROLLER(bug("makescroller: freevert arrowdim %ld\n", arrowdim));
776 } else {
777 arrowdim = GetTagData(GA_Height, 16, stdgadtags);
778 DEBUG_CREATESCROLLER(bug("makescroller: freehoriz arrowdim %ld\n", arrowdim));
780 DEBUG_CREATESCROLLER(bug("makescroller: arrowdim %ld\n", arrowdim));
783 scr_dim_tag = ((freedom == FREEVERT) ? GA_Height : GA_Width);
785 scr_dim_tagitem = FindTagItem(scr_dim_tag, stdgadtags);
786 scr_dim_tagitem->ti_Data -= 2 * arrowdim;
788 /* There are always GA_Left, GA_Top, GA_Width and GA_Height tags
789 thanks to creategadgeta.c! */
791 FindTagItem(GA_Left,stdgadtags)->ti_Data += BORDERPROPSPACINGX;
792 FindTagItem(GA_Top,stdgadtags)->ti_Data += BORDERPROPSPACINGY;
793 FindTagItem(GA_Width,stdgadtags)->ti_Data -= BORDERPROPSPACINGX * 2;
794 FindTagItem(GA_Height,stdgadtags)->ti_Data -= BORDERPROPSPACINGY * 2;
796 scroller = (struct Gadget *) NewObjectA(GadToolsBase->scrollerclass, NULL, stags);
798 if (!scroller)
799 return (NULL);
801 scroller->GadgetType |= GTYP_GADTOOLS;
803 DEBUG_CREATESCROLLER(bug("makescroller: scroller gadget 0x%lx scroller Width %ld Height %ld\n",scroller,scroller->Width,scroller->Height));
804 DEBUG_CREATESCROLLER(bug("makescroller: scroller nextgadget 0x%lx\n",scroller->NextGadget));
806 if (arrowdim) /* Scroller has arrows ? */
808 struct TagItem atags[] =
810 {GA_Left , 0 },
811 {GA_Top , 0 },
812 {GA_Width , 0 },
813 {GA_Height , 0 },
814 {GTA_Arrow_Type , 0 },
815 {GA_DrawInfo , (IPTR)NULL },
816 {GA_Next , (IPTR)NULL },
817 {GTA_Arrow_Scroller , (IPTR)NULL },
818 {GA_RelVerify , TRUE },
819 {GA_Immediate , TRUE },
820 {GA_ID , 0 },
821 {GTA_GadgetKind , arrowkind },
822 {GA_Previous , (IPTR)NULL },
823 {TAG_DONE }
825 struct TagItem tellscrollertags[] =
827 {GTA_Scroller_Arrow1, 0 },
828 {GTA_Scroller_Arrow2, 0 },
829 {TAG_DONE }
832 atags[5].ti_Data = (IPTR)vi->vi_dri; /* Set GA_DrawInfo */
833 atags[6].ti_Data = (IPTR)scroller; /* Set GA_Previous */
834 atags[7].ti_Data = (IPTR)scroller; /* Set GTA_Arrow_Scroller */
835 atags[12].ti_Data = (IPTR)GetTagData(GA_Previous, 0, stdgadtags);
837 /* These must be the same as for scroller */
838 /* atags[8].ti_Data = (IPTR)relverify;
839 atags[9].ti_Data = (IPTR)immediate;*/
840 atags[10].ti_Data = (IPTR)GetTagData(GA_ID, 0, stdgadtags);
842 if (freedom == FREEVERT)
844 DEBUG_CREATESCROLLER(bug("makescroller: Freedom=FREEVERT\n"));
845 atags[0].ti_Data = scroller->LeftEdge - BORDERPROPSPACINGX;
846 atags[1].ti_Data = scroller->TopEdge + BORDERPROPSPACINGY + scroller->Height;
847 atags[2].ti_Data = scroller->Width + BORDERPROPSPACINGX * 2;
848 atags[3].ti_Data = arrowdim;
849 atags[4].ti_Data = UPIMAGE;
851 DEBUG_CREATESCROLLER(bug("makescroller: Width %ld Height %ld\n",atags[2].ti_Data,atags[3].ti_Data));
853 arrow_dec = NewObjectA(GadToolsBase->arrowclass, NULL, atags);
854 if (!arrow_dec)
855 goto failure;
857 arrow_dec->GadgetType |= GTYP_GADTOOLS;
859 DEBUG_CREATESCROLLER(bug("makescroller: arrow_dec gadget 0x%lx\n",arrow_dec));
860 DEBUG_CREATESCROLLER(bug("makescroller: arrow_dec nextgadget 0x%lx\n",arrow_dec->NextGadget));
862 atags[1].ti_Data += arrowdim;
863 atags[4].ti_Data = DOWNIMAGE;
864 atags[6].ti_Data = (IPTR)arrow_dec;
866 arrow_inc = NewObjectA(GadToolsBase->arrowclass, NULL, atags);
867 if (!arrow_inc)
868 goto failure;
870 arrow_inc->GadgetType |= GTYP_GADTOOLS;
872 DEBUG_CREATESCROLLER(bug("makescroller: arrow_inc gadget 0x%lx\n",arrow_inc));
873 DEBUG_CREATESCROLLER(bug("makescroller: arrow_inc nextgadget 0x%lx\n",arrow_inc->NextGadget));
876 else
878 DEBUG_CREATESCROLLER(bug("makescroller: Freedom=FREEHORIZ\n"));
880 atags[0].ti_Data = scroller->LeftEdge + scroller->Width + BORDERPROPSPACINGX;
881 atags[1].ti_Data = scroller->TopEdge - BORDERPROPSPACINGY;
882 atags[2].ti_Data = arrowdim;
883 atags[3].ti_Data = scroller->Height + BORDERPROPSPACINGY * 2;
884 atags[4].ti_Data = LEFTIMAGE;
886 DEBUG_CREATESCROLLER(bug("makescroller: Width %ld Height %ld\n",atags[3].ti_Data,atags[2].ti_Data));
888 arrow_dec = NewObjectA(GadToolsBase->arrowclass, NULL, atags);
889 if (!arrow_dec)
890 goto failure;
892 arrow_dec->GadgetType |= GTYP_GADTOOLS;
894 DEBUG_CREATESCROLLER(bug("makescroller: arrow_dec gadget 0x%lx\n",arrow_dec));
896 atags[0].ti_Data += arrowdim;
897 atags[4].ti_Data = RIGHTIMAGE;
898 atags[6].ti_Data = (IPTR)arrow_dec;
900 arrow_inc = NewObjectA(GadToolsBase->arrowclass, NULL, atags);
901 if (!arrow_inc)
902 goto failure;
904 arrow_inc->GadgetType |= GTYP_GADTOOLS;
906 DEBUG_CREATESCROLLER(bug("makescroller: arrow_inc gadget 0x%lx\n",arrow_inc));
908 } /* if (scroller is FREEVERT or FREEHORIZ) */
910 tellscrollertags[0].ti_Data = (IPTR)arrow_dec;
911 tellscrollertags[1].ti_Data = (IPTR)arrow_inc;
913 DEBUG_CREATESCROLLER(bug("makescroller: tell scroller about arrows\n"));
914 SetAttrsA(scroller, tellscrollertags);
916 ReturnPtr ("makescroller", struct Gadget *, arrow_inc);
918 } /* if (scroller should have arrows attached) */
920 ReturnPtr ("makescroller", struct Gadget *, scroller);
922 failure:
923 if (scroller)
924 DisposeObject((Object *)scroller);
926 if (arrow_dec)
927 DisposeObject((Object *)arrow_dec);
929 if (arrow_inc)
930 DisposeObject((Object *)arrow_inc);
932 ReturnPtr("makescroller", struct Gadget *, NULL);
935 /****************************************************************************************/
937 struct Gadget *makestring(struct GadToolsBase_intern *GadToolsBase,
938 struct TagItem stdgadtags[],
939 struct VisualInfo *vi,
940 struct TextAttr *tattr,
941 struct TagItem *taglist)
943 struct Gadget *obj = NULL;
944 struct IBox bbox;
946 Class *cl;
948 struct TagItem *tag, tags[] =
950 {GA_Disabled , FALSE }, /* 0 */
951 {GA_Immediate , FALSE }, /* 1 */
952 {GA_RelVerify , TRUE }, /* 2 */
953 {GA_TabCycle , TRUE }, /* 3 */
954 {GTST_String , (IPTR)NULL }, /* 4 */
955 {GTST_MaxChars , 64UL }, /* 5 */
956 {GTST_EditHook , (IPTR)NULL }, /* 6 */
957 {STRINGA_ExitHelp , FALSE }, /* 7 */
958 {STRINGA_Justification , GACT_STRINGLEFT }, /* 8 */
959 {STRINGA_ReplaceMode , FALSE }, /* 9 */
960 {GA_TextAttr , (IPTR)NULL }, /* 10 */
961 {GTA_GadgetKind , STRING_KIND }, /* 11 */
962 {GA_Bounds , (IPTR)&bbox }, /* 12 */
963 {TAG_MORE , (IPTR)NULL } /* 13 */
967 /* Could use GetTagData(), but this is faster */
968 while ((tag = NextTagItem(&taglist)))
970 IPTR tidata = tag->ti_Data;
972 switch (tag->ti_Tag)
974 case GA_Disabled: tags[0].ti_Data = tidata; break;
975 case GA_Immediate: tags[1].ti_Data = tidata; break;
976 case GA_RelVerify: tags[2].ti_Data = tidata; break;
977 case GA_TabCycle: tags[3].ti_Data = tidata; break;
978 case GTST_String: tags[4].ti_Data = tidata; break;
979 case GTST_MaxChars: tags[5].ti_Data = tidata; break;
980 case GTST_EditHook: tags[6].ti_Data = tidata; break;
981 case STRINGA_ExitHelp: tags[7].ti_Data = tidata; break;
982 case STRINGA_Justification: tags[8].ti_Data = tidata; break;
983 case STRINGA_ReplaceMode: tags[9].ti_Data = tidata; break;
986 } /* while (iterate taglist) */
988 if (tattr) /* Text Attr supplied ? */
989 tags[10].ti_Data = (IPTR)tattr;
990 else
991 tags[10].ti_Tag = TAG_IGNORE; /* Don't pass GA_TextAttr, NULL */
993 /* if there is a bounding box the label position
994 will be calculated based on this box and not
995 the gadget coords */
997 bbox.Left = GetTagData(GA_Left, 0, stdgadtags);
998 bbox.Top = GetTagData(GA_Top, 0, stdgadtags);
999 bbox.Width = GetTagData(GA_Width, 0, stdgadtags);
1000 bbox.Height = GetTagData(GA_Height, 0, stdgadtags);
1002 /* There are always GA_Left, GA_Top, GA_Width and GA_Height tags
1003 thanks to creategadgeta.c! */
1005 FindTagItem(GA_Left,stdgadtags)->ti_Data += BORDERSTRINGSPACINGX;
1006 FindTagItem(GA_Top,stdgadtags)->ti_Data += BORDERSTRINGSPACINGY;
1007 FindTagItem(GA_Width,stdgadtags)->ti_Data -= BORDERSTRINGSPACINGX * 2;
1008 FindTagItem(GA_Height,stdgadtags)->ti_Data -= BORDERSTRINGSPACINGY * 2;
1010 tags[13].ti_Data = (IPTR)stdgadtags;
1012 obj = (struct Gadget *) NewObjectA(GadToolsBase->stringclass, NULL, tags);
1014 if (obj)
1016 obj->GadgetType |= GTYP_GADTOOLS;
1018 return (obj);
1021 /****************************************************************************************/
1023 struct Gadget *makeinteger(struct GadToolsBase_intern *GadToolsBase,
1024 struct TagItem stdgadtags[],
1025 struct VisualInfo *vi,
1026 struct TextAttr *tattr,
1027 struct TagItem *taglist)
1029 struct Gadget *obj = NULL;
1030 struct IBox bbox;
1031 Class *cl;
1033 struct TagItem *tag, tags[] =
1035 {GA_Disabled , FALSE }, /* 0 */
1036 {GA_Immediate , FALSE }, /* 1 */
1037 {GA_RelVerify , TRUE }, /* 2 */
1038 {GA_TabCycle , TRUE }, /* 3 */
1039 {GTIN_Number , 0L }, /* 4 */
1040 {GTIN_MaxChars , 10L }, /* 5 */
1041 {GTIN_EditHook , (IPTR)NULL }, /* 6 */
1042 {STRINGA_ExitHelp , FALSE }, /* 7 */
1043 {STRINGA_Justification , GACT_STRINGLEFT }, /* 8 */
1044 {STRINGA_ReplaceMode , FALSE }, /* 9 */
1045 {GA_TextAttr , (IPTR)NULL }, /* 10 */
1046 {GTA_GadgetKind , INTEGER_KIND }, /* 11 */
1047 {GA_Bounds , (IPTR)&bbox }, /* 12 */
1048 {TAG_MORE , (IPTR)NULL } /* 13 */
1052 /* Could use GetTagData(), but this is faster */
1053 while ((tag = NextTagItem(&taglist)))
1055 IPTR tidata = tag->ti_Data;
1057 switch (tag->ti_Tag)
1059 case GA_Disabled: tags[0].ti_Data = tidata; break;
1060 case GA_Immediate: tags[1].ti_Data = tidata; break;
1061 case GA_RelVerify: tags[2].ti_Data = tidata; break;
1062 case GA_TabCycle: tags[3].ti_Data = tidata; break;
1063 case GTIN_Number: tags[4].ti_Data = tidata; break;
1064 case GTIN_MaxChars: tags[5].ti_Data = tidata; break;
1065 case GTIN_EditHook: tags[6].ti_Data = tidata; break;
1066 case STRINGA_ExitHelp: tags[7].ti_Data = tidata; break;
1067 case STRINGA_Justification: tags[8].ti_Data = tidata; break;
1068 case STRINGA_ReplaceMode: tags[9].ti_Data = tidata; break;
1071 } /* while (iterate taglist) */
1073 if (tattr) /* Text Attr supplied ? */
1074 tags[10].ti_Data = (IPTR)tattr;
1075 else
1076 tags[10].ti_Tag = TAG_IGNORE; /* Don't pass GA_TextAttr, NULL */
1078 /* if there is a bounding box the label position
1079 will be calculated based on this box and not
1080 the gadget coords */
1082 bbox.Left = GetTagData(GA_Left, 0, stdgadtags);
1083 bbox.Top = GetTagData(GA_Top, 0, stdgadtags);
1084 bbox.Width = GetTagData(GA_Width, 0, stdgadtags);
1085 bbox.Height = GetTagData(GA_Height, 0, stdgadtags);
1087 /* There are always GA_Left, GA_Top, GA_Width and GA_Height tags
1088 thanks to creategadgeta.c! */
1090 FindTagItem(GA_Left,stdgadtags)->ti_Data += BORDERSTRINGSPACINGX;
1091 FindTagItem(GA_Top,stdgadtags)->ti_Data += BORDERSTRINGSPACINGY;
1092 FindTagItem(GA_Width,stdgadtags)->ti_Data -= BORDERSTRINGSPACINGX * 2;
1093 FindTagItem(GA_Height,stdgadtags)->ti_Data -= BORDERSTRINGSPACINGY * 2;
1095 tags[13].ti_Data = (IPTR)stdgadtags;
1097 obj = (struct Gadget *) NewObjectA(GadToolsBase->stringclass, NULL, tags);
1098 if (obj)
1100 obj->GadgetType |= GTYP_GADTOOLS;
1102 return (obj);
1106 /****************************************************************************************/
1108 const struct TagItem scroller2lv[] =
1110 {PGA_Top , GTLV_Top},
1111 {TAG_DONE , }
1114 /****************************************************************************************/
1116 /* Spacing between scroller and listview */
1117 #define SCROLLER_SPACING 2
1119 /****************************************************************************************/
1121 struct Gadget *makelistview(struct GadToolsBase_intern *GadToolsBase,
1122 struct TagItem stdgadtags[],
1123 struct VisualInfo *vi,
1124 struct TextAttr *tattr,
1125 struct TagItem *taglist)
1127 struct Gadget *lvgad = NULL, *showselgad = LV_SHOWSELECTED_NONE;
1128 struct Gadget *scrollergad;
1129 struct IBox bbox;
1132 WORD scroller_width = 16; /* default */
1134 struct TagItem *lv_width_tag, *lv_height_tag;
1135 WORD lv_width, lv_height;
1136 #if CORRECT_LISTVIEWHEIGHT
1137 WORD viewheight;
1138 #endif
1139 WORD ysize, totalitemheight = 0;
1141 struct TagItem *tag, lvtags[] =
1143 {GA_Disabled , FALSE }, /* 0 */
1144 {GTLV_Top , 0L }, /* 1 */
1145 {GTLV_MakeVisible , 0L }, /* 2 */
1146 {GTLV_Labels , (IPTR)NULL }, /* 3 */
1147 {GTLV_Selected , ~0L }, /* 4 */
1148 {GTLV_ItemHeight , 0L }, /* 5 */
1149 {GTLV_CallBack , (IPTR)NULL }, /* 6 */
1150 {GTLV_MaxPen , 0L }, /* 7 */
1151 {GTLV_ReadOnly , 0L }, /* 8 */
1152 {LAYOUTA_Spacing , 0L }, /* 9 */
1153 {GA_TextAttr , (IPTR)NULL }, /* 10 */
1154 {GA_RelVerify , TRUE }, /* 11 */
1155 {GA_Bounds , (IPTR)&bbox }, /* 12 */
1156 {GTLV_ShowSelected , (IPTR)showselgad }, /* 13 */
1157 {TAG_MORE , (IPTR)NULL } /* 14 */
1160 EnterFunc(bug("makelistview()\n"));
1162 /* Could use GetTagData(), but this is faster */
1163 while ((tag = NextTagItem(&taglist)))
1165 IPTR tidata = tag->ti_Data;
1167 switch (tag->ti_Tag)
1169 case GA_Disabled: lvtags[0].ti_Data = tidata; break;
1170 case GTLV_Top: lvtags[1].ti_Data = tidata; break;
1171 case GTLV_MakeVisible: lvtags[2].ti_Data = tidata; break;
1172 case GTLV_Labels: lvtags[3].ti_Data = tidata; break;
1173 case GTLV_Selected: lvtags[4].ti_Data = tidata; break;
1174 case GTLV_ItemHeight: lvtags[5].ti_Data = tidata; break;
1175 case GTLV_CallBack: lvtags[6].ti_Data = tidata; break;
1176 case GTLV_MaxPen: lvtags[7].ti_Data = tidata; break;
1177 case GTLV_ReadOnly: lvtags[8].ti_Data = tidata; break;
1178 case LAYOUTA_Spacing: lvtags[9].ti_Data = tidata; break;
1180 case GTLV_ShowSelected:
1181 showselgad = (struct Gadget *)tidata;
1182 lvtags[13].ti_Data = (IPTR)showselgad;
1183 break;
1185 case GTLV_ScrollWidth: scroller_width = (UWORD)tidata;
1188 } /* while (iterate taglist) */
1190 /* if there is a bounding box the label position
1191 will be calculated based on this box and not
1192 the gadget coords */
1194 bbox.Left = GetTagData(GA_Left, 0, stdgadtags);
1195 bbox.Top = GetTagData(GA_Top, 0, stdgadtags);
1196 bbox.Width = GetTagData(GA_Width, 0, stdgadtags);
1197 bbox.Height = GetTagData(GA_Height, 0, stdgadtags);
1199 /* Callback supplied ? */
1200 if (!lvtags[6].ti_Data)
1201 lvtags[6].ti_Tag = TAG_IGNORE; /* Don't pass GTLV_Callback, NULL */
1203 if (tattr) /* Text Attr supplied ? */
1205 lvtags[10].ti_Data = (IPTR)tattr;
1206 ysize = tattr->ta_YSize;
1208 else
1210 lvtags[10].ti_Tag = TAG_IGNORE; /* Don't pass GA_TextAttr, NULL */
1212 ysize = vi->vi_dri->dri_Font->tf_YSize;
1215 /* If not set allready, set ItemHeight */
1216 if (lvtags[5].ti_Data == 0)
1217 lvtags[5].ti_Data = ysize;
1219 /* If not set allready, set Spacing */
1220 if (lvtags[9].ti_Data == 0)
1221 lvtags[9].ti_Data = LV_DEF_INTERNAL_SPACING;
1223 DEBUG_CREATELISTVIEW(bug("makelistview: item ysize %ld\n", ysize));
1225 /* Find the dimension specific tags */
1226 lv_width_tag = FindTagItem(GA_Width, stdgadtags);
1227 lv_height_tag = FindTagItem(GA_Height, stdgadtags);
1229 lv_width = (WORD)lv_width_tag->ti_Data;
1230 lv_height = (WORD)lv_height_tag->ti_Data;
1233 /* Adjust the listview width according to scroller width + some spacing */
1234 lv_width -= (scroller_width + SCROLLER_SPACING);
1236 /* Adjust the listview height according to showsel gadget height */
1237 if ((showselgad) && (showselgad != LV_SHOWSELECTED_NONE))
1239 /* The showselected string gadget must have the same width as the
1240 listview gadget, otherwise fail (AmigaOS does the same). Fail
1241 also if the showselected string gadget is too high*/
1243 if ((EG(showselgad)->BoundsWidth != bbox.Width) ||
1244 (EG(showselgad)->BoundsHeight >= lv_height))
1246 ReturnPtr ("makelistview", struct Gadget *, NULL);
1249 /* the showselected string gadget shrinks the height of the listview */
1251 lv_height -= EG(showselgad)->BoundsHeight;
1253 /* the showselected string gadget will get its position automatically
1254 fixed to be under the listview gadget */
1256 EG(showselgad)->BoundsLeftEdge = bbox.Left;
1257 EG(showselgad)->BoundsTopEdge = bbox.Top + lv_height;
1258 EG(showselgad)->LeftEdge = EG(showselgad)->BoundsLeftEdge + BORDERSTRINGSPACINGX;
1259 EG(showselgad)->TopEdge = EG(showselgad)->BoundsTopEdge + BORDERSTRINGSPACINGY;
1261 D(bug("makelistview: Showselected gadget specified"));
1265 /* GTLV_ItemHeight + LAYOUTA_Spacing */
1266 totalitemheight = lvtags[5].ti_Data + lvtags[9].ti_Data;
1268 #if CORRECT_LISTVIEWHEIGHT
1269 /* stegerg: I think it looks better without this adjustment. Think of
1270 GTLV_ShowSelected and aligning with other gadgets */
1272 /* Adjust listview height so that an exact number of items fits in it */
1273 viewheight = lv_height - (2 * LV_BORDER_Y);
1274 lv_height -= (viewheight % totalitemheight);
1276 #endif
1278 /* Reinsert the modified dimension attrs into the listview taglist */
1280 D(bug("makelistview: Dimension passed to listview: w=%d, h=%d\n", lv_width, lv_height));
1282 lv_width_tag->ti_Data = (IPTR)lv_width;
1283 lv_height_tag->ti_Data = (IPTR)lv_height;
1285 lvtags[14].ti_Data = (IPTR)stdgadtags;
1287 D(bug("makelistview: Listview class opened\n"));
1288 lvgad = (struct Gadget *)NewObjectA(GadToolsBase->listviewclass, NULL, lvtags);
1289 if (lvgad)
1291 struct TagItem scr_stdtags[] =
1293 {GA_Left , 0L },
1294 {GA_Top , 0L },
1295 {GA_Width , 0L },
1296 {GA_Height , 0L },
1297 {GA_Next , (IPTR)NULL },
1298 {GA_ID , 0L },
1299 {GA_DrawInfo, (IPTR)NULL },
1300 {GA_Previous, (IPTR)NULL },
1301 {TAG_DONE }
1304 struct TagItem scr_specialtags[] =
1306 /* The listview will initialize the scrollers top, visible & total,
1307 ** in its GM_LAYOUT method
1309 {GTSC_Arrows , scroller_width },
1310 {PGA_Freedom , LORIENT_VERT },
1311 {GTA_Scroller_ArrowKind , LISTVIEW_KIND },
1312 {GTA_Scroller_ScrollerKind , LISTVIEW_KIND },
1313 {TAG_DONE }
1316 lvgad->GadgetType |= GTYP_GADTOOLS;
1318 D(bug("makelistview: Listview gadget created: %p\n", lvgad));
1319 D(bug("makelistview: scroller_width %ld\n",scroller_width));
1321 /* Create a scroller object to use with the listviev */
1322 scr_stdtags[0].ti_Data = lvgad->LeftEdge + lvgad->Width - 1 + SCROLLER_SPACING;
1323 scr_stdtags[1].ti_Data = lvgad->TopEdge;
1324 scr_stdtags[2].ti_Data = scroller_width;
1325 scr_stdtags[3].ti_Data = lvgad->Height;
1326 scr_stdtags[4].ti_Data = (IPTR)lvgad;
1327 scr_stdtags[5].ti_Data = lvgad->GadgetID;
1328 scr_stdtags[6].ti_Data = (IPTR)vi->vi_dri;
1329 scr_stdtags[7].ti_Data = (IPTR)GetTagData(GA_Previous, 0, stdgadtags);
1331 scrollergad = makescroller(GadToolsBase, scr_stdtags, vi, scr_specialtags);
1332 if (scrollergad)
1334 struct TagItem lvset_tags[] =
1336 {GTA_Listview_Scroller, (IPTR)NULL },
1337 {TAG_DONE, }
1339 struct TagItem scrnotify_tags[] =
1341 {ICA_TARGET , (IPTR)NULL },
1342 {ICA_MAP , (IPTR)NULL },
1343 {TAG_DONE }
1345 struct Gadget *prop_of_scrollergad;
1347 D(bug("makelistview: Scroller gadget created: %p\n", scrollergad));
1349 /* the scrollergadget is a multigadget gadget: arrowinc->arrowdec->prop */
1350 #warning This relies on scroller gadget to always contain arrow gadgets
1351 #warning If this ever changes the line below must be updated.
1352 prop_of_scrollergad = scrollergad->NextGadget->NextGadget;
1354 scrollergad->Activation &= ~GACT_FOLLOWMOUSE;
1356 /* Tell the listview about the scroller and the showselgad */
1357 DEBUG_CREATELISTVIEW(bug("makelistview: tell listview about scroller\n"));
1358 lvset_tags[0].ti_Data = (IPTR)prop_of_scrollergad;
1359 SetAttrsA((Object *)lvgad, lvset_tags);
1361 /* Tell the scroller to notify the listview when its PGA_Top attribute changes */
1362 DEBUG_CREATELISTVIEW(bug("makelistview: tell scroller about notification\n"));
1363 scrnotify_tags[0].ti_Data = (IPTR)lvgad;
1364 scrnotify_tags[1].ti_Data = (IPTR)scroller2lv;
1366 SetAttrsA((Object *)prop_of_scrollergad, scrnotify_tags);
1368 ReturnPtr ("makelistview", struct Gadget *, scrollergad);
1371 DisposeObject(lvgad);
1373 } /* if (lvgad created) */
1375 ReturnPtr ("makelistview", struct Gadget *, NULL);
1378 /****************************************************************************************/
1380 struct Gadget *makegeneric(struct GadToolsBase_intern *GadToolsBase,
1381 struct TagItem stdgadtags[],
1382 struct VisualInfo *vi,
1383 struct TextAttr *tattr,
1384 struct TagItem *taglist)
1386 struct GT_GenericGadget *gad;
1387 struct Gadget *prevgad;
1389 gad = AllocMem(sizeof(struct GT_GenericGadget), MEMF_PUBLIC | MEMF_CLEAR);
1390 if (gad)
1392 gad->gad.LeftEdge = stdgadtags[TAG_Left].ti_Data;
1393 gad->gad.TopEdge = stdgadtags[TAG_Top].ti_Data;
1394 gad->gad.Width = stdgadtags[TAG_Width].ti_Data;
1395 gad->gad.Height = stdgadtags[TAG_Height].ti_Data;
1396 gad->gad.Flags = GFLG_EXTENDED;
1397 gad->gad.Activation = 0;
1398 gad->gad.GadgetType = GTYP_GADTOOLS;
1399 gad->gad.GadgetRender = NULL;
1400 gad->gad.SelectRender = NULL;
1401 gad->gad.GadgetText = (struct IntuiText *)stdgadtags[TAG_IText].ti_Data;
1402 gad->gad.MutualExclude = 0;
1403 gad->gad.SpecialInfo = NULL;
1404 gad->gad.GadgetID = stdgadtags[TAG_ID].ti_Data;
1405 gad->gad.UserData = (APTR)stdgadtags[TAG_UserData].ti_Data;
1406 gad->gad.MoreFlags = GMORE_BOUNDS | GMORE_GADGETHELP;
1407 gad->gad.BoundsLeftEdge = stdgadtags[TAG_Left].ti_Data;
1408 gad->gad.BoundsTopEdge = stdgadtags[TAG_Top].ti_Data;
1409 gad->gad.BoundsWidth = stdgadtags[TAG_Width].ti_Data;
1410 gad->gad.BoundsHeight = stdgadtags[TAG_Height].ti_Data;
1411 gad->magic = GENERIC_MAGIC;
1412 gad->magic2 = GENERIC_MAGIC2;
1413 gad->itext = (struct IntuiText *)stdgadtags[TAG_IText].ti_Data;
1415 prevgad = (struct Gadget *)stdgadtags[TAG_Previous].ti_Data;
1416 prevgad->NextGadget = (struct Gadget *)gad;
1419 ReturnPtr ("makegeneric", struct Gadget *, (struct Gadget *)gad);
1422 /****************************************************************************************/