Updated PCI IDs to latest snapshot.
[tangerine.git] / workbench / libs / gadtools / gadgets.c
blob16e24e48a44e17e638f2a7faa93215d81ab98c98
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 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(&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(&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(&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 {TAG_DONE }
496 STRPTR lformat = NULL;
497 WORD lmaxlen = 0;
498 LONG lmaxpixellen = 0L;
499 UBYTE lplace = PLACETEXT_LEFT;
500 WORD level = 0;
502 struct Gadget *slidergad = NULL, *levelgad = NULL;
504 /* Parse tags */
505 while ((tag = NextTagItem(&taglist)))
507 IPTR tidata = tag->ti_Data;
509 switch (tag->ti_Tag)
512 /* Slider tags */
513 case GA_Disabled: stags[0].ti_Data = tidata; break;
514 case GA_RelVerify: stags[1].ti_Data = tidata; break;
515 case GA_Immediate: stags[2].ti_Data = tidata; break;
516 case GTSL_Min: stags[3].ti_Data = tidata; break;
517 case GTSL_Max: stags[4].ti_Data = tidata; break;
518 case GTSL_Level: level = stags[5].ti_Data = tidata; break;
519 case PGA_Freedom:
520 if (tidata == LORIENT_HORIZ)
521 stags[6].ti_Data = FREEHORIZ;
522 else
523 stags[6].ti_Data = FREEVERT;
524 break;
526 /* Level tags */
527 case GTSL_LevelFormat: lformat = (STRPTR)tidata; break;
528 case GTSL_MaxLevelLen: lmaxlen = (UWORD)tidata; break;
529 case GTSL_MaxPixelLen: lmaxpixellen = (ULONG)tidata; break;
530 case GTSL_LevelPlace: lplace = (UBYTE)tidata; break;
531 case GTSL_Justification: ltags[6].ti_Data = tidata; break;
532 case GTSL_DispFunc: ltags[7].ti_Data = tidata; break;
536 } /* while (iterate taglist) */
538 /* if there is a bounding box the label position
539 will be calculated based on this box and not
540 the gadget coords */
542 bbox.Left = GetTagData(GA_Left, 0, stdgadtags);
543 bbox.Top = GetTagData(GA_Top, 0, stdgadtags);
544 bbox.Width = GetTagData(GA_Width, 0, stdgadtags);
545 bbox.Height = GetTagData(GA_Height, 0, stdgadtags);
547 /* There are always GA_Left, GA_Top, GA_Width and GA_Height tags
548 thanks to creategadgeta.c! */
550 FindTagItem(GA_Left,stdgadtags)->ti_Data += BORDERPROPSPACINGX;
551 FindTagItem(GA_Top,stdgadtags)->ti_Data += BORDERPROPSPACINGY;
552 FindTagItem(GA_Width,stdgadtags)->ti_Data -= BORDERPROPSPACINGX * 2;
553 FindTagItem(GA_Height,stdgadtags)->ti_Data -= BORDERPROPSPACINGY * 2;
555 /* Create slider gadget */
556 stags[13].ti_Data = (IPTR)stdgadtags;
557 slidergad = NewObjectA(GadToolsBase->sliderclass, NULL, stags);
559 if (!slidergad)
560 return (NULL);
562 slidergad->GadgetType |= GTYP_GADTOOLS;
564 if (lformat || lmaxlen || lmaxpixellen)
566 WORD x = 0, y = 0;
567 UWORD ysize = 8;
569 struct TagItem lntags[] =
571 {ICA_TARGET, (IPTR)NULL },
572 {ICA_MAP , (IPTR)NULL },
573 {TAG_DONE }
576 /* Set some defaults */
577 if (!lformat)
578 lformat = "%ld";
579 if (!lmaxlen)
580 lmaxlen = 2;
581 if (!lmaxpixellen)
583 struct TextFont *font;
584 UWORD xsize;
586 ysize = vi->vi_dri->dri_Font->tf_YSize;
587 xsize = vi->vi_dri->dri_Font->tf_XSize;
589 if (tattr)
591 font = OpenFont(tattr);
592 if (font)
594 ysize = font->tf_YSize;
595 xsize = font->tf_XSize;
596 CloseFont(font);
598 else /* If no valid tattr */
599 ltags[4].ti_Tag = TAG_IGNORE;
601 else /* If no valid tattr */
602 ltags[4].ti_Tag = TAG_IGNORE;
604 lmaxpixellen = lmaxlen * xsize;
606 ltags[4].ti_Data = (ULONG)tattr;
608 } /* if (!lmaxpixellen) */
610 switch (lplace)
612 case PLACETEXT_LEFT:
613 x = slidergad->LeftEdge - BORDERPROPSPACINGX - lmaxpixellen - 4;
614 y = slidergad->TopEdge + (slidergad->Height - ysize) / 2 + 1;
615 break;
616 case PLACETEXT_RIGHT:
617 x = slidergad->LeftEdge + slidergad->Width + BORDERPROPSPACINGX + 5;
618 y = slidergad->TopEdge + (slidergad->Height - ysize) / 2 + 1;
619 break;
620 case PLACETEXT_ABOVE:
621 x = slidergad->LeftEdge - (lmaxpixellen - slidergad->Width) / 2;
622 y = slidergad->TopEdge - BORDERPROPSPACINGY - ysize - 2;
623 break;
624 case PLACETEXT_BELOW:
625 x = slidergad->LeftEdge - (lmaxpixellen - slidergad->Width) / 2;
626 y = slidergad->TopEdge + slidergad->Height + BORDERPROPSPACINGY + 3;
627 break;
630 /* Create the levelobj */
632 ltags[0].ti_Data = (IPTR)x;
633 ltags[1].ti_Data = (IPTR)y;
634 ltags[2].ti_Data = (IPTR)lmaxpixellen;
635 ltags[3].ti_Data = (IPTR)ysize;
636 ltags[5].ti_Data = (IPTR)lformat;
637 ltags[8].ti_Data = (IPTR)slidergad;
638 ltags[9].ti_Data = (IPTR)vi->vi_dri;
639 ltags[10].ti_Data = (IPTR)level;
640 ltags[12].ti_Data = (IPTR)GetTagData(GA_Previous, 0, stdgadtags);
642 levelgad = (struct Gadget *)NewObjectA(GadToolsBase->textclass, NULL, ltags);
643 if (!levelgad)
645 DisposeObject((Object *)slidergad);
646 return (NULL);
648 levelgad->GadgetType |= GTYP_GADTOOLS;
650 /* Set up a notification from the slider to the level */
651 lntags[0].ti_Data = (IPTR)levelgad;
652 lntags[1].ti_Data = (IPTR)slider2level;
653 SetAttrsA((Object *)slidergad, lntags);
655 return (levelgad);
657 } /* if (slider should have a level attached) */
659 return (slidergad);
663 /****************************************************************************************/
665 #ifdef SDEBUG
666 # undef SDEBUG
667 #endif
668 #ifdef DEBUG
669 # undef DEBUG
670 #endif
671 #define SDEBUG 0
672 #define DEBUG 0
673 #include <aros/debug.h>
675 /****************************************************************************************/
677 struct Gadget *makescroller(struct GadToolsBase_intern *GadToolsBase,
678 struct TagItem stdgadtags[],
679 struct VisualInfo *vi,
680 const struct TagItem *taglist)
682 struct Gadget *scroller = NULL,
683 *arrow_dec = NULL,
684 *arrow_inc = NULL ;
685 struct IBox bbox;
687 struct TagItem *tag, stags[] =
689 {GTSC_Top , 0 },
690 {GTSC_Total , 0 },
691 {GTSC_Visible , 2 },
692 {PGA_Freedom , FREEHORIZ },
693 {GA_Disabled , FALSE },
694 {GA_RelVerify , TRUE },
695 {GA_Immediate , TRUE },
696 {GTA_GadgetKind , SCROLLER_KIND },
697 {PGA_Borderless , TRUE },
698 #ifdef __MORPHOS__
699 {PGA_NewLook , FALSE },
700 #else
701 {PGA_NewLook , TRUE },
702 #endif
703 {GA_Bounds , (IPTR) &bbox },
704 {GA_FollowMouse , TRUE },
705 {PGA_NotifyBehaviour, PG_BEHAVIOUR_NICE },
706 {PGA_RenderBehaviour, PG_BEHAVIOUR_NICE },
707 {TAG_MORE , (IPTR)NULL }
710 struct TagItem *scr_dim_tagitem;
714 UWORD freedom = stags[3].ti_Data; /* default */
715 WORD arrowdim = 0 /* -1*/, arrowkind = SCROLLER_KIND;
716 BOOL relverify, immediate;
717 ULONG scr_dim_tag;
719 EnterFunc(bug("makescroller(stdgadtags=%p, vi=%p, taglist = %p)\n",
720 stdgadtags, vi, taglist));
721 /* Could use GetTagData(), but this is faster */
722 while ((tag = NextTagItem(&taglist)))
724 IPTR tidata = tag->ti_Data;
726 switch (tag->ti_Tag)
728 case GTSC_Top: stags[0].ti_Data = tidata; break;
729 case GTSC_Total: stags[1].ti_Data = tidata; break;
730 case GTSC_Visible: stags[2].ti_Data = tidata; break;
731 case PGA_Freedom:
732 if (tidata == LORIENT_HORIZ)
733 freedom = stags[3].ti_Data = FREEHORIZ;
734 else
735 freedom = stags[3].ti_Data = FREEVERT;
736 break;
737 case GA_Disabled: stags[4].ti_Data = tidata; break;
738 case GA_RelVerify: relverify = stags[5].ti_Data = tidata; break;
739 case GA_Immediate: immediate = stags[6].ti_Data = tidata; break;
741 case GTSC_Arrows: arrowdim = (WORD)tidata; break;
742 case GTA_Scroller_ArrowKind: arrowkind = (WORD)tidata; break;
743 case GTA_Scroller_ScrollerKind: stags[7].ti_Data = tidata; break;
747 } /* while (iterate taglist) */
749 /* if there is a bounding box the label position
750 will be calculated based on this box and not
751 the gadget coords */
753 DEBUG_CREATESCROLLER(bug("makescroller: arrowdim %ld\n", arrowdim));
755 bbox.Left = GetTagData(GA_Left, 0, stdgadtags);
756 bbox.Top = GetTagData(GA_Top, 0, stdgadtags);
757 bbox.Width = GetTagData(GA_Width, 0, stdgadtags);
758 bbox.Height = GetTagData(GA_Height, 0, stdgadtags);
760 DEBUG_CREATESCROLLER(bug("makescroller: left %ld top %ld width %ld height %ld\n", bbox.Left, bbox.Top, bbox.Width, bbox.Height));
762 stags[14].ti_Data = (IPTR)stdgadtags;
764 /* Substract the arrow's total size from the sroller's size */
766 if (arrowdim == -1)
768 DEBUG_CREATESCROLLER(bug("makescroller: default arrowdim\n"));
769 if (freedom == FREEVERT)
771 arrowdim = GetTagData(GA_Width, 16, stdgadtags);
772 DEBUG_CREATESCROLLER(bug("makescroller: freevert arrowdim %ld\n", arrowdim));
773 } else {
774 arrowdim = GetTagData(GA_Height, 16, stdgadtags);
775 DEBUG_CREATESCROLLER(bug("makescroller: freehoriz arrowdim %ld\n", arrowdim));
777 DEBUG_CREATESCROLLER(bug("makescroller: arrowdim %ld\n", arrowdim));
780 scr_dim_tag = ((freedom == FREEVERT) ? GA_Height : GA_Width);
782 scr_dim_tagitem = FindTagItem(scr_dim_tag, stdgadtags);
783 scr_dim_tagitem->ti_Data -= 2 * arrowdim;
785 /* There are always GA_Left, GA_Top, GA_Width and GA_Height tags
786 thanks to creategadgeta.c! */
788 FindTagItem(GA_Left,stdgadtags)->ti_Data += BORDERPROPSPACINGX;
789 FindTagItem(GA_Top,stdgadtags)->ti_Data += BORDERPROPSPACINGY;
790 FindTagItem(GA_Width,stdgadtags)->ti_Data -= BORDERPROPSPACINGX * 2;
791 FindTagItem(GA_Height,stdgadtags)->ti_Data -= BORDERPROPSPACINGY * 2;
793 scroller = (struct Gadget *) NewObjectA(GadToolsBase->scrollerclass, NULL, stags);
795 if (!scroller)
796 return (NULL);
798 scroller->GadgetType |= GTYP_GADTOOLS;
800 DEBUG_CREATESCROLLER(bug("makescroller: scroller gadget 0x%lx scroller Width %ld Height %ld\n",scroller,scroller->Width,scroller->Height));
801 DEBUG_CREATESCROLLER(bug("makescroller: scroller nextgadget 0x%lx\n",scroller->NextGadget));
803 if (arrowdim) /* Scroller has arrows ? */
805 struct TagItem atags[] =
807 {GA_Left , 0 },
808 {GA_Top , 0 },
809 {GA_Width , 0 },
810 {GA_Height , 0 },
811 {GTA_Arrow_Type , 0 },
812 {GA_DrawInfo , (IPTR)NULL },
813 {GA_Next , (IPTR)NULL },
814 {GTA_Arrow_Scroller , (IPTR)NULL },
815 {GA_RelVerify , TRUE },
816 {GA_Immediate , TRUE },
817 {GA_ID , 0 },
818 {GTA_GadgetKind , arrowkind },
819 {GA_Previous , (IPTR)NULL },
820 {TAG_DONE }
822 struct TagItem tellscrollertags[] =
824 {GTA_Scroller_Arrow1, 0 },
825 {GTA_Scroller_Arrow2, 0 },
826 {TAG_DONE }
829 atags[5].ti_Data = (IPTR)vi->vi_dri; /* Set GA_DrawInfo */
830 atags[6].ti_Data = (IPTR)scroller; /* Set GA_Previous */
831 atags[7].ti_Data = (IPTR)scroller; /* Set GTA_Arrow_Scroller */
832 atags[12].ti_Data = (IPTR)GetTagData(GA_Previous, 0, stdgadtags);
834 /* These must be the same as for scroller */
835 /* atags[8].ti_Data = (IPTR)relverify;
836 atags[9].ti_Data = (IPTR)immediate;*/
837 atags[10].ti_Data = (IPTR)GetTagData(GA_ID, 0, stdgadtags);
839 if (freedom == FREEVERT)
841 DEBUG_CREATESCROLLER(bug("makescroller: Freedom=FREEVERT\n"));
842 atags[0].ti_Data = scroller->LeftEdge - BORDERPROPSPACINGX;
843 atags[1].ti_Data = scroller->TopEdge + BORDERPROPSPACINGY + scroller->Height;
844 atags[2].ti_Data = scroller->Width + BORDERPROPSPACINGX * 2;
845 atags[3].ti_Data = arrowdim;
846 atags[4].ti_Data = UPIMAGE;
848 DEBUG_CREATESCROLLER(bug("makescroller: Width %ld Height %ld\n",atags[2].ti_Data,atags[3].ti_Data));
850 arrow_dec = NewObjectA(GadToolsBase->arrowclass, NULL, atags);
851 if (!arrow_dec)
852 goto failure;
854 arrow_dec->GadgetType |= GTYP_GADTOOLS;
856 DEBUG_CREATESCROLLER(bug("makescroller: arrow_dec gadget 0x%lx\n",arrow_dec));
857 DEBUG_CREATESCROLLER(bug("makescroller: arrow_dec nextgadget 0x%lx\n",arrow_dec->NextGadget));
859 atags[1].ti_Data += arrowdim;
860 atags[4].ti_Data = DOWNIMAGE;
861 atags[6].ti_Data = (IPTR)arrow_dec;
863 arrow_inc = NewObjectA(GadToolsBase->arrowclass, NULL, atags);
864 if (!arrow_inc)
865 goto failure;
867 arrow_inc->GadgetType |= GTYP_GADTOOLS;
869 DEBUG_CREATESCROLLER(bug("makescroller: arrow_inc gadget 0x%lx\n",arrow_inc));
870 DEBUG_CREATESCROLLER(bug("makescroller: arrow_inc nextgadget 0x%lx\n",arrow_inc->NextGadget));
873 else
875 DEBUG_CREATESCROLLER(bug("makescroller: Freedom=FREEHORIZ\n"));
877 atags[0].ti_Data = scroller->LeftEdge + scroller->Width + BORDERPROPSPACINGX;
878 atags[1].ti_Data = scroller->TopEdge - BORDERPROPSPACINGY;
879 atags[2].ti_Data = arrowdim;
880 atags[3].ti_Data = scroller->Height + BORDERPROPSPACINGY * 2;
881 atags[4].ti_Data = LEFTIMAGE;
883 DEBUG_CREATESCROLLER(bug("makescroller: Width %ld Height %ld\n",atags[3].ti_Data,atags[2].ti_Data));
885 arrow_dec = NewObjectA(GadToolsBase->arrowclass, NULL, atags);
886 if (!arrow_dec)
887 goto failure;
889 arrow_dec->GadgetType |= GTYP_GADTOOLS;
891 DEBUG_CREATESCROLLER(bug("makescroller: arrow_dec gadget 0x%lx\n",arrow_dec));
893 atags[0].ti_Data += arrowdim;
894 atags[4].ti_Data = RIGHTIMAGE;
895 atags[6].ti_Data = (IPTR)arrow_dec;
897 arrow_inc = NewObjectA(GadToolsBase->arrowclass, NULL, atags);
898 if (!arrow_inc)
899 goto failure;
901 arrow_inc->GadgetType |= GTYP_GADTOOLS;
903 DEBUG_CREATESCROLLER(bug("makescroller: arrow_inc gadget 0x%lx\n",arrow_inc));
905 } /* if (scroller is FREEVERT or FREEHORIZ) */
907 tellscrollertags[0].ti_Data = (IPTR)arrow_dec;
908 tellscrollertags[1].ti_Data = (IPTR)arrow_inc;
910 DEBUG_CREATESCROLLER(bug("makescroller: tell scroller about arrows\n"));
911 SetAttrsA(scroller, tellscrollertags);
913 ReturnPtr ("makescroller", struct Gadget *, arrow_inc);
915 } /* if (scroller should have arrows attached) */
917 ReturnPtr ("makescroller", struct Gadget *, scroller);
919 failure:
920 if (scroller)
921 DisposeObject((Object *)scroller);
923 if (arrow_dec)
924 DisposeObject((Object *)arrow_dec);
926 if (arrow_inc)
927 DisposeObject((Object *)arrow_inc);
929 ReturnPtr("makescroller", struct Gadget *, NULL);
932 /****************************************************************************************/
934 struct Gadget *makestring(struct GadToolsBase_intern *GadToolsBase,
935 struct TagItem stdgadtags[],
936 struct VisualInfo *vi,
937 struct TextAttr *tattr,
938 const struct TagItem *taglist)
940 struct Gadget *obj = NULL;
941 struct IBox bbox;
943 struct TagItem *tag, tags[] =
945 {GA_Disabled , FALSE }, /* 0 */
946 {GA_Immediate , FALSE }, /* 1 */
947 {GA_RelVerify , TRUE }, /* 2 */
948 {GA_TabCycle , TRUE }, /* 3 */
949 {GTST_String , (IPTR)NULL }, /* 4 */
950 {GTST_MaxChars , 64UL }, /* 5 */
951 {GTST_EditHook , (IPTR)NULL }, /* 6 */
952 {STRINGA_ExitHelp , FALSE }, /* 7 */
953 {STRINGA_Justification , GACT_STRINGLEFT }, /* 8 */
954 {STRINGA_ReplaceMode , FALSE }, /* 9 */
955 {GA_TextAttr , (IPTR)NULL }, /* 10 */
956 {GTA_GadgetKind , STRING_KIND }, /* 11 */
957 {GA_Bounds , (IPTR)&bbox }, /* 12 */
958 {TAG_MORE , (IPTR)NULL } /* 13 */
962 /* Could use GetTagData(), but this is faster */
963 while ((tag = NextTagItem(&taglist)))
965 IPTR tidata = tag->ti_Data;
967 switch (tag->ti_Tag)
969 case GA_Disabled: tags[0].ti_Data = tidata; break;
970 case GA_Immediate: tags[1].ti_Data = tidata; break;
971 case GA_RelVerify: tags[2].ti_Data = tidata; break;
972 case GA_TabCycle: tags[3].ti_Data = tidata; break;
973 case GTST_String: tags[4].ti_Data = tidata; break;
974 case GTST_MaxChars: tags[5].ti_Data = tidata; break;
975 case GTST_EditHook: tags[6].ti_Data = tidata; break;
976 case STRINGA_ExitHelp: tags[7].ti_Data = tidata; break;
977 case STRINGA_Justification: tags[8].ti_Data = tidata; break;
978 case STRINGA_ReplaceMode: tags[9].ti_Data = tidata; break;
981 } /* while (iterate taglist) */
983 if (tattr) /* Text Attr supplied ? */
984 tags[10].ti_Data = (IPTR)tattr;
985 else
986 tags[10].ti_Tag = TAG_IGNORE; /* Don't pass GA_TextAttr, NULL */
988 /* if there is a bounding box the label position
989 will be calculated based on this box and not
990 the gadget coords */
992 bbox.Left = GetTagData(GA_Left, 0, stdgadtags);
993 bbox.Top = GetTagData(GA_Top, 0, stdgadtags);
994 bbox.Width = GetTagData(GA_Width, 0, stdgadtags);
995 bbox.Height = GetTagData(GA_Height, 0, stdgadtags);
997 /* There are always GA_Left, GA_Top, GA_Width and GA_Height tags
998 thanks to creategadgeta.c! */
1000 FindTagItem(GA_Left,stdgadtags)->ti_Data += BORDERSTRINGSPACINGX;
1001 FindTagItem(GA_Top,stdgadtags)->ti_Data += BORDERSTRINGSPACINGY;
1002 FindTagItem(GA_Width,stdgadtags)->ti_Data -= BORDERSTRINGSPACINGX * 2;
1003 FindTagItem(GA_Height,stdgadtags)->ti_Data -= BORDERSTRINGSPACINGY * 2;
1005 tags[13].ti_Data = (IPTR)stdgadtags;
1007 obj = (struct Gadget *) NewObjectA(GadToolsBase->stringclass, NULL, tags);
1009 if (obj)
1011 obj->GadgetType |= GTYP_GADTOOLS;
1013 return (obj);
1016 /****************************************************************************************/
1018 struct Gadget *makeinteger(struct GadToolsBase_intern *GadToolsBase,
1019 struct TagItem stdgadtags[],
1020 struct VisualInfo *vi,
1021 struct TextAttr *tattr,
1022 const struct TagItem *taglist)
1024 struct Gadget *obj = NULL;
1025 struct IBox bbox;
1027 struct TagItem *tag, tags[] =
1029 {GA_Disabled , FALSE }, /* 0 */
1030 {GA_Immediate , FALSE }, /* 1 */
1031 {GA_RelVerify , TRUE }, /* 2 */
1032 {GA_TabCycle , TRUE }, /* 3 */
1033 {GTIN_Number , 0L }, /* 4 */
1034 {GTIN_MaxChars , 10L }, /* 5 */
1035 {GTIN_EditHook , (IPTR)NULL }, /* 6 */
1036 {STRINGA_ExitHelp , FALSE }, /* 7 */
1037 {STRINGA_Justification , GACT_STRINGLEFT }, /* 8 */
1038 {STRINGA_ReplaceMode , FALSE }, /* 9 */
1039 {GA_TextAttr , (IPTR)NULL }, /* 10 */
1040 {GTA_GadgetKind , INTEGER_KIND }, /* 11 */
1041 {GA_Bounds , (IPTR)&bbox }, /* 12 */
1042 {TAG_MORE , (IPTR)NULL } /* 13 */
1046 /* Could use GetTagData(), but this is faster */
1047 while ((tag = NextTagItem(&taglist)))
1049 IPTR tidata = tag->ti_Data;
1051 switch (tag->ti_Tag)
1053 case GA_Disabled: tags[0].ti_Data = tidata; break;
1054 case GA_Immediate: tags[1].ti_Data = tidata; break;
1055 case GA_RelVerify: tags[2].ti_Data = tidata; break;
1056 case GA_TabCycle: tags[3].ti_Data = tidata; break;
1057 case GTIN_Number: tags[4].ti_Data = tidata; break;
1058 case GTIN_MaxChars: tags[5].ti_Data = tidata; break;
1059 case GTIN_EditHook: tags[6].ti_Data = tidata; break;
1060 case STRINGA_ExitHelp: tags[7].ti_Data = tidata; break;
1061 case STRINGA_Justification: tags[8].ti_Data = tidata; break;
1062 case STRINGA_ReplaceMode: tags[9].ti_Data = tidata; break;
1065 } /* while (iterate taglist) */
1067 if (tattr) /* Text Attr supplied ? */
1068 tags[10].ti_Data = (IPTR)tattr;
1069 else
1070 tags[10].ti_Tag = TAG_IGNORE; /* Don't pass GA_TextAttr, NULL */
1072 /* if there is a bounding box the label position
1073 will be calculated based on this box and not
1074 the gadget coords */
1076 bbox.Left = GetTagData(GA_Left, 0, stdgadtags);
1077 bbox.Top = GetTagData(GA_Top, 0, stdgadtags);
1078 bbox.Width = GetTagData(GA_Width, 0, stdgadtags);
1079 bbox.Height = GetTagData(GA_Height, 0, stdgadtags);
1081 /* There are always GA_Left, GA_Top, GA_Width and GA_Height tags
1082 thanks to creategadgeta.c! */
1084 FindTagItem(GA_Left,stdgadtags)->ti_Data += BORDERSTRINGSPACINGX;
1085 FindTagItem(GA_Top,stdgadtags)->ti_Data += BORDERSTRINGSPACINGY;
1086 FindTagItem(GA_Width,stdgadtags)->ti_Data -= BORDERSTRINGSPACINGX * 2;
1087 FindTagItem(GA_Height,stdgadtags)->ti_Data -= BORDERSTRINGSPACINGY * 2;
1089 tags[13].ti_Data = (IPTR)stdgadtags;
1091 obj = (struct Gadget *) NewObjectA(GadToolsBase->stringclass, NULL, tags);
1092 if (obj)
1094 obj->GadgetType |= GTYP_GADTOOLS;
1096 return (obj);
1100 /****************************************************************************************/
1102 const struct TagItem scroller2lv[] =
1104 {PGA_Top , GTLV_Top},
1105 {TAG_DONE , }
1108 /****************************************************************************************/
1110 /* Spacing between scroller and listview */
1111 #define SCROLLER_SPACING 2
1113 /****************************************************************************************/
1115 struct Gadget *makelistview(struct GadToolsBase_intern *GadToolsBase,
1116 struct TagItem stdgadtags[],
1117 struct VisualInfo *vi,
1118 struct TextAttr *tattr,
1119 const struct TagItem *taglist)
1121 struct Gadget *lvgad = NULL, *showselgad = LV_SHOWSELECTED_NONE;
1122 struct Gadget *scrollergad;
1123 struct IBox bbox;
1126 WORD scroller_width = 16; /* default */
1128 struct TagItem *lv_width_tag, *lv_height_tag;
1129 WORD lv_width, lv_height;
1130 #if CORRECT_LISTVIEWHEIGHT
1131 WORD viewheight;
1132 #endif
1133 WORD ysize, totalitemheight = 0;
1135 struct TagItem *tag, lvtags[] =
1137 {GA_Disabled , FALSE }, /* 0 */
1138 {GTLV_Top , 0L }, /* 1 */
1139 {GTLV_MakeVisible , 0L }, /* 2 */
1140 {GTLV_Labels , (IPTR)NULL }, /* 3 */
1141 {GTLV_Selected , ~0L }, /* 4 */
1142 {GTLV_ItemHeight , 0L }, /* 5 */
1143 {GTLV_CallBack , (IPTR)NULL }, /* 6 */
1144 {GTLV_MaxPen , 0L }, /* 7 */
1145 {GTLV_ReadOnly , 0L }, /* 8 */
1146 {LAYOUTA_Spacing , 0L }, /* 9 */
1147 {GA_TextAttr , (IPTR)NULL }, /* 10 */
1148 {GA_RelVerify , TRUE }, /* 11 */
1149 {GA_Bounds , (IPTR)&bbox }, /* 12 */
1150 {GTLV_ShowSelected , (IPTR)showselgad }, /* 13 */
1151 {TAG_MORE , (IPTR)NULL } /* 14 */
1154 EnterFunc(bug("makelistview()\n"));
1156 /* Could use GetTagData(), but this is faster */
1157 while ((tag = NextTagItem(&taglist)))
1159 IPTR tidata = tag->ti_Data;
1161 switch (tag->ti_Tag)
1163 case GA_Disabled: lvtags[0].ti_Data = tidata; break;
1164 case GTLV_Top: lvtags[1].ti_Data = tidata; break;
1165 case GTLV_MakeVisible: lvtags[2].ti_Data = tidata; break;
1166 case GTLV_Labels: lvtags[3].ti_Data = tidata; break;
1167 case GTLV_Selected: lvtags[4].ti_Data = tidata; break;
1168 case GTLV_ItemHeight: lvtags[5].ti_Data = tidata; break;
1169 case GTLV_CallBack: lvtags[6].ti_Data = tidata; break;
1170 case GTLV_MaxPen: lvtags[7].ti_Data = tidata; break;
1171 case GTLV_ReadOnly: lvtags[8].ti_Data = tidata; break;
1172 case LAYOUTA_Spacing: lvtags[9].ti_Data = tidata; break;
1174 case GTLV_ShowSelected:
1175 showselgad = (struct Gadget *)tidata;
1176 lvtags[13].ti_Data = (IPTR)showselgad;
1177 break;
1179 case GTLV_ScrollWidth: scroller_width = (UWORD)tidata;
1182 } /* while (iterate taglist) */
1184 /* if there is a bounding box the label position
1185 will be calculated based on this box and not
1186 the gadget coords */
1188 bbox.Left = GetTagData(GA_Left, 0, stdgadtags);
1189 bbox.Top = GetTagData(GA_Top, 0, stdgadtags);
1190 bbox.Width = GetTagData(GA_Width, 0, stdgadtags);
1191 bbox.Height = GetTagData(GA_Height, 0, stdgadtags);
1193 /* Callback supplied ? */
1194 if (!lvtags[6].ti_Data)
1195 lvtags[6].ti_Tag = TAG_IGNORE; /* Don't pass GTLV_Callback, NULL */
1197 if (tattr) /* Text Attr supplied ? */
1199 lvtags[10].ti_Data = (IPTR)tattr;
1200 ysize = tattr->ta_YSize;
1202 else
1204 lvtags[10].ti_Tag = TAG_IGNORE; /* Don't pass GA_TextAttr, NULL */
1206 ysize = vi->vi_dri->dri_Font->tf_YSize;
1209 /* If not set allready, set ItemHeight */
1210 if (lvtags[5].ti_Data == 0)
1211 lvtags[5].ti_Data = ysize;
1213 /* If not set allready, set Spacing */
1214 if (lvtags[9].ti_Data == 0)
1215 lvtags[9].ti_Data = LV_DEF_INTERNAL_SPACING;
1217 DEBUG_CREATELISTVIEW(bug("makelistview: item ysize %ld\n", ysize));
1219 /* Find the dimension specific tags */
1220 lv_width_tag = FindTagItem(GA_Width, stdgadtags);
1221 lv_height_tag = FindTagItem(GA_Height, stdgadtags);
1223 lv_width = (WORD)lv_width_tag->ti_Data;
1224 lv_height = (WORD)lv_height_tag->ti_Data;
1227 /* Adjust the listview width according to scroller width + some spacing */
1228 lv_width -= (scroller_width + SCROLLER_SPACING);
1230 /* Adjust the listview height according to showsel gadget height */
1231 if ((showselgad) && (showselgad != LV_SHOWSELECTED_NONE))
1233 /* The showselected string gadget must have the same width as the
1234 listview gadget, otherwise fail (AmigaOS does the same). Fail
1235 also if the showselected string gadget is too high*/
1237 if ((EG(showselgad)->BoundsWidth != bbox.Width) ||
1238 (EG(showselgad)->BoundsHeight >= lv_height))
1240 ReturnPtr ("makelistview", struct Gadget *, NULL);
1243 /* the showselected string gadget shrinks the height of the listview */
1245 lv_height -= EG(showselgad)->BoundsHeight;
1247 /* the showselected string gadget will get its position automatically
1248 fixed to be under the listview gadget */
1250 EG(showselgad)->BoundsLeftEdge = bbox.Left;
1251 EG(showselgad)->BoundsTopEdge = bbox.Top + lv_height;
1252 EG(showselgad)->LeftEdge = EG(showselgad)->BoundsLeftEdge + BORDERSTRINGSPACINGX;
1253 EG(showselgad)->TopEdge = EG(showselgad)->BoundsTopEdge + BORDERSTRINGSPACINGY;
1255 D(bug("makelistview: Showselected gadget specified"));
1259 /* GTLV_ItemHeight + LAYOUTA_Spacing */
1260 totalitemheight = lvtags[5].ti_Data + lvtags[9].ti_Data;
1262 #if CORRECT_LISTVIEWHEIGHT
1263 /* stegerg: I think it looks better without this adjustment. Think of
1264 GTLV_ShowSelected and aligning with other gadgets */
1266 /* Adjust listview height so that an exact number of items fits in it */
1267 viewheight = lv_height - (2 * LV_BORDER_Y);
1268 lv_height -= (viewheight % totalitemheight);
1270 #endif
1272 /* Reinsert the modified dimension attrs into the listview taglist */
1274 D(bug("makelistview: Dimension passed to listview: w=%d, h=%d\n", lv_width, lv_height));
1276 lv_width_tag->ti_Data = (IPTR)lv_width;
1277 lv_height_tag->ti_Data = (IPTR)lv_height;
1279 lvtags[14].ti_Data = (IPTR)stdgadtags;
1281 D(bug("makelistview: Listview class opened\n"));
1282 lvgad = (struct Gadget *)NewObjectA(GadToolsBase->listviewclass, NULL, lvtags);
1283 if (lvgad)
1285 struct TagItem scr_stdtags[] =
1287 {GA_Left , 0L },
1288 {GA_Top , 0L },
1289 {GA_Width , 0L },
1290 {GA_Height , 0L },
1291 {GA_Next , (IPTR)NULL },
1292 {GA_ID , 0L },
1293 {GA_DrawInfo, (IPTR)NULL },
1294 {GA_Previous, (IPTR)NULL },
1295 {TAG_DONE }
1298 struct TagItem scr_specialtags[] =
1300 /* The listview will initialize the scrollers top, visible & total,
1301 ** in its GM_LAYOUT method
1303 {GTSC_Arrows , scroller_width },
1304 {PGA_Freedom , LORIENT_VERT },
1305 {GTA_Scroller_ArrowKind , LISTVIEW_KIND },
1306 {GTA_Scroller_ScrollerKind , LISTVIEW_KIND },
1307 {TAG_DONE }
1310 lvgad->GadgetType |= GTYP_GADTOOLS;
1312 D(bug("makelistview: Listview gadget created: %p\n", lvgad));
1313 D(bug("makelistview: scroller_width %ld\n",scroller_width));
1315 /* Create a scroller object to use with the listviev */
1316 scr_stdtags[0].ti_Data = lvgad->LeftEdge + lvgad->Width - 1 + SCROLLER_SPACING;
1317 scr_stdtags[1].ti_Data = lvgad->TopEdge;
1318 scr_stdtags[2].ti_Data = scroller_width;
1319 scr_stdtags[3].ti_Data = lvgad->Height;
1320 scr_stdtags[4].ti_Data = (IPTR)lvgad;
1321 scr_stdtags[5].ti_Data = lvgad->GadgetID;
1322 scr_stdtags[6].ti_Data = (IPTR)vi->vi_dri;
1323 scr_stdtags[7].ti_Data = (IPTR)GetTagData(GA_Previous, 0, stdgadtags);
1325 scrollergad = makescroller(GadToolsBase, scr_stdtags, vi, scr_specialtags);
1326 if (scrollergad)
1328 struct TagItem lvset_tags[] =
1330 {GTA_Listview_Scroller, (IPTR)NULL },
1331 {TAG_DONE, }
1333 struct TagItem scrnotify_tags[] =
1335 {ICA_TARGET , (IPTR)NULL },
1336 {ICA_MAP , (IPTR)NULL },
1337 {TAG_DONE }
1339 struct Gadget *prop_of_scrollergad;
1341 D(bug("makelistview: Scroller gadget created: %p\n", scrollergad));
1343 /* the scrollergadget is a multigadget gadget: arrowinc->arrowdec->prop */
1344 #warning This relies on scroller gadget to always contain arrow gadgets
1345 #warning 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 /****************************************************************************************/