Safer handling of Booleans.
[AROS.git] / workbench / libs / muimaster / classes / listview.c
blob7ff3b0c1bbfacce69b15526a6215a3b5a87959cb
1 /*
2 Copyright © 2002-2012, 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 <clib/alib_protos.h>
11 #include <proto/exec.h>
12 #include <proto/graphics.h>
13 #include <proto/utility.h>
14 #include <proto/intuition.h>
15 #include <proto/muimaster.h>
17 #include "mui.h"
18 #include "muimaster_intern.h"
19 #include "support.h"
21 extern struct Library *MUIMasterBase;
23 struct MUI_ListviewData
25 Object *list, *group, *vert;
26 struct Hook *layout_hook;
27 struct Hook hook;
28 struct Hook selfnofity_hook;
29 BOOL noforward;
32 ULONG Listview_Layout_Function(struct Hook *hook, Object *obj,
33 struct MUI_LayoutMsg *lm)
35 struct MUI_ListviewData *data = (struct MUI_ListviewData *)hook->h_Data;
36 switch (lm->lm_Type)
38 case MUILM_MINMAX:
40 /* Calculate the minmax dimension of the group,
41 ** We only have a fixed number of children, so we need
42 ** no NextObject()
44 lm->lm_MinMax.MinWidth =
45 _minwidth(data->list) + _minwidth(data->vert);
46 lm->lm_MinMax.DefWidth =
47 _defwidth(data->list) + _defwidth(data->vert);
48 lm->lm_MinMax.MaxWidth =
49 _maxwidth(data->list) + _maxwidth(data->vert);
50 lm->lm_MinMax.MaxWidth =
51 MIN(lm->lm_MinMax.MaxWidth, MUI_MAXMAX);
53 lm->lm_MinMax.MinHeight =
54 MAX(_minheight(data->list), _minheight(data->vert));
55 lm->lm_MinMax.DefHeight =
56 MAX(_defheight(data->list), lm->lm_MinMax.MinHeight);
57 lm->lm_MinMax.MaxHeight =
58 MIN(_maxheight(data->list), _maxheight(data->vert));
59 lm->lm_MinMax.MaxHeight =
60 MIN(lm->lm_MinMax.MaxHeight, MUI_MAXMAX);
61 return 0;
64 case MUILM_LAYOUT:
66 /* Now place the objects between
67 * (0, 0, lm->lm_Layout.Width - 1, lm->lm_Layout.Height - 1)
70 LONG vert_width = _minwidth(data->vert);
71 LONG lay_width = lm->lm_Layout.Width;
72 LONG lay_height = lm->lm_Layout.Height;
73 LONG cont_width;
74 LONG cont_height;
76 /* We need all scrollbars and the button */
77 set(data->vert, MUIA_ShowMe, TRUE);
78 /* We could also overload MUIM_Show... */
79 cont_width = lay_width - vert_width;
80 cont_height = lay_height;
82 MUI_Layout(data->vert, cont_width, 0, vert_width, cont_height,
83 0);
85 /* Layout the group a second time, note that setting _mwidth() and
86 _mheight() should be enough, or we invent a new flag */
87 MUI_Layout(data->list, 0, 0, cont_width, cont_height, 0);
88 return 1;
91 return 0;
94 #define PROP_VERT_FIRST 1
95 #define LIST_VERT_FIRST 4
96 #define LIST_VERT_VISIBLE 5
97 #define LIST_VERT_ENTRIES 6
99 ULONG Listview_Function(struct Hook *hook, APTR dummyobj, void **msg)
101 struct MUI_ListviewData *data = (struct MUI_ListviewData *)hook->h_Data;
102 SIPTR type = (SIPTR) msg[0];
103 SIPTR val = (SIPTR) msg[1];
105 D(bug("[ListView] List 0x%p, Event %d, value %ld\n", data->list, type,
106 val));
108 switch (type)
110 case PROP_VERT_FIRST:
111 get(data->vert, MUIA_Prop_First, &val);
112 nnset(data->list, MUIA_List_VertProp_First, val);
113 break;
115 case LIST_VERT_FIRST:
116 nnset(data->vert, MUIA_Prop_First, val);
117 break;
118 case LIST_VERT_VISIBLE:
119 nnset(data->vert, MUIA_Prop_Visible, val);
120 break;
121 case LIST_VERT_ENTRIES:
122 nnset(data->vert, MUIA_Prop_Entries, val);
123 break;
125 return 0;
128 ULONG SelfNotify_Function(struct Hook *hook, APTR obj, void **msg)
130 struct MUI_ListviewData *data = (struct MUI_ListviewData *)hook->h_Data;
131 SIPTR attribute = (SIPTR) msg[0];
132 SIPTR value = (SIPTR) msg[1];
134 /* This allows avoiding notify loops */
135 data->noforward = TRUE;
136 SetAttrs(obj, MUIA_Group_Forward, FALSE, attribute, value, TAG_DONE);
137 data->noforward = FALSE;
139 return 0;
142 /**************************************************************************
143 OM_NEW
144 **************************************************************************/
145 IPTR Listview__OM_NEW(struct IClass *cl, Object *obj, struct opSet *msg)
147 struct MUI_ListviewData *data;
148 struct TagItem *tag, *tags;
149 struct Hook *layout_hook;
150 Object *group, *vert;
151 Object *list =
152 (Object *) GetTagData(MUIA_Listview_List, (IPTR) NULL,
153 msg->ops_AttrList);
154 IPTR cyclechain =
155 (IPTR) GetTagData(MUIA_CycleChain, (IPTR) 0, msg->ops_AttrList);
156 LONG entries = 0, first = 0, visible = 0;
157 if (!list)
158 return (IPTR) NULL;
160 layout_hook = mui_alloc_struct(struct Hook);
161 if (!layout_hook)
162 return (IPTR) NULL;
164 layout_hook->h_Entry = HookEntry;
165 layout_hook->h_SubEntry = (HOOKFUNC) Listview_Layout_Function;
167 obj = (Object *) DoSuperNewTags(cl, obj, NULL,
168 MUIA_Group_Horiz, FALSE,
169 MUIA_CycleChain, cyclechain,
170 MUIA_InnerLeft, 0,
171 MUIA_InnerRight, 0,
172 Child, (IPTR) (group = GroupObject,
173 MUIA_InnerLeft, 0,
174 MUIA_InnerRight, 0,
175 MUIA_Group_LayoutHook, (IPTR) layout_hook,
176 Child, (IPTR) list,
177 Child, (IPTR) (vert =
178 ScrollbarObject, MUIA_Group_Horiz, FALSE, End), End),
179 TAG_DONE);
181 if (!obj)
183 mui_free(layout_hook);
184 return (IPTR) NULL;
187 data = INST_DATA(cl, obj);
188 layout_hook->h_Data = data;
189 data->list = list;
190 data->vert = vert;
191 data->group = group;
192 data->layout_hook = layout_hook;
194 data->hook.h_Entry = HookEntry;
195 data->hook.h_SubEntry = (HOOKFUNC) Listview_Function;
196 data->hook.h_Data = data;
198 data->selfnofity_hook.h_Entry = HookEntry;
199 data->selfnofity_hook.h_SubEntry = (HOOKFUNC) SelfNotify_Function;
200 data->selfnofity_hook.h_Data = data;
201 data->noforward = FALSE;
203 /* parse initial taglist */
204 for (tags = msg->ops_AttrList; (tag = NextTagItem(&tags));)
206 switch (tag->ti_Tag)
211 get(list, MUIA_List_VertProp_First, &first);
212 get(list, MUIA_List_VertProp_Visible, &visible);
213 get(list, MUIA_List_VertProp_Entries, &entries);
215 D(bug
216 ("[ListView 0x%p] List 0x%p, First %ld, Visible %ld, Entries %ld\n",
217 obj, list, first, visible, entries));
219 SetAttrs(data->vert,
220 MUIA_Prop_First, first,
221 MUIA_Prop_Visible, visible, MUIA_Prop_Entries, entries, TAG_DONE);
223 DoMethod(vert, MUIM_Notify, MUIA_Prop_First, MUIV_EveryTime, (IPTR) obj,
224 4, MUIM_CallHook, (IPTR) & data->hook, PROP_VERT_FIRST,
225 MUIV_TriggerValue);
226 DoMethod(list, MUIM_Notify, MUIA_List_VertProp_First, MUIV_EveryTime,
227 (IPTR) obj, 4, MUIM_CallHook, (IPTR) & data->hook, LIST_VERT_FIRST,
228 MUIV_TriggerValue);
229 DoMethod(list, MUIM_Notify, MUIA_List_VertProp_Visible, MUIV_EveryTime,
230 (IPTR) obj, 4, MUIM_CallHook, (IPTR) & data->hook,
231 LIST_VERT_VISIBLE, MUIV_TriggerValue);
232 DoMethod(list, MUIM_Notify, MUIA_List_VertProp_Entries, MUIV_EveryTime,
233 (IPTR) obj, 4, MUIM_CallHook, (IPTR) & data->hook,
234 LIST_VERT_ENTRIES, MUIV_TriggerValue);
235 DoMethod(list, MUIM_Notify, MUIA_List_Active, MUIV_EveryTime,
236 (IPTR) obj, 4, MUIM_CallHook, (IPTR) & data->selfnofity_hook,
237 MUIA_List_Active, MUIV_TriggerValue);
239 return (IPTR) obj;
242 /**************************************************************************
243 OM_DISPOSE
244 **************************************************************************/
245 IPTR Listview__OM_DISPOSE(struct IClass *cl, Object *obj, Msg msg)
247 struct MUI_ListviewData *data = INST_DATA(cl, obj);
249 mui_free(data->layout_hook); /* is always here */
250 return DoSuperMethodA(cl, obj, msg);
253 /**************************************************************************
254 OM_SET
255 **************************************************************************/
256 void ListView__OM_SET(struct IClass *cl, Object *obj, struct opSet *msg)
258 struct TagItem *tag, *tags;
259 IPTR no_notify = GetTagData(MUIA_NoNotify, FALSE, msg->ops_AttrList);
260 struct MUI_ListviewData *data = INST_DATA(cl, obj);
262 if (data->noforward)
264 DoSuperMethodA(cl, obj, (Msg) msg);
265 return;
268 for (tags = msg->ops_AttrList; (tag = NextTagItem(&tags));)
270 switch (tag->ti_Tag)
272 case MUIA_List_CompareHook:
273 case MUIA_List_ConstructHook:
274 case MUIA_List_DestructHook:
275 case MUIA_List_DisplayHook:
276 case MUIA_List_VertProp_First:
277 case MUIA_List_Format:
278 case MUIA_List_VertProp_Entries:
279 case MUIA_List_VertProp_Visible:
280 case MUIA_List_Active:
281 case MUIA_List_First:
282 case MUIA_List_Visible:
283 case MUIA_List_Entries:
284 case MUIA_List_Quiet:
286 struct MUI_ListviewData *data = INST_DATA(cl, obj);
288 SetAttrs(data->list, MUIA_NoNotify, no_notify, tag->ti_Tag,
289 tag->ti_Data, TAG_DONE);
295 /**************************************************************************
296 OM_GET
297 **************************************************************************/
298 IPTR ListView__OM_GET(struct IClass *cl, Object *obj, struct opGet *msg)
300 /* small macro to simplify return value storage */
301 #define STORE *(msg->opg_Storage)
302 struct MUI_ListviewData *data = INST_DATA(cl, obj);
304 switch (msg->opg_AttrID)
306 case MUIA_List_CompareHook:
307 case MUIA_List_ConstructHook:
308 case MUIA_List_DestructHook:
309 case MUIA_List_DisplayHook:
310 case MUIA_List_VertProp_First:
311 case MUIA_List_Format:
312 case MUIA_List_VertProp_Entries:
313 case MUIA_List_VertProp_Visible:
314 case MUIA_List_Active:
315 case MUIA_List_First:
316 case MUIA_List_Visible:
317 case MUIA_List_Entries:
318 case MUIA_List_Quiet:
320 struct MUI_ListviewData *data = INST_DATA(cl, obj);
322 return GetAttr(msg->opg_AttrID, data->list, msg->opg_Storage);
324 case MUIA_Listview_List:
325 STORE = (IPTR) data->list;
326 return 1;
329 return DoSuperMethodA(cl, obj, (Msg) msg);
330 #undef STORE
333 BOOPSI_DISPATCHER(IPTR, Listview_Dispatcher, cl, obj, msg)
335 switch (msg->MethodID)
337 case OM_SET:
338 ListView__OM_SET(cl, obj, (struct opSet *)msg);
339 break;
340 case OM_GET:
341 return ListView__OM_GET(cl, obj, (struct opGet *)msg);
342 case OM_NEW:
343 return Listview__OM_NEW(cl, obj, (struct opSet *)msg);
344 case OM_DISPOSE:
345 return Listview__OM_DISPOSE(cl, obj, msg);
346 case MUIM_List_Clear:
347 case MUIM_List_CreateImage:
348 case MUIM_List_DeleteImage:
349 case MUIM_List_Exchange:
350 case MUIM_List_GetEntry:
351 case MUIM_List_Insert:
352 case MUIM_List_InsertSingle:
353 case MUIM_List_Jump:
354 case MUIM_List_NextSelected:
355 case MUIM_List_Redraw:
356 case MUIM_List_Remove:
357 case MUIM_List_Select:
358 case MUIM_List_Sort:
359 case MUIM_List_TestPos:
361 struct MUI_ListviewData *data = INST_DATA(cl, obj);
363 return DoMethodA(data->list, msg);
368 return DoSuperMethodA(cl, obj, msg);
370 BOOPSI_DISPATCHER_END
373 * Class descriptor.
375 const struct __MUIBuiltinClass _MUI_Listview_desc =
377 MUIC_Listview,
378 MUIC_Group,
379 sizeof(struct MUI_ListviewData),
380 (void *) Listview_Dispatcher