2 Copyright © 2002-2012, The AROS Development Team. All rights reserved.
9 #include <exec/memory.h>
10 #include <graphics/gfx.h>
11 #include <graphics/view.h>
12 #include <devices/rawkeycodes.h>
13 #include <clib/alib_protos.h>
14 #include <proto/exec.h>
15 #include <proto/graphics.h>
16 #include <proto/utility.h>
17 #include <proto/dos.h>
18 #include <proto/intuition.h>
19 #include <proto/muimaster.h>
21 /* #define MYDEBUG 1 */
24 #include "muimaster_intern.h"
27 #include "textengine.h"
28 #include "listimage.h"
31 extern struct Library
*MUIMasterBase
;
33 #define ENTRY_TITLE (-1)
35 #define FORMAT_TEMPLATE "DELTA=D/N,PREPARSE=P/K,WEIGHT=W/N,MINWIDTH=MIW/N," \
36 "MAXWIDTH=MAW/N,COL=C/N,BAR/S"
56 LONG
*widths
; /* Widths of the columns */
57 LONG width
; /* Line width */
58 LONG height
; /* Line height */
59 WORD flags
; /* see below */
65 int colno
; /* Column number */
66 int user_width
; /* user set width; -1 if entry width */
67 int min_width
; /* min width percentage */
68 int max_width
; /* min width percentage */
70 int delta
; /* ignored for the first and last column, defaults to 4 */
73 int entries_width
; /* width of the entries (maximum of all widths) */
76 struct MUI_ImageSpec_intern
;
83 APTR intern_pool
; /* The internal pool which the class has allocated */
84 LONG intern_puddle_size
;
85 LONG intern_tresh_size
;
86 APTR pool
; /* the pool which is used to allocate list entries */
88 struct Hook
*construct_hook
;
89 struct Hook
*compare_hook
;
90 struct Hook
*destruct_hook
;
91 struct Hook
*display_hook
;
93 struct Hook default_compare_hook
;
95 /* List managment, currently we use a simple flat array, which is not
96 * good if many entries are inserted/deleted */
97 LONG entries_num
; /* Number of Entries in the list */
98 LONG entries_allocated
;
99 struct ListEntry
**entries
;
101 LONG entries_first
; /* first visible entry */
102 LONG entries_visible
; /* number of visible entries,
103 * determined at MUIM_Layout */
105 LONG insert_position
; /* pos of the last insertion */
107 LONG entry_maxheight
; /* Maximum height of an entry */
108 ULONG entry_minheight
; /* from MUIA_List_MinLineHeight */
110 LONG entries_totalheight
;
111 LONG entries_maxwidth
;
113 LONG vertprop_entries
;
114 LONG vertprop_visible
;
117 LONG confirm_entries_num
; /* These are the correct entries num, used
118 * so you cannot set MUIA_List_Entries to
121 LONG entries_top_pixel
; /* Where the entries start */
123 /* Column managment, is allocated by ParseListFormat() and freed
124 * by CleanListFormat() */
126 LONG columns
; /* Number of columns the list has */
127 struct ColumnInfo
*ci
;
129 STRPTR
*strings
; /* the strings for the display function, one
130 * more than needed (for the entry position) */
133 int title_height
; /* The complete height of the title */
134 STRPTR title
; /* On single comlums this is the title, otherwise 1 */
136 struct MUI_EventHandlerNode ehn
;
137 int mouse_click
; /* see below if mouse is hold down */
140 struct MUI_ImageSpec_intern
*list_cursor
;
141 struct MUI_ImageSpec_intern
*list_select
;
142 struct MUI_ImageSpec_intern
*list_selcur
;
144 /* Render optimization */
145 int update
; /* 1 - update everything, 2 - redraw entry at update_pos,
146 * 3 - scroll to current entries_first (old value is in
160 ULONG input
; /* FALSE - readonly, otherwise TRUE */
163 struct MinList images
;
166 ListviewMulti prefs_multi
;
167 ListviewRefresh prefs_refresh
;
168 UWORD prefs_linespacing
;
170 UWORD prefs_smoothval
;
173 #define LIST_ADJUSTWIDTH (1<<0)
174 #define LIST_ADJUSTHEIGHT (1<<1)
175 #define LIST_AUTOVISIBLE (1<<2)
176 #define LIST_DRAGSORTABLE (1<<3)
177 #define LIST_SHOWDROPMARKS (1<<4)
178 #define LIST_QUIET (1<<5)
181 #define MOUSE_CLICK_ENTRY 1 /* on entry clicked */
182 #define MOUSE_CLICK_TITLE 2 /* on title clicked */
184 /**************************************************************************
185 Allocate a single list entry, does not initialize it (except the pointer)
186 **************************************************************************/
187 static struct ListEntry
*AllocListEntry(struct MUI_ListData
*data
)
190 struct ListEntry
*le
;
191 int size
= sizeof(struct ListEntry
) + sizeof(LONG
) * data
->columns
+ 4;
195 mem
= AllocPooled(data
->pool
, size
);
198 D(bug("List AllocListEntry %p, %ld bytes\n", mem
, size
));
200 mem
[0] = size
; /* Save the size */
201 le
= (struct ListEntry
*)(mem
+ 1);
202 le
->widths
= (LONG
*) (le
+ 1);
204 /* Initialize fields */
207 for (j
= 0; j
< data
->columns
; j
++)
213 /**************************************************************************
214 Deallocate a single list entry, does not deinitialize it
215 **************************************************************************/
216 static void FreeListEntry(struct MUI_ListData
*data
,
217 struct ListEntry
*entry
)
219 ULONG
*mem
= ((ULONG
*) entry
) - 1;
220 D(bug("FreeListEntry %p size=%ld\n", mem
, mem
[0]));
221 FreePooled(data
->pool
, mem
, mem
[0]);
224 /**************************************************************************
225 Ensures that we there can be at least the given amount of entries within
226 the list. Returns 0 if not. It also allocates the space for the title.
227 It can be accesses with data->entries[ENTRY_TITLE]
228 **************************************************************************/
229 static int SetListSize(struct MUI_ListData
*data
, LONG size
)
231 struct ListEntry
**new_entries
;
232 int new_entries_allocated
;
234 if (size
+ 1 <= data
->entries_allocated
)
237 new_entries_allocated
= data
->entries_allocated
* 2 + 4;
238 if (new_entries_allocated
< size
+ 1)
239 new_entries_allocated
= size
+ 1 + 10; /* 10 is just random */
241 D(bug("List %p : SetListSize allocating %ld bytes\n", data
,
242 new_entries_allocated
* sizeof(struct ListEntry
*)));
244 AllocVec(new_entries_allocated
* sizeof(struct ListEntry
*), 0);
245 if (NULL
== new_entries
)
249 CopyMem(data
->entries
- 1, new_entries
,
250 (data
->entries_num
+ 1) * sizeof(struct ListEntry
*));
251 FreeVec(data
->entries
- 1);
253 data
->entries
= new_entries
+ 1;
254 data
->entries_allocated
= new_entries_allocated
;
258 /**************************************************************************
259 Prepares the insertion of count entries at pos.
260 This function doesn't care if there is enough space in the datastructure.
261 SetListSize() must be used first.
262 With current implementation, this call will never fail
263 **************************************************************************/
264 static int PrepareInsertListEntries(struct MUI_ListData
*data
, int pos
,
267 memmove(&data
->entries
[pos
+ count
], &data
->entries
[pos
],
268 (data
->entries_num
- pos
) * sizeof(struct ListEntry
*));
272 /**************************************************************************
273 Inserts a already initialized array of Entries at the given position.
274 This function doesn't care if there is enough space in the datastructure
275 Returns 1 if something failed (never in current implementation)
276 **************************************************************************/
278 static int InsertListEntries(struct MUI_ListData
*data
, int pos
,
279 struct ListEntry
**array
, int count
)
281 memmove(&data
->entries
[pos
+ count
], &data
->entries
[pos
],
282 data
->entries_num
- pos
);
283 memcpy(&data
->entries
[pos
], array
, count
);
289 /**************************************************************************
290 Removes count (already deinitalized) list entries starting az pos.
291 **************************************************************************/
292 static void RemoveListEntries(struct MUI_ListData
*data
, int pos
, int count
)
294 // FIXME: segfault if entries_num = pos = count = 1
295 memmove(&data
->entries
[pos
], &data
->entries
[pos
+ count
],
296 (data
->entries_num
- (pos
+ count
)) * sizeof(struct ListEntry
*));
299 /**************************************************************************
300 Frees all memory allocated by ParseListFormat()
301 **************************************************************************/
302 static void FreeListFormat(struct MUI_ListData
*data
)
308 for (i
= 0; i
< data
->columns
; i
++)
310 FreeVec(data
->ci
[i
].preparse
);
311 data
->ci
[i
].preparse
= NULL
;
318 FreeVec(data
->preparses
);
319 data
->preparses
= NULL
;
323 FreeVec(data
->strings
- 1);
324 data
->strings
= NULL
;
329 /**************************************************************************
330 Parses the given format string (also frees a previouly parsed format).
332 **************************************************************************/
333 static int ParseListFormat(struct MUI_ListData
*data
, STRPTR format
)
341 struct RDArgs
*rdargs
;
344 format
= (STRPTR
) "";
348 FreeListFormat(data
);
352 /* Count the number of columns first */
357 if (!(data
->preparses
=
358 AllocVec((new_columns
+ 10) * sizeof(STRPTR
), 0)))
361 if (!(data
->strings
= AllocVec((new_columns
+ 1 + 10)
362 * sizeof(STRPTR
), 0))) /* hold enough space also for the entry pos,
363 * used by orginal MUI and also some
367 if (!(data
->ci
= AllocVec(new_columns
* sizeof(struct ColumnInfo
), 0)))
371 for (i
= 0; i
< new_columns
; i
++)
373 data
->ci
[i
].colno
= -1; // -1 means: use unassigned column
374 data
->ci
[i
].weight
= 100;
375 data
->ci
[i
].delta
= 4;
376 data
->ci
[i
].min_width
= -1;
377 data
->ci
[i
].max_width
= -1;
378 data
->ci
[i
].user_width
= -1;
379 data
->ci
[i
].bar
= FALSE
;
380 data
->ci
[i
].preparse
= NULL
;
383 if ((format_sep
= StrDup(format
)) != 0)
385 for (i
= 0; format_sep
[i
] != '\0'; i
++)
387 if (format_sep
[i
] == ',')
388 format_sep
[i
] = '\0';
391 if ((rdargs
= AllocDosObject(DOS_RDARGS
, NULL
)) != 0)
397 rdargs
->RDA_Source
.CS_Buffer
= ptr
;
398 rdargs
->RDA_Source
.CS_Length
= strlen(ptr
);
399 rdargs
->RDA_Source
.CS_CurChr
= 0;
400 rdargs
->RDA_DAList
= 0;
401 rdargs
->RDA_Buffer
= NULL
;
402 rdargs
->RDA_BufSiz
= 0;
403 rdargs
->RDA_ExtHelp
= NULL
;
404 rdargs
->RDA_Flags
= 0;
406 memset(args
, 0, sizeof args
);
407 if (ReadArgs(FORMAT_TEMPLATE
, args
, rdargs
))
410 data
->ci
[i
].colno
= *(LONG
*) args
[ARG_COL
];
411 if (args
[ARG_WEIGHT
])
412 data
->ci
[i
].weight
= *(LONG
*) args
[ARG_WEIGHT
];
414 data
->ci
[i
].delta
= *(LONG
*) args
[ARG_DELTA
];
415 if (args
[ARG_MINWIDTH
])
416 data
->ci
[i
].min_width
=
417 *(LONG
*) args
[ARG_MINWIDTH
];
418 if (args
[ARG_MAXWIDTH
])
419 data
->ci
[i
].max_width
=
420 *(LONG
*) args
[ARG_MAXWIDTH
];
421 data
->ci
[i
].bar
= args
[ARG_BAR
];
422 if (args
[ARG_PREPARSE
])
423 data
->ci
[i
].preparse
=
424 StrDup((STRPTR
) args
[ARG_PREPARSE
]);
428 ptr
+= strlen(ptr
) + 1;
431 while (i
< new_columns
);
432 FreeDosObject(DOS_RDARGS
, rdargs
);
437 for (i
= 0; i
< new_columns
; i
++)
439 D(bug("colno %d weight %d delta %d preparse %s\n",
440 data
->ci
[i
].colno
, data
->ci
[i
].weight
, data
->ci
[i
].delta
,
441 data
->ci
[i
].preparse
));
444 data
->columns
= new_columns
;
445 data
->strings
++; /* Skip entry pos */
450 /**************************************************************************
451 Call the MUIM_List_Display for the given entry. It fills out
452 data->string and data->preparses
453 **************************************************************************/
454 static void DisplayEntry(struct IClass
*cl
, Object
*obj
, int entry_pos
)
456 struct MUI_ListData
*data
= INST_DATA(cl
, obj
);
460 for (col
= 0; col
< data
->columns
; col
++)
461 data
->preparses
[col
] = data
->ci
[col
].preparse
;
463 if (entry_pos
== ENTRY_TITLE
)
465 if ((data
->columns
== 1) && (data
->title
!= (STRPTR
) 1))
467 *data
->strings
= data
->title
;
470 entry_data
= NULL
; /* it's a title request */
473 entry_data
= data
->entries
[entry_pos
]->data
;
475 /* Get the display formation */
476 DoMethod(obj
, MUIM_List_Display
, (IPTR
) entry_data
,
477 (IPTR
) data
->strings
, entry_pos
, (IPTR
) data
->preparses
);
480 /**************************************************************************
481 Determine the dims of a single entry and adapt the columinfo according
482 to it. pos might be ENTRY_TITLE. Returns 0 if pos entry needs to
483 be redrawn after this operation, 1 if all entries need to be redrawn.
484 **************************************************************************/
485 static int CalcDimsOfEntry(struct IClass
*cl
, Object
*obj
, int pos
)
487 struct MUI_ListData
*data
= INST_DATA(cl
, obj
);
488 struct ListEntry
*entry
= data
->entries
[pos
];
495 if (!(_flags(obj
) & MADF_SETUP
))
498 DisplayEntry(cl
, obj
, pos
);
500 /* Set height to at least minheight */
501 if (data
->entries
[pos
]->height
< data
->entry_minheight
)
502 data
->entries
[pos
]->height
= data
->entry_minheight
;
504 for (j
= 0; j
< data
->columns
; j
++)
507 zune_text_new(data
->preparses
[j
], data
->strings
[j
],
511 zune_text_get_bounds(text
, obj
);
513 if (text
->height
> data
->entries
[pos
]->height
)
515 data
->entries
[pos
]->height
= text
->height
;
516 /* entry height changed, redraw all entries later */
519 data
->entries
[pos
]->widths
[j
] = text
->width
;
521 if (text
->width
> data
->ci
[j
].entries_width
)
523 /* This columns width is bigger than the other in the same
524 * columns, so we store this value
526 data
->ci
[j
].entries_width
= text
->width
;
527 /* column width changed, redraw all entries later */
531 zune_text_destroy(text
);
534 if (data
->entries
[pos
]->height
> data
->entry_maxheight
)
536 data
->entry_maxheight
= data
->entries
[pos
]->height
;
537 /* maximum entry height changed, redraw all entries later */
544 /**************************************************************************
545 Determine the widths of the entries
546 **************************************************************************/
547 static void CalcWidths(struct IClass
*cl
, Object
*obj
)
550 struct MUI_ListData
*data
= INST_DATA(cl
, obj
);
552 if (!(_flags(obj
) & MADF_SETUP
))
555 for (j
= 0; j
< data
->columns
; j
++)
556 data
->ci
[j
].entries_width
= 0;
558 data
->entry_maxheight
= 0;
559 data
->entries_totalheight
= 0;
560 data
->entries_maxwidth
= 0;
562 for (i
= (data
->title
? ENTRY_TITLE
: 0); i
< data
->entries_num
; i
++)
564 CalcDimsOfEntry(cl
, obj
, i
);
565 data
->entries_totalheight
+= data
->entries
[i
]->height
;
568 for (j
= 0; j
< data
->columns
; j
++)
569 data
->entries_maxwidth
+= data
->ci
[j
].entries_width
;
571 if (!data
->entry_maxheight
)
572 data
->entry_maxheight
= 1;
575 /**************************************************************************
576 Calculates the number of visible entry lines. Returns 1 if it has
578 **************************************************************************/
579 static int CalcVertVisible(struct IClass
*cl
, Object
*obj
)
581 struct MUI_ListData
*data
= INST_DATA(cl
, obj
);
582 int old_entries_visible
= data
->entries_visible
;
583 int old_entries_top_pixel
= data
->entries_top_pixel
;
585 data
->entries_visible
= (_mheight(obj
) - data
->title_height
)
586 / (data
->entry_maxheight
/* + data->prefs_linespacing */ );
588 data
->entries_top_pixel
= _mtop(obj
) + data
->title_height
589 + (_mheight(obj
) - data
->title_height
591 data
->entries_visible
*
592 (data
->entry_maxheight
/* + data->prefs_linespacing */ )) / 2;
594 return (old_entries_visible
!= data
->entries_visible
)
595 || (old_entries_top_pixel
!= data
->entries_top_pixel
);
598 /**************************************************************************
599 Default hook to compare two list entries. Works for strings only.
600 **************************************************************************/
601 AROS_UFH3S(int, default_compare_func
,
602 AROS_UFHA(struct Hook
*, h
, A0
),
603 AROS_UFHA(char *, s2
, A2
),
604 AROS_UFHA(char *, s1
, A1
))
608 return Stricmp(s1
, s2
);
613 /**************************************************************************
615 **************************************************************************/
616 IPTR
List__OM_NEW(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
618 struct MUI_ListData
*data
;
620 struct TagItem
*tags
;
622 LONG new_entries_active
= MUIV_List_Active_Off
;
624 obj
= (Object
*) DoSuperNewTags(cl
, obj
, NULL
,
625 MUIA_Font
, MUIV_Font_List
,
626 MUIA_Background
, MUII_ListBack
, TAG_MORE
, (IPTR
) msg
->ops_AttrList
);
630 data
= INST_DATA(cl
, obj
);
633 data
->entries_active
= MUIV_List_Active_Off
;
634 data
->intern_puddle_size
= 2008;
635 data
->intern_tresh_size
= 1024;
637 data
->default_compare_hook
.h_Entry
= (HOOKFUNC
) default_compare_func
;
638 data
->default_compare_hook
.h_SubEntry
= 0;
639 data
->compare_hook
= &(data
->default_compare_hook
);
641 /* parse initial taglist */
642 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
));)
646 case MUIA_List_Active
:
647 new_entries_active
= tag
->ti_Data
;
651 data
->pool
= (APTR
) tag
->ti_Data
;
654 case MUIA_List_PoolPuddleSize
:
655 data
->intern_puddle_size
= tag
->ti_Data
;
658 case MUIA_List_PoolThreshSize
:
659 data
->intern_tresh_size
= tag
->ti_Data
;
662 case MUIA_List_CompareHook
:
663 /* Not tested, if List_CompareHook really works. */
664 data
->compare_hook
= (struct Hook
*)tag
->ti_Data
;
667 case MUIA_List_ConstructHook
:
668 data
->construct_hook
= (struct Hook
*)tag
->ti_Data
;
671 case MUIA_List_DestructHook
:
672 data
->destruct_hook
= (struct Hook
*)tag
->ti_Data
;
675 case MUIA_List_DisplayHook
:
676 data
->display_hook
= (struct Hook
*)tag
->ti_Data
;
679 case MUIA_List_SourceArray
:
680 array
= (APTR
*) tag
->ti_Data
;
683 case MUIA_List_Format
:
684 data
->format
= StrDup((STRPTR
) tag
->ti_Data
);
687 case MUIA_List_Title
:
688 data
->title
= (STRPTR
) tag
->ti_Data
;
691 case MUIA_List_MinLineHeight
:
692 data
->entry_minheight
= tag
->ti_Data
;
695 case MUIA_List_AdjustHeight
:
696 _handle_bool_tag(data
->flags
, tag
->ti_Data
, LIST_ADJUSTHEIGHT
);
699 case MUIA_List_AdjustWidth
:
700 _handle_bool_tag(data
->flags
, tag
->ti_Data
, LIST_ADJUSTWIDTH
);
708 /* No memory pool given, so we create our own */
709 data
->pool
= data
->intern_pool
=
710 CreatePool(0, data
->intern_puddle_size
,
711 data
->intern_tresh_size
);
714 CoerceMethod(cl
, obj
, OM_DISPOSE
);
719 /* parse the list format */
720 if (!(ParseListFormat(data
, data
->format
)))
722 CoerceMethod(cl
, obj
, OM_DISPOSE
);
726 /* This is neccessary for at least the title */
727 if (!SetListSize(data
, 0))
729 CoerceMethod(cl
, obj
, OM_DISPOSE
);
735 if (!(data
->entries
[ENTRY_TITLE
] = AllocListEntry(data
)))
737 CoerceMethod(cl
, obj
, OM_DISPOSE
);
742 data
->entries
[ENTRY_TITLE
] = NULL
;
748 /* Count the number of elements */
749 for (i
= 0; array
[i
] != NULL
; i
++)
752 DoMethod(obj
, MUIM_List_Insert
, (IPTR
) array
, i
,
753 MUIV_List_Insert_Top
);
757 if ((data
->entries_num
) && (new_entries_active
!= MUIV_List_Active_Off
))
759 switch (new_entries_active
)
761 case MUIV_List_Active_Top
:
762 new_entries_active
= 0;
765 case MUIV_List_Active_Bottom
:
766 new_entries_active
= data
->entries_num
- 1;
770 if (new_entries_active
< 0)
771 new_entries_active
= 0;
772 else if (new_entries_active
>= data
->entries_num
)
773 new_entries_active
= data
->entries_num
- 1;
775 data
->entries_active
= new_entries_active
;
776 /* Selected entry will be moved into visible area */
780 data
->ehn
.ehn_Events
= IDCMP_MOUSEBUTTONS
|
781 IDCMP_RAWKEY
| IDCMP_ACTIVEWINDOW
| IDCMP_INACTIVEWINDOW
;
782 data
->ehn
.ehn_Priority
= 0;
783 data
->ehn
.ehn_Flags
= 0;
784 data
->ehn
.ehn_Object
= obj
;
785 data
->ehn
.ehn_Class
= cl
;
787 NewList((struct List
*)&data
->images
);
789 D(bug("List_New(%lx)\n", obj
));
794 /**************************************************************************
796 **************************************************************************/
797 IPTR
List__OM_DISPOSE(struct IClass
*cl
, Object
*obj
, Msg msg
)
799 struct MUI_ListData
*data
= INST_DATA(cl
, obj
);
801 D(bug("List Dispose\n"));
803 /* Call destruct method for every entry and free the entries manually
804 * to avoid notification */
805 while (data
->confirm_entries_num
)
807 struct ListEntry
*lentry
=
808 data
->entries
[--data
->confirm_entries_num
];
809 DoMethod(obj
, MUIM_List_Destruct
, (IPTR
) lentry
->data
,
811 FreeListEntry(data
, lentry
);
814 if (data
->intern_pool
)
815 DeletePool(data
->intern_pool
);
817 FreeVec(data
->entries
- 1);
818 /* title is currently before all other elements */
820 FreeListFormat(data
);
821 FreeVec(data
->format
);
823 return DoSuperMethodA(cl
, obj
, msg
);
827 /**************************************************************************
829 **************************************************************************/
830 IPTR
List__OM_SET(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
832 struct MUI_ListData
*data
= INST_DATA(cl
, obj
);
834 struct TagItem
*tags
;
836 /* parse initial taglist */
837 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
));)
841 case MUIA_List_CompareHook
:
842 data
->compare_hook
= (struct Hook
*)tag
->ti_Data
;
845 case MUIA_List_ConstructHook
:
846 data
->construct_hook
= (struct Hook
*)tag
->ti_Data
;
849 case MUIA_List_DestructHook
:
850 data
->destruct_hook
= (struct Hook
*)tag
->ti_Data
;
853 case MUIA_List_DisplayHook
:
854 data
->display_hook
= (struct Hook
*)tag
->ti_Data
;
857 case MUIA_List_VertProp_First
:
858 data
->vertprop_first
= tag
->ti_Data
;
859 if (data
->entries_first
!= tag
->ti_Data
)
861 set(obj
, MUIA_List_First
, tag
->ti_Data
);
865 case MUIA_List_Format
:
866 data
->format
= StrDup((STRPTR
) tag
->ti_Data
);
867 ParseListFormat(data
, data
->format
);
868 // FIXME: should we check for errors?
869 DoMethod(obj
, MUIM_List_Redraw
, MUIV_List_Redraw_All
);
872 case MUIA_List_VertProp_Entries
:
873 data
->vertprop_entries
= tag
->ti_Data
;
876 case MUIA_List_VertProp_Visible
:
877 data
->vertprop_visible
= tag
->ti_Data
;
878 data
->entries_visible
= tag
->ti_Data
;
881 case MUIA_List_Active
:
883 LONG new_entries_active
= tag
->ti_Data
;
885 if ((data
->entries_num
)
886 && (new_entries_active
!= MUIV_List_Active_Off
))
888 switch (new_entries_active
)
890 case MUIV_List_Active_Top
:
891 new_entries_active
= 0;
894 case MUIV_List_Active_Bottom
:
895 new_entries_active
= data
->entries_num
- 1;
898 case MUIV_List_Active_Up
:
899 new_entries_active
= data
->entries_active
- 1;
902 case MUIV_List_Active_Down
:
903 new_entries_active
= data
->entries_active
+ 1;
906 case MUIV_List_Active_PageUp
:
908 data
->entries_active
- data
->entries_visible
;
911 case MUIV_List_Active_PageDown
:
913 data
->entries_active
+ data
->entries_visible
;
917 if (new_entries_active
< 0)
918 new_entries_active
= 0;
919 else if (new_entries_active
>= data
->entries_num
)
920 new_entries_active
= data
->entries_num
- 1;
923 new_entries_active
= -1;
925 if (data
->entries_active
!= new_entries_active
)
927 LONG old
= data
->entries_active
;
928 data
->entries_active
= new_entries_active
;
931 data
->update_pos
= old
;
932 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
934 data
->update_pos
= data
->entries_active
;
935 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
937 /* Selectchange stuff */
940 DoMethod(obj
, MUIM_List_SelectChange
, old
,
941 MUIV_List_Select_Off
, 0);
944 if (new_entries_active
!= -1)
946 DoMethod(obj
, MUIM_List_SelectChange
,
947 new_entries_active
, MUIV_List_Select_On
, 0);
948 DoMethod(obj
, MUIM_List_SelectChange
,
949 new_entries_active
, MUIV_List_Select_Active
, 0);
952 DoMethod(obj
, MUIM_List_SelectChange
,
953 MUIV_List_Active_Off
, MUIV_List_Select_Off
, 0);
955 set(obj
, MUIA_Listview_SelectChange
, TRUE
);
957 if (new_entries_active
!= -1)
959 DoMethod(obj
, MUIM_List_Jump
,
960 MUIV_List_Jump_Active
);
966 case MUIA_List_First
:
967 data
->update_pos
= data
->entries_first
;
969 data
->entries_first
= tag
->ti_Data
;
971 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
972 if (data
->vertprop_first
!= tag
->ti_Data
)
974 set(obj
, MUIA_List_VertProp_First
, tag
->ti_Data
);
978 case MUIA_List_Visible
:
979 if (data
->vertprop_visible
!= tag
->ti_Data
)
980 set(obj
, MUIA_List_VertProp_Visible
, tag
->ti_Data
);
983 case MUIA_List_Entries
:
984 if (data
->confirm_entries_num
== tag
->ti_Data
)
986 data
->entries_num
= tag
->ti_Data
;
987 set(obj
, MUIA_List_VertProp_Entries
, data
->entries_num
);
991 D(bug("Bug: confirm_entries != MUIA_List_Entries!\n"));
995 case MUIA_List_Quiet
:
996 _handle_bool_tag(data
->flags
, tag
->ti_Data
, LIST_QUIET
);
999 DoMethod(obj
, MUIM_List_Redraw
, MUIV_List_Redraw_All
);
1003 case MUIA_Listview_ClickColumn
:
1004 data
->click_column
= tag
->ti_Data
;
1009 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
1012 /**************************************************************************
1014 **************************************************************************/
1015 IPTR
List__OM_GET(struct IClass
*cl
, Object
*obj
, struct opGet
*msg
)
1017 /* small macro to simplify return value storage */
1018 #define STORE *(msg->opg_Storage)
1019 struct MUI_ListData
*data
= INST_DATA(cl
, obj
);
1021 switch (msg
->opg_AttrID
)
1023 case MUIA_List_Entries
:
1024 STORE
= data
->entries_num
;
1026 case MUIA_List_First
:
1027 STORE
= data
->entries_first
;
1029 case MUIA_List_Active
:
1030 STORE
= data
->entries_active
;
1032 case MUIA_List_InsertPosition
:
1033 STORE
= data
->insert_position
;
1035 case MUIA_List_Title
:
1036 STORE
= (unsigned long)data
->title
;
1038 case MUIA_List_VertProp_Entries
:
1039 STORE
= data
->vertprop_entries
;
1041 case MUIA_List_VertProp_Visible
:
1042 STORE
= data
->vertprop_visible
;
1044 case MUIA_List_VertProp_First
:
1045 STORE
= data
->vertprop_first
;
1047 case MUIA_List_Format
:
1048 STORE
= (IPTR
) data
->format
;
1051 case MUIA_Listview_DoubleClick
:
1054 case MUIA_Listview_ClickColumn
:
1055 STORE
= data
->click_column
;
1057 case MUIA_Listview_List
:
1059 return 1; /* Validated with 3rd party application */
1062 if (DoSuperMethodA(cl
, obj
, (Msg
) msg
))
1068 /**************************************************************************
1070 **************************************************************************/
1071 IPTR
List__MUIM_Setup(struct IClass
*cl
, Object
*obj
,
1072 struct MUIP_Setup
*msg
)
1074 struct MUI_ListData
*data
= INST_DATA(cl
, obj
);
1076 if (!DoSuperMethodA(cl
, obj
, (Msg
) msg
))
1079 data
->prefs_multi
= muiGlobalInfo(obj
)->mgi_Prefs
->list_multi
;
1080 data
->prefs_refresh
= muiGlobalInfo(obj
)->mgi_Prefs
->list_refresh
;
1081 data
->prefs_linespacing
=
1082 muiGlobalInfo(obj
)->mgi_Prefs
->list_linespacing
;
1083 data
->prefs_smoothed
= muiGlobalInfo(obj
)->mgi_Prefs
->list_smoothed
;
1084 data
->prefs_smoothval
= muiGlobalInfo(obj
)->mgi_Prefs
->list_smoothval
;
1086 CalcWidths(cl
, obj
);
1090 data
->title_height
= data
->entries
[ENTRY_TITLE
]->height
+ 2;
1094 data
->title_height
= 0;
1097 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
, (IPTR
) & data
->ehn
);
1100 zune_imspec_setup(MUII_ListCursor
, muiRenderInfo(obj
));
1102 zune_imspec_setup(MUII_ListSelect
, muiRenderInfo(obj
));
1104 zune_imspec_setup(MUII_ListSelCur
, muiRenderInfo(obj
));
1109 /**************************************************************************
1111 **************************************************************************/
1112 IPTR
List__MUIM_Cleanup(struct IClass
*cl
, Object
*obj
,
1113 struct MUIP_Cleanup
*msg
)
1115 struct MUI_ListData
*data
= INST_DATA(cl
, obj
);
1116 struct ListImage
*li
= List_First(&data
->images
);
1120 struct ListImage
*next
= Node_Next(li
);
1121 DoMethod(obj
, MUIM_List_DeleteImage
, (IPTR
) li
);
1125 zune_imspec_cleanup(data
->list_cursor
);
1126 zune_imspec_cleanup(data
->list_select
);
1127 zune_imspec_cleanup(data
->list_selcur
);
1129 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, (IPTR
) & data
->ehn
);
1130 data
->ehn
.ehn_Events
&= ~(IDCMP_MOUSEMOVE
| IDCMP_INTUITICKS
);
1131 data
->mouse_click
= 0;
1133 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
1136 /**************************************************************************
1138 **************************************************************************/
1139 IPTR
List__MUIM_AskMinMax(struct IClass
*cl
, Object
*obj
,
1140 struct MUIP_AskMinMax
*msg
)
1142 struct MUI_ListData
*data
= INST_DATA(cl
, obj
);
1144 DoSuperMethodA(cl
, obj
, (Msg
) msg
);
1147 if ((data
->flags
& LIST_ADJUSTWIDTH
) && (data
->entries_num
> 0))
1149 msg
->MinMaxInfo
->MinWidth
+= data
->entries_maxwidth
;
1150 msg
->MinMaxInfo
->DefWidth
+= data
->entries_maxwidth
;
1151 msg
->MinMaxInfo
->MaxWidth
+= data
->entries_maxwidth
;
1155 msg
->MinMaxInfo
->MinWidth
+= 40;
1156 msg
->MinMaxInfo
->DefWidth
+= 100;
1157 msg
->MinMaxInfo
->MaxWidth
= MUI_MAXMAX
;
1160 if (data
->entries_num
> 0)
1162 if (data
->flags
& LIST_ADJUSTHEIGHT
)
1164 msg
->MinMaxInfo
->MinHeight
+= data
->entries_totalheight
;
1165 msg
->MinMaxInfo
->DefHeight
+= data
->entries_totalheight
;
1166 msg
->MinMaxInfo
->MaxHeight
+= data
->entries_totalheight
;
1170 ULONG h
= data
->entry_maxheight
+ data
->prefs_linespacing
;
1171 msg
->MinMaxInfo
->MinHeight
+= 2 * h
+ data
->prefs_linespacing
;
1172 msg
->MinMaxInfo
->DefHeight
+= 8 * h
+ data
->prefs_linespacing
;
1173 msg
->MinMaxInfo
->MaxHeight
= MUI_MAXMAX
;
1178 msg
->MinMaxInfo
->MinHeight
+= 36;
1179 msg
->MinMaxInfo
->DefHeight
+= 96;
1180 msg
->MinMaxInfo
->MaxHeight
= MUI_MAXMAX
;
1182 D(bug("List %p minheigh=%d, line maxh=%d\n",
1183 obj
, msg
->MinMaxInfo
->MinHeight
, data
->entry_maxheight
));
1187 /**************************************************************************
1189 **************************************************************************/
1190 IPTR
List__MUIM_Layout(struct IClass
*cl
, Object
*obj
,
1191 struct MUIP_Layout
*msg
)
1193 struct MUI_ListData
*data
= INST_DATA(cl
, obj
);
1194 ULONG rc
= DoSuperMethodA(cl
, obj
, (Msg
) msg
);
1195 LONG new_entries_first
= data
->entries_first
;
1197 /* Calc the numbers of entries visible */
1198 CalcVertVisible(cl
, obj
);
1200 #if 0 /* Don't do this! */
1201 if (data
->entries_active
< new_entries_first
)
1202 new_entries_first
= data
->entries_active
;
1205 if (data
->entries_active
+ 1 >=
1206 (data
->entries_first
+ data
->entries_visible
))
1208 data
->entries_active
- data
->entries_visible
+ 1;
1210 if ((new_entries_first
+ data
->entries_visible
>=
1212 && (data
->entries_visible
<= data
->entries_num
))
1213 new_entries_first
= data
->entries_num
- data
->entries_visible
;
1215 if (data
->entries_num
<= data
->entries_visible
)
1216 new_entries_first
= 0;
1218 if (new_entries_first
< 0)
1219 new_entries_first
= 0;
1221 set(obj
, new_entries_first
!= data
->entries_first
?
1222 MUIA_List_First
: TAG_IGNORE
, new_entries_first
);
1224 /* So the notify takes happens */
1225 set(obj
, MUIA_List_VertProp_Visible
, data
->entries_visible
);
1231 /**************************************************************************
1233 **************************************************************************/
1234 IPTR
List__MUIM_Show(struct IClass
*cl
, Object
*obj
,
1235 struct MUIP_Show
*msg
)
1237 struct MUI_ListData
*data
= INST_DATA(cl
, obj
);
1238 ULONG rc
= DoSuperMethodA(cl
, obj
, (Msg
) msg
);
1240 zune_imspec_show(data
->list_cursor
, obj
);
1241 zune_imspec_show(data
->list_select
, obj
);
1242 zune_imspec_show(data
->list_selcur
, obj
);
1247 /**************************************************************************
1249 **************************************************************************/
1250 IPTR
List__MUIM_Hide(struct IClass
*cl
, Object
*obj
,
1251 struct MUIP_Hide
*msg
)
1253 struct MUI_ListData
*data
= INST_DATA(cl
, obj
);
1256 if (data
->ehn
.ehn_Events
& (IDCMP_MOUSEMOVE
| IDCMP_INTUITICKS
))
1258 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
,
1259 (IPTR
) & data
->ehn
);
1260 data
->ehn
.ehn_Events
&= ~(IDCMP_MOUSEMOVE
| IDCMP_INTUITICKS
);
1261 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
,
1262 (IPTR
) & data
->ehn
);
1264 data
->mouse_click
= 0;
1267 zune_imspec_hide(data
->list_cursor
);
1268 zune_imspec_hide(data
->list_select
);
1269 zune_imspec_hide(data
->list_selcur
);
1271 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
1275 /**************************************************************************
1276 Draw an entry at entry_pos at the given y location. To draw the title,
1277 set pos to ENTRY_TITLE
1278 **************************************************************************/
1279 static VOID
List_DrawEntry(struct IClass
*cl
, Object
*obj
, int entry_pos
,
1282 struct MUI_ListData
*data
= INST_DATA(cl
, obj
);
1285 /* To be surem we don't draw anything if there is no title */
1286 if (entry_pos
== ENTRY_TITLE
&& !data
->title
)
1289 DisplayEntry(cl
, obj
, entry_pos
);
1292 for (col
= 0; col
< data
->columns
; col
++)
1295 x2
= x1
+ data
->ci
[col
].entries_width
;
1298 zune_text_new(data
->preparses
[col
], data
->strings
[col
],
1299 ZTEXT_ARG_NONE
, 0)))
1301 /* Could be made simpler, as we don't really need the bounds */
1302 zune_text_get_bounds(text
, obj
);
1303 /* Note, this was MPEN_SHADOW before */
1304 SetAPen(_rp(obj
), muiRenderInfo(obj
)->mri_Pens
[MPEN_TEXT
]);
1305 zune_text_draw(text
, obj
, x1
, x2
, y
); /* totally wrong! */
1306 zune_text_destroy(text
);
1308 x1
= x2
+ data
->ci
[col
].delta
+ (data
->ci
[col
].bar
? BAR_WIDTH
: 0);
1312 /**************************************************************************
1314 **************************************************************************/
1315 IPTR
List__MUIM_Draw(struct IClass
*cl
, Object
*obj
, struct MUIP_Draw
*msg
)
1317 struct MUI_ListData
*data
= INST_DATA(cl
, obj
);
1321 BOOL scroll_caused_damage
= FALSE
;
1323 DoSuperMethodA(cl
, obj
, (Msg
) msg
);
1325 if (msg
->flags
& MADF_DRAWUPDATE
)
1327 if (data
->update
== 1)
1328 DoMethod(obj
, MUIM_DrawBackground
, _mleft(obj
), _mtop(obj
),
1329 _mwidth(obj
), _mheight(obj
),
1330 0, data
->entries_first
* data
->entry_maxheight
, 0);
1334 DoMethod(obj
, MUIM_DrawBackground
, _mleft(obj
), _mtop(obj
),
1335 _mwidth(obj
), _mheight(obj
),
1336 0, data
->entries_first
* data
->entry_maxheight
, 0);
1339 clip
= MUI_AddClipping(muiRenderInfo(obj
), _mleft(obj
), _mtop(obj
),
1340 _mwidth(obj
), _mheight(obj
));
1342 if (!(msg
->flags
& MADF_DRAWUPDATE
)
1343 || ((msg
->flags
& MADF_DRAWUPDATE
) && data
->update
== 1))
1348 if (data
->title_height
&& data
->title
)
1350 List_DrawEntry(cl
, obj
, ENTRY_TITLE
, y
);
1351 y
+= data
->entries
[ENTRY_TITLE
]->height
;
1352 SetAPen(_rp(obj
), _pens(obj
)[MPEN_SHADOW
]);
1353 Move(_rp(obj
), _mleft(obj
), y
);
1354 Draw(_rp(obj
), _mright(obj
), y
);
1355 SetAPen(_rp(obj
), _pens(obj
)[MPEN_SHINE
]);
1357 Move(_rp(obj
), _mleft(obj
), y
);
1358 Draw(_rp(obj
), _mright(obj
), y
);
1362 y
= data
->entries_top_pixel
;
1364 start
= data
->entries_first
;
1365 end
= data
->entries_first
+ data
->entries_visible
;
1367 if ((msg
->flags
& MADF_DRAWUPDATE
) && data
->update
== 3)
1369 int diffy
= data
->entries_first
- data
->update_pos
;
1371 if (abs(diffy
) < data
->entries_visible
)
1373 scroll_caused_damage
=
1374 (_rp(obj
)->Layer
->Flags
& LAYERREFRESH
) ? FALSE
: TRUE
;
1376 ScrollRaster(_rp(obj
), 0, diffy
* data
->entry_maxheight
,
1379 y
+ data
->entry_maxheight
* data
->entries_visible
);
1381 scroll_caused_damage
=
1382 scroll_caused_damage
1383 && (_rp(obj
)->Layer
->Flags
& LAYERREFRESH
);
1387 start
= end
- diffy
;
1388 y
+= data
->entry_maxheight
* (data
->entries_visible
-
1392 end
= start
- diffy
;
1396 bottom
= y
+ (end
- start
) * data
->entry_maxheight
;
1398 DoMethod(obj
, MUIM_DrawBackground
, _mleft(obj
), top
,
1399 _mwidth(obj
), bottom
- top
+ 1,
1401 top
- _mtop(obj
) + data
->entries_first
* data
->entry_maxheight
,
1405 for (entry_pos
= start
;
1406 entry_pos
< end
&& entry_pos
< data
->entries_num
; entry_pos
++)
1408 //struct ListEntry *entry = data->entries[entry_pos];
1410 if (!(msg
->flags
& MADF_DRAWUPDATE
) ||
1411 ((msg
->flags
& MADF_DRAWUPDATE
) && data
->update
== 1) ||
1412 ((msg
->flags
& MADF_DRAWUPDATE
) && data
->update
== 3) ||
1413 ((msg
->flags
& MADF_DRAWUPDATE
) && data
->update
== 2
1414 && data
->update_pos
== entry_pos
))
1416 if (entry_pos
== data
->entries_active
)
1418 zune_imspec_draw(data
->list_cursor
, muiRenderInfo(obj
),
1419 _mleft(obj
), y
, _mwidth(obj
), data
->entry_maxheight
,
1420 0, y
- data
->entries_top_pixel
, 0);
1424 if ((msg
->flags
& MADF_DRAWUPDATE
) && data
->update
== 2
1425 && data
->update_pos
== entry_pos
)
1427 DoMethod(obj
, MUIM_DrawBackground
, _mleft(obj
), y
,
1428 _mwidth(obj
), data
->entry_maxheight
, 0,
1430 data
->entries_first
* data
->entry_maxheight
, 0);
1433 List_DrawEntry(cl
, obj
, entry_pos
, y
);
1435 y
+= data
->entry_maxheight
;
1438 MUI_RemoveClipping(muiRenderInfo(obj
), clip
);
1442 if (scroll_caused_damage
)
1444 if (MUI_BeginRefresh(muiRenderInfo(obj
), 0))
1446 /* Theoretically it might happen that more damage is caused
1447 after ScrollRaster. By something else, like window movement
1448 in front of our window. Therefore refresh root object of
1449 window, not just this object */
1453 get(_win(obj
), MUIA_Window_RootObject
, &o
);
1454 MUI_Redraw(o
, MADF_DRAWOBJECT
);
1456 MUI_EndRefresh(muiRenderInfo(obj
), 0);
1460 ULONG x1
= _mleft(obj
);
1464 if (data
->title_height
&& data
->title
)
1466 for (col
= 0; col
< data
->columns
; col
++)
1468 ULONG halfdelta
= data
->ci
[col
].delta
/ 2;
1469 x1
+= data
->ci
[col
].entries_width
+ halfdelta
;
1471 if (x1
+ (data
->ci
[col
].bar
? BAR_WIDTH
: 0) > _mright(obj
))
1474 if (data
->ci
[col
].bar
)
1476 SetAPen(_rp(obj
), _pens(obj
)[MPEN_SHINE
]);
1477 Move(_rp(obj
), x1
, y
);
1479 y
+ data
->entries
[ENTRY_TITLE
]->height
- 1);
1480 SetAPen(_rp(obj
), _pens(obj
)[MPEN_SHADOW
]);
1481 Move(_rp(obj
), x1
+ 1, y
);
1482 Draw(_rp(obj
), x1
+ 1,
1483 y
+ data
->entries
[ENTRY_TITLE
]->height
- 1);
1487 x1
+= data
->ci
[col
].delta
- halfdelta
;
1489 y
+= data
->entries
[ENTRY_TITLE
]->height
+ 1;
1494 for (col
= 0; col
< data
->columns
; col
++)
1496 ULONG halfdelta
= data
->ci
[col
].delta
/ 2;
1497 x1
+= data
->ci
[col
].entries_width
+ halfdelta
;
1499 if (x1
+ (data
->ci
[col
].bar
? BAR_WIDTH
: 0) > _mright(obj
))
1502 if (data
->ci
[col
].bar
)
1504 SetAPen(_rp(obj
), _pens(obj
)[MPEN_SHINE
]);
1505 Move(_rp(obj
), x1
, y
);
1506 Draw(_rp(obj
), x1
, _mbottom(obj
));
1507 SetAPen(_rp(obj
), _pens(obj
)[MPEN_SHADOW
]);
1508 Move(_rp(obj
), x1
+ 1, y
);
1509 Draw(_rp(obj
), x1
+ 1, _mbottom(obj
));
1514 x1
+= data
->ci
[col
].delta
- halfdelta
;
1520 /**************************************************************************
1521 Makes the entry at the given mouse position the active one.
1522 Relx and Rely are relative mouse coordinates to the upper left of
1524 **************************************************************************/
1525 static VOID
List_MakeActive(struct IClass
*cl
, Object
*obj
, LONG relx
,
1528 struct MUI_ListData
*data
= INST_DATA(cl
, obj
);
1530 if (data
->entries_num
== 0)
1533 LONG eclicky
= rely
+ _top(obj
) - data
->entries_top_pixel
;
1534 /* y coordinates transformed to the entries */
1535 LONG new_act
= eclicky
/ data
->entry_maxheight
+ data
->entries_first
;
1536 LONG old_act
= data
->entries_active
;
1540 new_act
= data
->entries_first
- 1;
1542 else if (new_act
> data
->entries_first
+ data
->entries_visible
)
1544 new_act
= data
->entries_first
+ data
->entries_visible
;
1547 if (new_act
>= data
->entries_num
)
1548 new_act
= data
->entries_num
- 1;
1549 else if (new_act
< 0)
1552 /* Notify only when active entry has changed */
1553 if (old_act
!= new_act
)
1554 set(obj
, MUIA_List_Active
, new_act
);
1557 static void DoWheelMove(struct IClass
*cl
, Object
*obj
, LONG wheely
,
1560 struct MUI_ListData
*data
= INST_DATA(cl
, obj
);
1561 LONG
new = data
->entries_first
;
1563 if (qual
& IEQUALIFIER_CONTROL
)
1568 new = data
->entries_num
;
1570 else if (qual
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
))
1572 new += (wheely
* data
->entries_visible
);
1579 if (new > data
->entries_num
- data
->entries_visible
)
1581 new = data
->entries_num
- data
->entries_visible
;
1589 if (new != data
->entries_first
)
1591 set(obj
, MUIA_List_First
, new);
1596 /**************************************************************************
1598 **************************************************************************/
1599 IPTR
List__MUIM_HandleEvent(struct IClass
*cl
, Object
*obj
,
1600 struct MUIP_HandleEvent
*msg
)
1602 struct MUI_ListData
*data
= INST_DATA(cl
, obj
);
1606 LONG mx
= msg
->imsg
->MouseX
- _left(obj
);
1607 LONG my
= msg
->imsg
->MouseY
- _top(obj
);
1608 switch (msg
->imsg
->Class
)
1610 case IDCMP_MOUSEBUTTONS
:
1611 if (msg
->imsg
->Code
== SELECTDOWN
)
1613 if (mx
>= 0 && mx
< _width(obj
) && my
>= 0
1614 && my
< _height(obj
))
1616 LONG eclicky
= my
+ _top(obj
) - data
->entries_top_pixel
;
1617 /* y coordinates transformed to the entries */
1618 data
->mouse_click
= MOUSE_CLICK_ENTRY
;
1620 /* Now check if it was clicked on a title or on entries */
1623 data
->entries_visible
* data
->entry_maxheight
)
1625 List_MakeActive(cl
, obj
, mx
, my
);
1626 /* sets data->entries_active */
1628 if (data
->last_active
== data
->entries_active
1629 && DoubleClick(data
->last_secs
, data
->last_mics
,
1630 msg
->imsg
->Seconds
, msg
->imsg
->Micros
))
1632 /* Handle MUIA_ListView_ClickColumn */
1633 data
->click_column
= 0;
1634 if (data
->entries_num
> 0 && data
->columns
> 0)
1638 for (col
= 0; col
< data
->columns
; col
++)
1641 data
->ci
[col
].entries_width
+
1642 data
->ci
[col
].delta
+
1643 (data
->ci
[col
].bar
? BAR_WIDTH
: 0);
1645 ("[List/MUIM_HandleEvent] col %d "
1646 "width %d width_sum %d mx %d\n",
1648 data
->ci
[col
].entries_width
,
1653 ("[List/MUIM_HandleEvent] "
1656 set(obj
, MUIA_Listview_ClickColumn
,
1663 set(obj
, MUIA_Listview_DoubleClick
, TRUE
);
1664 data
->last_active
= -1;
1665 data
->last_secs
= data
->last_mics
= 0;
1669 data
->last_active
= data
->entries_active
;
1670 data
->last_secs
= msg
->imsg
->Seconds
;
1671 data
->last_mics
= msg
->imsg
->Micros
;
1675 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
,
1676 (IPTR
) & data
->ehn
);
1677 data
->ehn
.ehn_Events
|=
1678 (IDCMP_MOUSEMOVE
| IDCMP_INTUITICKS
);
1679 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
,
1680 (IPTR
) & data
->ehn
);
1682 return MUI_EventHandlerRC_Eat
;
1687 if (msg
->imsg
->Code
== SELECTUP
&& data
->mouse_click
)
1689 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
,
1690 (IPTR
) & data
->ehn
);
1691 data
->ehn
.ehn_Events
&=
1692 ~(IDCMP_MOUSEMOVE
| IDCMP_INTUITICKS
);
1693 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
,
1694 (IPTR
) & data
->ehn
);
1695 data
->mouse_click
= 0;
1701 case IDCMP_INTUITICKS
:
1702 case IDCMP_MOUSEMOVE
:
1703 if (data
->mouse_click
)
1705 List_MakeActive(cl
, obj
, mx
, my
);
1710 switch (msg
->imsg
->Code
)
1712 case RAWKEY_NM_WHEEL_UP
:
1713 if (_isinobject(msg
->imsg
->MouseX
, msg
->imsg
->MouseY
))
1715 DoWheelMove(cl
, obj
, -1, msg
->imsg
->Qualifier
);
1719 case RAWKEY_NM_WHEEL_DOWN
:
1720 if (_isinobject(msg
->imsg
->MouseX
, msg
->imsg
->MouseY
))
1722 DoWheelMove(cl
, obj
, 1, msg
->imsg
->Qualifier
);
1729 case IDCMP_ACTIVEWINDOW
:
1730 case IDCMP_INACTIVEWINDOW
:
1731 if (data
->ehn
.ehn_Events
& (IDCMP_MOUSEMOVE
| IDCMP_INTUITICKS
))
1733 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
,
1734 (IPTR
) & data
->ehn
);
1735 data
->ehn
.ehn_Events
&=
1736 ~(IDCMP_MOUSEMOVE
| IDCMP_INTUITICKS
);
1737 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
,
1738 (IPTR
) & data
->ehn
);
1739 data
->mouse_click
= 0;
1748 /**************************************************************************
1750 **************************************************************************/
1751 IPTR
List__MUIM_Clear(struct IClass
*cl
, Object
*obj
,
1752 struct MUIP_List_Clear
*msg
)
1754 struct MUI_ListData
*data
= INST_DATA(cl
, obj
);
1756 while (data
->confirm_entries_num
)
1758 struct ListEntry
*lentry
=
1759 data
->entries
[--data
->confirm_entries_num
];
1760 DoMethod(obj
, MUIM_List_Destruct
, (IPTR
) lentry
->data
,
1762 FreeListEntry(data
, lentry
);
1764 /* Should never fail when shrinking */
1765 SetListSize(data
, 0);
1767 if (data
->confirm_entries_num
!= data
->entries_num
)
1769 SetAttrs(obj
, MUIA_List_Entries
, 0, MUIA_List_First
, 0,
1770 /* Notify only when no entry was active */
1771 data
->entries_active
!=
1772 MUIV_List_Active_Off
? MUIA_List_Active
: TAG_DONE
,
1773 MUIV_List_Active_Off
, TAG_DONE
);
1776 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
1782 /**************************************************************************
1784 **************************************************************************/
1785 IPTR
List__MUIM_Exchange(struct IClass
*cl
, Object
*obj
,
1786 struct MUIP_List_Exchange
*msg
)
1788 struct MUI_ListData
*data
= INST_DATA(cl
, obj
);
1793 case MUIV_List_Exchange_Top
:
1796 case MUIV_List_Exchange_Active
:
1797 pos1
= data
->entries_active
;
1799 case MUIV_List_Exchange_Bottom
:
1800 pos1
= data
->entries_num
- 1;
1808 case MUIV_List_Exchange_Top
:
1811 case MUIV_List_Exchange_Active
:
1812 pos2
= data
->entries_active
;
1814 case MUIV_List_Exchange_Bottom
:
1815 pos2
= data
->entries_num
- 1;
1817 case MUIV_List_Exchange_Next
:
1820 case MUIV_List_Exchange_Previous
:
1827 if (pos1
>= 0 && pos1
< data
->entries_num
&& pos2
>= 0
1828 && pos2
< data
->entries_num
&& pos1
!= pos2
)
1830 struct ListEntry
*save
= data
->entries
[pos1
];
1831 data
->entries
[pos1
] = data
->entries
[pos2
];
1832 data
->entries
[pos2
] = save
;
1835 data
->update_pos
= pos1
;
1836 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
1839 data
->update_pos
= pos2
;
1840 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
1850 /**************************************************************************
1852 **************************************************************************/
1853 IPTR
List__MUIM_Redraw(struct IClass
*cl
, Object
*obj
,
1854 struct MUIP_List_Redraw
*msg
)
1856 struct MUI_ListData
*data
= INST_DATA(cl
, obj
);
1858 if (msg
->pos
== MUIV_List_Redraw_All
)
1861 CalcWidths(cl
, obj
);
1862 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
1867 if (msg
->pos
== MUIV_List_Redraw_Active
)
1868 pos
= data
->entries_active
;
1869 else if (msg
->pos
== MUIV_List_Redraw_Entry
)
1872 for (i
= 0; i
< data
->entries_num
; i
++)
1873 if (data
->entries
[i
]->data
== msg
->entry
)
1884 if (CalcDimsOfEntry(cl
, obj
, pos
))
1889 data
->update_pos
= pos
;
1891 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
1897 /**************************************************************************
1899 **************************************************************************/
1900 IPTR
List__MUIM_Remove(struct IClass
*cl
, Object
*obj
,
1901 struct MUIP_List_Remove
*msg
)
1903 struct MUI_ListData
*data
= INST_DATA(cl
, obj
);
1906 struct ListEntry
*lentry
;
1907 //int rem_count = 1;
1909 if (!data
->entries_num
)
1914 case MUIV_List_Remove_First
:
1918 case MUIV_List_Remove_Active
:
1919 pos
= data
->entries_active
;
1922 case MUIV_List_Remove_Last
:
1923 pos
= data
->entries_num
- 1;
1926 case MUIV_List_Remove_Selected
:
1927 /* TODO: needs special handling */
1928 pos
= data
->entries_active
;
1936 if (pos
< 0 || pos
>= data
->entries_num
)
1939 new_act
= data
->entries_active
;
1941 if (pos
== new_act
&& new_act
== data
->entries_num
- 1)
1942 new_act
--; /* might become MUIV_List_Active_Off */
1944 lentry
= data
->entries
[pos
];
1945 DoMethod(obj
, MUIM_List_Destruct
, (IPTR
) lentry
->data
,
1950 RemoveListEntries(data
, pos
, cur
- pos
);
1951 data
->confirm_entries_num
-= cur
- pos
;
1953 /* ensure that the active element is in a valid range */
1954 if (new_act
>= data
->entries_num
)
1955 new_act
= data
->entries_num
- 1;
1957 SetAttrs(obj
, MUIA_List_Entries
, data
->confirm_entries_num
,
1958 (new_act
>= pos
) || (new_act
!= data
->entries_active
) ?
1959 MUIA_List_Active
: TAG_DONE
,
1960 new_act
, /* Inform only if neccessary (for notify) */
1964 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
1969 /**************************************************************************
1971 **************************************************************************/
1973 IPTR
List__MUIM_Insert(struct IClass
*cl
, Object
*obj
,
1974 struct MUIP_List_Insert
*msg
)
1976 struct MUI_ListData
*data
= INST_DATA(cl
, obj
);
1977 LONG pos
, count
, sort
;
1984 /* Count the number of entries */
1985 for (count
= 0; msg
->entries
[count
] != NULL
; count
++)
1994 case MUIV_List_Insert_Top
:
1998 case MUIV_List_Insert_Active
:
1999 if (data
->entries_active
!= -1)
2000 pos
= data
->entries_active
;
2002 pos
= data
->entries_active
;
2005 case MUIV_List_Insert_Sorted
:
2006 pos
= data
->entries_num
;
2007 sort
= 1; /* we sort'em later */
2010 case MUIV_List_Insert_Bottom
:
2011 pos
= data
->entries_num
;
2015 if (msg
->pos
> data
->entries_num
)
2016 pos
= data
->entries_num
;
2017 else if (msg
->pos
< 0)
2024 if (!(SetListSize(data
, data
->entries_num
+ count
)))
2027 LONG until
= pos
+ count
;
2028 APTR
*toinsert
= msg
->entries
;
2030 if (!(PrepareInsertListEntries(data
, pos
, count
)))
2035 struct ListEntry
*lentry
;
2037 if (!(lentry
= AllocListEntry(data
)))
2039 /* Panic, but we must be in a consistent state, so remove
2040 ** the space where the following list entries should have gone
2042 RemoveListEntries(data
, pos
, until
- pos
);
2046 /* now call the construct method which returns us a pointer which
2048 lentry
->data
= (APTR
) DoMethod(obj
, MUIM_List_Construct
,
2049 (IPTR
) * toinsert
, (IPTR
) data
->pool
);
2052 FreeListEntry(data
, lentry
);
2053 RemoveListEntries(data
, pos
, until
- pos
);
2055 /* TODO: Also check for visible stuff like below */
2056 if (data
->entries_num
!= data
->confirm_entries_num
)
2057 set(obj
, MUIA_List_Entries
, data
->confirm_entries_num
);
2061 data
->entries
[pos
] = lentry
;
2062 data
->confirm_entries_num
++;
2064 if (_flags(obj
) & MADF_SETUP
)
2066 /* We have to calculate the width and height of the newly
2067 * inserted entry. This has to be done after inserting the
2068 * element into the list */
2069 CalcDimsOfEntry(cl
, obj
, pos
);
2074 } // while (pos < until)
2077 /* Recalculate the number of visible entries */
2078 if (_flags(obj
) & MADF_SETUP
)
2079 CalcVertVisible(cl
, obj
);
2081 if (data
->entries_num
!= data
->confirm_entries_num
)
2084 MUIA_List_Entries
, data
->confirm_entries_num
,
2085 MUIA_List_Visible
, data
->entries_visible
, TAG_DONE
);
2088 /* If the array is already sorted, we could do a simple insert
2089 * sort and would be much faster than with qsort.
2090 * If an array is not yet sorted, does a MUIV_List_Insert_Sorted
2091 * sort the whole array?
2093 * I think, we better sort the whole array:
2097 DoMethod(obj
, MUIM_List_Sort
);
2098 /* TODO: which pos to return here !? */
2099 /* MUIM_List_Sort already called MUI_Redraw */
2103 if (!(data
->flags
& LIST_QUIET
))
2106 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
2109 data
->insert_position
= pos
;
2114 /**************************************************************************
2115 MUIM_List_InsertSingle
2116 **************************************************************************/
2117 IPTR
List__MUIM_InsertSingle(struct IClass
*cl
, Object
*obj
,
2118 struct MUIP_List_InsertSingle
*msg
)
2120 return DoMethod(obj
, MUIM_List_Insert
, (IPTR
) & msg
->entry
, 1,
2124 /**************************************************************************
2126 **************************************************************************/
2127 IPTR
List__MUIM_GetEntry(struct IClass
*cl
, Object
*obj
,
2128 struct MUIP_List_GetEntry
*msg
)
2130 struct MUI_ListData
*data
= INST_DATA(cl
, obj
);
2133 if (pos
== MUIV_List_GetEntry_Active
)
2134 pos
= data
->entries_active
;
2136 if (pos
< 0 || pos
>= data
->entries_num
)
2141 *msg
->entry
= data
->entries
[pos
]->data
;
2142 return (IPTR
) *msg
->entry
;
2145 /**************************************************************************
2147 **************************************************************************/
2148 IPTR
List__MUIM_Construct(struct IClass
*cl
, Object
*obj
,
2149 struct MUIP_List_Construct
*msg
)
2151 struct MUI_ListData
*data
= INST_DATA(cl
, obj
);
2153 if (NULL
== data
->construct_hook
)
2154 return (IPTR
) msg
->entry
;
2155 if ((IPTR
) data
->construct_hook
== MUIV_List_ConstructHook_String
)
2157 int len
= msg
->entry
? strlen((STRPTR
) msg
->entry
) : 0;
2158 ULONG
*mem
= AllocPooled(msg
->pool
, len
+ 5);
2163 if (msg
->entry
!= NULL
)
2164 strcpy((STRPTR
) (mem
+ 1), (STRPTR
) msg
->entry
);
2166 *(STRPTR
) (mem
+ 1) = 0;
2167 return (IPTR
) (mem
+ 1);
2169 return CallHookPkt(data
->construct_hook
, msg
->pool
, msg
->entry
);
2172 /**************************************************************************
2174 **************************************************************************/
2175 IPTR
List__MUIM_Destruct(struct IClass
*cl
, Object
*obj
,
2176 struct MUIP_List_Destruct
*msg
)
2178 struct MUI_ListData
*data
= INST_DATA(cl
, obj
);
2180 if (NULL
== data
->destruct_hook
)
2183 if ((IPTR
) data
->destruct_hook
== MUIV_List_DestructHook_String
)
2185 ULONG
*mem
= ((ULONG
*) msg
->entry
) - 1;
2186 FreePooled(msg
->pool
, mem
, mem
[0]);
2190 CallHookPkt(data
->destruct_hook
, msg
->pool
, msg
->entry
);
2195 /**************************************************************************
2197 **************************************************************************/
2198 IPTR
List__MUIM_Compare(struct IClass
*cl
, Object
*obj
,
2199 struct MUIP_List_Compare
*msg
)
2201 struct MUI_ListData
*data
= INST_DATA(cl
, obj
);
2203 return CallHookPkt(data
->compare_hook
, msg
->entry2
, msg
->entry1
);
2206 /**************************************************************************
2208 **************************************************************************/
2209 IPTR
List__MUIM_Display(struct IClass
*cl
, Object
*obj
,
2210 struct MUIP_List_Display
*msg
)
2212 struct MUI_ListData
*data
= INST_DATA(cl
, obj
);
2214 if (NULL
== data
->display_hook
)
2217 *msg
->array
= msg
->entry
;
2223 *((ULONG
*) (msg
->array
- 1)) = msg
->entry_pos
;
2224 return CallHookPkt(data
->display_hook
, msg
->array
, msg
->entry
);
2227 /**************************************************************************
2228 MUIM_List_SelectChange
2229 **************************************************************************/
2230 IPTR
List__MUIM_SelectChange(struct IClass
*cl
, Object
*obj
,
2231 struct MUIP_List_SelectChange
*msg
)
2236 /**************************************************************************
2237 MUIM_List_CreateImage
2238 Called by a List subclass in its Setup method.
2239 Connects an Area subclass object to the list, much like an object gets
2240 connected to a window. List call Setup and AskMinMax on that object,
2241 keeps a reference to it (that reference will be returned).
2242 Text engine will dereference that pointer and draw the object with its
2244 **************************************************************************/
2245 IPTR
List__MUIM_CreateImage(struct IClass
*cl
, Object
*obj
,
2246 struct MUIP_List_CreateImage
*msg
)
2248 struct MUI_ListData
*data
= INST_DATA(cl
, obj
);
2249 struct ListImage
*li
;
2251 /* List must be already setup in Setup of your subclass */
2252 if (!(_flags(obj
) & MADF_SETUP
))
2254 li
= AllocPooled(data
->pool
, sizeof(struct ListImage
));
2259 AddTail((struct List
*)&data
->images
, (struct Node
*)li
);
2260 DoMethod(li
->obj
, MUIM_ConnectParent
, (IPTR
) obj
);
2261 DoSetupMethod(li
->obj
, muiRenderInfo(obj
));
2267 /**************************************************************************
2268 MUIM_List_DeleteImage
2269 **************************************************************************/
2270 IPTR
List__MUIM_DeleteImage(struct IClass
*cl
, Object
*obj
,
2271 struct MUIP_List_DeleteImage
*msg
)
2273 struct MUI_ListData
*data
= INST_DATA(cl
, obj
);
2274 struct ListImage
*li
= (struct ListImage
*)msg
->listimg
;
2278 DoMethod(li
->obj
, MUIM_Cleanup
);
2279 DoMethod(li
->obj
, MUIM_DisconnectParent
);
2280 Remove((struct Node
*)li
);
2281 FreePooled(data
->pool
, li
, sizeof(struct ListImage
));
2287 /**************************************************************************
2289 **************************************************************************/
2290 IPTR
List__MUIM_Jump(struct IClass
*cl
, Object
*obj
,
2291 struct MUIP_List_Jump
*msg
)
2293 struct MUI_ListData
*data
= INST_DATA(cl
, obj
);
2294 LONG pos
= msg
->pos
;
2298 case MUIV_List_Jump_Top
:
2302 case MUIV_List_Jump_Active
:
2303 pos
= data
->entries_active
;
2306 case MUIV_List_Jump_Bottom
:
2307 pos
= data
->entries_num
- 1;
2310 case MUIV_List_Jump_Down
:
2311 pos
= data
->entries_first
+ data
->entries_visible
;
2314 case MUIV_List_Jump_Up
:
2315 pos
= data
->entries_first
- 1;
2320 if (pos
> data
->entries_num
)
2322 pos
= data
->entries_num
- 1;
2327 if (pos
< data
->entries_first
)
2329 set(obj
, MUIA_List_First
, pos
);
2331 else if (pos
>= data
->entries_first
+ data
->entries_visible
)
2333 pos
-= (data
->entries_visible
- 1);
2336 if (pos
!= data
->entries_first
)
2338 set(obj
, MUIA_List_First
, pos
);
2346 /**************************************************************************
2348 **************************************************************************/
2349 IPTR
List__MUIM_Sort(struct IClass
*cl
, Object
*obj
,
2350 struct MUIP_List_Sort
*msg
)
2352 struct MUI_ListData
*data
= INST_DATA(cl
, obj
);
2355 struct MUIP_List_Compare cmpmsg
=
2356 { MUIM_List_Compare
, NULL
, NULL
, 0, 0 };
2358 if (data
->entries_num
> 1)
2361 Simple sort algorithm. Feel free to improve it.
2363 for (i
= 0; i
< data
->entries_num
- 1; i
++)
2366 for (j
= i
+ 1; j
< data
->entries_num
; j
++)
2368 cmpmsg
.entry1
= data
->entries
[max
]->data
;
2369 cmpmsg
.entry2
= data
->entries
[j
]->data
;
2370 if ((LONG
) DoMethodA(obj
, (Msg
) & cmpmsg
) > 0)
2377 APTR tmp
= data
->entries
[i
];
2378 data
->entries
[i
] = data
->entries
[max
];
2379 data
->entries
[max
] = tmp
;
2384 if (!(data
->flags
& LIST_QUIET
))
2387 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
2393 /**************************************************************************
2395 **************************************************************************/
2396 IPTR
List__MUIM_Move(struct IClass
*cl
, Object
*obj
,
2397 struct MUIP_List_Move
*msg
)
2399 struct MUI_ListData
*data
= INST_DATA(cl
, obj
);
2406 case MUIV_List_Move_Top
:
2409 case MUIV_List_Move_Active
:
2410 from
= data
->entries_active
;
2412 case MUIV_List_Move_Bottom
:
2413 from
= data
->entries_num
- 1;
2421 case MUIV_List_Move_Top
:
2424 case MUIV_List_Move_Active
:
2425 to
= data
->entries_active
;
2427 case MUIV_List_Move_Bottom
:
2428 to
= data
->entries_num
- 1;
2430 case MUIV_List_Move_Next
:
2433 case MUIV_List_Move_Previous
:
2440 if (from
> data
->entries_num
- 1 || from
< 0
2441 || to
> data
->entries_num
- 1 || to
< 0 || from
== to
)
2442 return (IPTR
) FALSE
;
2446 struct ListEntry
*backup
= data
->entries
[from
];
2447 for (i
= from
; i
< to
; i
++)
2448 data
->entries
[i
] = data
->entries
[i
+ 1];
2449 data
->entries
[to
] = backup
;
2453 struct ListEntry
*backup
= data
->entries
[from
];
2454 for (i
= from
; i
> to
; i
--)
2455 data
->entries
[i
] = data
->entries
[i
- 1];
2456 data
->entries
[to
] = backup
;
2460 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
2465 /**************************************************************************
2467 **************************************************************************/
2468 BOOPSI_DISPATCHER(IPTR
, List_Dispatcher
, cl
, obj
, msg
)
2470 switch (msg
->MethodID
)
2473 return List__OM_NEW(cl
, obj
, (struct opSet
*)msg
);
2475 return List__OM_DISPOSE(cl
, obj
, msg
);
2477 return List__OM_SET(cl
, obj
, (struct opSet
*)msg
);
2479 return List__OM_GET(cl
, obj
, (struct opGet
*)msg
);
2482 return List__MUIM_Setup(cl
, obj
, (struct MUIP_Setup
*)msg
);
2484 return List__MUIM_Cleanup(cl
, obj
, (struct MUIP_Cleanup
*)msg
);
2485 case MUIM_AskMinMax
:
2486 return List__MUIM_AskMinMax(cl
, obj
, (struct MUIP_AskMinMax
*)msg
);
2488 return List__MUIM_Show(cl
, obj
, (struct MUIP_Show
*)msg
);
2490 return List__MUIM_Hide(cl
, obj
, (struct MUIP_Hide
*)msg
);
2492 return List__MUIM_Draw(cl
, obj
, (struct MUIP_Draw
*)msg
);
2494 return List__MUIM_Layout(cl
, obj
, (struct MUIP_Layout
*)msg
);
2495 case MUIM_HandleEvent
:
2496 return List__MUIM_HandleEvent(cl
, obj
,
2497 (struct MUIP_HandleEvent
*)msg
);
2498 case MUIM_List_Clear
:
2499 return List__MUIM_Clear(cl
, obj
, (struct MUIP_List_Clear
*)msg
);
2500 case MUIM_List_Sort
:
2501 return List__MUIM_Sort(cl
, obj
, (struct MUIP_List_Sort
*)msg
);
2502 case MUIM_List_Exchange
:
2503 return List__MUIM_Exchange(cl
, obj
,
2504 (struct MUIP_List_Exchange
*)msg
);
2505 case MUIM_List_Insert
:
2506 return List__MUIM_Insert(cl
, obj
, (APTR
) msg
);
2507 case MUIM_List_InsertSingle
:
2508 return List__MUIM_InsertSingle(cl
, obj
, (APTR
) msg
);
2509 case MUIM_List_GetEntry
:
2510 return List__MUIM_GetEntry(cl
, obj
, (APTR
) msg
);
2511 case MUIM_List_Redraw
:
2512 return List__MUIM_Redraw(cl
, obj
, (APTR
) msg
);
2513 case MUIM_List_Remove
:
2514 return List__MUIM_Remove(cl
, obj
, (APTR
) msg
);
2516 case MUIM_List_Construct
:
2517 return List__MUIM_Construct(cl
, obj
, (APTR
) msg
);
2518 case MUIM_List_Destruct
:
2519 return List__MUIM_Destruct(cl
, obj
, (APTR
) msg
);
2520 case MUIM_List_Compare
:
2521 return List__MUIM_Compare(cl
, obj
, (APTR
) msg
);
2522 case MUIM_List_Display
:
2523 return List__MUIM_Display(cl
, obj
, (APTR
) msg
);
2524 case MUIM_List_SelectChange
:
2525 return List__MUIM_SelectChange(cl
, obj
, (APTR
) msg
);
2526 case MUIM_List_CreateImage
:
2527 return List__MUIM_CreateImage(cl
, obj
, (APTR
) msg
);
2528 case MUIM_List_DeleteImage
:
2529 return List__MUIM_DeleteImage(cl
, obj
, (APTR
) msg
);
2530 case MUIM_List_Jump
:
2531 return List__MUIM_Jump(cl
, obj
, (APTR
) msg
);
2532 case MUIM_List_Move
:
2533 return List__MUIM_Move(cl
, obj
, (struct MUIP_List_Move
*)msg
);
2536 return DoSuperMethodA(cl
, obj
, msg
);
2538 BOOPSI_DISPATCHER_END
2543 const struct __MUIBuiltinClass _MUI_List_desc
=
2547 sizeof(struct MUI_ListData
),
2548 (void *) List_Dispatcher