1 /***************************************************************************
3 NListview.mcc - New Listview MUI Custom Class
4 Registered MUI class, Serial Number: 1d51 (0x9d510020 to 0x9d51002F)
6 Copyright (C) 1996-2001 by Gilles Masson
7 Copyright (C) 2001-2014 NList Open Source Team
9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Lesser General Public
11 License as published by the Free Software Foundation; either
12 version 2.1 of the License, or (at your option) any later version.
14 This library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
19 NList classes Support Site: http://www.sf.net/projects/nlist-classes
23 ***************************************************************************/
27 #include <clib/alib_protos.h>
28 #include <proto/muimaster.h>
29 #include <proto/intuition.h>
30 #include <proto/utility.h>
31 #include <proto/keymap.h>
36 #include "NListviews_mcp.h"
42 #ifndef MUI_EHF_GUIMODE
43 #define MUI_EHF_GUIMODE (1<<1) /* set this if you dont want your handler to be called */
44 /* when your object is disabled or invisible */
47 static LONG
IMsgToChar(struct IntuiMessage
*imsg
, ULONG dccode
, ULONG dcquali
)
54 memset(&ie
, 0, sizeof(struct InputEvent
));
55 ie
.ie_Class
= IECLASS_RAWKEY
;
57 if(imsg
->Class
== IDCMP_RAWKEY
)
61 ie
.ie_Code
= imsg
->Code
& ~dccode
;
62 ie
.ie_Qualifier
= imsg
->Qualifier
& ~dcquali
;
63 ie
.ie_EventAddress
= (APTR
*)*((IPTR
*)imsg
->IAddress
);
65 #if defined(__amigaos4__)
66 ie
.ie_TimeStamp
.Seconds
= imsg
->Seconds
;
67 ie
.ie_TimeStamp
.Microseconds
= imsg
->Micros
;
69 ie
.ie_TimeStamp
.tv_secs
= imsg
->Seconds
;
70 ie
.ie_TimeStamp
.tv_micro
= imsg
->Micros
;
73 if(MapRawKey(&ie
, buf
, 3, 0) > 0)
81 static IPTR
mNLV_HandleEvent(struct IClass
*cl
, Object
*obj
, struct MUIP_HandleEvent
*msg
)
83 struct NLVData
*data
= INST_DATA(cl
, obj
);
84 struct IntuiMessage
*imsg
= msg
->imsg
;
89 if(data
->LI_NList
!= NULL
)
91 #if !defined(__amigaos4__) && !defined(__MORPHOS__) && !defined(__AROS__)
92 // with MUI 3.8 the embedded list object doesn't get this method,
93 // hence we must forward it ourself.
94 if(MUIMasterBase
!= NULL
&& MUIMasterBase
->lib_Version
<= 19 && msg
->muikey
!= MUIKEY_NONE
)
96 result
= DoMethodA(data
->LI_NList
, (Msg
)msg
);
105 if(data
->ControlChar
!= '\0' && IMsgToChar(imsg
, 0, (IEQUALIFIER_LSHIFT
|IEQUALIFIER_RSHIFT
)) == data
->ControlChar
)
107 set(data
->LI_NList
, MUIA_NList_Active
, imsg
->Qualifier
& (IEQUALIFIER_LSHIFT
|IEQUALIFIER_RSHIFT
) ? MUIV_NList_Active_Up
: MUIV_NList_Active_Down
);
119 static IPTR
mNLV_HandleInput(struct IClass
*cl
, Object
*obj
, struct MUIP_HandleInput
*msg
)
121 struct NLVData
*data
= INST_DATA(cl
, obj
);
126 if(data
->LI_NList
!= NULL
&& msg
->muikey
!= MUIKEY_NONE
)
127 result
= DoMethodA(data
->LI_NList
, (Msg
)msg
);
129 result
= DoSuperMethodA(cl
, obj
, (Msg
)msg
);
135 static void AddVerticalScroller(Object
*obj
, struct NLVData
*data
)
139 if(data
->Vert_Attached
== FALSE
)
146 D(DBF_STARTUP
, "adding vertical scrollbar");
148 // restore the list's current disabled state, because the scrollbar might
149 // have been removed in disabled state and the list has been reactivated
151 set(data
->PR_Vert
, MUIA_Disabled
, xget(data
->LI_NList
, MUIA_Disabled
));
152 DoMethod(obj
, OM_ADDMEMBER
, data
->PR_Vert
);
155 DoMethod(data
->LI_NList
, MUIM_Notify
, MUIA_NList_Prop_Entries
, MUIV_EveryTime
, data
->PR_Vert
, 3, MUIM_NoNotifySet
, MUIA_Prop_Entries
, MUIV_TriggerValue
);
156 DoMethod(data
->LI_NList
, MUIM_Notify
, MUIA_NList_Prop_Visible
, MUIV_EveryTime
, data
->PR_Vert
, 3, MUIM_NoNotifySet
, MUIA_Prop_Visible
, MUIV_TriggerValue
);
157 DoMethod(data
->LI_NList
, MUIM_Notify
, MUIA_NList_Prop_First
, MUIV_EveryTime
, data
->PR_Vert
, 3, MUIM_NoNotifySet
, MUIA_Prop_First
, MUIV_TriggerValue
);
158 DoMethod(data
->PR_Vert
, MUIM_Notify
, MUIA_Prop_First
, MUIV_EveryTime
, data
->LI_NList
, 3, MUIM_NoNotifySet
, MUIA_NList_Prop_First
, MUIV_TriggerValue
);
159 DoMethod(data
->LI_NList
, MUIM_Notify
, MUIA_NList_VertDeltaFactor
, MUIV_EveryTime
, data
->PR_Vert
, 3, MUIM_NoNotifySet
, MUIA_Prop_DeltaFactor
, MUIV_TriggerValue
);
161 // Get and set the attributes we just have installed the notifications for to
162 // immediately trigger them. Otherwise hiding and showing again the scrollbar
163 // while the number of entries changed in the meantime will result in wrong
164 // scrollbar dimensions (i.e. when switching folders in YAM).
165 entries
= xget(data
->LI_NList
, MUIA_NList_Prop_Entries
);
166 visible
= xget(data
->LI_NList
, MUIA_NList_Prop_Visible
);
167 first
= xget(data
->LI_NList
, MUIA_NList_Prop_First
);
168 deltaFactor
= xget(data
->LI_NList
, MUIA_NList_VertDeltaFactor
);
169 SetAttrs(data
->LI_NList
,
170 MUIA_NList_Prop_Entries
, entries
,
171 MUIA_NList_Prop_Visible
, visible
,
172 MUIA_NList_Prop_First
, first
,
173 MUIA_NList_VertDeltaFactor
, deltaFactor
,
176 data
->Vert_Attached
= TRUE
;
178 D(DBF_STARTUP
, "vertical scrollbar added");
184 static void RemoveVerticalScroller(Object
*obj
, struct NLVData
*data
)
188 if(data
->Vert_Attached
== TRUE
)
190 D(DBF_STARTUP
, "removing vertical scrollbar");
192 // remove notifications
193 DoMethod(data
->LI_NList
, MUIM_KillNotifyObj
, MUIA_NList_Prop_Entries
, data
->PR_Vert
);
194 DoMethod(data
->LI_NList
, MUIM_KillNotifyObj
, MUIA_NList_Prop_Visible
, data
->PR_Vert
);
195 DoMethod(data
->LI_NList
, MUIM_KillNotifyObj
, MUIA_NList_Prop_First
, data
->PR_Vert
);
196 DoMethod(data
->PR_Vert
, MUIM_KillNotifyObj
, MUIA_Prop_First
, data
->LI_NList
);
197 DoMethod(data
->LI_NList
, MUIM_KillNotifyObj
, MUIA_NList_VertDeltaFactor
, data
->PR_Vert
);
199 DoMethod(obj
, OM_REMMEMBER
, data
->PR_Vert
);
201 data
->Vert_Attached
= FALSE
;
203 D(DBF_STARTUP
, "vertical scrollbar removed");
209 static void AddHorizontalScroller(Object
*obj
, struct NLVData
*data
)
213 if(data
->Horiz_Attached
== FALSE
)
221 D(DBF_STARTUP
, "adding horizontal scrollbar");
223 // restore the list's current disabled state, because the scrollbar might
224 // have been removed in disabled state and the list has been reactivated
226 set(data
->PR_Horiz
, MUIA_Disabled
, xget(data
->LI_NList
, MUIA_Disabled
));
227 DoMethod(obj
, OM_ADDMEMBER
, data
->PR_Horiz
);
230 DoMethod(data
->LI_NList
, MUIM_Notify
, MUIA_NList_Horiz_Entries
, MUIV_EveryTime
, data
->PR_Horiz
, 3, MUIM_NoNotifySet
, MUIA_Prop_Entries
, MUIV_TriggerValue
);
231 DoMethod(data
->LI_NList
, MUIM_Notify
, MUIA_NList_Horiz_Visible
, MUIV_EveryTime
, data
->PR_Horiz
, 3, MUIM_NoNotifySet
, MUIA_Prop_Visible
, MUIV_TriggerValue
);
232 DoMethod(data
->LI_NList
, MUIM_Notify
, MUIA_NList_Horiz_First
, MUIV_EveryTime
, data
->PR_Horiz
, 3, MUIM_NoNotifySet
, MUIA_Prop_First
, MUIV_TriggerValue
);
233 DoMethod(data
->PR_Horiz
, MUIM_Notify
, MUIA_Prop_First
, MUIV_EveryTime
, data
->LI_NList
, 3, MUIM_NoNotifySet
, MUIA_NList_Horiz_First
, MUIV_TriggerValue
);
234 DoMethod(data
->LI_NList
, MUIM_Notify
, MUIA_NList_HorizDeltaFactor
, MUIV_EveryTime
, data
->PR_Horiz
, 3, MUIM_NoNotifySet
, MUIA_Prop_DeltaFactor
, MUIV_TriggerValue
);
236 // Get and set the attributes we just have installed the notifications for to
237 // immediately trigger them. Otherwise hiding and showing again the scrollbar
238 // while the number of entries changed in the meantime will result in wrong
239 // scrollbar dimensions (i.e. when switching folders in YAM).
240 active
= xget(data
->LI_NList
, MUIA_NList_Active
);
241 entries
= xget(data
->LI_NList
, MUIA_NList_Horiz_Entries
);
242 visible
= xget(data
->LI_NList
, MUIA_NList_Horiz_Visible
);
243 first
= xget(data
->LI_NList
, MUIA_NList_Horiz_First
);
244 deltaFactor
= xget(data
->LI_NList
, MUIA_NList_HorizDeltaFactor
);
245 SetAttrs(data
->LI_NList
,
246 MUIA_NList_Horiz_Entries
, entries
,
247 MUIA_NList_Horiz_Visible
, visible
,
248 MUIA_NList_Horiz_First
, first
,
249 MUIA_NList_HorizDeltaFactor
, deltaFactor
,
252 // make sure the active entry is still visible after adding the scrollbar
253 // since the scrollbar is added at the bottom we only have to check for the
255 entries
= xget(data
->LI_NList
, MUIA_NList_Entries
);
256 visible
= xget(data
->LI_NList
, MUIA_NList_Visible
);
257 first
= xget(data
->LI_NList
, MUIA_NList_First
);
258 if(active
== first
+visible
-1)
260 // the method must be pushed because we are currently inside a InitChange/ExitChange pair
261 // and the final height of the list cannot yet be determined correctly
262 // Additionally we must have completed the MUIM_Setup method to have a valid application pointer
263 if(data
->SETUP
== TRUE
)
264 DoMethod(_app(obj
), MUIM_Application_PushMethod
, data
->LI_NList
, 2, MUIM_NList_Jump
, active
);
267 data
->Horiz_Attached
= TRUE
;
269 D(DBF_STARTUP
, "horizontal scrollbar added");
275 static void RemoveHorizontalScroller(Object
*obj
, struct NLVData
*data
)
279 if(data
->Horiz_Attached
== TRUE
)
281 D(DBF_STARTUP
, "removing horizontal scrollbar");
283 // remove notifications
284 DoMethod(data
->LI_NList
, MUIM_KillNotifyObj
, MUIA_NList_Horiz_Entries
, data
->PR_Horiz
);
285 DoMethod(data
->LI_NList
, MUIM_KillNotifyObj
, MUIA_NList_Horiz_Visible
, data
->PR_Horiz
);
286 DoMethod(data
->LI_NList
, MUIM_KillNotifyObj
, MUIA_NList_Horiz_First
, data
->PR_Horiz
);
287 DoMethod(data
->PR_Horiz
, MUIM_KillNotifyObj
, MUIA_Prop_First
, data
->LI_NList
);
288 DoMethod(data
->LI_NList
, MUIM_KillNotifyObj
, MUIA_NList_HorizDeltaFactor
, data
->PR_Horiz
);
290 DoMethod(obj
, OM_REMMEMBER
, data
->PR_Horiz
);
292 data
->Horiz_Attached
= FALSE
;
294 D(DBF_STARTUP
, "horizontal scrollbar removed");
300 static void NLV_Scrollers(Object
*obj
, struct NLVData
*data
, LONG vert
, LONG horiz
)
307 #if defined(__amigaos3__) || defined(__amigaos4__)
308 if(LIB_VERSION_IS_AT_LEAST(MUIMasterBase
, 20, 5824))
310 // MUI4 for AmigaOS is safe for V20.5824+
313 else if(LIB_VERSION_IS_AT_LEAST(MUIMasterBase
, 20, 2346) && LIBREV(MUIMasterBase
) < 5000)
315 // MUI3.9 for AmigaOS is safe for V20.2346+
320 // MUI 3.8 and older version of MUI 3.9 or MUI4 are definitely unsafe
321 safeNotifies
= FALSE
;
324 // MorphOS and AROS must be considered unsafe unless someone from the
325 // MorphOS/AROS team confirms that removing notifies in nested OM_SET
327 safeNotifies
= FALSE
;
332 data
->Vert_ScrollBar
= vert
& 0x0F;
334 if(data
->Vert_ScrollBar
== MUIV_NListview_VSB_Default
)
338 if(DoMethod(obj
, MUIM_GetConfigItem
, MUICFG_NListview_VSB
, (IPTR
)&scrollbar
))
339 data
->VertSB
= *scrollbar
;
341 data
->VertSB
= MUIV_NListview_VSB_Always
;
344 data
->VertSB
= data
->Vert_ScrollBar
;
346 // switch to always visible scrollbars if removing notifies is unsafe
347 if(safeNotifies
== FALSE
)
348 data
->VertSB
= MUIV_NListview_VSB_Always
;
352 case MUIV_NListview_VSB_Always
:
353 case MUIV_NListview_VSB_Left
:
355 scrollers
|= MUIV_NListview_VSB_On
;
359 case MUIV_NListview_VSB_Auto
:
360 case MUIV_NListview_VSB_FullAuto
:
366 case MUIV_NListview_VSB_None
:
368 scrollers
|= MUIV_NListview_VSB_Off
;
376 data
->Horiz_ScrollBar
= horiz
& 0x0F;
378 if(data
->Horiz_ScrollBar
== MUIV_NListview_HSB_Default
)
382 if(DoMethod(obj
, MUIM_GetConfigItem
, MUICFG_NListview_HSB
, (IPTR
)&scrollbar
))
383 data
->HorizSB
= *scrollbar
;
385 data
->HorizSB
= DEFAULT_HSB
;
388 data
->HorizSB
= data
->Horiz_ScrollBar
;
390 // switch to always visible scrollbars if removing notifies is unsafe
391 if(safeNotifies
== FALSE
)
392 data
->HorizSB
= MUIV_NListview_VSB_Always
;
394 switch (data
->HorizSB
)
396 case MUIV_NListview_HSB_Always
:
398 scrollers
|= MUIV_NListview_HSB_On
;
402 case MUIV_NListview_HSB_Auto
:
403 case MUIV_NListview_HSB_FullAuto
:
409 case MUIV_NListview_HSB_None
:
411 scrollers
|= MUIV_NListview_HSB_Off
;
417 scrollers
|= ((vert
| horiz
) & (MUIV_NListview_VSB_On
| MUIV_NListview_HSB_On
));
419 if(((data
->VertSB
== MUIV_NListview_VSB_Auto
|| data
->VertSB
== MUIV_NListview_VSB_Always
) && (scrollers
& MUIV_NListview_VSB_On
) == MUIV_NListview_VSB_Off
) ||
420 (data
->VertSB
== MUIV_NListview_VSB_None
&& (scrollers
& MUIV_NListview_VSB_On
) == MUIV_NListview_VSB_On
) ||
421 (data
->Vert_Attached
== TRUE
&& (scrollers
& MUIV_NListview_VSB_On
) == MUIV_NListview_VSB_On
) ||
422 (data
->Vert_Attached
== FALSE
&& (scrollers
& MUIV_NListview_VSB_On
) == MUIV_NListview_VSB_Off
))
424 scrollers
&= ~MUIV_NListview_VSB_On
;
427 if(((data
->HorizSB
== MUIV_NListview_HSB_Auto
|| data
->HorizSB
== MUIV_NListview_HSB_Always
) && (scrollers
& MUIV_NListview_HSB_On
) == MUIV_NListview_HSB_Off
) ||
428 (data
->HorizSB
== MUIV_NListview_HSB_None
&& (scrollers
& MUIV_NListview_HSB_On
) == MUIV_NListview_HSB_On
) ||
429 (data
->Horiz_Attached
== TRUE
&& (scrollers
& MUIV_NListview_HSB_On
) == MUIV_NListview_HSB_On
) ||
430 (data
->Horiz_Attached
== FALSE
&& (scrollers
& MUIV_NListview_HSB_On
) == MUIV_NListview_HSB_Off
))
432 scrollers
&= ~MUIV_NListview_HSB_On
;
435 // Don't do the dirty work of adding/removing the scrollbars here directly,
436 // but delay this until the application is idle again. This is necessary,
437 // because the OM_SET method calling this function can be called from within
438 // an OM_SET method of our group object. Removing any scrollbar in this
439 // situation will cause an access to the just removed object (or better its
440 // Exec node structure) which has become invalid due to the removal.
441 // The AmigaOS4 debug kernel shows this very good, because an access to the
442 // address 0xcccccccc happens which definitely proves the invalid access.
443 if(scrollers
& (MUIV_NListview_VSB_On
|MUIV_NListview_HSB_On
))
445 // we must have completed the MUIM_Setup method to have a valid application pointer
446 if(data
->SETUP
== TRUE
)
447 DoMethod(_app(obj
), MUIM_Application_PushMethod
, obj
, 2, MUIM_NListview_SetScrollers
, scrollers
);
453 #if !defined(__MORPHOS__)
455 static __attribute__ ((noinline
)) Object
* VARARGS68K
DoSuperNew(struct IClass
*cl
, Object
*obj
, Tag tag1
, ...)
457 AROS_SLOWSTACKTAGS_PRE_AS(tag1
, Object
*)
458 retval
= (Object
*)DoSuperMethod(cl
, obj
, OM_NEW
, AROS_SLOWSTACKTAGS_ARG(tag1
), NULL
);
459 AROS_SLOWSTACKTAGS_POST
462 static Object
* VARARGS68K
DoSuperNew(struct IClass
*cl
, Object
*obj
, ...)
470 rc
= (Object
*)DoSuperMethod(cl
, obj
, OM_NEW
, VA_ARG(args
, ULONG
), NULL
);
477 #endif // !__MORPHOS__
479 /* static ULONG mNLV_New(struct IClass *cl,Object *obj,Msg msg) */
480 static IPTR
mNLV_New(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
482 struct NLVData
*data
;
484 Object
*nlist
= NULL
;
485 Object
*vgroup
= NULL
;
486 BOOL cyclechain
= FALSE
;
487 BOOL dropable
= FALSE
;
491 if((tag
= FindTagItem(MUIA_Draggable
, msg
->ops_AttrList
)) != NULL
)
492 tag
->ti_Tag
= TAG_IGNORE
;
494 if((tag
= FindTagItem(MUIA_Dropable
, msg
->ops_AttrList
)) != NULL
)
496 tag
->ti_Tag
= TAG_IGNORE
;
497 dropable
= tag
->ti_Data
;
500 if((tag
= FindTagItem(MUIA_CycleChain
, msg
->ops_AttrList
)) != NULL
)
502 tag
->ti_Tag
= TAG_IGNORE
;
503 cyclechain
= tag
->ti_Data
;
506 if((tag
= FindTagItem(MUIA_NListview_NList
, msg
->ops_AttrList
)) != NULL
||
507 (tag
= FindTagItem(MUIA_Listview_List
, msg
->ops_AttrList
)) != NULL
)
509 nlist
= (Object
*) tag
->ti_Data
;
515 nnset(nlist
,MUIA_Dropable
, dropable
);
518 if((tag
= FindTagItem(MUIA_NList_DragType
, msg
->ops_AttrList
)) != NULL
||
519 (tag
= FindTagItem(MUIA_Listview_DragType
, msg
->ops_AttrList
)) != NULL
)
521 nnset(nlist
,tag
->ti_Tag
,tag
->ti_Data
);
524 if((tag
= FindTagItem(MUIA_Listview_Input
, msg
->ops_AttrList
)) != NULL
||
525 (tag
= FindTagItem(MUIA_NList_Input
, msg
->ops_AttrList
)) != NULL
)
527 nnset(nlist
,tag
->ti_Tag
,tag
->ti_Data
);
530 if((tag
= FindTagItem(MUIA_Listview_MultiSelect
, msg
->ops_AttrList
)) != NULL
||
531 (tag
= FindTagItem(MUIA_NList_MultiSelect
, msg
->ops_AttrList
)) != NULL
)
533 nnset(nlist
,tag
->ti_Tag
,tag
->ti_Data
);
536 if((tag
= FindTagItem(MUIA_Listview_DoubleClick
, msg
->ops_AttrList
)) != NULL
||
537 (tag
= FindTagItem(MUIA_NList_DoubleClick
, msg
->ops_AttrList
)) != NULL
)
539 nnset(nlist
,tag
->ti_Tag
,tag
->ti_Data
);
542 if((tag
= FindTagItem(MUIA_Listview_DefClickColumn
, msg
->ops_AttrList
)) != NULL
||
543 (tag
= FindTagItem(MUIA_NList_DefClickColumn
, msg
->ops_AttrList
)) != NULL
)
545 nnset(nlist
,tag
->ti_Tag
,tag
->ti_Data
);
557 nlist
= MUI_NewObject(MUIC_NList
, MUIA_Dropable
, dropable
, TAG_MORE
, msg
->ops_AttrList
);
560 obj
= (Object
*)DoSuperNew(cl
, obj
,
561 MUIA_Group_Horiz
, TRUE
,
562 MUIA_Group_Spacing
, 0,
563 MUIA_CycleChain
, cyclechain
,
565 Child
, vgroup
= VGroup
,
566 MUIA_Group_Spacing
, 0,
569 TAG_MORE
, msg
->ops_AttrList
574 data
= INST_DATA(cl
,obj
);
577 data
->LI_NList
= nlist
;
578 data
->Group
= vgroup
;
579 data
->Vert_Attached
= FALSE
;
580 data
->Horiz_Attached
= FALSE
;
581 data
->Vert_ScrollBar
= MUIV_NListview_VSB_Default
;
582 data
->Horiz_ScrollBar
= MUIV_NListview_HSB_Default
;
583 if((tag
= FindTagItem(MUIA_Listview_ScrollerPos
, msg
->ops_AttrList
)) != NULL
)
585 if(tag
->ti_Data
== MUIV_Listview_ScrollerPos_None
)
587 data
->Vert_ScrollBar
= MUIV_NListview_VSB_None
;
588 data
->Horiz_ScrollBar
= MUIV_NListview_HSB_None
;
590 else if(tag
->ti_Data
== MUIV_Listview_ScrollerPos_Left
)
592 data
->Vert_ScrollBar
= MUIV_NListview_VSB_Left
;
594 else if(tag
->ti_Data
== MUIV_Listview_ScrollerPos_Right
)
596 data
->Vert_ScrollBar
= MUIV_NListview_VSB_Always
;
600 if((tag
= FindTagItem(MUIA_NListview_Vert_ScrollBar
, msg
->ops_AttrList
)) != NULL
)
601 data
->Vert_ScrollBar
= tag
->ti_Data
;
603 if((tag
= FindTagItem(MUIA_NListview_Horiz_ScrollBar
, msg
->ops_AttrList
)) != NULL
)
604 data
->Horiz_ScrollBar
= tag
->ti_Data
;
606 if((tag
= FindTagItem(MUIA_ControlChar
, msg
->ops_AttrList
)) != NULL
)
607 data
->ControlChar
= tag
->ti_Data
;
609 data
->VertSB
= data
->Vert_ScrollBar
;
610 data
->HorizSB
= data
->Horiz_ScrollBar
;
612 // create the two scrollbar objects
613 data
->PR_Vert
= ScrollbarObject
,
614 MUIA_Group_Horiz
, FALSE
,
617 data
->PR_Horiz
= ScrollbarObject
,
618 MUIA_Group_Horiz
, TRUE
,
621 DoMethod(data
->LI_NList
, MUIM_Notify
, MUIA_NListview_Horiz_ScrollBar
, MUIV_EveryTime
, obj
, 3, MUIM_Set
, MUIA_NListview_Horiz_ScrollBar
, MUIV_TriggerValue
);
623 set(data
->LI_NList
, MUIA_NList_KeepActive
, (IPTR
)obj
);
625 // derive the "active border visible" setting from the embedded list
626 if(xget(data
->LI_NList
, MUIA_NList_ActiveObjectOnClick
) == TRUE
)
627 _flags(obj
) |= (1<<7);
635 static IPTR
mNLV_Dispose(struct IClass
*cl
,Object
*obj
,Msg msg
)
637 struct NLVData
*data
= INST_DATA(cl
, obj
);
641 // dispose the scrollbars if they are not currently part of the layout
642 if(data
->PR_Vert
!= NULL
&& data
->Vert_Attached
== FALSE
)
644 MUI_DisposeObject(data
->PR_Vert
);
645 data
->PR_Vert
= NULL
;
647 if(data
->PR_Horiz
!= NULL
&& data
->Horiz_Attached
== FALSE
)
649 MUI_DisposeObject(data
->PR_Horiz
);
650 data
->PR_Horiz
= NULL
;
654 return DoSuperMethodA(cl
,obj
,msg
);
657 static IPTR
mNLV_Setup(struct IClass
*cl
, Object
*obj
, struct MUIP_Setup
*msg
)
659 struct NLVData
*data
= INST_DATA(cl
, obj
);
666 if(data
->sem
== FALSE
)
669 NLV_Scrollers(obj
, data
, data
->Vert_ScrollBar
, data
->Horiz_ScrollBar
);
673 // Add the event handler for RAWKEY now
674 data
->eh
.ehn_Class
= cl
;
675 data
->eh
.ehn_Object
= obj
;
676 data
->eh
.ehn_Events
= IDCMP_RAWKEY
;
677 data
->eh
.ehn_Flags
= MUI_EHF_GUIMODE
;
678 data
->eh
.ehn_Priority
= -1;
679 if(_win(obj
) != NULL
)
680 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
, (IPTR
)&data
->eh
);
682 if(DoSuperMethodA(cl
, obj
, (Msg
)msg
))
693 static IPTR
mNLV_Cleanup(struct IClass
*cl
, Object
*obj
, struct MUIP_Cleanup
*msg
)
695 struct NLVData
*data
= INST_DATA(cl
, obj
);
699 if(_win(obj
) != NULL
)
700 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, (IPTR
)&data
->eh
);
705 return DoSuperMethodA(cl
, obj
, (Msg
)msg
);
709 static IPTR
mNLV_Notify(struct IClass
*cl
, Object
*obj
, struct MUIP_Notify
*msg
)
711 struct NLVData
*data
= INST_DATA(cl
, obj
);
713 switch(msg
->TrigAttr
)
715 case MUIA_List_Prop_Entries
:
716 case MUIA_List_Prop_Visible
:
717 case MUIA_List_Prop_First
:
718 case MUIA_NList_Horiz_Entries
:
719 case MUIA_NList_Horiz_Visible
:
720 case MUIA_NList_Horiz_First
:
721 case MUIA_NList_HorizDeltaFactor
:
722 case MUIA_NList_Prop_Entries
:
723 case MUIA_NList_Prop_Visible
:
724 case MUIA_NList_Prop_First
:
725 case MUIA_NList_VertDeltaFactor
:
726 case MUIA_NList_SelectChange
:
727 case MUIA_NList_MultiClick
:
728 case MUIA_NList_DoubleClick
:
729 case MUIA_NList_EntryClick
:
730 case MUIA_NList_Active
:
731 case MUIA_NList_First
:
732 case MUIA_NList_Entries
:
733 case MUIA_NList_TitleClick
:
734 case MUIA_List_Active
:
735 case MUIA_Listview_SelectChange
:
736 case MUIA_Listview_DoubleClick
:
738 return DoMethodA(data
->LI_NList
, (Msg
)msg
);
742 return DoSuperMethodA(cl
, obj
, (Msg
)msg
);
748 static IPTR
mNLV_Set(struct IClass
*cl
,Object
*obj
,Msg msg
)
750 struct NLVData
*data
= INST_DATA(cl
, obj
);
751 struct TagItem
*tags
, *tag
;
755 tags
= ((struct opSet
*)msg
)->ops_AttrList
;
756 while((tag
= NextTagItem((APTR
)&tags
)) != NULL
)
760 case MUIA_Listview_ScrollerPos
:
762 if(tag
->ti_Data
== MUIV_Listview_ScrollerPos_None
)
763 tag
->ti_Data
= MUIV_NListview_VSB_None
;
764 else if(tag
->ti_Data
== MUIV_Listview_ScrollerPos_Left
)
765 tag
->ti_Data
= MUIV_NListview_VSB_Left
;
766 else if(tag
->ti_Data
== MUIV_Listview_ScrollerPos_Right
)
767 tag
->ti_Data
= MUIV_NListview_VSB_Always
;
769 tag
->ti_Data
= MUIV_NListview_VSB_Default
;
773 case MUIA_NListview_Vert_ScrollBar
:
775 tag
->ti_Tag
= TAG_IGNORE
;
776 if(data
->sem
== FALSE
)
779 NLV_Scrollers(obj
, data
, tag
->ti_Data
, 0);
785 case MUIA_NListview_Horiz_ScrollBar
:
787 tag
->ti_Tag
= TAG_IGNORE
;
788 if(data
->sem
== FALSE
)
791 NLV_Scrollers(obj
, data
, 0, tag
->ti_Data
);
797 case MUIA_NList_KeyUpFocus
:
798 case MUIA_NList_KeyDownFocus
:
799 case MUIA_NList_KeyLeftFocus
:
800 case MUIA_NList_KeyRightFocus
:
802 // forward these to the embedded list object
803 if(data
->LI_NList
!= NULL
)
804 set(data
->LI_NList
, tag
->ti_Tag
, tag
->ti_Data
);
811 return DoSuperMethodA(cl
, obj
, msg
);
815 static IPTR
mNLV_Get(struct IClass
*cl
,Object
*obj
,Msg msg
)
817 struct NLVData
*data
= INST_DATA(cl
, obj
);
818 IPTR
*store
= ((struct opGet
*)msg
)->opg_Storage
;
823 switch(((struct opGet
*)msg
)->opg_AttrID
)
825 case MUIA_Listview_List
:
826 case MUIA_NListview_NList
:
828 *store
= (IPTR
)data
->LI_NList
;
833 case MUIA_NListview_Vert_ScrollBar
:
835 *store
= (IPTR
)data
->VertSB
;
840 case MUIA_NListview_Horiz_ScrollBar
:
842 *store
= (IPTR
)data
->HorizSB
;
847 case MUIA_NListview_VSB_Width
:
849 if(data
->Vert_Attached
== TRUE
)
850 *store
= (IPTR
)_width(data
->PR_Vert
);
858 case MUIA_NListview_HSB_Height
:
860 if(data
->Horiz_Attached
== TRUE
)
861 *store
= (IPTR
)_height(data
->PR_Horiz
);
871 *store
= LIB_VERSION
;
878 *store
= LIB_REVISION
;
885 result
= DoSuperMethodA(cl
, obj
, msg
);
894 static IPTR
mNLV_GoActive(struct IClass
*cl
, Object
*obj
, Msg msg
)
896 struct NLVData
*data
= INST_DATA(cl
, obj
);
898 // forward the method to the NList object
899 D(DBF_ALWAYS
, "go active %08lx", obj
);
900 if(data
->LI_NList
!= NULL
)
901 DoMethod(data
->LI_NList
, MUIM_NList_GoActive
);
903 return DoSuperMethodA(cl
, obj
, msg
);
906 static IPTR
mNLV_GoInactive(struct IClass
*cl
, Object
*obj
, Msg msg
)
908 struct NLVData
*data
= INST_DATA(cl
, obj
);
910 D(DBF_ALWAYS
, "go inactive %08lx", obj
);
911 // forward the method to the NList object
912 if(data
->LI_NList
!= NULL
)
913 DoMethod(data
->LI_NList
, MUIM_NList_GoInactive
);
915 return DoSuperMethodA(cl
, obj
, msg
);
918 static IPTR
mNLV_SetScrollers(struct IClass
*cl
, Object
*obj
, struct MUIP_NListview_SetScrollers
*msg
)
920 struct NLVData
*data
= INST_DATA(cl
, obj
);
922 if(msg
->scrollers
& MUIV_NListview_VSB_On
)
924 if(data
->SETUP
== FALSE
|| DoMethod(obj
, MUIM_Group_InitChange
))
926 if((msg
->scrollers
& MUIV_NListview_VSB_On
) == MUIV_NListview_VSB_On
)
928 AddVerticalScroller(obj
, data
);
929 if(data
->VertSB
== MUIV_NListview_VSB_Left
)
930 DoMethod(obj
, MUIM_Group_Sort
, data
->PR_Vert
, data
->Group
, NULL
);
934 RemoveVerticalScroller(obj
, data
);
937 if(msg
->scrollers
& MUIV_NListview_HSB_On
)
939 if(data
->SETUP
== FALSE
|| DoMethod(data
->Group
, MUIM_Group_InitChange
))
941 if((msg
->scrollers
& MUIV_NListview_HSB_On
) == MUIV_NListview_HSB_On
)
942 AddHorizontalScroller(data
->Group
, data
);
944 RemoveHorizontalScroller(data
->Group
, data
);
946 if(data
->SETUP
== TRUE
)
947 DoMethod(data
->Group
, MUIM_Group_ExitChange
);
951 if(data
->SETUP
== TRUE
)
952 DoMethod(obj
, MUIM_Group_ExitChange
);
955 else if(msg
->scrollers
& MUIV_NListview_HSB_On
)
957 if(data
->SETUP
== FALSE
|| DoMethod(data
->Group
, MUIM_Group_InitChange
))
959 if((msg
->scrollers
& MUIV_NListview_HSB_On
) == MUIV_NListview_HSB_On
)
960 AddHorizontalScroller(data
->Group
, data
);
962 RemoveHorizontalScroller(data
->Group
, data
);
964 if(data
->SETUP
== TRUE
)
965 DoMethod(data
->Group
, MUIM_Group_ExitChange
);
972 DISPATCHER(_Dispatcher
)
974 switch(msg
->MethodID
)
976 case OM_NEW
: return(mNLV_New(cl
,obj
,(APTR
)msg
));
977 case OM_DISPOSE
: return(mNLV_Dispose(cl
,obj
,(APTR
)msg
));
978 case OM_GET
: return(mNLV_Get(cl
,obj
,(APTR
)msg
));
979 case OM_SET
: return(mNLV_Set(cl
,obj
,(APTR
)msg
));
980 case MUIM_Setup
: return(mNLV_Setup(cl
,obj
,(APTR
)msg
));
981 case MUIM_Cleanup
: return(mNLV_Cleanup(cl
,obj
,(APTR
)msg
));
982 case MUIM_HandleInput
: return(mNLV_HandleInput(cl
,obj
,(APTR
)msg
));
983 case MUIM_HandleEvent
: return(mNLV_HandleEvent(cl
,obj
,(APTR
)msg
));
984 case MUIM_NList_QueryBeginning
: return(0);
985 case MUIM_DragQuery
: return(MUIV_DragQuery_Refuse
);
987 // we catch all notify relevant method
988 // calls in one function
989 case MUIM_KillNotify
:
990 case MUIM_KillNotifyObj
:
991 case MUIM_Notify
: return (mNLV_Notify(cl
,obj
,(APTR
)msg
));
993 case MUIM_GoActive
: return mNLV_GoActive(cl
, obj
, msg
);
994 case MUIM_GoInactive
: return mNLV_GoInactive(cl
, obj
, msg
);
996 // the following method calls are all forwarded
997 // to the corresponding NList object
998 case MUIM_List_Sort
:
999 case MUIM_List_Insert
:
1000 case MUIM_List_InsertSingle
:
1001 case MUIM_List_GetEntry
:
1002 case MUIM_List_Clear
:
1003 case MUIM_List_Jump
:
1004 case MUIM_List_Select
:
1005 case MUIM_List_TestPos
:
1006 case MUIM_List_Redraw
:
1007 case MUIM_List_Exchange
:
1008 case MUIM_List_Move
:
1009 case MUIM_List_NextSelected
:
1010 case MUIM_List_Remove
:
1011 case MUIM_List_CreateImage
:
1012 case MUIM_List_DeleteImage
:
1013 case MUIM_NList_Sort
:
1014 case MUIM_NList_Sort2
:
1015 case MUIM_NList_Insert
:
1016 case MUIM_NList_InsertSingle
:
1017 case MUIM_NList_GetEntry
:
1018 case MUIM_NList_Clear
:
1019 case MUIM_NList_Jump
:
1020 case MUIM_NList_Select
:
1021 case MUIM_NList_TestPos
:
1022 case MUIM_NList_Redraw
:
1023 case MUIM_NList_RedrawEntry
:
1024 case MUIM_NList_Exchange
:
1025 case MUIM_NList_Move
:
1026 case MUIM_NList_NextSelected
:
1027 case MUIM_NList_Remove
:
1028 case MUIM_NList_CreateImage
:
1029 case MUIM_NList_DeleteImage
:
1030 case MUIM_NList_CopyToClip
:
1031 case MUIM_NList_UseImage
:
1032 case MUIM_NList_ReplaceSingle
:
1033 case MUIM_NList_InsertWrap
:
1034 case MUIM_NList_InsertSingleWrap
:
1035 case MUIM_NList_GetEntryInfo
:
1036 case MUIM_NList_GetSelectInfo
:
1037 case MUIM_NList_CopyTo
:
1038 case MUIM_NList_DropType
:
1039 case MUIM_NList_DropDraw
:
1040 case MUIM_NList_DoMethod
:
1041 case MUIM_NList_ColWidth
:
1042 case MUIM_NList_ColToColumn
:
1043 case MUIM_NList_ColumnToCol
:
1045 struct NLVData
*data
= INST_DATA(cl
, obj
);
1047 if(data
->LI_NList
!= NULL
)
1048 return DoMethodA(data
->LI_NList
, msg
);
1053 case MUIM_NListview_SetScrollers
: return mNLV_SetScrollers(cl
, obj
, (APTR
)msg
);
1055 default: return DoSuperMethodA(cl
, obj
, msg
);