Updated indentation (done separately for clarity).
[AROS.git] / workbench / libs / muimaster / classes / listview.c
blobcd13a9e617ff0a8ac0ffd6574d08dafd4474b156
1 /*
2 Copyright © 2002-2013, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <aros/debug.h>
8 #include <graphics/gfx.h>
9 #include <graphics/view.h>
10 #include <devices/rawkeycodes.h>
11 #include <clib/alib_protos.h>
12 #include <proto/exec.h>
13 #include <proto/graphics.h>
14 #include <proto/utility.h>
15 #include <proto/intuition.h>
16 #include <proto/muimaster.h>
18 #include "mui.h"
19 #include "muimaster_intern.h"
20 #include "support.h"
21 #include "window.h"
22 #include "list.h"
23 #include "prefs.h"
25 extern struct Library *MUIMasterBase;
27 struct MUI_ListviewData
29 Object *list, *group, *vert;
30 struct Hook *layout_hook;
31 struct Hook hook;
32 struct Hook selfnotify_hook;
33 BOOL noforward;
34 BOOL read_only;
35 IPTR multiselect;
36 struct MUI_EventHandlerNode ehn;
38 int mouse_click; /* see below if mouse is held down */
40 /* double click */
41 ULONG last_secs;
42 ULONG last_mics;
43 ULONG last_active;
44 BOOL doubleclick;
46 /* clicked column */
47 LONG click_column;
48 LONG def_click_column;
50 /* user prefs */
51 ListviewMulti prefs_multi;
54 #define MOUSE_CLICK_ENTRY 1 /* on entry clicked */
55 #define MOUSE_CLICK_TITLE 2 /* on title clicked */
57 static void DoWheelMove(struct IClass *cl, Object *obj, LONG wheely);
59 ULONG Listview_Layout_Function(struct Hook *hook, Object *obj,
60 struct MUI_LayoutMsg *lm)
62 struct MUI_ListviewData *data = (struct MUI_ListviewData *)hook->h_Data;
64 switch (lm->lm_Type)
66 case MUILM_MINMAX:
68 /* Calculate the minmax dimension of the group,
69 ** We only have a fixed number of children, so we need
70 ** no NextObject()
72 lm->lm_MinMax.MinWidth =
73 _minwidth(data->list) + _minwidth(data->vert);
74 lm->lm_MinMax.DefWidth =
75 _defwidth(data->list) + _defwidth(data->vert);
76 lm->lm_MinMax.MaxWidth =
77 _maxwidth(data->list) + _maxwidth(data->vert);
78 lm->lm_MinMax.MaxWidth =
79 MIN(lm->lm_MinMax.MaxWidth, MUI_MAXMAX);
81 lm->lm_MinMax.MinHeight =
82 MAX(_minheight(data->list), _minheight(data->vert));
83 lm->lm_MinMax.DefHeight =
84 MAX(_defheight(data->list), lm->lm_MinMax.MinHeight);
85 lm->lm_MinMax.MaxHeight =
86 MIN(_maxheight(data->list), _maxheight(data->vert));
87 lm->lm_MinMax.MaxHeight =
88 MIN(lm->lm_MinMax.MaxHeight, MUI_MAXMAX);
89 return 0;
92 case MUILM_LAYOUT:
94 /* Now place the objects between
95 * (0, 0, lm->lm_Layout.Width - 1, lm->lm_Layout.Height - 1)
98 LONG vert_width = _minwidth(data->vert);
99 LONG lay_width = lm->lm_Layout.Width;
100 LONG lay_height = lm->lm_Layout.Height;
101 LONG cont_width;
102 LONG cont_height;
104 /* We need all scrollbars and the button */
105 set(data->vert, MUIA_ShowMe, TRUE);
106 /* We could also overload MUIM_Show... */
107 cont_width = lay_width - vert_width;
108 cont_height = lay_height;
110 MUI_Layout(data->vert, cont_width, 0, vert_width, cont_height,
113 /* Layout the group a second time, note that setting _mwidth() and
114 _mheight() should be enough, or we invent a new flag */
115 MUI_Layout(data->list, 0, 0, cont_width, cont_height, 0);
116 return 1;
119 return 0;
122 #define PROP_VERT_FIRST 1
123 #define LIST_VERT_FIRST 4
124 #define LIST_VERT_VISIBLE 5
125 #define LIST_VERT_ENTRIES 6
127 ULONG Listview_Function(struct Hook *hook, APTR dummyobj, void **msg)
129 struct MUI_ListviewData *data = (struct MUI_ListviewData *)hook->h_Data;
130 SIPTR type = (SIPTR) msg[0];
131 SIPTR val = (SIPTR) msg[1];
133 D(bug("[ListView] List 0x%p, Event %d, value %ld\n", data->list, type,
134 val));
136 switch (type)
138 case PROP_VERT_FIRST:
139 get(data->vert, MUIA_Prop_First, &val);
140 nnset(data->list, MUIA_List_VertProp_First, val);
141 break;
143 case LIST_VERT_FIRST:
144 nnset(data->vert, MUIA_Prop_First, val);
145 break;
146 case LIST_VERT_VISIBLE:
147 nnset(data->vert, MUIA_Prop_Visible, val);
148 break;
149 case LIST_VERT_ENTRIES:
150 nnset(data->vert, MUIA_Prop_Entries, val);
151 break;
153 return 0;
156 ULONG SelfNotify_Function(struct Hook *hook, APTR obj, void **msg)
158 struct MUI_ListviewData *data = (struct MUI_ListviewData *)hook->h_Data;
159 SIPTR attribute = (SIPTR) msg[0];
160 SIPTR value = (SIPTR) msg[1];
162 /* This allows avoiding notify loops */
163 data->noforward = TRUE;
164 SetAttrs(obj, MUIA_Group_Forward, FALSE, attribute, value, TAG_DONE);
165 data->noforward = FALSE;
167 return 0;
170 /**************************************************************************
171 OM_NEW
172 **************************************************************************/
173 IPTR Listview__OM_NEW(struct IClass *cl, Object *obj, struct opSet *msg)
175 struct MUI_ListviewData *data;
176 struct TagItem *tag, *tags;
177 struct Hook *layout_hook;
178 Object *group, *vert;
179 Object *list =
180 (Object *) GetTagData(MUIA_Listview_List, (IPTR) NULL,
181 msg->ops_AttrList);
182 IPTR cyclechain =
183 (IPTR) GetTagData(MUIA_CycleChain, (IPTR) 0, msg->ops_AttrList);
184 LONG entries = 0, first = 0, visible = 0;
186 if (!list)
187 return (IPTR) NULL;
189 layout_hook = mui_alloc_struct(struct Hook);
190 if (!layout_hook)
191 return (IPTR) NULL;
193 layout_hook->h_Entry = HookEntry;
194 layout_hook->h_SubEntry = (HOOKFUNC) Listview_Layout_Function;
196 obj = (Object *) DoSuperNewTags(cl, obj, NULL,
197 MUIA_Group_Horiz, FALSE,
198 MUIA_CycleChain, cyclechain,
199 MUIA_InnerLeft, 0,
200 MUIA_InnerRight, 0,
201 Child, (IPTR) (group = GroupObject,
202 MUIA_InnerLeft, 0,
203 MUIA_InnerRight, 0,
204 MUIA_Group_LayoutHook, (IPTR) layout_hook,
205 Child, (IPTR) list,
206 Child, (IPTR) (vert =
207 ScrollbarObject, MUIA_Group_Horiz, FALSE, End), End),
208 TAG_DONE);
210 if (!obj)
212 mui_free(layout_hook);
213 return (IPTR) NULL;
216 data = INST_DATA(cl, obj);
217 layout_hook->h_Data = data;
218 data->list = list;
219 data->vert = vert;
220 data->group = group;
221 data->layout_hook = layout_hook;
223 data->hook.h_Entry = HookEntry;
224 data->hook.h_SubEntry = (HOOKFUNC) Listview_Function;
225 data->hook.h_Data = data;
227 data->selfnotify_hook.h_Entry = HookEntry;
228 data->selfnotify_hook.h_SubEntry = (HOOKFUNC) SelfNotify_Function;
229 data->selfnotify_hook.h_Data = data;
230 data->noforward = FALSE;
232 data->last_active = -1;
234 data->ehn.ehn_Events = IDCMP_MOUSEBUTTONS | IDCMP_RAWKEY;
235 data->ehn.ehn_Priority = 0;
236 data->ehn.ehn_Flags = 0;
237 data->ehn.ehn_Object = obj;
238 data->ehn.ehn_Class = cl;
240 /* parse initial taglist */
241 for (tags = msg->ops_AttrList; (tag = NextTagItem(&tags));)
243 switch (tag->ti_Tag)
245 case MUIA_Listview_DoubleClick:
246 data->doubleclick = tag->ti_Data != 0;
247 break;
248 case MUIA_Listview_Input:
249 data->read_only = !tag->ti_Data;
250 break;
251 case MUIA_Listview_MultiSelect:
252 data->multiselect = tag->ti_Data;
253 break;
257 get(list, MUIA_List_VertProp_First, &first);
258 get(list, MUIA_List_VertProp_Visible, &visible);
259 get(list, MUIA_List_VertProp_Entries, &entries);
261 D(bug
262 ("[ListView 0x%p] List 0x%p, First %ld, Visible %ld, Entries %ld\n",
263 obj, list, first, visible, entries));
265 SetAttrs(data->vert,
266 MUIA_Prop_First, first,
267 MUIA_Prop_Visible, visible, MUIA_Prop_Entries, entries, TAG_DONE);
269 DoMethod(vert, MUIM_Notify, MUIA_Prop_First, MUIV_EveryTime, (IPTR) obj,
270 4, MUIM_CallHook, (IPTR) &data->hook, PROP_VERT_FIRST,
271 MUIV_TriggerValue);
272 DoMethod(list, MUIM_Notify, MUIA_List_VertProp_First, MUIV_EveryTime,
273 (IPTR) obj, 4, MUIM_CallHook, (IPTR) &data->hook, LIST_VERT_FIRST,
274 MUIV_TriggerValue);
275 DoMethod(list, MUIM_Notify, MUIA_List_VertProp_Visible, MUIV_EveryTime,
276 (IPTR) obj, 4, MUIM_CallHook, (IPTR) &data->hook,
277 LIST_VERT_VISIBLE, MUIV_TriggerValue);
278 DoMethod(list, MUIM_Notify, MUIA_List_VertProp_Entries, MUIV_EveryTime,
279 (IPTR) obj, 4, MUIM_CallHook, (IPTR) &data->hook,
280 LIST_VERT_ENTRIES, MUIV_TriggerValue);
281 DoMethod(list, MUIM_Notify, MUIA_List_Active, MUIV_EveryTime,
282 (IPTR) obj, 4, MUIM_CallHook, (IPTR) &data->selfnotify_hook,
283 MUIA_List_Active, MUIV_TriggerValue);
285 return (IPTR) obj;
288 /**************************************************************************
289 OM_DISPOSE
290 **************************************************************************/
291 IPTR Listview__OM_DISPOSE(struct IClass *cl, Object *obj, Msg msg)
293 struct MUI_ListviewData *data = INST_DATA(cl, obj);
295 mui_free(data->layout_hook); /* is always here */
296 return DoSuperMethodA(cl, obj, msg);
299 /**************************************************************************
300 OM_SET
301 **************************************************************************/
302 void Listview__OM_SET(struct IClass *cl, Object *obj, struct opSet *msg)
304 struct TagItem *tag, *tags;
305 IPTR no_notify = GetTagData(MUIA_NoNotify, FALSE, msg->ops_AttrList);
306 struct MUI_ListviewData *data = INST_DATA(cl, obj);
308 if (data->noforward)
310 DoSuperMethodA(cl, obj, (Msg) msg);
311 return;
314 for (tags = msg->ops_AttrList; (tag = NextTagItem(&tags));)
316 switch (tag->ti_Tag)
318 case MUIA_List_CompareHook:
319 case MUIA_List_ConstructHook:
320 case MUIA_List_DestructHook:
321 case MUIA_List_DisplayHook:
322 case MUIA_List_VertProp_First:
323 case MUIA_List_Format:
324 case MUIA_List_VertProp_Entries:
325 case MUIA_List_VertProp_Visible:
326 case MUIA_List_Active:
327 case MUIA_List_First:
328 case MUIA_List_Visible:
329 case MUIA_List_Entries:
330 case MUIA_List_Quiet:
331 SetAttrs(data->list, MUIA_NoNotify, no_notify, tag->ti_Tag,
332 tag->ti_Data, TAG_DONE);
333 break;
334 case MUIA_Listview_DoubleClick:
335 data->doubleclick = tag->ti_Data != 0;
336 break;
341 /**************************************************************************
342 OM_GET
343 **************************************************************************/
344 IPTR Listview__OM_GET(struct IClass *cl, Object *obj, struct opGet *msg)
346 /* small macro to simplify return value storage */
347 #define STORE *(msg->opg_Storage)
348 struct MUI_ListviewData *data = INST_DATA(cl, obj);
350 switch (msg->opg_AttrID)
352 case MUIA_List_CompareHook:
353 case MUIA_List_ConstructHook:
354 case MUIA_List_DestructHook:
355 case MUIA_List_DisplayHook:
356 case MUIA_List_VertProp_First:
357 case MUIA_List_Format:
358 case MUIA_List_VertProp_Entries:
359 case MUIA_List_VertProp_Visible:
360 case MUIA_List_Active:
361 case MUIA_List_First:
362 case MUIA_List_Visible:
363 case MUIA_List_Entries:
364 case MUIA_List_Quiet:
365 return GetAttr(msg->opg_AttrID, data->list, msg->opg_Storage);
366 case MUIA_Listview_DoubleClick:
367 STORE = data->doubleclick;
368 return 1;
369 case MUIA_Listview_ClickColumn:
370 STORE = data->click_column;
371 return 1;
372 case MUIA_Listview_List:
373 STORE = (IPTR) data->list;
374 return 1;
377 return DoSuperMethodA(cl, obj, (Msg) msg);
378 #undef STORE
381 /**************************************************************************
382 MUIM_Setup
383 **************************************************************************/
384 IPTR Listview__MUIM_Setup(struct IClass *cl, Object *obj,
385 struct MUIP_Setup *msg)
387 struct MUI_ListviewData *data = INST_DATA(cl, obj);
389 if (!DoSuperMethodA(cl, obj, (Msg) msg))
390 return 0;
392 data->prefs_multi = muiGlobalInfo(obj)->mgi_Prefs->list_multi;
393 if (data->multiselect == MUIV_Listview_MultiSelect_Default)
395 if (data->prefs_multi == LISTVIEW_MULTI_SHIFTED)
396 data->multiselect = MUIV_Listview_MultiSelect_Shifted;
397 else
398 data->multiselect = MUIV_Listview_MultiSelect_Always;
401 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR) &data->ehn);
403 return 1;
406 /**************************************************************************
407 MUIM_Cleanup
408 **************************************************************************/
409 IPTR Listview__MUIM_Cleanup(struct IClass *cl, Object *obj,
410 struct MUIP_Cleanup *msg)
412 struct MUI_ListviewData *data = INST_DATA(cl, obj);
414 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR) &data->ehn);
415 data->mouse_click = 0;
417 return DoSuperMethodA(cl, obj, (Msg) msg);
420 /**************************************************************************
421 MUIM_HandleEvent
422 **************************************************************************/
423 IPTR Listview__MUIM_HandleEvent(struct IClass *cl, Object *obj,
424 struct MUIP_HandleEvent *msg)
426 struct MUI_ListviewData *data = INST_DATA(cl, obj);
427 Object *list = data->list;
428 struct MUI_List_TestPos_Result pos;
429 LONG seltype, old_active, new_active, visible;
430 IPTR result = 0;
431 BOOL select = FALSE, multiselect = FALSE, clear = FALSE;
432 WORD delta;
433 typeof(msg->muikey) muikey = msg->muikey;
435 new_active = old_active = XGET(list, MUIA_List_Active);
436 visible = XGET(list, MUIA_List_Visible);
438 if (muikey != MUIKEY_NONE)
440 result = MUI_EventHandlerRC_Eat;
442 /* Make keys behave differently in read-only mode */
443 if (data->read_only)
445 switch (muikey)
447 case MUIKEY_TOP:
448 muikey = MUIKEY_LINESTART;
449 break;
451 case MUIKEY_BOTTOM:
452 muikey = MUIKEY_LINEEND;
453 break;
455 case MUIKEY_UP:
456 muikey = MUIKEY_LEFT;
457 break;
459 case MUIKEY_DOWN:
460 case MUIKEY_PRESS:
461 muikey = MUIKEY_RIGHT;
462 break;
466 switch (muikey)
468 case MUIKEY_TOGGLE:
469 if (data->multiselect != MUIV_Listview_MultiSelect_None
470 && !data->read_only)
472 select = TRUE;
473 multiselect = TRUE;
474 seltype = MUIV_List_Select_Toggle;
475 data->click_column = data->def_click_column;
476 new_active = MUIV_List_Active_Down;
478 else
479 DoMethod(list, MUIM_List_Jump, 0);
480 break;
482 case MUIKEY_TOP:
483 new_active = MUIV_List_Active_Top;
484 break;
486 case MUIKEY_BOTTOM:
487 new_active = MUIV_List_Active_Bottom;
488 break;
490 case MUIKEY_LEFT:
491 case MUIKEY_WORDLEFT:
492 DoMethod(list, MUIM_List_Jump, MUIV_List_Jump_Up);
493 break;
495 case MUIKEY_RIGHT:
496 case MUIKEY_WORDRIGHT:
497 DoMethod(list, MUIM_List_Jump, MUIV_List_Jump_Down);
498 break;
500 case MUIKEY_LINESTART:
501 DoMethod(list, MUIM_List_Jump, MUIV_List_Jump_Top);
502 break;
504 case MUIKEY_LINEEND:
505 DoMethod(list, MUIM_List_Jump, MUIV_List_Jump_Bottom);
506 break;
508 case MUIKEY_UP:
509 new_active = MUIV_List_Active_Up;
510 break;
512 case MUIKEY_DOWN:
513 new_active = MUIV_List_Active_Down;
514 break;
516 case MUIKEY_PAGEUP:
517 if (data->read_only)
518 DoWheelMove(cl, obj, -visible);
519 else
520 new_active = MUIV_List_Active_PageUp;
521 break;
523 case MUIKEY_PAGEDOWN:
524 if (data->read_only)
525 DoWheelMove(cl, obj, visible);
526 else
527 new_active = MUIV_List_Active_PageDown;
528 break;
530 default:
531 result = 0;
534 if (new_active != old_active)
536 select = clear =
537 data->multiselect == MUIV_Listview_MultiSelect_None;
538 seltype = MUIV_List_Select_On;
541 else if (msg->imsg)
543 DoMethod(list, MUIM_List_TestPos, msg->imsg->MouseX,
544 msg->imsg->MouseY, (IPTR) &pos);
546 switch (msg->imsg->Class)
548 case IDCMP_MOUSEBUTTONS:
549 if (msg->imsg->Code == SELECTDOWN)
551 if (_isinobject(list, msg->imsg->MouseX, msg->imsg->MouseY))
553 data->mouse_click = MOUSE_CLICK_ENTRY;
555 if (!data->read_only)
557 new_active = pos.entry;
559 clear =
560 data->multiselect == MUIV_Listview_MultiSelect_None
561 || (data->multiselect
562 == MUIV_Listview_MultiSelect_Shifted
563 && (msg->imsg->Qualifier
564 & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)) == 0);
565 seltype = clear ?
566 MUIV_List_Select_On: MUIV_List_Select_Toggle;
567 select = new_active != old_active
568 || data->multiselect
569 != MUIV_Listview_MultiSelect_None;
571 /* Handle MUIA_Listview_ClickColumn */
572 data->click_column = pos.column;
574 if (data->last_active == pos.entry
575 && DoubleClick(data->last_secs, data->last_mics,
576 msg->imsg->Seconds, msg->imsg->Micros))
578 set(obj, MUIA_Listview_DoubleClick, TRUE);
579 data->last_active = -1;
580 data->last_secs = data->last_mics = 0;
582 else
584 data->last_active = pos.entry;
585 data->last_secs = msg->imsg->Seconds;
586 data->last_mics = msg->imsg->Micros;
589 DoMethod(_win(list), MUIM_Window_RemEventHandler,
590 (IPTR) &data->ehn);
591 data->ehn.ehn_Events |=
592 (IDCMP_MOUSEMOVE | IDCMP_INTUITICKS);
593 DoMethod(_win(list), MUIM_Window_AddEventHandler,
594 (IPTR) &data->ehn);
598 else
600 if (msg->imsg->Code == SELECTUP && data->mouse_click)
602 set(_win(obj), MUIA_Window_ActiveObject, (IPTR)obj);
603 data->mouse_click = 0;
606 DoMethod(_win(list), MUIM_Window_RemEventHandler,
607 (IPTR) &data->ehn);
608 data->ehn.ehn_Events &=
609 ~(IDCMP_MOUSEMOVE | IDCMP_INTUITICKS);
610 DoMethod(_win(list), MUIM_Window_AddEventHandler,
611 (IPTR) &data->ehn);
613 break;
615 case IDCMP_MOUSEMOVE:
616 case IDCMP_INTUITICKS:
617 if (pos.flags & MUI_LPR_ABOVE)
618 new_active = MUIV_List_Active_Up;
619 else if (pos.flags & MUI_LPR_BELOW)
620 new_active = MUIV_List_Active_Down;
621 else
622 new_active = pos.entry;
624 select = new_active != old_active;
626 if (select)
628 clear = data->multiselect == MUIV_Listview_MultiSelect_None;
629 if (clear)
630 seltype = MUIV_List_Select_On;
631 else
632 DoMethod(list, MUIM_List_Select, MUIV_List_Select_Active,
633 MUIV_List_Select_Ask, &seltype);
635 break;
637 case IDCMP_RAWKEY:
638 if (_isinobject(data->vert, msg->imsg->MouseX, msg->imsg->MouseY))
639 delta = 1;
640 else if (_isinobject(list, msg->imsg->MouseX, msg->imsg->MouseY))
641 delta = 4;
642 else
643 delta = 0;
645 if (delta != 0)
647 switch (msg->imsg->Code)
649 case RAWKEY_NM_WHEEL_UP:
650 DoWheelMove(cl, obj, -delta);
651 break;
653 case RAWKEY_NM_WHEEL_DOWN:
654 DoWheelMove(cl, obj, delta);
655 break;
657 result = MUI_EventHandlerRC_Eat;
659 break;
663 if (select || new_active != old_active)
665 multiselect = multiselect
666 || data->multiselect != MUIV_Listview_MultiSelect_None;
668 if (clear)
670 DoMethod(list, MUIM_List_Select, multiselect ?
671 MUIV_List_Select_All : MUIV_List_Select_Active,
672 MUIV_List_Select_Off, NULL);
674 if (multiselect && muikey == MUIKEY_TOGGLE)
676 DoMethod(list, MUIM_List_Select,
677 MUIV_List_Select_Active,
678 MUIV_List_Select_Toggle, NULL);
681 if (new_active != old_active)
682 set(list, MUIA_List_Active, new_active);
684 if (select)
685 DoMethod(list, MUIM_List_Select, MUIV_List_Select_Active,
686 seltype, NULL);
689 return result;
692 static void DoWheelMove(struct IClass *cl, Object *obj, LONG wheely)
694 struct MUI_ListviewData *data = INST_DATA(cl, obj);
695 LONG new, first, entries, visible;
697 new = first = XGET(data->list, MUIA_List_First);
698 entries = XGET(data->list, MUIA_List_Entries);
699 visible = XGET(data->list, MUIA_List_Visible);
701 new += wheely;
703 if (new > entries - visible)
705 new = entries - visible;
708 if (new < 0)
710 new = 0;
713 if (new != first)
715 set(data->list, MUIA_List_First, new);
719 BOOPSI_DISPATCHER(IPTR, Listview_Dispatcher, cl, obj, msg)
721 switch (msg->MethodID)
723 case OM_SET:
724 Listview__OM_SET(cl, obj, (struct opSet *)msg);
725 break;
726 case OM_GET:
727 return Listview__OM_GET(cl, obj, (struct opGet *)msg);
728 case OM_NEW:
729 return Listview__OM_NEW(cl, obj, (struct opSet *)msg);
730 case OM_DISPOSE:
731 return Listview__OM_DISPOSE(cl, obj, msg);
732 case MUIM_Setup:
733 return Listview__MUIM_Setup(cl, obj, (struct MUIP_Setup *)msg);
734 case MUIM_Cleanup:
735 return Listview__MUIM_Cleanup(cl, obj, (struct MUIP_Cleanup *)msg);
736 case MUIM_HandleEvent:
737 return Listview__MUIM_HandleEvent(cl, obj,
738 (struct MUIP_HandleEvent *)msg);
739 case MUIM_List_Clear:
740 case MUIM_List_CreateImage:
741 case MUIM_List_DeleteImage:
742 case MUIM_List_Exchange:
743 case MUIM_List_GetEntry:
744 case MUIM_List_Insert:
745 case MUIM_List_InsertSingle:
746 case MUIM_List_Jump:
747 case MUIM_List_NextSelected:
748 case MUIM_List_Redraw:
749 case MUIM_List_Remove:
750 case MUIM_List_Select:
751 case MUIM_List_Sort:
752 case MUIM_List_TestPos:
754 struct MUI_ListviewData *data = INST_DATA(cl, obj);
756 return DoMethodA(data->list, msg);
761 return DoSuperMethodA(cl, obj, msg);
763 BOOPSI_DISPATCHER_END
766 * Class descriptor.
768 const struct __MUIBuiltinClass _MUI_Listview_desc =
770 MUIC_Listview,
771 MUIC_Group,
772 sizeof(struct MUI_ListviewData),
773 (void *) Listview_Dispatcher