Aros/Developer/Zune/CustomClasses
What is a Zune custom class?
[edit | edit source]A Zune custom class is a newly created Zune class based on an existing one. A custom class may provide improvements or changes to the one it's based upon, thus extending Zune.
Zune custom classes are identified by the suffix ".mcc".
AROS' Zune classes (including supplied custom classes) are located at SYS:Classes/Zune.
Mui Custom Classes (MCC) some of which are closed sources.
Examples of open sourced ones...
- Betterstring 11.15
- Date.mcc
- HTMLview 13.4
- Mailtext 19.9
- NList 20.121
- NListtree 18.28.
- NListview 19.76.
- NBitmap 15.6.
- NBalance 15.2.
- Speedbar 19.4.
- SpeedCFG 11.0.
- SpeedbarVirt 19.4.
- Speedbutton 19.4.
- TextEditor 15.27.
- TheBar 26.2.
- TheBarVirt 26.2.
- TheButton 26.2.
- TWFmultiLED.mcc 12.8
- URLText 19.7.
http://www.jens-langner.de/dev
Using custom classes
[edit | edit source]Here is an example how a private class is defined:
extern struct MUI_CustomClass *FPEditor_CLASS; /*** Macros *****************************************************************/ #define FPEditorObject BOOPSIOBJMACRO_START(FPEditor_CLASS->mcc_Class)
Some custom classes are supplied with AROS. Others can be installed into AROS. Others can be loaded from disk.
Custom classes usage in your application is mostly straightforward (just like any built-in class). The only prerequisite might be including the appropriate #include-file.
For example: If you've been using the (built-in) "Text" class/object of Zune...
#include <proto/muimaster.h> #include <libraries/mui.h> ... TextObject, MUIA_Text_Contents, "hello world", ...
...you may use the custom class "TextEditor" exactly the same way, just add the proper include-file and adjust the attribute (MUIA_...) to match the new class:
#include <proto/muimaster.h> #include <libraries/mui.h> #include <mui/TextEditor_mcc.h> ... TextEditorObject, MUIA_TextEditor_Contents, "hello world", ...
Another example is the "NListview"/"NList" class, which is an enhanced replacement of the (built-in) "Listview"/"List" class. In this case even the custom classes' attributes match the original classes' ones.
Of course it all depends on the way a custom class is built - it might introduce completely new attributes or method. In any case it is strongly recommended to obtain a custom classes' developer documentation of attributes and methods.
If you have a custom class,and this should have an extra attribute, which needs to trigger via a Notify-method. You simply need to forward the OM_SET message to your superclass.
struct TagItem *tags, *tag; for ( tags = message->ops_AttrList; (tag = NextTagItem(&tags)); ) { switch (tag->ti_Tag) { .... } } return DoSuperMethodA(CLASS, self, (Msg)message);
If you want the app to be able to check the attribute via a Notify that is setup at progstart. Than you want to set the attribute inside the class, and the app should react according to that notify.
References
[edit | edit source]BetterString
[edit | edit source]Can scrollback buffers be achieved with betterstring.mcc? Yes, simply subclass it and add an eventhandler with priority above zero, and react on the arrow up/down keys. My idea for an API would be a method a la MUIM_BetterString_Freeze, which would add the contents of the current buffer to the history. Normally one would then setup a notify to let MUIA_String_Acknowledge trigger this method. Additionally there should be a tag to force moving to a certain buffer.
If you do create a buffer-system, please let the Freeze-method verify that the buffer has changed, and only add it if so - there's nothing as irritating as the unix shell which keeps adding repeated commands to the history, so that one has to press arrow-up a zillion times before getting to the previous *different* command...
NList
[edit | edit source]It is more powerful, as it supports horizontal scroll, clickable titles, re-arranging of columns, re-layout of columns etc. - but most consider it more complex and not as fast plus it has a few flaws.
creating your list like so
MUIA_NList_Format, "BAR,BAR,BAR,",
That will give you a four column list, each column separated by a vertical bar. Add or remove 'BAR,' entries to the desired number of columns. If you have enabled the titles (a good idea for multi-column lists) then you should also ensure that your display hook sets the titles for each column.
For sorting you must supply MUIA_NList_CompareHook (or overload MUIM_NList_Compare) to get proper comparison. The default comparison method works only for single column lists with plain string pointers.
How to tell if a certain entry is in the visible part of the NList then? You can calculate the visible entries using: MUIA_NList_Horiz_DeltaFactor, MUIA_NList_Horiz_First & MUIA_NList_Horiz_Visible.
If you are using custom data structures:
- Display method/hook is required.
- Compare method/hook is required if you are using sorting.
- Construct/Destruct is optional, to temporary copy these structures or whatever you want.
If Construct/Destruct are missing NList.mcc will pass entry which you inserted directly to f.e. Display/Compare/Destruct.
Procedure with variable amount of parameters in aros, and some damn macro... here is a valid and working procedures, resolves some problems with "End" macro, and implementation of DoSuperNew
IPTR NewObjectAROS( struct IClass *classPtr, STRPTR classID, ULONG tag1, ... ) { AROS_SLOWSTACKTAGS_PRE(tag1) retval = (IPTR) NewObject(classPtr, classID, AROS_SLOWSTACKTAGS_ARG(tag1)); AROS_SLOWSTACKTAGS_POST } IPTR DoSuperNew(struct IClass *cl, Object *obj, ULONG tag1, ...) { AROS_SLOWSTACKTAGS_PRE(tag1) retval = (IPTR)DoSuperMethod(cl, obj, OM_NEW, AROS_SLOWSTACKTAGS_ARG(tag1)); AROS_SLOWSTACKTAGS_POST }
IPTR DoSuperNew(Class *cl, Object *obj, Tag tag1, ...) { AROS_SLOWSTACKTAGS_PRE(tag1) retval = DoSuperNewTagList(cl, obj, NULL, AROS_SLOWSTACKTAGS_ARG(tag1)); AROS_SLOWSTACKTAGS_POST }
or in a more portable manner
Object *DoSuperNew(struct IClass *cl, Object *obj, ...) { Object *rc; va_list args; va_start(args, obj); rc = (Object *)DoSuperMethod(cl, obj, OM_NEW, va_arg(args, IPTR), NULL); va_end(args); return rc; }
DMethod(my_listview, MUIM_NList_ReplaceSingle, "foo", MUIV_NList_Insert_Active, NOWRAP, ALIGN_LEFT); DoMethod(my_listview, MUIM_NList_Redraw, MUIV_NList_Redraw_Active);
I intentionally ignore __stackparm in the prototype because it has no meaning for PPC and x86-64 at the moment, and it never had it for i386 and m68k. When the preprocessor expands macros on i386 (or any other architecture which puts all arguments on stack). The code is turned into this:
IPTR DoSuperNew(Class *cl, Object *obj, Tag tag1, ...) { IPTR retval; retval = DoSuperNewTagList(cl, obj, NULL, &tag1); return retval; }
If you declare the function static, gcc's optimizer looks at this and decides that the function uses only its first tag1 argument. And calls like:
DoSuperNew(cl, o, MUIA_Foo, MUIV_Foo, MUIA_Bar, MUIV_Bar, TAG_MORE, and more)
are turned into: DoSuperNew(cl, o, MUIA_Foo)
Which in fact cause undefined behavior. In most cases FindTagItem() browses the stack's contents until it hits zero longword occasionally appeared somewhere, so you notice almost nothing. In some cases this can cause memory-trashing and illegal address accesses.
Perhaps a more future-proof solution would be to use va_start() and va_end() macros. On architecture, we talk about va_list is simply a pointer to current argument (i. e. in our example it will be &tag1 right after va_start()).
IPTR DoSuperNew(Class *cl, Object *obj, Tag tag1, ...) { IPTR retval; va_list args; va_start(args, tag1); retval = DoSuperNewTagList(cl, obj, NULL, args); va_end(args); return retval; }
NList.mcc/NList.mcc NList.mcc/MUIA_NList_Active NList.mcc/MUIA_NList_ActiveObjectOnClick NList.mcc/MUIA_NList_AdjustHeight NList.mcc/MUIA_NList_AdjustWidth NList.mcc/MUIA_NList_AutoCopyToClip NList.mcc/MUIA_NList_AutoVisible NList.mcc/MUIA_NList_ButtonClick NList.mcc/MUIA_NList_ClickColumn NList.mcc/MUIA_NList_Columns NList.mcc/MUIA_NList_CompareHook NList.mcc/MUIA_NList_CompareHook2 NList.mcc/MUIA_NList_ConstructHook NList.mcc/MUIA_NList_ConstructHook2 NList.mcc/MUIA_NList_CopyColumnToClipHook NList.mcc/MUIA_NList_CopyColumnToClipHook2 NList.mcc/MUIA_NList_CopyEntryToClipHook NList.mcc/MUIA_NList_CopyEntryToClipHook2 NList.mcc/MUIA_NList_DefaultObjectOnClick NList.mcc/MUIA_NList_DefClickColumn NList.mcc/MUIA_NList_DestructHook NList.mcc/MUIA_NList_DestructHook2 NList.mcc/MUIA_NList_DisplayHook NList.mcc/MUIA_NList_DisplayHook2 NList.mcc/MUIA_NList_DisplayRecall NList.mcc/MUIA_NList_DoubleClick NList.mcc/MUIA_NList_DragColOnly NList.mcc/MUIA_NList_DragSortable NList.mcc/MUIA_NList_DragSortInsert NList.mcc/MUIA_NList_DragType NList.mcc/MUIA_NList_DropMark NList.mcc/MUIA_NList_DropType NList.mcc/MUIA_NList_Entries NList.mcc/MUIA_NList_EntryClick NList.mcc/MUIA_NList_EntryValueDependent NList.mcc/MUIA_NList_Exports NList.mcc/MUIA_NList_First NList.mcc/MUIA_NList_ForcePen NList.mcc/MUIA_NList_Format NList.mcc/MUIA_NList_Horiz_DeltaFactor NList.mcc/MUIA_NList_Horiz_Entries NList.mcc/MUIA_NList_Horiz_First NList.mcc/MUIA_NList_Horiz_Visible NList.mcc/MUIA_NList_IgnoreSpecialChars NList.mcc/MUIA_NList_Imports NList.mcc/MUIA_NList_Input NList.mcc/MUIA_NList_InsertPosition NList.mcc/MUIA_NList_KeepActive NList.mcc/MUIA_NList_KeyUpFocus NList.mcc/MUIA_NList_KeyDownFocus NList.mcc/MUIA_NList_KeyLeftFocus NList.mcc/MUIA_NList_KeyRightFocus NList.mcc/MUIA_NList_LineHeight NList.mcc/MUIA_NList_MakeActive NList.mcc/MUIA_NList_MinColSortable NList.mcc/MUIA_NList_MinLineHeight NList.mcc/MUIA_NList_MultiClick NList.mcc/MUIA_NList_MultiClickAlone NList.mcc/MUIA_NList_MultiSelect NList.mcc/MUIA_NList_MultiTestHook NList.mcc/MUIA_NList_Pool NList.mcc/MUIA_NList_PoolPuddleSize NList.mcc/MUIA_NList_PoolThreshSize NList.mcc/MUIA_NList_PrivateData NList.mcc/MUIA_NList_Prop_DeltaFactor NList.mcc/MUIA_NList_Prop_Entries NList.mcc/MUIA_NList_Prop_First NList.mcc/MUIA_NList_Prop_Visible NList.mcc/MUIA_NList_Quiet NList.mcc/MUIA_NList_SelectChange NList.mcc/MUIA_NList_ShowDropMarks NList.mcc/MUIA_NList_SkipChars NList.mcc/MUIA_NList_SortType NList.mcc/MUIA_NList_SortType2 NList.mcc/MUIA_NList_SourceArray NList.mcc/MUIA_NList_SourceInsert NList.mcc/MUIA_NList_SourceString NList.mcc/MUIA_NList_TabSize NList.mcc/MUIA_NList_Title NList.mcc/MUIA_NList_TitleClick NList.mcc/MUIA_NList_TitleClick2 NList.mcc/MUIA_NList_TitleMark NList.mcc/MUIA_NList_TitleMark2 NList.mcc/MUIA_NList_TitleSeparator NList.mcc/MUIA_NList_TypeSelect NList.mcc/MUIA_NList_Visible NList.mcc/MUIA_NList_XXXBackground NList.mcc/MUIA_NList_XXXPen NList.mcc/MUIM_NList_Clear NList.mcc/MUIM_NList_ColWidth NList.mcc/MUIM_NList_ColToColumn NList.mcc/MUIM_NList_ColumnToCol NList.mcc/MUIM_NList_Compare NList.mcc/MUIM_NList_Construct NList.mcc/MUIM_NList_ContextMenuBuild NList.mcc/MUIM_NList_CopyTo NList.mcc/MUIM_NList_CopyToClip NList.mcc/MUIM_NList_CreateImage NList.mcc/MUIM_NList_DeleteImage NList.mcc/MUIM_NList_Destruct NList.mcc/MUIM_NList_Display NList.mcc/MUIM_NList_DoMethod NList.mcc/MUIM_NList_DropDraw NList.mcc/MUIM_NList_DropEntryDrawErase NList.mcc/MUIM_NList_DropType NList.mcc/MUIM_NList_Exchange NList.mcc/MUIM_NList_GetEntry NList.mcc/MUIM_NList_GetEntryInfo NList.mcc/MUIM_NList_GetPos NList.mcc/MUIM_NList_GetSelectInfo NList.mcc/MUIM_NList_Insert NList.mcc/MUIM_NList_InsertSingle NList.mcc/MUIM_NList_InsertSingleWrap NList.mcc/MUIM_NList_InsertWrap NList.mcc/MUIM_NList_Jump NList.mcc/MUIM_NList_Move NList.mcc/MUIM_NList_NextSelected NList.mcc/MUIM_NList_PrevSelected NList.mcc/MUIM_NList_Redraw NList.mcc/MUIM_NList_RedrawEntry NList.mcc/MUIM_NList_Remove NList.mcc/MUIM_NList_ReplaceSingle NList.mcc/MUIM_NList_Select NList.mcc/MUIM_NList_SelectChange NList.mcc/MUIM_NList_SetActive NList.mcc/MUIM_NList_SetColumnCol NList.mcc/MUIM_NList_Sort NList.mcc/MUIM_NList_Sort2 NList.mcc/MUIM_NList_Sort3 NList.mcc/MUIM_NList_TestPos NList.mcc/MUIM_NList_UseImage
NList.mcc This MCC public custom class is very similar to the MUI's list class. It handles directly most attributes which are handled by Listview in the original couple List/Listview. The NListview exist anyway to provide a complete object with scrollbars, so you should use it as child of NListview. Anyway, you can use NList without NListview if you don't want any built-in scrollbar. NOTE: NList class will not work with Listview without some conflicts, and NListview class can't use List as child but only NList or a NList subclass. MUIM_NList_TestPos and MUIM_List_TestPos are similar but use a different struct to store data. MUIM_List_TestPos works like with a List object. NOTE: Avoid as possible to do many things in MUIM_Show and MUIM_Hide methods because when an object is in a virtual group, your object will receive them for each one of its moves !!! Standard tags with NList special values : MUIA_Background has the same meaning than MUIA_NList_ListBackground but only at init. MUIA_Font is settable only at init. MUIV_NList_Font, MUIV_NList_Font_Little and MUIV_NList_Font_Fixed are special values usable for it (settable in prefs) but standard values are usable too. MUIA_Frame you can override the defaults frames of the classe by setting it, but it will be overrided again by defaults if a set(obj,MUIA_NList_Input,bool) is made after. if MUIA_NList_Input is TRUE then the default is MUIV_Frame_InputList, if FALSE it's MUIV_Frame_ReadList. MUIA_ContextMenu MUIM_ContextMenuBuild MUIM_ContextMenuChoice MUIA_NList_Active -- [ISGN], LONG MUIV_NList_Active_Off MUIV_NList_Active_Top MUIV_NList_Active_Bottom MUIV_NList_Active_Up MUIV_NList_Active_Down MUIV_NList_Active_PageUp MUIV_NList_Active_PageDown MUIA_NList_ActiveObjectOnClick -- [ISG], BOOL Default FALSE. If set to TRUE, the NList object will become the MUIA_Window_ActiveObject of its window when you click on it. In addition, the active selected entries will switch an inactive color (e.g. grey) in case the NList object isn't currently active. As soon as the object is active it will then also receive all user keys pressed. MUIA_NList_AdjustHeight -- [I..], BOOL Same function as List.mui/MUIA_List_AdjustHeight. Will adjust the nlist height if the nlist object is in a virtual group or if MUIA_NList_SourceInsert, MUIA_NList_SourceString, MUIA_NList_SourceArray or MUIA_List_SourceArray was used. When the object is in a virtual group, a re-layout of this one will be forced when the entries number of the NList object change, so all entries should always be visible. DEFAULT FALSE MUIA_NList_AdjustWidth -- [I..], BOOL FUNCTION Same function as List.mui/MUIA_List_AdjustWidth. Will adjust the nlist width if the nlist object is in a virtual group or if MUIA_NList_SourceInsert, MUIA_NList_SourceString, MUIA_NList_SourceArray or MUIA_List_SourceArray was used. DEFAULT FALSE NList.mcc/MUIA_NList_AutoClip NAME MUIA_NList_AutoClip -- [ISG], BOOL FUNCTION If set to TRUE and the NList object is in read-only (NoInput) mode and is set to select char-wide rather than by line, the selected content is immediately copied to the clipboard as soon as it is selected via the mouse. MUIA_NList_AutoCopyToClip -- [IS.], BOOL FUNCTION If set to TRUE you can copy the selected area to the clipboard 0 with Amiga-C and Amiga-X (Amiga-X because i have seen that sometimes Amiga-C is a shortcut !). (works with both Right-Amiga and Left-Amiga keys) MUIA_NList_AutoCopyToClip == TRUE also requires that the NList object is either the window's active object (see MUIA_Window_ActiveObject) or the attached list object is window's default object (see MUIA_Window_DefaultObject). Otherwise nothing will ever be copied! MUIA_NList_AutoVisible -- [ISG], BOOL FUNCTION Same function as List.mui/MUIA_List_AutoVisible. Seting this to TRUE, the NList object will automatically and always jump to show the active entry. DEFAULT FALSE MUIA_NList_ButtonClick -- [..GN], LONG FUNCTION You'll get a notify on it each time the user clicks one of the buttons made by ESC O[...@<n>] or ESC o[...@<n>]. The returned value is the <n> of the clicked image/object. (see MUIA_NList_DisplayHook for more). If you get that value later, it will still be <n> of the latest image/object clicked that you'll get. MUIA_NList_ClickColumn -- [..G], LONG FUNCTION Same function as Listview.mui/MUIA_Listview_ClickColumn. MUIA_NList_Columns -- [ISGN], BYTE * FUNCTION With this tag you can set/get the visible order of columns (as if changed by the user). It work for all columns in one time (use MUIM_NList_SetColumnCol if you want to exchange 2 columns). The value is a pointer on an BYTE array, each byte is for a column (in the visible order) and have the value of the display hook col which have to be displayed in it. The array must be ended with a -1 value. MUIA_NList_CompareHook -- [IS.], struct Hook * FUNCTION Same function as List.mui/MUIA_List_CompareHook. MUIA_NList_CompareHook2 -- [IS.], struct Hook * FUNCTION Same function as MUIA_NList_CompareHook but A2 will be the object and A1 a NList_CompareMessage struct pointer. MUIA_NList_ConstructHook -- [IS.], struct Hook * FUNCTION Same function as List.mui/MUIA_List_ConstructHook. Think to finish lines entries on a \0 , \n and \r. The list will not display anything which come after a \n , \r or \0, so finish lines entries on a \0, \r and \n if you dont want to waste memory. SPECIAL INPUTS MUIV_NList_ConstructHook_String It's a built-in hook that copy a string entry. (so original string can be trash after) the MUIV_NList_DestructHook_String must be set, too if you use it. MUIA_NList_ConstructHook2 -- [IS.], struct Hook * FUNCTION Same function as MUIA_NList_ConstructHook but A2 will be the object and A1 a NList_ConstructMessage struct pointer. MUIA_NList_CopyColumnToClipHook -- [IS.], struct Hook * FUNCTION This hook will be called while a MUIM_NList_CopyToClip for each column string. You will get in entry a string given by your own MUIA_NList_DisplayHook/2, so you must not use the same buffer for both ! You'll get the entry num in -1 element of the given array, elements 1 and 2 are the positions of the first selected char and the last+1. You must return the pointer of the string to copy to clipboard in element 0, a the string length in element 1. The builtin hook skip all ESC chars plus their next char (and [...] for ESC-P, ESC-I, ESC-O and ESC-o), and add a tab char between columns. MUIA_NList_CopyColumnToClipHook2 -- [IS.], struct Hook * FUNCTION Same function as MUIA_NList_CopyColumnToClipHook but A2 will be the object and A1 a NList_CopyColumnToClipMessage struct pointer. MUIA_NList_CopyEntryToClipHook -- [IS.], struct Hook * FUNCTION This work near like MUIA_NList_DisplayHook, except that it is not called when the NList object want to display its lines but when it want to copy them to clipboard (or other). See MUIM_NList_CopyToClip. You can return only one string pointer (only one column for copy), as element 0 of the array. The -1 element is the entry number only when you don't give a entry pointer to NList_CopyToClip method, else it's -1. Elements 1,2,3 and 4 of the given array are first column/pos and last column/pos which are selected. Elements 5 and 6 are 2, 1 or 0 when the 1th and 3rd pos are in the format preparse string, the special entry preparse string or in the normal string for that entry/columns. For column, -1 is the first and -2 the last, else it's its number. This is the number of displayed columns and not the corresponding entry in the array return by DisplayHook. Anyway, positions are calculated from strings returned by DisplayHook. For pos, -1 is left of column and -2 its end. The last pos should not be included. You should use MUIA_NList_CopyColumnToClipHook unless you don't want what is seen in the list to be copied. MUIA_NList_CopyEntryToClipHook2 -- [IS.], struct Hook * FUNCTION Same function as MUIA_NList_CopyEntryToClipHook but A2 will be the object and A1 a NList_CopyEntryToClipMessage struct pointer. MUIA_NList_DefaultObjectOnClick -- [ISG], BOOL FUNCTION If set to TRUE, the NList object will become the MUIA_Window_DefaultObject of its window when you click on it, so the user will be able to control the list with keys. The MUIA_Window_ActiveObject will be set to None, unless the current active object is the NList one itself or if it's the MUIA_NList_KeepActive one. There is a special meaning if you use both DefaultObjectOnClick and MUIA_NList_MakeActive. (see MUIA_NList_MakeActive) DEFAULT TRUE MUIA_NList_DefClickColumn -- [ISG], LONG FUNCTION Same function as Listview.mui/MUIA_Listview_DefClickColumn. MUIA_NList_DestructHook -- [IS.], struct Hook * FUNCTION Same function as List.mui/MUIA_List_DestructHook. SPECIAL INPUTS MUIV_NList_DestructHook_String It's a built-in hook that free the string entry previously allocated and copied by the MUIV_NList_ConstructHook_String built-in hook. MUIA_NList_DestructHook2 -- [IS.], struct Hook * FUNCTION Same function as MUIA_NList_DestructHook but A2 will be the object and A1 a NList_DestructMessage struct pointer. MUIA_NList_DisplayHook -- [IS.], struct Hook * FUNCTION Same function as List.mui/MUIA_List_DisplayHook. Do not modify the buffers you return in the hook anywhere else than in the hook when called by NList. (if you do so you MUST set MUIA_NList_DisplayRecall) You should return the same thing if it is called another time with the same inputs! The hook will be called with a pointer to the entry to be displayed in A1 and a pointer to a string array containing as many entries as your list may have cols in A2. You must fill this array with the strings that you want to display. The array is DISPLAY_ARRAY_MAX*2 large. In the DISPLAY_ARRAY_MAX+col element you can set a preparse string for the corresponding col element. Using it you'll be able to avoid copying the string in a buffer to add something in the beginning of the col string. The display hook also gets the position of the current entry as additional parameter. It is stored in the longword preceding the col array (don't forget it's a LONG). (setting that LONG value to -2 is another way to tell the object to not consider the return string pointer as valid next time he will want to use it, and he will recall the hook). When the hook function will be called to get the title strings, you'll get NULL in A1, and -1 as position of current entry. The hook function will be called each time a line (or a part of it) needs to be drawn (and when NList needs to compute length of columns contents). Here are the escape sequence known by the parsing of NList : (If you use C, ESC b can be written "\033b") \t Tabulation. Go to the next tab boundary of the col. tab positions are separated by 8 spaces by default. ESC - Disable text engine, following chars will be printed without further parsing. ESC u Set the soft style to underline. ESC b Set the soft style to bold. ESC i Set the soft style to italic. ESC n Set the soft style back to normal. ESC <n> Use pen number n (2..9) as front pen. n must be a valid DrawInfo pen as specified in "intuition/screens.h". ESC c Center current line. only valid at the beginning. ESC r Right justify current line. only valid at the beginning. ESC l Left justify current line. only valid at the beginning. These ones are new or modified : ESC j Justify left and right current line, but only at the beginning. ESC I[<s>] Draw MUI image with specification <s>. See Image.mui/MUIA_Image_Spec for image spec definition. ESC O[<p>] (ESC O[<s>|<width>|<height>,<minwidth>]) Draw the MUIM_NList_CreateImage at adress <p>. (<p> should be an 8 hex digits number). ESC o[<n>] (ESC o[<s>|<width>|<height>,<minwidth>]) Draw the MUIM_NList_UseImage number <n>. If the <n> UseImage don't exist or has been set to NULL, no image is drawn. ESC P[] Use default front pen. ESC P[<n>] Use pen number <n>. (it's a direct pen number, so you must make MUI_ObtainPen and MUI_ReleasePen for it yourself, best to do it is in Setup() and Cleanup() of a subclass). ESC T Draw horizontal line on top of the entry for the col. ESC C Draw horizontal line centered in the entry for the col. ESC B Draw horizontal line on bottom of the entry for the col. ESC E Draw horizontal line centered in the entry for the col, but only on the left and right of the line contents. ESC t , ESC t[<n>] , ESC t[M<n>] , ESC t[I<n>] Make the ESC C and ESC E horizontal line become thick and filled with some color : default is MPEN_FILL. [<n>] means than <n> is a direct pen color, like for ESC P[<n>] [M<n>] means that <n> is MUI pen color number (MPEN_xxx ie 0..8) [I<n>] means that <n> is Intuition dri pen number 0..11 (see "intuition/screens.h") ESC t[N], ESC t[N<n>], ESC t[NM<n>], ESC t[NI<n>] Make the ESC T, ESC C,ESC B, ESC E become a single black line, or not black when using a <n>, M<n> or I<n> pen color. ('N' is for Not thick ;) with ESC O[] and ESC o[], you can add [...@<n>] which will make the image/object act as a relverify button. When this "button" is released NList will notify MUIA_NList_ButtonClick with the value <n>. with ESC I[], ESC O[] and ESC o[], you can add [...|<width>] or [...|<width>|<height>] or [...|<width>|<height>,<minwidth>] or [...,<minwidth>] where : <width> will be the width in pixels of the image/object. -1 means default image width unless <minwidth> is set. 0 means default image width. <height> will be the height in pixels of the image/object. -1 means default image height (entry height is max). 0 means entry height. <minwidth> will be the min width in pixels before the next char/string/image. when present, default height become entry height and width become minwidth (if minwdith is bigger than image default width), unless you set <width> and/or <height>. <minwidth> <width> and <height> must be a decimal number (%ld). MUIA_NList_DisplayHook2 -- [IS.], struct Hook * FUNCTION Same function as MUIA_NList_DisplayHook but A2 will be the object and A1 a NList_DisplayMessage struct pointer. MUIA_NList_DisplayRecall -- [.S.], BOOL FUNCTION If for some unusual reason you modify one of the buffer that your DisplayHook function usually return anywhere else than in the DisplayHook function when called by the NList object, you must set it to TRUE, so the object will know it. MUIA_NList_DoubleClick -- [..GN], LONG FUNCTION You'll get a notify on it each time the user double clicks on an entry in the list, or on the title. The value is the entry number, which will be -1 when it's the title. You'll get a notify on it too when you press the 'return' key and the NList object is active or default. If you get() it, you'll get the last click position, which can be -2 if it was on nothing (ie not entry or title). For triple clicks and more, use MUIA_NList_MultiClick. NOTE Disabled for the title when MUIA_NList_TitleClick is used. MUIA_NList_DragColOnly -- [ISG], LONG FUNCTION When set to a col number (displayhook col number, not the visible one), only the text of that col for the selected entry will be dragged instead of the visible part of the entry. Set it to -1 to come back to standard/default mode when you have changed it ! MUIA_NList_DragSortable -- [ISG], BOOL FUNCTION Same function as List.mui/MUIA_List_DragSortable. DragType will be MUIV_NList_DragType_Default unless you set it. No need for you to set MUIA_Dropable or MUIA_Draggable. DEFAULT FALSE MUIA_NList_DragSortInsert -- [..GN], BOOL FUNCTION Same as MUIA_NList_InsertPosition but the notify is made only after a MUIA_NList_DragSortable move. MUIA_NList_DragType -- [ISG], LONG SPECIAL INPUTS MUIV_NList_DragType_None no drag MUIV_NList_DragType_Default as set in prefs. MUIV_NList_DragType_Immediate drag on borders and with qualifier, and immediate drag if non-multiselect mode. MUIV_NList_DragType_Borders drag on borders and with qualifier. MUIV_NList_DragType_Qualifier drag only using qualifier. FUNCTION Same function as Listview.mui/MUIA_Listview_DragType. If you want the user to be able to drag items out of your list, you must set this. Don't use MUIA_Draggable with NList or NListview. MUIA_NList_DropMark -- [..G], LONG FUNCTION Same function as List.mui/MUIA_List_DropMark. After a successful drop-operation, this attribute holds the position where we should insert the new entry(ies). MUIA_NList_DropType -- [..G], LONG FUNCTION Same function as MUIA_NList_DropMark but will return the current DropMark type instead of the DropMark entry number. After a successful drop operation, this attribute holds the type of dropmark which where drawn. MUIA_NList_Entries -- [..GN], LONG FUNCTION Same function as List.mui/MUIA_List_Entries. MUIA_NList_EntryClick -- [..GN], LONG FUNCTION You'll get a notify on it each time the user click on an entry in the list (on the title, use MUIA_NList_TitleClick for that). The value is the entry number. You'll get a notify on it too when you press the 'return' key and the NList object is active or default, but only if there is no notify asked on MUIA_NList_DoubleClick. If you get() it, you'll get the last click position, which can be -1 when on title and -2 if it was on nothing. MUIA_NList_EntryValueDependent -- [ISG], BOOL FUNCTION If your display hook return different strings when the entry num value change for an identical entry pointer then you should set it. DEFAULT FALSE MUIA_NList_Exports -- [ISG], LONG FUNCTION Tell the NList object what parts of it's state will have to be saved in MUIM_Export method (which is called by the MUIM_Application_Save method if the object has a ObjectID). SPECIAL INPUTS MUIV_NList_Exports_Active save active entry number. MUIV_NList_Exports_Selected save selected entries numbers. MUIV_NList_Exports_First save first visible entry number. MUIV_NList_Exports_ColWidth save widths of columns. MUIV_NList_Exports_ColOrder save order of columns. MUIV_NList_Exports_Cols save all about columns (width and order actually). MUIV_NList_Exports_All NOTE MUIV_NList_Exports_Selected can make a very long export (so a big program .cfg file) if the list has many selected entries. One long int (ie four bytes) is required for each selected entry... Active and First are always exported by the MUIM_Export method, having MUIV_NList_Exports_Active and MUIV_NList_Exports_First set or not. DEFAULT (MUIV_NList_Exports_Active | MUIV_NList_Exports_First | MUIV_NList_Exports_Cols) MUIA_NList_First -- [ISGN], LONG SPECIAL INPUTS MUIV_NList_First_Top MUIV_NList_First_Bottom MUIV_NList_First_Up MUIV_NList_First_Down MUIV_NList_First_PageUp MUIV_NList_First_PageDown FUNCTION Get the number of the first visible entry. It can be set to change the first entry you want to be visible. MUIA_NList_ForcePen -- [ISG], LONG SPECIAL INPUTS MUIV_NList_ForcePen_On MUIV_NList_ForcePen_Off MUIV_NList_ForcePen_Default FUNCTION Set the ForcePen mode, when on it force the 'selected pen' color in all the selected area. Else the color is forced only at the beginning of the area and can be changed by text escape sequences. The default is set by the user in the pref .mcp class. Getting in will give its current value. MUIA_NList_Format -- [ISG], STRPTR FUNCTION NList is able to handle multi column lists. To define how many columns should be displayed and how they should be formatted, you specify a format string. This format string must contain one entry for each column you want to see. Entries are separated by commas, one entry is parsed via dos.library/ReadArgs(). The template for a single entry looks like this: DELTA=D/N,PREPARSE=P/K,COL=C/N,BAR/S,TBAR/S,NOBAR=NB/S, SIMPLEBAR=SBAR/S,NOTITLEBUTTON=NOTB/S, WEIGHT=W/N,MINWIDTH=MIW/N,MAXWIDTH=MAW/N, COLWIDTH=CW/N,MINCOLWIDTH=MICW/N,MAXCOLWIDTH=MACW/N, PIXWIDTH=PW/N,MINPIXWIDTH=MIPW/N,MAXPIXWIDTH=MAPW/N, PARTCOLSUBST=PCS/K The first are similar to MUIA_List_Format ones : DELTA Space in pixel between this column and the next. the last displayed column ignores this setting. Defaults to 4. PREPARSE A preparse string for this column. COL This value adjusts the col number of the current column. Defaults to current column number (0,1,...) You can't use identical COL values for 2 or more columns. BAR Will draw a vertical bar between this and the next column. WEIGHT The weight of the column. As for MUI's group. MINWIDTH Minimum percentage of the list width for the current column. MAXWIDTH Maximum percentage of the list width for the current column. TBAR Will draw a vertical bar between this and the next column but only in the title (ignored if BAR is set). THIS IS A DEFAULT ! NOBAR Don't draw a vertical bar between this and the next column at all. SIMPLEBAR Make te vertical bar a simple black one. NOTITLEBUTTON Will prevent the title of the column to act as a reverify button when you set MUIA_NList_TitleClick (or make a notify on it). COLWIDTH Wanted number of chars for the current column. You will get as PIXWIDTH with number*font_with. Possibly more than number chars will fit in the column if you use proportional font, anyway you are sure than number non-italic chars will fit. MINCOLWIDTH Minimum number of chars for the current column. MAXCOLWIDTH Maximum number of chars for the current column. PIXWIDTH Wanted number of chars for the current column. MINPIXWIDTH Minimum number of chars for the current column. MAXPIXWIDTH Maximum number of chars for the current column. PARTCOLSUBST If the partial column feature is turned on by the user (in his configuration) and the application developer has specified this option for a particular column, then a "..." text is displayed at the defined position if not all text fits into the column rather than showing a dotted vertical line at the end of the column. Possible values for this option are: DISABLED explicitly disables this feature for this column LEFT put "..." on the left side and strip text left aligned. CENTER put "..." at the center of the column and strip text on both sides around it. RIGHT put "..." on the right side and strip text right aligned. Note: You will have as many columns in your list as entries in the format string (i.e. number of commas + 1). Empty entries, e.g. with a format string of ",,,," are perfectly ok. MINPIXWIDTH, MAXPIXWIDTH, MINCOLWIDTH, MAXCOLWIDTH, MINWIDTH and MAXWIDTH will not be used if PIXWIDTH, or COLWIDTH is used. Only one of PIXWIDTH, COLWIDTH and WEIGHT will be used, the first find in this order. Biggest of MINPIXWIDTH, MINCOLWIDTH and MINWIDTH. Smallest of MAXPIXWIDTH, MAXCOLWIDTH and MAXWIDTH. If the min is bigger than the max the min will be used. Use PIX ones only for columns with images, and COL ones to be sure to get as many chars as wanted. All chars/images will be drawn for the last column always, specify some width for it anyway, as it will be used for centered and right aligned texts ! Default values : WEIGHT=-1, MINWIDTH=5, MAXWIDTH=10000. Use MINWIDTH=0 if you don't use PIXWIDTH or COLWIDTH and don't want any min value. To get WEIGHT values as a percentage of the list width, choose them to have their total being 100. WEIGHT = -1 means that you want the column to have the width of the largest entry's column contents. MINWIDTH = -1 has the same meaning as for WEIGHT but for the min value. Default will be 100 for the last column, set it to -1 or -2 if you want to force it when more than one column, and to -2 to force it when only one column. Be aware that it can take long time to do that when there are many entries since this need a call to the dislpayhook, parse and find real length of all entries. Anyway using such stuff for one or more columns has the same overhead. The default list format is an empty string (""), this means an unformatted, single-column list. NOTE MUIA_NList_Format will not try to see if the new format is similar to previous one. It means that all column width will be re-computed (and all entries parsed if WEIGHT or MINWIDTH is -1), same for wrapping which will be recomputed for all entries. So, it's better to do it before inserting entries in order to do both. To clear, insert and set the format, the best is to set the format after the clear (fastest, no entry to parse) and before the insert. BUGS (FEATURE) Currently there is a maximum of 64 columns for a list. MUIA_NList_Horiz_DeltaFactor -- [..GN], LONG FUNCTION Used for NListview. You can make a notification on it if you want to attach your own horizontal scrollbar and set the increment value of scrollbar's arrows : DoMethod(NLobj, MUIM_Notify, MUIA_NList_Horiz_DeltaFactor,MUIV_EveryTime, SBobj, 3, MUIM_Set,MUIA_Prop_DeltaFactor,MUIV_TriggerValue); MUIA_NList_Horiz_Entries -- [..GN], LONG FUNCTION Used for NListview. You can make a notification on it in order to attach your own horizontal scrollbar : DoMethod(NLobj, MUIM_Notify, MUIA_NList_Horiz_Entries,MUIV_EveryTime, SBobj, 3, MUIM_Set,MUIA_Prop_Entries,MUIV_TriggerValue); MUIA_NList_Horiz_First -- [.SGN], LONG FUNCTION Used for NListview. You can make a notification on it in order to attach your own horizontal scrollbar : DoMethod(NLobj, MUIM_Notify, MUIA_NList_Horiz_First,MUIV_EveryTime, SBobj, 3, MUIM_NoNotifySet,MUIA_Prop_First,MUIV_TriggerValue); DoMethod(SBobj, MUIM_Notify, MUIA_Prop_First,MUIV_EveryTime, NLobj, 3, MUIM_NoNotifySet,MUIA_NList_Horiz_First,MUIV_TriggerValue); MUIA_NList_Horiz_Visible -- [..GN], LONG FUNCTION Used for NListview. You can make a notification on it in order to attach your own horizontal scrollbar : DoMethod(NLobj, MUIM_Notify, MUIA_NList_Horiz_Visible,MUIV_EveryTime, SBobj, 3, MUIM_NoNotifySet,MUIA_Prop_Visible,MUIV_TriggerValue); MUIA_NList_IgnoreSpecialChars -- [ISG], const char * FUNCTION Used to let NList ignore a list of user definable characters during string parsing. Some Greek fonts need the 0xA0 character to display an Alpha characters. In this case the string "\xa0" should be supplied to make NList ignore this character and not treat 0xA0 as a "non breaking space". This string will *NOT* be copied by NList and must remain valid as long as the object exists! DEFAULT NULL MUIA_NList_Imports -- [ISG], LONG FUNCTION Tell the NList object what parts of it's state must be loaded (and used) in MUIM_Import method (which is called by the MUIM_Application_Load method if the object has a ObjectID). SPECIAL INPUTS MUIV_NList_Imports_Active load previous active entry number (and make it active). MUIV_NList_Imports_Selected load previous selected entries numbers (and make them selected). MUIV_NList_Imports_First load previous first visible entry number (and make it the first visible). MUIV_NList_Imports_ColWidth load previous widths of columns (and set them). MUIV_NList_Imports_ColOrder load previous order of columns (and set it). MUIV_NList_Imports_Cols load all about columns (width and order actually). MUIV_NList_Imports_All DEFAULT (MUIV_NList_Imports_Active | MUIV_NList_Imports_First | MUIV_NList_Imports_Cols) MUIA_NList_Input -- [ISG], BOOL FUNCTION Same function as NListview.mcc/MUIA_Listview_Input. DEFAULT TRUE MUIA_NList_InsertPosition -- [..GN], LONG FUNCTION Same function as List.mui/MUIA_List_InsertPosition. MUIA_NList_KeepActive -- [.S.], Obj * FUNCTION Useful when MUIA_NList_DefaultObjectOnClick to not have the specified object deactivated. A NListview object set it to it's NList child at creation time, so you should not have to use that tag. MUIA_NList_KeyUpFocus -- [ISG], Object * FUNCTION Allows to specify an object that will be set as the new window's active object in case the user pressed the UP cursor key and the NList object itself doesn't have anything further to scroll up. MUIA_NList_KeyDownFocus -- [ISG], Object * FUNCTION Allows to specify an object that will be set as the new window's active object in case the user pressed the DOWN cursor key and the NList object itself doesn't have anything further to scroll down. MUIA_NList_KeyLeftFocus -- [ISG], Object * FUNCTION Allows to specify an object that will be set as the new window's active object in case the user pressed the LEFT cursor key and the NList object itself doesn't have anything further to scroll to the left. MUIA_NList_KeyRightFocus -- [ISG], Object * FUNCTION Allows to specify a specific object that will be set as the new window's active object in case the user pressed the RIGHT cursor key and the NList object itself doesn't have anything further to scroll to the right. MUIA_NList_LineHeight -- [..GN], LONG FUNCTION Get the current line height. MUIA_NList_MakeActive -- [.S.], Obj * FUNCTION Use it if you want an object to be activated when you click in the list object. To be able to control the list with key, use MUIA_NList_DefaultObjectOnClick instead. Using both MUIA_NList_MakeActive and MUIA_NList_DefaultObjectOnClick then the specified object will be activated only if there is already an active one. The only object which should be set should be the NListview parent object of the current NList one. MUIA_NList_MinColSortable -- [ISG], LONG FUNCTION Sets the number of the first visible column which can be sorted, ie exchanged with some other one. Default is 1, making the leftmost (0) column not sortable. Just set it to a big number (100 for example) to forbid the columns sorting. MUIA_NList_MinLineHeight -- [IS.], LONG FUNCTION Same function as List.mui/MUIA_List_MinLineHeight. Sets the minimum line height for lists in pixels. If <= 0 then it's absolute value will replace the 'Leading' value of prefs which is added to the font height. It seems that the original MUIA_List_MinLineHeight uses its positive value as a 'leading' one, which is not logical when I read its doc (!), so I do the change internally to get it works like with list... MUIA_NList_MultiClick -- [..GN], LONG FUNCTION You'll get a notification on it each time the user multiclicks more than twice on an entry in the list, or on the title. You'll get the number of the click (3, 4, 5...) for each. Note that you'll not get MUIA_NList_MultiClick for a double click; you must use MUIA_NList_DoubleClick for that. The time between each click must be less or equal to the double click time set in Amiga Input prefs. To know on which entry the multiclick was made getting MUIA_NList_DoubleClick value. So you can make a notification on it. NOTE Disabled for the title when MUIA_NList_TitleClick is used. MUIA_NList_MultiClickAlone -- [..GN], LONG FUNCTION You'll get a notification only for the final multiclick number, so if there are three clicks there will be only one multiclickalone notified, a little (max time between two clicks) after the third one. It is the major change with classic MUIA_NList_DoubleClick and MUIA_NList_MultiClick which do the notify for all clicks. The drawback is the unavoidable delay between the last click and the notification. You can know on which entry the multiclickalone was made getting MUIA_NList_DoubleClick value. A notification can be made on it. MUIA_NList_MultiSelect -- (V7 ) [I..], LONG SPECIAL INPUTS MUIV_NList_MultiSelect_None MUIV_NList_MultiSelect_Default MUIV_NList_MultiSelect_Shifted MUIV_NList_MultiSelect_Always FUNCTION Same function as Listview.mui/MUIA_Listview_MultiSelect. < At the moment MultiSelect_Default is the same as MultiSelect_Shifted > MUIA_NList_MultiTestHook -- [IS.], struct Hook * FUNCTION Same function as List.mui/MUIA_List_MultiTestHook. MUIA_NList_Pool -- [I..], APTR FUNCTION Same function as List.mui/MUIA_List_Pool. MUIA_NList_PoolPuddleSize -- [I..], ULONG FUNCTION Same function as List.mui/MUIA_List_PoolPuddleSize. MUIA_NList_PoolThreshSize -- [I..], ULONG FUNCTION Same function as List.mui/MUIA_List_PoolThreshSize. MUIA_NList_PrivateData -- [ISG], APTR FUNCTION It's private data of the object that is unused by NList. It can be used as wanted, as for MUIA_UserData. MUIA_NList_Prop_DeltaFactor -- [..GN], LONG FUNCTION Used for NListview. You can make a notification on it in order to attach your own vertical scrollbar and set the increment value of scrollbar's arrows : DoMethod(NLobj, MUIM_Notify, MUIA_NList_Prop_DeltaFactor,MUIV_EveryTime, SBobj, 3, MUIM_Set,MUIA_Prop_DeltaFactor,MUIV_TriggerValue); MUIA_NList_Prop_Entries -- [..GN], LONG FUNCTION Used for NListview. You can make a notification on it in order to attach your own vertical scrollbar : DoMethod(NLobj, MUIM_Notify, MUIA_NList_Prop_Entries,MUIV_EveryTime, SBobj, 3, MUIM_NoNotifySet,MUIA_Prop_Entries,MUIV_TriggerValue); MUIA_NList_Prop_First -- [.SGN], LONG FUNCTION Used for NListview. You can make a notification on it in order to attach your own vertical scrollbar : DoMethod(NLobj, MUIM_Notify, MUIA_Prop_First,MUIV_EveryTime, SBobj, 3, MUIM_Set,MUIA_Prop_First,MUIV_TriggerValue); DoMethod(SBobj, MUIM_Notify, MUIA_Prop_First,MUIV_EveryTime, NLobj, 3, MUIM_Set,MUIA_Prop_First,MUIV_TriggerValue); MUIA_NList_Prop_Visible -- [..GN], LONG FUNCTION Used for NListview. You can make a notification on it in order to attach your own vertical scrollbar : DoMethod(NLobj, MUIM_Notify, MUIA_NList_Prop_Visible,MUIV_EveryTime, SBobj, 3, MUIM_NoNotifySet,MUIA_Prop_Visible,MUIV_TriggerValue); MUIA_NList_Quiet -- [.S.], BOOL FUNCTION Same function as List.mui/MUIA_List_Quiet. Consider using it when inserting or removing several entries one-by-one, it will go much faster. In all cases, all changes which can be done later are delayed. Quiet_Full mean that no notification caused by changes in the list will be made, while Quiet_Visual will do them (but delayed to after the Quiet_None). SPECIAL INPUTS MUIV_NList_Quiet_None same as FALSE. MUIV_NList_Quiet_Full all values but FALSE and MUIV_NList_Quiet_Visual (-2). MUIV_NList_Quiet_Visual MUIA_NList_SelectChange -- [...N], BOOL FUNCTION Same function as Listview.mui/MUIA_Listview_SelectChange. A set(NLobj,MUIA_NList_SelectChange,TRUE) is made by NList whenever the selection state of one or more items in the list is changing. DEFAULT FALSE MUIA_NList_ShowDropMarks -- [ISG], BOOL FUNCTION Same function as List.mui/MUIA_List_ShowDropMarks. DEFAULT FALSE MUIA_NList_SkipChars -- [ISG], char * FUNCTION Same function as Floattext.mui/MUIA_Floattext_SkipChars. MUIA_NList_SortType -- [ISGN], LONG FUNCTION This value will be set in the NList_CompareMessage struct of MUIA_NList_CompareHook2 hook function. It is set by MUIM_NList_Sort2 and MUIM_NList_Sort3 methods too. EXAMPLES See NList-Demo program. MUIA_NList_SortType2 -- [ISGN], LONG FUNCTION This value will be set in the NList_CompareMessage struct of MUIA_NList_CompareHook2 hook function. It is set by MUIM_NList_Sort3 method, too. EXAMPLES See NList-Demo program. MUIA_NList_SourceArray -- [I..], APTR FUNCTION Same function as List.mui/MUIA_List_SourceArray. MUIA_NList_SourceInsert -- [I..], struct MUIP_NList_InsertWrap * FUNCTION Same as DoMethod(obj,MUIM_NList_InsertWrap,...) with ... same as the contents of the passed struct, but at init. MUIA_NList_SourceString -- [I..], char * FUNCTION Same as DoMethod(obj,MUIM_List_Insert,string,-2,MUIV_NList_Insert_Bottom) but at init. MUIA_NList_TabSize -- [ISG], ULONG FUNCTION Same function as Floattext.mui/MUIA_Floattext_TabSize. Set how many spaces is the tabulation. Default is 8. MUIA_NList_Title -- [ISG], char * FUNCTION Same function as List.mui/MUIA_List_Title. The title will be redrawn each time you set it. When you use a display hook, its value is used as a BOOL/LONG which can have any value (just not NULL if you want to see it). The value returned by get() will be the same than the last one given in the set() or at init. MUIA_NList_TitleClick -- [ISGN], LONG FUNCTION A notification is received each time the user clicks one the title (only if on a column, so not on the vertical bar column separator which is used to modify the column-width with mouse). The returned value is the col number (display hook col number). If you get that value later, it will still be the latest *title* click col received. If a notification on that tag is requested, or if you set it (with any value), the title will act as if each of its column titles were separated buttons, notifying that tag when they are released. Using MUIA_NList_TitleSeparator and BAR or TBAR for each column in the MUIA_NList_Format string will improve the (released) look for those title "buttons". There are no shortkeys for these custom buttons and never will be, so find another way to access the related material. Don't ask for customized frames for them : they are not real MUI and separated buttons but directly handled by NList, and I consider it already sufficient. NOTE When you use MUIA_NList_TitleClick, you will not receive MUIA_NList_DoubleClick and MUIA_NList_MultiClick when clicking on the title any more. EXAMPLES See NList-Demo program. MUIA_NList_TitleClick2 -- [ISGN], LONG FUNCTION Works like MUIA_NList_TitleClick but when the qualifier is pressed while clicking EXAMPLES See NList-Demo program. MUIA_NList_TitleMark -- [ISG], LONG FUNCTION Draw a mark on the corresponding display hook column. The value give two informations : the column and the type of mark. Usually set to the MUIA_NList_SortType value (which is set by MUIM_NList_Sort3, this one called from a MUIA_NList_TitleClick notify). SPECIAL INPUTS MUIV_NList_TitleMark_None MUIV_NList_TitleMark_Down | col MUIV_NList_TitleMark_Up | col MUIV_NList_TitleMark_Box | col MUIV_NList_TitleMark_Circle | col EXAMPLES See NList-Demo program. MUIA_NList_TitleMark2 -- [ISG], LONG FUNCTION Draw a secondary mark on the corresponding display hook column. The value give 2 informations : the column and the type of mark. Usually set to the MUIA_NList_SortType2 value (which is set by MUIM_NList_Sort3, this one called from a MUIA_NList_TitleClick/2 notify). SPECIAL INPUTS MUIV_NList_TitleMark2_None MUIV_NList_TitleMark2_Down | col MUIV_NList_TitleMark2_Up | col MUIV_NList_TitleMark2_Box | col MUIV_NList_TitleMark2_Circle | col EXAMPLES See NList-Demo program. MUIA_NList_TitleSeparator -- [ISG], BOOL FUNCTION Setting it creates a horizontal bar between the title and the first visible entry (only when some title is visible). DEFAULT TRUE MUIA_NList_TypeSelect -- [IS.], LONG SPECIAL INPUTS MUIV_NList_TypeSelect_Line MUIV_NList_TypeSelect_Char FUNCTION This tag offers a choice between the classic list selection by line and using a char precision selection. This should be used only for textviewer-like stuff, and never for standard lists. Anyway it's the only way to make direct copytoclip of a part of a line... Default is MUIV_NList_TypeSelect_Line of course. MUIA_NList_Visible -- [..G], LONG FUNCTION Same function as List.mui/MUIA_List_Visible. MUIA_NList_TitleBackground -- [ISG], LONG MUIA_NList_ListBackground -- [ISG], LONG MUIA_NList_SelectBackground -- [ISG], LONG MUIA_NList_CursorBackground -- [ISG], LONG MUIA_NList_UnselCurBackground -- [ISG], LONG FUNCTION All backgrounds of NList can be set with these attributes, look at Area.mui/MUIA_Background and Image.mui/MUIA_Image_Spec to see what kind of value can be used. Anyway, the defaults can be set with prefs and so do not set it yourself. MUIA_NList_TitlePen -- [ISG], LONG MUIA_NList_ListPen -- [ISG], LONG MUIA_NList_SelectPen -- [ISG], LONG MUIA_NList_CursorPen -- [ISG], LONG MUIA_NList_UnselCurPen -- [ISG], LONG FUNCTION You can set all pens of NList with these attributes, their value must be of the type Pendisplay.mui/MUIA_Pendisplay_Spec. Look at Pendisplay.mui, Area.mui/MUIA_Background and Image.mui/MUIA_Image_Spec. Anyway, you can set the defaults with prefs and should not set it yourself.
MUIM_NList_Clear -- SYNOPSIS DoMethod(obj,MUIM_NList_Clear,); FUNCTION Same function as List.mui/MUIM_List_Clear. MUIM_NList_ColWidth -- SYNOPSIS DoMethod(obj,MUIM_NList_ColWidth,LONG col,LONG width); FUNCTION Set a width for a col as if changed by the user with mouse, or reset it to its default size. Permit to get the user width of a col too. INPUTS col number of the col (numbered as in display hook). special value : MUIV_NList_ColWidth_All will set it for all columns. width width to set (four is the minimum acceptable width). special values : MUIV_NList_ColWidth_Default reset to default. MUIV_NList_ColWidth_Get set nothing, only return current. RESULT When a col is specified (ie not MUIV_NList_ColWidth_All), the current *user* width of the col will be returned : o -1 mean that the col has its default width, ie not set by the user or with this method. o 0 mean that the specified col is not valid. When MUIV_NList_ColWidth_All you'll get always 0. MUIM_NList_ColToColumn -- SYNOPSIS DoMethod(obj,MUIM_NList_ColToColumn,LONG col); FUNCTION converts display hook col number to visible column number. INPUTS col number of the col (numbered as in display hook). RESULT column number, -1 if no column use that col number. MUIM_NList_ColumnToCol -- SYNOPSIS DoMethod(obj,MUIM_NList_ColumnToCol,LONG column); FUNCTION converts visible column number to display hook col number. INPUTS column number of the column (visible). RESULT col number, -1 if the column is not valid. MUIM_NList_Compare -- SYNOPSIS DoMethod(obj,MUIM_NList_Compare,APTR entry1,APTR entry2, ULONG sort_type1,ULONG sort_type2); FUNCTION This method is called ONLY by NList.mcc when the application needs to compare two list entries, for example when MUIM_NList_Sort, MUIM_NList_Sort2, MUIM_NList_Sort3 are called. So, this method is only useful within NList.mcc subclass, function method should looks like normal MUIA_NList_CompareHook or MUIA_NList_CompareHook2 hook function. If your subclass will not override this method NList.mcc implementation will be used and it will call MUIA_NList_CompareHook or MUIA_NList_CompareHook2 hook in that case. When you are overriding this method you probably would like to override MUIM_NList_Construct, MUIM_NList_Destruct and MUIM_NList_Display method as well. INPUTS entry1 - First entry to compare. entry2 - Second entry to compare. sort_type1 - Sort type 1. sort_type2 - Sort type 2. RESULTS If entry1 > entry2 1, if entry1 == entry2 0 and if entry1 < entry2 -1. i.e. the same as MUIA_NList_Compare, MUIA_NList_CompareHook2 or strcmp() alike functions. NOTE Do not call it by yourself! Method parameters structure might grow in the future! Be warned. Internal implementation of this method can use internal or passed arguments, so please do not cheat and if you do not override it, pass the original arguments to super class. MUIM_NList_Construct -- SYNOPSIS DoMethod(obj,MUIM_NList_Construct,APTR entry,APTR pool); FUNCTION This method is called ONLY by NList.mcc when application is creating new entry f.e. when MUIM_NList_Insert, MUIM_NList_InsertSingle or MUIM_NList_Replace is called. So, this method is only useful within NList.mcc subclass, function method should looks like normal MUIA_NList_ConstructHook or MUIA_NList_ConstructHook2 hook function. If your subclass will not override this method NList.mcc implementation will be used, and it'll call MUIA_NList_ContructHook or MUIA_NList_ConstructHook2 hook in that case. When, overriding this method, it is probably to override MUIM_NList_Destruct, MUIM_NList_Compare and MUIM_NList_Display methods as well. INPUTS entry - original entry pointer passed to f.e. MUIM_NList_Insert method. Equivalent of A1 register of MUIA_NList_ConstructHook. pool - pool header pointer. Equivalent of A2 register of MUIA_NList_ConstructHook. RESULT New entry, similar as returned by one of construct hooks. NOTE Do not call it by yourself! Method parameters structure might grow in the future! Be warned. Internal implementation of this method can use internal or passed arguments, so please do not cheat and if you are not overriding it, pass the original arguments to super class. MUIM_NList_ContextMenuBuild -- SYNOPSIS DoMethod(obj,MUIM_NList_ContextMenuBuild, LONG mx, LONG my, LONG pos, LONG column, LONG flags,LONG ontop); FUNCTION Give possibilities to use MUIM_ContextMenuBuild builtin in NList and a custom context menu for a NList subclass. Here is how NList MUIM_ContextMenuBuild work : If MUIA_ContextMenu is NULL, NULL is returned (no menu). If MUIA_ContextMenu is none of special values, the supermethod is called. If MUIA_ContextMenu is MUIV_NList_ContextMenu_Never, MUIA_ContextMenu is set to NULL and NULL is returned. Else (it's a special value) MUIM_NList_ContextMenuBuild is called : If MUIM_NList_ContextMenuBuild return -1, NULL will be returned (no menu). If MUIM_NList_ContextMenuBuild return NULL, NList will return its own context menu, depending on prefs (it's the default case). If MUIM_NList_ContextMenuBuild return an menu object, NList will enable/disable its own menu entries in the menu if it found some, then return thqt object. 2 special menuitems are recognised by NList, and are found by : DoMethod(MenuObj,MUIM_FindUData,MUIV_NList_Menu_Default_This) and DoMethod(MenuObj,MUIM_FindUData,MUIV_NList_Menu_Default_All) MUIA_ContextMenu special values are actually used : MUIV_NList_ContextMenu_Default replaced by one of following. MUIV_NList_ContextMenu_TopOnly only on title/top of list. MUIV_NList_ContextMenu_Always always. MUIV_NList_ContextMenu_Never never, replaced by NULL after. when using MUIV_NList_ContextMenu_TopOnly NList will set MUIA_ContextMenu NULL/non-NULL when the mouse move, which should permit to have the window menu avaible when the contents menu is not visible. Anyway actually (MUI 3.8) MUI has a bug/feature which make the MUIA_ContextMenu being looked at only when the mouse *enter* within the object bounds. MUIV_NList_ContextMenu_TopOnly stuff will be nicer when that MUI problem is fixed... Of course if you want NList to do what has to be done when a menu item has been selected, your MUIM_ContextMenuChoice should call the supermethod. INPUTS (for MUIM_NList_ContextMenuBuild) mx current mouse x. my current mouse y. pos entry number returned by NList_TestPos. column column returned by NList_TestPos. flags flags returned by NList_TestPos. ontop TRUE if mouse is on title/top of the list. RESULT NULL, -1 or a menustrip object. EXAMPLES To make a ContextMenu but have the NList one appear when the mouse in on title/top, just set MUIA_ContextMenu,MUIV_NList_ContextMenu_Always and make MUIM_NList_ContextMenuBuild return NULL when ontop in TRUE (else return your menustrip object). Call MUIM_ContextMenuChoice supermethod too. To make your own context menu which have the same menuitems as ones in NList context menu, set MUIA_ContextMenu,MUIV_NList_ContextMenu_Always and make MUIM_NList_ContextMenuBuild return always your menustrip object. Make 4 menuitems in your menustrip object which will be like these : { NM_ITEM , "Default Width: this" , 0 ,0 ,0 ,(APTR) MUIV_NList_Menu_DefWidth_This }, { NM_ITEM , "Default Width: all" , 0 ,0 ,0 ,(APTR) MUIV_NList_Menu_DefWidth_All }, { NM_ITEM , "Default Order: this" , 0 ,0 ,0 ,(APTR) MUIV_NList_Menu_DefOrder_This }, { NM_ITEM , "Default Order: all" , 0 ,0 ,0 ,(APTR) MUIV_NList_Menu_DefOrder_All }, They will be automatically enabled/disabled as needed by NList :) Call MUIM_ContextMenuChoice supermethod too. MUIM_NList_CopyTo -- SYNOPSIS DoMethod(obj,MUIM_NList_CopyTo, LONG pos, char *filename, APTR *result, APTR *entries); FUNCTION Do a copy to clipboard from some list entries or strings. INPUTS pos entry number to be copied. if MUIA_NList_CopyToClipHook is specified, it's what it will return which will be copied instead of just using the entry pointer as a string pointer. special values : MUIV_NList_CopyTo_Active copy list active entry MUIV_NList_CopyTo_Selected copy list selected entries MUIV_NList_CopyTo_All copy all list entries MUIV_NList_CopyTo_Entries copy specified entries MUIV_NList_CopyTo_Entry copy specified entry a "\n" will be inserted after each entry contents. filename name of the file to copy to. If NULL then the copy will be done to a string (strptr). result LONG pointer which fill be filled with MUIV_NLCT_Success if no error occured while opening and writing in the file, else it will be filled with MUIV_NLCT_OpenErr, MUIV_NLCT_WriteErr or MUIV_NLCT_Failed (failed somewhere when making copy data). if filename is NULL, result will be filled with a string pointer to a string allocated by AllocVec(). Data will have been copied in that string. You will have to free that string pointer yourself, with a FreeVec(). If the returned string pointer is NULL then the copy failed. entries pointer to some entry, string, entries array or string array. Its use depend on the pos value : if MUIV_NList_CopyTo_Entry then it's an entry pointer. if MUIV_NList_CopyTo_Entries then it's an entry pointer array NULL terminated. else : not used, set to NULL. EXAMPLES LONG result = 0; DoMethod(obj,MUIM_NList_CopyTo, 5, "RAM:test.txt", &result, NULL, NULL); will copy the 5th entry to file RAM:test.txt, using MUIA_NList_CopyToClipHook if set. LONG result = 0; DoMethod(obj,MUIM_NList_CopyTo, MUIV_NList_CopyToClip_Selected, "PRT:", &result, NULL, NULL); will copy all selected entries to printer, using MUIA_NList_CopyToClipHook for each if set. char *strptr = NULL; DoMethod(obj,MUIM_NList_CopyTo, MUIV_NList_CopyTo_All, NULL, &strptr, NULL, NULL); will copy all list entries to the string returned in strptr. you must make a FreeVec(strptr) by yourself after. MUIM_NList_CopyToClip -- SYNOPSIS DoMethod(obj,MUIM_NList_CopyToClip, LONG pos, ULONG clipnum, APTR *entries, struct Hook *hook); FUNCTION Do a copy to clipboard from some list entries or strings. INPUTS pos entry number to be copied. if MUIA_NList_CopyToClipHook is specified, it's what it will return which will be copied instead of just using the entry pointer as a string pointer. special values : MUIV_NList_CopyToClip_Active copy list active entry MUIV_NList_CopyToClip_Selected copy list selected entries MUIV_NList_CopyToClip_All copy all list entries MUIV_NList_CopyToClip_Entries copy specified entries MUIV_NList_CopyToClip_Entry copy specified entry MUIV_NList_CopyToClip_Strings copy specified strings using hook MUIV_NList_CopyToClip_String copy specified string using hook a "\n" will be insert after each entry contents, for all but MUIV_NList_CopyToClip_Strings and MUIV_NList_CopyToClip_String. clipnum clipboard number to copy to. entries pointer to some entry, string, entries array or string array. Its use depend on the pos value : if MUIV_NList_CopyToClip_Entry then it's an entry pointer. if MUIV_NList_CopyToClip_Entries then it's an entry pointer array NULL terminated. if MUIV_NList_CopyToClip_String then it's a string pointer. if MUIV_NList_CopyToClip_Strings then it's an string pointer array NULL terminated. else : not used, set to NULL. hook hook function which will be used (if not NULL) for MUIV_NList_CopyToClip_Strings and MUIV_NList_CopyToClip_String instead of MUIA_NList_CopyToClipHook Should be NULL most of time. EXAMPLES DoMethod(obj,MUIM_NList_CopyToClip, 5, 0, NULL, NULL); will copy the 5th entry to clipboard 0, using MUIA_NList_CopyToClipHook if set. DoMethod(obj,MUIM_NList_CopyToClip, MUIV_NList_CopyToClip_Selected, 0, NULL, NULL); will copy all selected entries to clipboard 0, using MUIA_NList_CopyToClipHook for each if set. DoMethod(obj,MUIM_NList_CopyToClip, MUIV_NList_CopyToClip_String, 0, "my string", NULL); will copy "my string" to clipboard 0. NOTE MUIV_NList_CopyToClip_Strings and MUIV_NList_CopyToClip_String are here to permit simple text copy to clipboard for non nlist object related stuff (anyway a NList object must be here to use them...). They can use their own hook instead of the nlist's if non NULL, anyway look at MUIA_NList_CopyToClipHook to see how this hook will be used. MUIM_NList_CreateImage -- SYNOPSIS DoMethod(obj,MUIM_NList_CreateImage,Object *imgobj, ULONG flags); FUNCTION Same function as List.mui/MUIM_List_CreateImage. Any transparent color in the source Bitmap/Bodychunk object will work (except if flags is ~0L). MUIM_NList_CreateImage must be used in Setup() or after and MUIM_NList_DeleteImage, in Cleanup() or before, because the mri of the NList object must be valid. Setup() and Cleanup() are the best because MUI_ObtainPen() and MUI_ReleasePen() are used, and then pens will be released while iconification and will be re-obtained if the screen change. Take a look at MUIM_NList_UseImage which is far easier to use. Standard flags value is 0. If flags is ~0L then FillArea will not be set to FALSE on the object (for any other value, FillArea is set to FALSE) If flags is ~0L for a Bitmap/Bodychunk then it will be really the given object which will be drawn, as for non Bitmap/Bodychunk objects. The imgobj can (nearly) be any object, but take care of that : - the object should not test and use user inputs, the object should just be able to draw itself within the _left(obj), _top(obj), _width(obj) and height(obj) it will have when its Draw method is called. - the object class MUST NOT be Group or subclass of it. - the given imgobj must not be attached to any group object anywhere else, because a ADDMEMBER will be done with it. - Each imgobj can be used with one and only one NList object. - you can use the return pointer with ESC O[<ptr>] and ESC o[<num>]. - the object will receive two tags just before its Draw method will be called : set(imgobj,MUIA_NLIMG_EntryCurrent,current_entry_number) and set(imgobj,MUIA_NLIMG_EntryHeight,height_of_each_entry_of_the_list) which are usefull in some case to draw things (see demo example). - a new stuff is to use it with ESC O[<ptr>;<tag>;<value>], in that case a set(imgobj,tag,value) will be done just before drawing it, so you can make an object which will draw different things when that tag value is changed. Setting this tag MUST NOT cause the item to be redrawn! <tag> and <value> must both be in hexadecimal (%lx). - If you use ;<tag>;<value> in one ESC sequence for an imgobj, you should use it everywhere you use that imgobj because there is no default for it. - The imgobj height will always be set to the entries height. - The mindefheight of imgobj will become the min height for entries. - Think it's still a new testing stuff... Note: Previously the object was disposed by NList at its end, actually a call to MUIM_NList_DeleteImage will REMMEMBER it, and so you have to dispose of it yourself afterwards ! Look the demo program to see a way to use it... RESULT The result you get is a struct BitMapImage pointer which will exist between the MUIM_NList_CreateImage and MUIM_NList_DeleteImage, with a valid bitmap, width and height for the current screen. If you use it for a non Bitmap/Bodychunk object (or with flags set to ~0L) then the mask and imgbmp fields of the returned struct BitMapImage are not valid, and obtainpens is a pointer to the object. The only thing you should do with it is to include it in \33O[%08lx]. The result may be NULL in which case NList was unable to create the image, but the \33O[] combination simply draws nothing when receiving a NULL. ATTENTION: The returned pointer doesn't give the same structure than MUIM_List_CreateImage (in standard List class) would do : both are not compatible at all ! MUIM_NList_DeleteImage -- SYNOPSIS DoMethod(obj,MUIM_NList_DeleteImage,APTR listimg); FUNCTION Same function as List.mui/MUIM_List_DeleteImage. Delete the image pointer returned from MUIM_NList_CreateImage. Read explains in MUIM_NList_CreateImage. MUIM_NList_Destruct -- SYNOPSIS DoMethod(obj,MUIM_NList_Destruct,APTR entry,APTR pool); FUNCTION This method is called ONLY by NList.mcc when application is deleting entry f.e. when MUIM_NList_Remove or MUIM_NList_Replace are called. So, this method is only useful within NList.mcc subclass, function method should looks like normal MUIA_NList_DestructHook or MUIA_NList_DestructHook2 hook function. If your subclass will not override this method NList.mcc implementation will be used, and it'll call MUIA_NList_DestructHook or MUIA_NList_DestructHook2 hook in that case. When you are overriding this method you must override MUIM_NList_Construct and probably MUIM_NList_Compare and MUIM_NList_Display method as well. INPUTS entry - entry pointer returned by MUIM_NList_Construct method. pool - pool header pointer. RESULT Currently undefined. When overriding it completely, please return 0, if not, use the value returned by super class! NOTE Do not call it by yourself! Method parameters structure might grow in the future! Be warned. Internal implementation of this method can use internal or passed arguments, so please do not cheat and if you are not overriding it, pass the original arguments to super class. MUIM_NList_Display -- SYNOPSIS DoMethod(obj,MUIM_NList_Display,APTR entry,ULONG entry_pos, STRPTR *strings,STRPTR *preparses); FUNCTION This method is called ONLY by NList.mcc when application is displaying entry f.e. when MUI_Redraw(), MUIM_NList_Redraw or MUIM_NList_RedrawEntry are called. So, this method is only useful within NList.mcc subclass, function method should looks like normal MUIA_NList_DisplayHook or MUIA_NList_DisplayHook2 hook function. If your subclass will not override this method NList.mcc implementation will be used, and it will call MUIA_NList_DisplayHook or MUIA_NList_DisplayHook2 hook in that case. INPUTS entry - Entry pointer returned by f.e. MUIM_NList_Construct, MUIA_NList_ConstructHook or MUIA_NList_ConstructHook2 hooks. entry_pos - Entry position. strings - Pointer to strings table. preparses - Pointer to preparse strings table. RESULT Currently undefined. If you are overriding it completely, please return 0, if not, use the value returned by super class! NOTE Do not call it by yourself! Method parameters the structure might grow in the future! Be warned. Internal implementation of this method can use internal or passed arguments, so please do not cheat and if you are not overriding it, pass the original arguments to super class. MUIM_NList_DoMethod -- SYNOPSIS DoMethod(obj,MUIM_NList_DoMethod,LONG pos, APTR DestObj,ULONG FollowParams,ULONG method,...); FUNCTION The given method will be executed for each selected entry, the active entry, all entries, or one specified entry of the NList object. Each DoMethod() can be done on the NList object, its _app object, a specified object, or the entry pointer if (and only if) it's an object. Following arguments can be automatically adjusted for each call using special values, like in the MUIM_Notify method (you must specified the numer of following argument too, as there will be copied in a temporary buffer - alloced in the stack). INPUTS pos - the entry number for which you want to do the method. special values : MUIV_NList_DoMethod_Active do it for the active entry. MUIV_NList_DoMethod_Selected do it for all selected entries. MUIV_NList_DoMethod_All do it DestObj - the object on which the method will be done. special values : MUIV_NList_DoMethod_Entry use entry pointer as target object for method. MUIV_NList_DoMethod_Self use the NList object as target for method. MUIV_NList_DoMethod_App use the _app(NList object) as target for method. FollowParams - the number of following parameters (including "method"). (maximum 40 to prevent errors and stack overflow) method - the method which will be done. ... - the method parameters. special values : MUIV_NList_EntryValue replaced by the "current" entry pointer. MUIV_NList_EntryPosValue replaced by the "current" entry number. MUIV_NList_SelfValue replaced by the NList object. MUIV_NList_AppValue replaced by _app(NList object) NOTES Don't use this to do things on the NList object when a specific way to do it exists (don't use it to remove entries in the nlist object itself for example). When using it in a notification, MUIV_TriggerValue and MUIV_TriggerValue special values will be replaced by the notify superclass as usual. EXAMPLES Insert all entries from nlist L1 to nlist L2 : DoMethod(L1, MUIM_NList_DoMethod, MUIV_NList_DoMethod_All, L2, 3, MUIM_NList_InsertSingle, MUIV_NList_EntryValue, MUIV_NList_Insert_Bottom); (it would be better to make set(L2,MUIA_NList_Quiet,TRUE) before and set(L2,MUIA_NList_Quiet,FALSE) after when there are many entries...) If the entries of nlist L1 are objects (and only in that case), it can be done to call a method (MUIM_Foo,x) for each selected of them : DoMethod(L1, MUIM_NList_DoMethod, MUIV_NList_DoMethod_Selected, MUIV_NList_DoMethod_Entry, 2, MUIM_Foo,x); MUIM_NList_DropDraw -- SYNOPSIS DoMethod(obj,MUIM_NList_DropDraw, LONG pos, LONG type, LONG minx,LONG maxx,LONG miny,LONG maxy); FUNCTION This method MUST NOT be called directly ! It will be called by NList, and will draw the drop mark previously fixed (pos and type) by MUIM_NList_DropType within the minx, maxx, miny, maxy in the _rp(obj) rasport. Do draw outside of the given box because only the corresponding NList entry will be refreshed to erase what is drawn in that method. Calling the supermethod (so the builtin MUIM_NList_DropDraw method) will draw the standard dropmark specified by (type & MUIV_NList_DropType_Mask), so MUIV_NList_DropType_None,MUIV_NList_DropType_Above,MUIV_NList_DropType_Below or MUIV_NList_DropType_Onto. You can draw directly in the rastport (or a clone of it) in that method, because it will be called from the Draw method within the DragReport in Refresh mode. MUIM_NList_DropEntryDrawErase -- SYNOPSIS DoMethod(obj,MUIM_NList_DropEntryDrawErase,LONG type,LONG drawpos,LONG erasepos); FUNCTION This method MUST NOT be called directly ! It will be called by NList while the DragReport just before the redraw which will draw a new mark or erase the old one. This method can be used to change something so your displayhook will return something different for the marked entry, like changing its color or making it bold or italic. Don't call the superclass unless you know that the superclass uses it. You should return 0. INPUTS type has the same meaning as *type in MUIM_NList_DropType, it will be useless in most cases (and has no meaning at all for erasepos). drawpos is the entry number which will be draw with a dropmark, -1 mean none. erasepos is the entry number which is not any more the dropmark one, -1 mean none. MUIM_NList_DropType -- SYNOPSIS DoMethod(obj,MUIM_NList_DropType, LONG *pos,LONG *type, LONG minx,LONG maxx,LONG miny,LONG maxy, LONG mousex,LONG mousey); FUNCTION This method MUST NOT be called directly ! It will be called by NList while the DragReport, with default *pos and *type values depending on the drag pointer position that you can modify as you want. Default *type can be MUIV_NList_DropType_Above or MUIV_NList_DropType_Below. You can change it to any of MUIV_NList_DropType_None,MUIV_NList_DropType_Above, MUIV_NList_DropType_Below and MUIV_NList_DropType_Onto if you want, using the mouse position and the entry box. You can make your own *type value as long as you don't set it in MUIV_NList_DropType_Mask, and so draw what you want depending on that value in the MUIM_NList_DropDraw method. Note that any MUIV_NList_DropType_Below *type will be changed to MUIV_NList_DropType_Above with a *pos incremented by 1 just after the return of that method. If you change the *pos, the list will be scrolled to see it (if the value is correct). getting MUIA_NList_DropType or MUIA_NList_DropMark will return the same values as *pos and *type. If your subclass is a direct NList subclass, then there is no need to call the supermethod which has done nothing at all ! MUIM_NList_Exchange -- SYNOPSIS DoMethod(obj,MUIM_NList_Exchange,LONG pos1, LONG pos2); FUNCTION Same function as List.mui/MUIM_List_Exchange. Exchange two entries in a NList object. INPUTS pos1 - number of the first entry. pos2 - number of the second entry. MUIV_NList_Exchange_Top MUIV_NList_Exchange_Active MUIV_NList_Exchange_Bottom MUIV_NList_Exchange_Next only valid for second parameter MUIV_NList_Exchange_Previous only valid for second parameter MUIM_NList_GetEntry -- SYNOPSIS DoMethod(obj,MUIM_NList_GetEntry,LONG pos, APTR *entry); FUNCTION Same function as List.mui/MUIM_List_GetEntry. SPECIAL INPUTS MUIV_NList_GetEntry_Active give active entry (or NULL if none) MUIM_NList_GetEntryInfo -- SYNOPSIS DoMethod(obj,MUIM_NList_GetEntryInfo,struct MUI_NList_GetEntryInfo *res); FUNCTION You get useful information about some entry from its number, or from the real line number which can be different when there is word wrap in the list. INPUTS res - pointer to a MUI_NList_GetEntryInfo struct : LONG pos; number of entry you want info about */ LONG line; real line number */ LONG entry_pos; entry number of returned entry ptr */ APTR entry; entry pointer */ LONG wrapcol; NOWRAP, WRAPCOLx, or WRAPPED|WRAPCOLx */ LONG charpos; start char number in string (unused if NOWRAP) */ LONG charlen; string length (unused if NOWRAP) */ if pos is MUIV_NList_GetEntryInfo_Line then the method will use the line number to search infos, or else the line will be set to its correct number for the value of pos. entry is the entry ptr, think that if it's a word wrapped entry then it come from the returned entry_pos entry. Think, too, that if wrapcol tell you that it's a WRAPPED entry, only the WRAPCOLx col is drawn, from the charpos position in the string returned by DisplayHook for the column and for entry_pos/entry. MUIM_NList_GetPos -- SYNOPSIS DoMethod(obj,MUIM_NList_GetPos,APTR entry,LONG *pos); FUNCTION Give the (next) entry number which have the given entry number. It's the entry ptr which is stored in the list, ie the one returned by the ConstructHook if any. INPUTS entry - Entry ptr of the entry you want to get the pos. pos - a pointer to longword that will hold the next entry number of the given entry ptr. Must be set to MUIV_NList_GetPos_Start if you want to search from the beginning of the list. Is set to MUIV_NList_GetPos_End no more is found. MUIM_NList_GetSelectInfo -- SYNOPSIS DoMethod(obj,MUIM_NList_GetSelectInfo,struct MUI_NList_GetSelectInfo *res); FUNCTION Useful information about selected entries state is provided. INPUTS res - pointer to a MUI_NList_GetSelectInfo struct : LONG start num of first selected *REAL* entry/line (first of wrapped from which start is issued) LONG end num of last selected *REAL* entry/line (first of wrapped from which start is issued) LONG num not used LONG start_column column of start of selection in 'start' entry LONG end_column column of end of selection in 'end' entry LONG start_pos char pos of start of selection in 'start_column' entry LONG end_pos char pos of end of selection in 'end_column' entry LONG vstart num of first visually selected entry (ie can be the second or third line of a word wrap entry) LONG vend num of last visually selected entry (ie can be the second or third line of a word wrap entry) LONG vnum number of visually selected entries NOTE If no entry is selected, then start, end, vstart, vend are -1, vnum is 0. When start_column, end_column, start_pos, end_pos are -1 then the whole line/entry/column is selected. start_column, end_columb, start_pos and end_pos have the same meaning than parameters passed to the MUIA_NList_CopyEntryToClipHook. remember that in case of automatically added word wrapped entries, only the concerned column have any contents. You get that case for 'vstart' when 'start' is different, and for 'end' when 'vend' is different. MUIM_NList_Insert -- SYNOPSIS DoMethod(obj,MUIM_NList_Insert,APTR *entries, LONG count, LONG pos, LONG flags); FUNCTION Same function as List.mui/MUIM_List_Insert. Entry (display) contents will be display until \0 , \n or \r. You can insert a multiline string with count==-2. INPUTS entries - pointer to an array of pointers to be inserted. Warning: This is a pointer to a pointer. It's a pointer to string if count==-2. count - Number of elements to be inserted. If count==-1, entries will be inserted until NULL pointer in the entries array is found. If count==-2 then entries must be a string pointer which can be multiline with \n , \r or \r\n separators. There will be as many entries inserted as lines in the string. The end char is \0. pos - New entries will be added in front of this entry. MUIV_NList_Insert_Top insert as first entry. MUIV_NList_Insert_Active insert in front of the active entry. MUIV_NList_Insert_Sorted insert sorted (all entries will be sorted if necessary). MUIV_NList_Insert_Bottom insert as last entry. flags - Special flags for the insert operation or 0. MUIV_NList_Insert_Flag_Raw insert the entries without the automatic reordering of the columns. This could significantly accelerate the insertion of entries very, but will not automatically change the width of a column. MUIM_NList_InsertSingle -- SYNOPSIS DoMethod(obj,MUIM_NList_InsertSingle,APTR entry, LONG pos); FUNCTION Same function as List.mui/MUIM_List_InsertSingle. INPUTS entry - item to insert. pos - New entry will be added in front of this entry. MUIV_NList_Insert_Top insert as first entry. MUIV_NList_Insert_Active insert in front of the active entry. MUIV_NList_Insert_Sorted insert sorted (all entries will be sorted if necessary). MUIV_NList_Insert_Bottom insert as last entry. MUIM_NList_InsertSingleWrap -- SYNOPSIS DoMethod(obj,MUIM_NList_InsertSingleWrap, APTR entry, LONG pos, LONG wrapcol, LONG align); FUNCTION Same function as MUIM_NList_InsertSingle but permit word wrap and alignment for the entry. INPUTS entry - item to insert. pos - New entry will be added in front of this entry. MUIV_NList_Insert_Top insert as first entry. MUIV_NList_Insert_Active insert in front of the active entry. MUIV_NList_Insert_Sorted insert sorted (all entries will be sorted if necessary). MUIV_NList_Insert_Bottom insert as last entry. wrapcol - WRAPCOL0 to WRAPCOL6. You can't ask word wrap for an other col. NOWRAP if you don't want word wrap. So only one of (display hook) col 0 to 6 can be wrapped. align - ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT or ALIGN_JUSTIFY. be aware that align will be used if there is no escape align sequence in the preparses or column entry string. MUIM_NList_InsertWrap -- SYNOPSIS DoMethod(obj,MUIM_NList_InsertWrap, APTR *entries, LONG count, LONG pos, LONG wrapcol, LONG align); FUNCTION Same function as MUIM_NList_Insert but permit word wrap and alignement for the entry. INPUTS entries - pointer to an array of pointers to be inserted. Warning: This is a pointer to a pointer. It's a pointer to string if count==-2. count - Number of elements to be inserted. If count==-1, entries will be inserted until NULL pointer in the entries array is found. If count==-2 then entries must be a string pointer which can be multiline with \n , \r or \r\n separators. As many entries inserted as lines in the string will be provided. The end char is \0. pos - New entry will be added in front of this entry. MUIV_NList_Insert_Top insert as first entry. MUIV_NList_Insert_Active insert in front of the active entry. MUIV_NList_Insert_Sorted insert sorted (all entries will be sorted if necessary). MUIV_NList_Insert_Bottom insert as last entry. wrapcol - WRAPCOL0 to WRAPCOL6. You can't ask word wrap for an other col. NOWRAP if you don't want word wrap. So only one of (display hook) col 0 to 6 can be wrapped. align - ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT or ALIGN_JUSTIFY. be aware that align will be used if there is no escape align sequence in the preparses or column entry string. MUIM_NList_Jump -- SYNOPSIS DoMethod(obj,MUIM_NList_Jump,LONG pos); FUNCTION Same function as List.mui/MUIM_List_Jump. INPUTS pos - Number of the entry that should be made visible. Use MUIV_NList_Jump_Active to jump to the active entry. And use MUIV_NList_Jump_Active_Center to make the active entry visible centered in the listview. MUIM_NList_Move -- SYNOPSIS DoMethod(obj,MUIM_NList_Move,LONG from, LONG to); FUNCTION Same function as List.mui/MUIM_List_Move. INPUTS pos1 - number of the first entry. pos2 - number of the second entry. Possible special values : MUIV_NList_Move_Top MUIV_NList_Move_Active MUIV_NList_Move_Bottom MUIV_NList_Move_Next only valid for second parameter if first one is not Move_Selected MUIV_NList_Move_Previous only valid for second parameter if first one is not Move_Selected MUIV_NList_Move_Selected only valid for first parameter MUIM_NList_NextSelected -- SYNOPSIS DoMethod(obj,MUIM_NList_NextSelected,LONG *pos); FUNCTION Same function as List.mui/MUIM_List_NextSelected. In TypeSelect_Char mode you'll get all entries of the selected area, even the first and last which can be partially selected. INPUTS pos - a pointer to longword that will hold the number of the returned entry. Must be set to MUIV_NList_NextSelected_Start at start of iteration. Is set to MUIV_NList_NextSelected_End when iteration is finished. MUIM_NList_PrevSelected -- SYNOPSIS DoMethod(obj,MUIM_NList_PrevSelected,LONG *pos); FUNCTION Work like MUIM_NList_NextSelected but give the previous selected entry. In TypeSelect_Char mode you'll get all the entries of the selected area, even the first and last which can be partially selected. INPUTS pos - a pointer to longword that will hold the number of the returned entry. Must be set to MUIV_NList_PrevSelected_Start at start of iteration. Is set to MUIV_NList_PrevSelected_End when iteration is finished. MUIM_NList_Redraw -- SYNOPSIS DoMethod(obj,MUIM_NList_Redraw,LONG pos); FUNCTION Same function as List.mui/MUIM_List_Redraw. Redraw some entries or all. INPUTS pos - Number of the line to redraw. When the line is not currently visible, nothing will happen. Specials: MUIV_NList_Redraw_Active redraw the active line (if any), MUIV_NList_Redraw_All redraw all lines. MUIV_NList_Redraw_Title redraw the title. MUIM_NList_RedrawEntry -- SYNOPSIS DoMethod(obj,MUIM_NList_RedrawEntry,APTR entry); FUNCTION Redraw some entries, like MUIM_NList_Redraw, but using the entry pointer instead of the entry number. INPUTS entry - Enter the part of the entry (entries) to be redrawn. MUIM_NList_Remove -- SYNOPSIS DoMethod(obj,MUIM_NList_Remove,LONG pos); FUNCTION Same function as List.mui/MUIM_List_Remove. INPUTS pos - number of the entries to be removed or one of MUIV_NList_Remove_First MUIV_NList_Remove_Active MUIV_NList_Remove_Selected MUIV_NList_Remove_Last When the active or a selected entry is removed, the following entry will become active. When the active is the removed and is the last, the new last become active. MUIM_NList_ReplaceSingle -- FUNCTION DoMethod(obj,MUIM_NList_ReplaceSingle, APTR entry, LONG pos, LONG wrapcol, LONG align); FUNCTION Same function as MUIM_NList_InsertSingleWrap but replace an existing entry rather than inserting. It's better to do a direct replace than remove then insert it ! INPUTS entry - item to insert. pos - position of the entry to be replaced MUIV_NList_Insert_Top replace the first entry. MUIV_NList_Insert_Active replace the active entry. MUIV_NList_Insert_Bottom replace the last entry. Invalid positions will cause the replacement to fail! wrapcol - WRAPCOL0 to WRAPCOL6. You can't ask word wrap for an other col. NOWRAP if you don't want word wrap. So only one of (display hook) col 0 to 6 can be wrapped. align - ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT or ALIGN_JUSTIFY. be aware that align will be used if there is no escape align sequence in the preparses or column entry string. MUIM_NList_Select -- SYNOPSIS DoMethod(obj,MUIM_NList_Select,LONG pos, LONG seltype, LONG *state); FUNCTION Same function as List.mui/MUIM_List_Select when in TypeSelect_Line mode. In TypeSelect_Char mode, MUIV_NList_Select_Off will clear the selected area (don't look what is pos). MUIV_NList_Select_On will select the pos entry only (can be MUIV_NList_Select_Active or MUIV_NList_Select_All). MUIV_NList_Select_Ask will give the number off entry in the selected area. INPUTS pos - Number of the entry or MUIV_NList_Select_Active for the active entry. MUIV_NList_Select_All for all entries. seltype - MUIV_NList_Select_Off unselect entry. MUIV_NList_Select_On select entry. MUIV_NList_Select_Toggle toggle entry. MUIV_NList_Select_Ask just ask about the state. state - Pointer to a longword. If not NULL, this will be filled with the current selection state. MUIM_NList_SelectChange -- Called on every selection change (V19.98) SYNOPSIS DoMethod(obj,MUIM_NList_SelectChange,LONG pos, LONG state, ULONG flags); FUNCTION This method cannot/should not be called. Its purpose is only to indicate selection state changes of entries in a more powerful form than MUIA_NList_SelectChange does. It is only called when you are in line mode ie. MUIA_NList_TypeSelect is set to MUIV_NList_TypeSelect_Line, which is the default. pos - The position of the (un)selected entry. Can be MUIV_NList_Active_Off or something. state - The resulting state of the entry which can be MUIV_NList_Select_On, MUIV_NList_Select_Off or MUIV_NList_Select_Active. flags - Can be MUIV_NList_SelectChange_Flag_Multi for now which means that the entry was selected while holding down the mouse button. INPUTS MUIM_NList_SetActive -- make a specific entry the active one (v20.125) SYNOPSIS DoMethod(obj, MUIM_NList_SetActive, LONG pos, ULONG flags); FUNCTION This method is a replacement function for the old-style way of making an entry active via a simple set(obj, MUIA_NList_Active, pos) call. While the old method still works, this new function has the advantage that it allows to set an entry active together with making it immediately visible in the listview. Previously, a developer had to do a combination of a set() call to set MUIA_NList_Active and then immediately perform a MUIM_NList_Jump function call so that the entry becomes visible at the specific position. With this new function both operations are combined, potentially allowing future enhancements to be added via the additional 'flags' variable. INPUTS The parameter description is as followed: pos - The position (int) of the entry which should be made the new active entry. This can also be MUIV_NList_Active_XXXX values as explained in the MUIA_NList_Active documentation. Furthermore, pos might also be a perfect pointer to the entry directly in case you have specified the correct flag. flags - Can be a combination of the following flags: MUIV_NList_SetActive_Entry: the parameter 'pos' will be a pointer to the entry rather than the position (int) of the entry to be made active. If this flag is set NList will perform an internal GetPos() operation to first obtain the position and then set this entry active. MUIV_NList_SetActive_Jump_Center: Together with making the specified entry the new active one the listview will also be scrolled so that the new entry will be shown centered instead of having it simply visible. MUIM_NList_SetColumnCol -- SYNOPSIS DoMethod(obj,MUIM_NList_SetColumnCol,LONG column,LONG col); FUNCTION set which displayhook col is at the visible column. INPUTS column number of the column (visible). if MUIV_NList_SetColumnCol_Default then the given (diplayhook) col will come back to its default/original (from List_Format) position. col col number (displayhook one). if MUIV_NList_SetColumnCol_Default then the given visible column will come back to its default/original (from List_Format) position. both set to MUIV_NList_SetColumnCol_Default make all columns come back to their default/original (from List_Format) position. RESULT None. NOTE MUIM_NList_SetColumnCol always exchanges the moved column with the column which was where it moved. MUIM_NList_Sort -- SYNOPSIS DoMethod(obj,MUIM_NList_Sort); FUNCTION Same function as List.mui/MUIM_List_Sort. MUIM_NList_Sort2 -- SYNOPSIS DoMethod(obj,MUIM_NList_Sort2,LONG sort_type, LONG sort_type_add); FUNCTION Same function as MUIM_NList_Sort but will set MUIA_NList_SortType before starting the sort. It is really useful only if you use MUIA_NList_CompareHook2 instead of classic MUIA_NList_CompareHook so your hook will be able to do different type of sort when NList_SortType change. INPUTS sort_type - The new MUIA_NList_SortType value (see below). sort_type_add - If 0 then sort_type will be the new MUIA_NList_SortType, else if current MUIA_NList_SortType & MUIV_NList_SortTypeValue_Mask is same as sort_type then sort_type_add will be added to the MUIA_NList_SortType value, else sort_type will be the new MUIA_NList_SortType. See examples for special values. EXAMPLES Often, this method will be used to sort multicolumn list in different ways when the user click on title buttons : DoMethod(list,MUIM_Notify,MUIA_NList_TitleClick, MUIV_EveryTime, list, 3, MUIM_NList_Sort2, MUIV_TriggerValue, MUIV_NList_SortTypeAdd_xxx); if MUIV_NList_SortTypeAdd_None then the hook sort_type value will be the column number. if MUIV_NList_SortTypeAdd_2Values then the hook sort_type value will be a cycle of values which change on each click : o Column number (first time) o Column number + MUIV_NList_SortTypeAdd_2Values o back to column number ... if MUIV_NList_SortTypeAdd_4Values then the hook sort_type value will be a cycle of values which change on each click : o Column number (first time) o Column number + MUIV_NList_SortTypeAdd_4Values o Column number + MUIV_NList_SortTypeAdd_4Values*2 o Column number + MUIV_NList_SortTypeAdd_4Values*3 o back to column number ... See NList-Demo program. MUIM_NList_Sort3 -- SYNOPSIS DoMethod(obj,MUIM_NList_Sort3,LONG sort_type, LONG sort_type_add, LONG which); FUNCTION Same function as MUIM_NList_Sort2 but will set MUIA_NList_SortType, MUIA_NList_SortType2 or both before starting the sort. When using MUIV_NList_Sort3_SortType_Both the method will change MUIA_NList_SortType exactly the same way as MUIM_NList_Sort2 would do it, then copy that value to MUIA_NList_SortType2. It is really useful only if you use MUIA_NList_CompareHook2 instead of classic MUIA_NList_CompareHook so your hook will be able to do a different type of sort when NList_SortType changes. INPUTS sort_type - The new MUIA_NList_SortType/2 value. sort_type_add - If 0 then sort_type will be the new MUIA_NList_SortType/2, else if current MUIA_NList_SortType/2 & MUIV_NList_SortTypeValue_Mask is same as sort_type then sort_type_add will be added to the MUIA_NList_SortType/2 value, else sort_type will be the new MUIA_NList_SortType/2. which - MUIV_NList_Sort3_SortType_1 set MUIA_NList_SortType value. MUIV_NList_Sort3_SortType_2 set MUIA_NList_SortType2 value. MUIV_NList_Sort3_SortType_Both set MUIA_NList_SortType value then copy it to MUIA_NList_SortType2. EXAMPLES See NList-Demo program. MUIM_NList_TestPos -- SYNOPSIS DoMethod(obj,MUIM_NList_TestPos,LONG x, LONG y, struct MUI_NList_TestPos_Result *res); FUNCTION Find out which information of a list which is currently displayed at a certain position. You must give a pointer to a valid MUI_NList_TestPos_Result struct. Set x AND y to MUI_MAXMAX to get infos about the last click position ! See NList_mcc.h to know what values will be set in the struct. Preset char_number to -2 in the struct to not get char_number and char_xoffset informations. It's useful if you don't need them because it will be faster for the method without finding them. The -2 value will stay valid for next call. You'll get char number from what you return from the DisplayHook if there is one, else from the beginning of the string/entry ptr. Be aware: if you use MUIM_List_TestPos you have to give a pointer to a struct MUI_List_TestPos_Result, and you will get same infos as using a List object. It wasn't done as before, making enforcer hits when trying to use NList or NFloattext with a Listview instead of a NListview (avoid it please, it's not done for it as Listview try to make many things itself, with possible conficts), because struct MUI_NList_TestPos_Result is bigger !!! NOTE column in the struct MUI_NList_TestPos_Result is the visible column number ! MUIM_NList_UseImage -- SYNOPSIS DoMethod(obj,MUIM_NList_UseImage,Object *obj, ULONG imgnum, ULONG flags); FUNCTION To use MUIM_NList_CreateImage/MUIM_NList_DeleteImage as you should, make a NList subclass which calls them from Setup() and Cleanup(), and it's sometimes complicated. To avoid that, use MUIM_NList_UseImage. NList will store the Bitmap/Bodychunk object you give and will make CreateImage and DeleteImage itself ! MUIM_NList_UseImage can use same object as MUIM_NList_CreateImage ! NULL is a valid obj. It will erase any previously UseImage with the same imgnum. The imgnum you give is the number that you will use in \33o[<n>] sequence as the <n> number. MUIM_NList_UseImage will accept 0 <= imgnum < 8192, anyway use small value if you can because an array will be allocated with the biggest imgnum value as size to store the Bitmap/Bodychunk objects. DoMethod(obj,MUIM_NList_UseImage, NULL, MUIV_NList_UseImage_All, 0) will set NULL to all stored objects, so you willll be able to dispose your Bitmap/Bodychunk objects if you want, without waiting for the NList object dispose. flags is the same than for MUIM_NList_CreateImage (0 unless special case). RESULT TRUE if succeeded to store the obj (and allocate the array if needed), else FALSE. There is no way to know if the MUIM_NList_CreateImage needed to draw will succeed/has succeeded. ATTENTION: The given Bitmap/Bodychunk object MUST be valid until the NList object is disposed or you set another object (or NULL) at the same imgnum ! The Bitmap/Bodychunk object can be shared with other NList object because NList just use it to get informations, anyway you mustn't change informations of that object. If you to do so, do a UseImage,NULL,x , change it then do UseImage,imgobj,x again.
/*************************************************************************** NList.mcc - New List MUI Custom Class Registered MUI class, Serial Number: 1d51 0x9d510030 to 0x9d5100A0 0x9d5100C0 to 0x9d5100FF Copyright (C) 1996-2001 by Gilles Masson Copyright (C) 2001-2006 by NList Open Source Team This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. NList classes Support Site: http://www.sf.net/projects/nlist-classes $Id: NList-Demo3.c 43734 2012-01-28 14:26:37Z mazze $ ***************************************************************************/ #include <stdlib.h> #include <string.h> #include <stdio.h> #include <dos/dos.h> #include <exec/types.h> #include <exec/memory.h> #include <exec/ports.h> #include <exec/io.h> #include <libraries/dos.h> #include <libraries/dosextens.h> #include <libraries/gadtools.h> #include <libraries/asl.h> #include <libraries/mui.h> #include <workbench/workbench.h> #include <intuition/intuition.h> #include <intuition/classusr.h> #include <graphics/gfxmacros.h> #undef GetOutlinePen #if !defined(__amigaos4__) #include <clib/alib_protos.h> #endif #include <proto/exec.h> #include <proto/dos.h> #include <proto/gadtools.h> #include <proto/graphics.h> #include <proto/utility.h> #include <proto/asl.h> #include <proto/intuition.h> extern struct Library *MUIMasterBase; #include <mui/NListview_mcc.h> #include <mui/NFloattext_mcc.h> #include "NList-Demo3.h" #include <proto/muimaster.h> #include "SDI_hook.h" /* *********************************************** */ struct MUI_CustomClass *NLI_Class = NULL; /* *********************************************** */ struct NLIData { LONG special; LONG EntryCurrent; LONG EntryHeight; }; /* *********************************************** */ IPTR mNLI_Draw(struct IClass *cl,Object *obj,struct MUIP_Draw *msg) { register struct NLIData *data = INST_DATA(cl,obj); DoSuperMethodA(cl,obj,(Msg) msg); if ((msg->flags & MADF_DRAWOBJECT) || (msg->flags & MADF_DRAWUPDATE)) { WORD x1,x2,x3,x4,x5,y1,y2,y3,y4,y5; y1 = _top(obj); y2 = _bottom(obj); x1 = _left(obj); x2 = _right(obj); if ((data->special == 0) || (data->special == 1)) { y3 = (y1+y2)/2; x3 = (x1+x2)/2; SetAPen(_rp(obj),_pens(obj)[MPEN_MARK]); SetBPen(_rp(obj),_pens(obj)[MPEN_SHADOW]); SetDrMd(_rp(obj),JAM2); SetDrPt(_rp(obj),(UWORD) ~0); if (data->special == 0) { Move(_rp(obj), x3-2, y1+1); Draw(_rp(obj), x3-2, y2-1); Move(_rp(obj), x3, y1+1); Draw(_rp(obj), x3, y2-1); Move(_rp(obj), x3+2, y1+1); Draw(_rp(obj), x3+2, y2-1); } else if (data->special == 1) { Move(_rp(obj), x1, y3-2); Draw(_rp(obj), x2, y3-2); Move(_rp(obj), x1, y3); Draw(_rp(obj), x2, y3); Move(_rp(obj), x1, y3+2); Draw(_rp(obj), x2, y3+2); } SetAPen(_rp(obj),_pens(obj)[MPEN_SHADOW]); Move(_rp(obj), x1, y2-1); Draw(_rp(obj), x1, y1+1); Draw(_rp(obj), x2, y1+1); SetAPen(_rp(obj),_pens(obj)[MPEN_SHINE]); Draw(_rp(obj), x2, y2-1); Draw(_rp(obj), x1, y2-1); SetDrMd(_rp(obj),JAM1); } else if (((x2 - x1) >= 10) && ((y2 - y1) >= 8)) /* and special==2 to 9 */ { y3 = (y1+y2)/2; x3 = x1 + 1; x2--; SetAPen(_rp(obj),_pens(obj)[MPEN_SHADOW]); SetDrMd(_rp(obj),JAM1); y4 = y1; x4 = x3 + 2; y5 = y2; x5 = x2-6; if ((data->EntryHeight & 1) && (data->EntryCurrent & 1)) y4++; if ((y4 & 1) != (y3 & 1)) x4--; if (data->special > 5) x5 = x2; if (data->special & 1) y5 = y3; while (y4 <= y5) { WritePixel(_rp(obj), x3, y4); y4 += 2; } if (data->special <= 7) { while (x4 <= x5) { WritePixel(_rp(obj), x4, y3); x4 += 2; } } if (data->special <= 5) { Move(_rp(obj), x2-6, y3); Draw(_rp(obj), x2-6, y3-3); Draw(_rp(obj), x2, y3-3); Draw(_rp(obj), x2, y3+3); Draw(_rp(obj), x2-6, y3+3); Draw(_rp(obj), x2-6, y3); Move(_rp(obj), x2-4, y3); Draw(_rp(obj), x2-2, y3); if ((data->special == 2) || (data->special == 3)) { Move(_rp(obj), x2-3, y3-1); Draw(_rp(obj), x2-3, y3+1); } } } } msg->flags = 0; return(0); } IPTR mNLI_New(struct IClass *cl,Object *obj,struct opSet *msg) { register struct NLIData *data; if (!(obj = (Object *)DoSuperMethodA(cl,obj,(Msg) msg))) return(0); data = INST_DATA(cl,obj); data->special = 0; return((IPTR) obj); } IPTR mNLI_AskMinMax(struct IClass *cl,Object *obj,struct MUIP_AskMinMax *msg) { DoSuperMethodA(cl,obj,(Msg) msg); msg->MinMaxInfo->MinWidth += 8; msg->MinMaxInfo->DefWidth += 18; /* the only width def value really used by NList object */ msg->MinMaxInfo->MaxWidth += MUI_MAXMAX; msg->MinMaxInfo->MinHeight += 7; /* the only height def value really used by NList object */ msg->MinMaxInfo->DefHeight += 12; msg->MinMaxInfo->MaxHeight += MUI_MAXMAX; return(0); } IPTR mNLI_Set(struct IClass *cl,Object *obj,Msg msg) { register struct NLIData *data = INST_DATA(cl,obj); struct TagItem *tags,*tag; for(tags=((struct opSet *)msg)->ops_AttrList; (tag=(struct TagItem *)NextTagItem((APTR)&tags)); ) { switch (tag->ti_Tag) { case MUIA_NLIMG_EntryCurrent: data->EntryCurrent = tag->ti_Data; break; case MUIA_NLIMG_EntryHeight: data->EntryHeight = tag->ti_Data; break; case MUIA_NLIMG_Spec: data->special = tag->ti_Data; break; } } return (0); } DISPATCHER(NLI_Dispatcher) { switch (msg->MethodID) { case OM_NEW : return ( mNLI_New(cl,obj,(APTR)msg)); case OM_SET : return ( mNLI_Set(cl,obj,(APTR)msg)); case MUIM_AskMinMax : return (mNLI_AskMinMax(cl,obj,(APTR)msg)); case MUIM_Draw : return ( mNLI_Draw(cl,obj,(APTR)msg)); } return(DoSuperMethodA(cl,obj,msg)); } struct MUI_CustomClass *NLI_Create(void) { NLI_Class = MUI_CreateCustomClass(NULL, (STRPTR)MUIC_Area, NULL, sizeof(struct NLIData), ENTRY(NLI_Dispatcher)); return (NLI_Class); } void NLI_Delete(void) { if (NLI_Class) MUI_DeleteCustomClass(NLI_Class); NLI_Class = NULL; }
NListtree
[edit | edit source]NListtree.mcc/MUIA_NListtree_Active NListtree.mcc/MUIA_NListtree_ActiveList NListtree.mcc/MUIA_NListtree_AutoVisible NListtree.mcc/MUIA_NListtree_CloseHook NListtree.mcc/MUIA_NListtree_CompareHook NListtree.mcc/MUIA_NListtree_ConstructHook NListtree.mcc/MUIA_NListtree_CopyToClipHook NListtree.mcc/MUIA_NListtree_DestructHook NListtree.mcc/MUIA_NListtree_DisplayHook NListtree.mcc/MUIA_NListtree_DoubleClick NListtree.mcc/MUIA_NListtree_DragDropSort NListtree.mcc/MUIA_NListtree_DropTarget NListtree.mcc/MUIA_NListtree_DropTargetPos NListtree.mcc/MUIA_NListtree_DropType NListtree.mcc/MUIA_NListtree_DupNodeName NListtree.mcc/MUIA_NListtree_EmptyNodes NListtree.mcc/MUIA_NListtree_FindNameHook NListtree.mcc/MUIA_NListtree_FindUserDataHook NListtree.mcc/MUIA_NListtree_Format NListtree.mcc/MUIA_NListtree_MultiSelect NListtree.mcc/MUIA_NListtree_MultiTestHook NListtree.mcc/MUIA_NListtree_OpenHook NListtree.mcc/MUIA_NListtree_Quiet NListtree.mcc/MUIA_NListtree_ShowTree NListtree.mcc/MUIA_NListtree_Title NListtree.mcc/MUIA_NListtree_TreeColumn NListtree.mcc/MUIM_NListtree_Active NListtree.mcc/MUIM_NListtree_Clear NListtree.mcc/MUIM_NListtree_Close NListtree.mcc/MUIM_NListtree_Compare NListtree.mcc/MUIM_NListtree_Construct NListtree.mcc/MUIM_NListtree_Copy NListtree.mcc/MUIM_NListtree_CopyToClip NListtree.mcc/MUIM_NListtree_Destruct NListtree.mcc/MUIM_NListtree_Display NListtree.mcc/MUIM_NListtree_DoubleClick NListtree.mcc/MUIM_NListtree_DropDraw NListtree.mcc/MUIM_NListtree_DropType NListtree.mcc/MUIM_NListtree_Exchange NListtree.mcc/MUIM_NListtree_FindName NListtree.mcc/MUIM_NListtree_FindUserData NListtree.mcc/MUIM_NListtree_GetEntry NListtree.mcc/MUIM_NListtree_GetNr NListtree.mcc/MUIM_NListtree_Insert NListtree.mcc/MUIM_NListtree_InsertStruct NListtree.mcc/MUIM_NListtree_Move NListtree.mcc/MUIM_NListtree_MultiTest NListtree.mcc/MUIM_NListtree_NextSelected NListtree.mcc/MUIM_NListtree_Open NListtree.mcc/MUIM_NListtree_PrevSelected NListtree.mcc/MUIM_NListtree_Redraw NListtree.mcc/MUIM_NListtree_Remove NListtree.mcc/MUIM_NListtree_Rename NListtree.mcc/MUIM_NListtree_Select NListtree.mcc/MUIM_NListtree_Sort NListtree.mcc/MUIM_NListtree_TestPos
NListtree.mcc/ There are two possible entry-types in a NListtree class list: Leaves and nodes. Leaves are simple entries which have no special features except they are holding some data. Nodes are almost the same type, holding data too, but having a list attached where you can simply add other entries which can be again leaves or nodes. Every node is structured as follows: struct MUI_NListtree_TreeNode { struct MinNode tn_Node; STRPTR tn_Name; UWORD tn_Flags; APTR tn_User; }; It contains a name field tn_Name, flags tn_Flags and a pointer to user data tn_User. The tn_Flags field can hold the following flags: TNF_LIST The node contains a list where other nodes can be inserted. TNF_OPEN The list node is open, sub nodes are displayed. TNF_FROZEN The node doesn't react on doubleclick or open/close by the user. TNF_NOSIGN The indicator of list nodes isn't shown. TNF_SELECTED The entry is currently selected. These flags, except TNF_SELECTED, can be used in MUIM_NListtree_Insert at creation time. They will be passed to the newly created entry. Also you can do a quick check about the state and kind of each entry. But DO NOT EVER modify any flag yourself or NListtree will crash. Be warned! ********************************************************************* THE ABOVE STRUCT IS READ-ONLY!! NEVER CHANGE ANY ENTRY OF THIS STRUCTURE DIRECTLY NOR THINK ABOUT THE CONTENTS OF ANY PRIVATE FIELD OR YOU WILL DIE IN HELL! ********************************************************************* You can create very complex tree structures. NListtree only uses one list which holds all information needed and has no extra display list like other list tree classes ;-) The tree nodes can be inserted and removed, sorted, moved, exchanged, renamed or multi selected. To sort you can also drag&drop them. Modifications can be made in relation to the whole tree, to only one level, to a sub-tree or to only one tree node. The user can control the listtree by the MUI keys, this means a node is opened with "Right" and closed with "Left". Check your MUI prefs for the specified keys. You can define which of the columns will react on double-clicking. The node toggles its status from open or closed and vice versa. Drag&Drop capabilities: If you set MUIA_NList_DragSortable to TRUE, the list tree will become active for Drag&Drop. This means you can drag and drop entries on the same list tree again. While dragging an indicator shows where to drop. Drag a Drop on Result leaf leaf Exchange leaves. node leaf Nothing happens. entry closed node Move entry, the compare hook is used. entry open node Move entry to defined position. You can not drop an entry on itself, nor can you drop an opened node on any of its members. To exchange data with other objects, you have to create your own subclass of NListtree class and react on the drag methods. MUIA_NListtree_Active -- [.SG], struct MUI_NListtree_TreeNode * SPECIAL VALUES MUIV_NListtree_Active_Off MUIV_NListtree_Active_Parent MUIV_NListtree_Active_First MUIV_NListtree_Active_FirstVisible MUIV_NListtree_Active_LastVisible FUNCTION Setting this attribute will move the cursor to the defined tree node if it is visible. If the node is in an opened tree the listview is scrolling into the visible area. Setting MUIV_NListtree_Active_Off will vanish the cursor. MUIV_NListtree_Active_First/FirstVisible/LastVisible are special values for activating the lists first or the top/bottom visible entry. See MUIA_NListtree_AutoVisible for special activation features. If this attribute is read it returns the active tree node. The result is MUIV_NListtree_Active_Off if there is no active entry. NOTIFICATIONS You can create a notification on MUIA_NListtree_Active. The TriggerValue is the active tree node. MUIA_NListtree_ActiveList -- [..G], struct MUI_NListtree_TreeNode * SPECIAL VALUES MUIV_NListtree_ActiveList_Off FUNCTION If this attribute is read it returns the active list node. The active list node is always the parent of the active entry. The result is MUIV_NListtree_ActiveList_Off if there is no active list (when there is no active entry). NOTIFICATIONS You can create notifications on MUIA_NListtree_ActiveList. The TriggerValue is the active list node. MUIA_NListtree_AutoVisible -- [ISG], struct MUI_NListtree_TreeNode * SPECIAL VALUES MUIV_NListtree_AutoVisible_Off MUIV_NListtree_AutoVisible_Normal MUIV_NListtree_AutoVisible_FirstOpen MUIV_NListtree_AutoVisible_Expand FUNCTION Set this to make your list automatically jump to the active entry. MUIV_NListtree_AutoVisible_Off: The display does NOT scroll the active entry into the visible area. MUIV_NListtree_AutoVisible_Normal: This will scroll the active entry into the visible area if it is visible (entry is a member of an open node). This is the default. MUIV_NListtree_AutoVisible_FirstOpen: Nodes are not opened, but the first open parent node of the active entry is scrolled into the visible area if the active entry is not visible. MUIV_NListtree_AutoVisible_Expand: All parent nodes are opened until the first open node is reached and the active entry will be scrolled into the visible area. MUIA_NListtree_CloseHook -- [IS.], struct Hook * SPECIAL VALUES FUNCTION The close hook is called after a list node is closed, then the list can be changed. The close hook will be called with the hook in A0, the object in A2 and a MUIP_NListtree_CloseMessage struct in A1 (see nlisttree_mcc.h). To remove the hook set this to NULL. MUIA_NListtree_CompareHook -- [IS.], struct Hook * SPECIAL VALUES MUIV_NListtree_CompareHook_Head MUIV_NListtree_CompareHook_Tail MUIV_NListtree_CompareHook_LeavesTop MUIV_NListtree_CompareHook_LeavesMixed MUIV_NListtree_CompareHook_LeavesBottom FUNCTION Set this attribute to your own hook in order to sort the entries in the list tree by your own way. When you sort your list or parts of your list via MUIM_NListtree_Sort, using the insert method with MUIV_NListtree_Insert_Sort or dropping an entry on a closed node, this compare hook is called. There are some builtin compare hooks available, called: MUIV_NListtree_CompareHook_Head Any entry is inserted at the head of the list. MUIV_NListtree_CompareHook_Tail Any entry is inserted at the tail of the list. MUIV_NListtree_CompareHook_LeavesTop Leaves are inserted at the top of the list, nodes at bottom. They are alphabetically sorted. MUIV_NListtree_CompareHook_LeavesMixed The entries are only alphabetically sorted. MUIV_NListtree_CompareHook_LeavesBottom Leaves are inserted at bottom of the list, nodes at top. They are alphabetically sorted. This is default. The hook will be called with the hook in A0, the object in A2 and a MUIP_NListtree_CompareMessage struct in A1 (see nlisttree_mcc.h). You should return something like: <0 (TreeNode1 < TreeNode2) 0 (TreeNode1 == TreeNode2) >0 (TreeNode1 > TreeNode2) MUIA_NListtree_ConstructHook -- [IS.], struct Hook * SPECIAL VALUES MUIV_NListtree_ConstructHook_String MUIV_NListtree_ConstructHook_Flag_AutoCreate If using the KeepStructure feature in MUIM_NListtree_Move or MUIM_NListtree_Copy, this flag will be set when calling your construct hook. Then you can react if your hook is not simply allocating memory. FUNCTION The construct hook is called whenever you add an entry to your listtree. The pointer isn't inserted directly, the construct hook is called and its result code is added. When an entry shall be removed the corresponding destruct hook is called. The construct hook will be called with the hook in A0, the object in A2 and a MUIP_NListtree_ConstructMessage struct in A1 (see nlisttree_mcc.h). The message holds a standard kick 3.x memory pool pointer. If you want, you can use the exec or amiga.lib functions for allocating memory within this pool, but this is only an option. If the construct hook returns NULL, nothing will be added to the list. There is a builtin construct hook available called MUIV_NListtree_ConstructHook_String. This expects that the field 'tn_User' in the treenode is a string pointer (STRPTR), whose string is copied. MUIV_NListtree_DestructHook_String must be used in this case! To remove the hook set this to NULL. NEVER pass a NULL pointer when you have specified the internal string construct/destruct hooks or NListtree will die! MUIA_NListtree_CopyToClipHook -- [IS.], SPECIAL VALUES MUIV_NListtree_CopyToClipHook_Default FUNCTION This works similarly to MUIA_NListtree_DisplayHook, but is called when the NListtree object want to make a clipboard copy. You can return only one string pointer. If you return NULL, nothing will be copied. If you return -1, the entry will be handled as a normal string and the name field is used. The built-in hook skips all ESC sequences and adds a tab char between columns. MUIA_NListtree_DestructHook -- [IS.], struct Hook * SPECIAL VALUES MUIV_NListtree_DestructHook_String FUNCTION Set up a destruct hook for your listtree. The destruct hook is called whenevere you remove an entry from the listtree. Here you can free memory which was allocated by the construct hook before. The destruct hook will be called with the hook in A0, the object in A2 and a MUIP_NListtree_DestructMessage struct in A1 (see nlisttree_mcc.h). The message holds a standard kick 3.x memory pool pointer. This pool must be used when you have used it inside the construct hook to allocate pooled memory. There is a built-in destruct hook available called MUIV_NListtree_DestructHook_String. This expects that the 'User' data in the treenode is a string and you have used MUIV_NListtree_ConstructHook_String in the construct hook! To remove the hook set this to NULL. MUIA_NListtree_DisplayHook -- [IS.], SPECIAL VALUES FUNCTION You have to supply a display hook to specify what should be shown in the listview, otherwise only the name of the nodes is displayed. The display hook will be called with the hook in A0, the object in A2 and a MUIP_NListtree_DisplayMessage struct in A1 (see nlisttree_mcc.h). The structure holds a pointer to a string array containing as many entries as your listtree may have columns. You have to fill this array with the strings you want to display. Check out that the array pointer of the tree column is set to NULL, if the normal name of the node should appear. You can set a preparse string in Preparse for the corresponding col element. Using it you'll be able to avoid copying the string in a buffer to add something in the beginning of the col string. The display hook also gets the position of the current entry as additional parameter. It is stored in the longword preceding the col array (don't forget it's a LONG). You can set the array pointer of the tree column to a string, which is displayed instead of the node name. You can use this to mark nodes. See MUIA_NList_Format for details about column handling. To remove the hook and use the internal default display hook set this to NULL. MUIA_NListtree_DoubleClick -- [ISG], ULONG SPECIAL VALUES MUIV_NListtree_DoubleClick_Off MUIV_NListtree_DoubleClick_All MUIV_NListtree_DoubleClick_Tree MUIV_NListtree_DoubleClick_NoTrigger FUNCTION A doubleclick opens a node if it was closed, it is closed if the node was open. You have to set the column which should do this. Normally only the column number is set here, but there are special values: MUIV_NListtree_DoubleClick_Off: A doubleclick is not handled. MUIV_NListtree_DoubleClick_All: All columns react on doubleclick. MUIV_NListtree_DoubleClick_Tree Only a doubleclick on the defined tree column is recognized. MUIV_NListtree_DoubleClick_NoTrigger: A doubleclick is not handled and not triggered! NOTIFICATION The TriggerValue of the notification is the tree node you have double- clicked, you can GetAttr() MUIA_NListtree_DoubleClick for the column number. The struct 'MUI_NListtree_TreeNode *'is used for trigger. The notification is done on leaves and on node columns, which are not set in MUIA_NListtree_DoubleClick. MUIA_NListtree_DragDropSort -- [IS.], BOOL SPECIAL VALUES FUNCTION Setting this attribute to FALSE will disable the ability to sort the list tree by drag & drop. Defaults to TRUE. MUIA_NListtree_DropTarget -- [..G], ULONG SPECIAL VALUES FUNCTION After a successful drop operation, this value holds the entry where the entry was dropped. The relative position (above etc.) can be obtained by reading the attribute MUIA_NListtree_DropType. MUIA_NListtree_DropTargetPos -- [..G], ULONG SPECIAL VALUES FUNCTION After a successful drop operation, this value holds the integer position of the entry where the dragged entry was dropped. The entry itself can be obtained by reading MUIA_NListtree_DropTarget, the relative position (above etc.) can be obtained by reading the attribute MUIA_NListtree_DropType. MUIA_NListtree_DropType -- [..G], ULONG SPECIAL VALUES MUIV_NListtree_DropType_None MUIV_NListtree_DropType_Above MUIV_NListtree_DropType_Below MUIV_NListtree_DropType_Onto FUNCTION After a successful drop operation, this value holds the position relative to the value of MUIA_NListtree_DropTarget/DropTargetPos. NOTIFICATION MUIA_NListtree_DupNodeName -- [IS.], BOOL SPECIAL VALUES FUNCTION If this attribute is set to FALSE the names of the node will not be duplicated, only the string pointers are used. Be careful the strings have to be valid every time. NOTIFICATION MUIA_NListtree_EmptyNodes -- [IS.], BOOL SPECIAL VALUES FUNCTION Setting this attribute to TRUE will display all empty nodes as leaves, this means no list indicator is shown. Nevertheless the entry is handled like a node. NOTIFICATION MUIA_NListtree_FindNameHook -- [IS.], SPECIAL VALUES MUIV_NListtree_FindNameHook_CaseSensitive Search for the complete string, case sensitive. MUIV_NListtree_FindNameHook_CaseInsensitive Search for the complete string, case insensitive. MUIV_NListtree_FindNameHook_Part Search for the first part of the string, case sensitive. MUIV_NListtree_FindNameHook_PartCaseInsensitive Search for the first part of the string, case insensitive. MUIV_NListtree_FindNameHook_PointerCompare Do only a pointer comparison. This is a pointer subtraction to fit into the rules. It returns the difference (~0) of the two fields if there is no match. FUNCTION You can install a FindName hook to specify your own search criteria. The find name hook will be called with the hook in A0, the object in A2 and a MUIP_NListtree_FindNameMessage struct in A1 (see nlisttree_mcc.h). It should return ~ 0 for entries which are not matching the pattern and a value of 0 if a match. The find name message structure holds a pointer to a string containing the name to search for and pointers to the name- and user- field of the node which is currently processed. The MUIV_NListtree_FindNameHook_CaseSensitive will be used as default. NOTIFICATION MUIA_NListtree_FindUserDataHook -- [IS.], SPECIAL VALUES MUIV_NListtree_FindUserDataHook_CaseSensitive Search for the complete string, case sensitive. MUIV_NListtree_FindUserDataHook_CaseInsensitive Search for the complete string, case insensitive. MUIV_NListtree_FindUserDataHook_Part Search for the first part of the string, case sensitive. MUIV_NListtree_FindUserDataHook_PartCaseInsensitive Search for the first part of the string, case insensitive. MUIV_NListtree_FindUserDataHook_PointerCompare Do only a pointer comparison. This is in fact a pointer subtraction to fit into the rules. It returns the difference (~0) of the two user fields if there is no match. FUNCTION You can install a FindUserData hook to specify your own search criteria. The find user data hook will be called with the hook in A0, the object in A2 and a MUIP_NListtree_FindUserDataMessage struct in A1 (see nlisttree_mcc.h). It should return ~ 0 for entries which are not matching the pattern and a value of 0 if a match. The find user data message structure holds a pointer to a string containing the data to search for and pointers to the user- and name- field of the node which is currently processed. MUIV_NListtree_FindUserDataHook_CaseSensitive will be used as default. NOTIFICATION MUIA_NListtree_Format -- [IS.], STRPTR SPECIAL VALUES FUNCTION Same as MUIA_NList_Format, but one column is reserved for the tree indicators and the names of the nodes. For further detailed information see MUIA_NList_Format! NOTIFICATION MUIA_NListtree_MultiSelect -- [I..], SPECIAL VALUES MUIV_NListtree_MultiSelect_None MUIV_NListtree_MultiSelect_Default MUIV_NListtree_MultiSelect_Shifted MUIV_NListtree_MultiSelect_Always FUNCTION Four possibilities exist for a listviews multi select capabilities: MUIV_NListtree_MultiSelect_None: The list tree cannot multiselect at all. MUIV_NListtree_MultiSelect_Default: The multi select type (with or without shift) depends on the users preferences setting. MUIV_NListtree_MultiSelect_Shifted: Overrides the users prefs, multi selecting only together with shift key. MUIV_NListtree_MultiSelect_Always: Overrides the users prefs, multi-selecting without shift key. NOTIFICATION MUIA_NListtree_MultiTestHook -- [IS.], struct Hook * SPECIAL VALUES FUNCTION If you plan to have a multi-selecting list tree but not all of your entries are actually multi-selectable, you can supply a MUIA_NListtree_MultiTestHook. The multi-test hook will be called with the hook in A0, the object in A2 and a MUIP_NListtree_MultiTestMessage struct in A1 (see nlisttree_mcc.h) and should return TRUE if the entry is multi- selectable, FALSE otherwise. To remove the hook set this to NULL. NOTIFICATION MUIA_NListtree_OpenHook -- [IS.], struct Hook * SPECIAL VALUES FUNCTION The open hook is called whenever a list node will be opened, so you can change the list before the node is open. The open hook will be called with the hook in A0, the object in A2 and a MUIP_NListtree_OpenMessage struct in A1 (see nlisttree_mcc.h). To remove the hook set this to NULL. NOTIFICATION MUIA_NListtree_Quiet -- [.S.], QUIET SPECIAL VALUES FUNCTION If you add/remove lots of entries to/from a listtree, this will cause lots of screen action and slow down the operation. Setting MUIA_NListtree_Quiet to TRUE will temporarily prevent the listtree from being refreshed, this refresh will take place only once when you set it back to FALSE again. MUIA_NListtree_Quiet holds a nesting count to avoid trouble with multiple setting/unsetting this attribute. You are encouraged to always use TRUE/FALSE pairs here or you will have difficulty. DO NOT USE MUIA_NList_Quiet here! NOTIFICATION MUIA_NListtree_ShowTree -- [ISG], ULONG SPECIAL VALUES FUNCTION Specify FALSE here if you want the whole tree to be disappear. Defaults to TRUE; NOTIFICATION MUIA_NListtree_Title -- [IS.], BOOL SPECIAL VALUES FUNCTION Specify a title for the current listtree. For detailed information see MUIA_NList_Title! NOTIFICATION BUGS The title should not be a string as for single column listviews. This attribute can only be set to TRUE or FALSE. MUIA_NListtree_TreeColumn -- [ISG], ULONG SPECIAL VALUES FUNCTION Specify the column of the list tree, the node indicator and the name of the node are displayed in. NOTIFICATION
MUIM_NListtree_Active -- Called for every active change. (V1) SYNOPSIS DoMethodA(obj, MUIM_NListtree_Active, struct MUIP_NListtree_Active *activemessage); FUNCTION This method must not be called directly. It will be called by NListtree if the active entry changes. This is an addition to MUIA_NListtree_Active INPUTS RESULT EXAMPLE NOTES BUGS MUIM_NListtree_Clear -- Clear the complete listview. (V1) SYNOPSIS DoMethod(obj, MUIM_NListtree_Clear, NULL, 0) FUNCTION Clear the complete listview, calling destruct hook for each entry. INPUTS RESULT EXAMPLE // Clear the listview! DoMethod( nlisttree, MUIM_NListtree_Clear, NULL, 0 ); NOTES For now, when using this method, you must supply NULL for the list node and 0 for flags for future compatibility. This will change! BUGS MUIM_NListtree_Close -- Close the specified list node. (V1) SYNOPSIS DoMethod(obj, MUIM_NListtree_Close, struct MUI_NListtree_TreeNode *listnode, struct MUI_NListtree_TreeNode *treenode, ULONG flags); FUNCTION Close a node or nodes of a listtree. It is checked if the tree node is a node, not a leaf! When the active entry was a child of the closed node, the closed node will become active. INPUTS listnode - Specify the node which list is used to find the entry. The search is started at the head of this list. MUIV_NListtree_Close_ListNode_Root The root list is used. MUIV_NListtree_Close_ListNode_Parent The list which is the parent of the active list is used. MUIV_NListtree_Close_ListNode_Active The list of the active node is used. treenode - The node which should be closed. If there are children of the node, they are also closed. MUIV_NListtree_Close_TreeNode_Head The head of the list defined in 'listnode' is closed. MUIV_NListtree_Close_TreeNode_Tail: Closes the tail of the list defined in 'listnode'. MUIV_NListtree_Close_TreeNode_Active: Closes the active node. MUIV_NListtree_Close_TreeNode_All: Closes all nodes of the list which is specified in 'listnode'. RESULT EXAMPLE // Close the active list. DoMethod(obj, MUIM_NListtree_Close, MUIV_NListtree_Close_ListNode_Active, MUIV_NListtree_Close_TreeNode_Active, 0); NOTES BUGS MUIM_NListtree_Compare -- Compare two nodes SYNOPSIS DoMethod(obj, MUIM_NListtree_Compare, struct MUI_NListtree_TreeNode *TreeNode1, struct MUI_NListtree_TreeNode *TreeNode2, ULONG SortType); FUNCTION Compares the two given treenodes. You should return something like: <0 (TreeNode1 < TreeNode2) 0 (TreeNode1 == TreeNode2) >0 (TreeNode1 > TreeNode2) NOTIFICATION MUIM_NListtree_Construct -- Create a new treenode SYNOPSIS DoMethod(obj, MUIM_NListtree_Construct, STRPTR Name, APTR UserData, APTR MemPool, ULONG Flags); FUNCTION This method is called whenever a new treenode is to be added to the listtree. See MUIA_NListtree_ConstructHook for more details. If the method returns NULL, nothing will be added to the list. NOTIFICATION MUIM_NListtree_Copy -- Copy an entry (create it) to the spec. pos. (V1) SYNOPSIS DoMethod(obj, MUIM_NListtree_Copy, struct MUI_NListtree_TreeNode *srclistnode, struct MUI_NListtree_TreeNode *srctreenode, struct MUI_NListtree_TreeNode *destlistnode, struct MUI_NListtree_TreeNode *desttreenode, ULONG flags); FUNCTION Copy an entry to the position after a defined node. The complete child structure will be copied. INPUTS srclistnode - Specify the node which list is used to find the entry. The search is started at the head of this list. MUIV_NListtree_Copy_SourceListNode_Root The root list is used as the starting point. MUIV_NListtree_Copy_SourceListNode_Active The active list (the list of the active node) is used as the starting point. srctreenode - Specifies the node which should be copied. MUIV_NListtree_Copy_SourceTreeNode_Head The head of the list defined in 'srclistnode' is copied. MUIV_NListtree_Copy_SourceTreeNode_Tail The tail of the list defined in 'srclistnode' is copied. MUIV_NListtree_Copy_SourceTreeNode_Active The active node is copied. destlistnode - Specify the node which list is used to find the entry. The search is started at the head of this list. MUIV_NListtree_Copy_DestListNode_Root The root list. MUIV_NListtree_Copy_DestListNode_Active The list of the active node. desttreenode - This node is the predecessor of the entry which is inserted. MUIV_NListtree_Copy_DestTreeNode_Head The node is copied to the head of the list defined in 'destlistnode'. MUIV_NListtree_Copy_DestTreeNode_Tail The node is copied to the tail of the list defined in 'destlistnode'. MUIV_NListtree_Copy_DestTreeNode_Active: The node is copied to one entry after the active node. MUIV_NListtree_Copy_DestTreeNode_Sorted: The node is copied to the list using the sort hook. flags - Some flags to adjust moving. MUIV_NListtree_Copy_Flag_KeepStructure The full tree structure from the selected entry to the root list is copied (created) at the destination. RESULT EXAMPLE // Copy the active entry to the head of // another list node. DoMethod(obj, MUIV_NListtree_Copy_SourceListNode_Active, MUIV_NListtree_Copy_SourceTreeNode_Active, anylistnode, MUIV_NListtree_Copy_DestTreeNode_Head, 0); NOTES BUGS MUIM_NListtree_CopyToClip -- Called for every clipboard copy action. (V1) SYNOPSIS DoMethodA(obj, MUIM_NListtree_CopyToClip, struct MUIP_NListtree_CopyToClip *ctcmessage); FUNCTION Do a copy to clipboard from an entry/entry content. INPUTS TreeNode - Tree node to copy contents from. Use MUIV_NListtree_CopyToClip_Active to copy the active entry. Pos - Entry position. Unit - Clipboard unit to copy entry contents to. RESULT EXAMPLE NOTES BUGS MUIN_NListtree_Destruct -- Free a new treenode SYNOPSIS DoMethod(obj, MUIM_NListtree_Destruct, STRPTR Name, APTR UserData, APTR MemPool, ULONG Flags); FUNCTION This method is called whenever a new treenode is to be removed from the listtree. See MUIA_NListtree_DestructHook for more details. NOTIFICATION MUIN_NListtree_Display -- Display a treenode SYNOPSIS DoMethod(obj, MUIM_NListtree_Dispose, struct MUI_NListtree_TreeNode *TreeNode, LONG EntryPos, STRPTR *Array, STRPTR *Preparse); FUNCTION This method is called whenever a new treenode is to be displayed in the listtree. See MUIA_NListtree_DisplayHook for more details. NOTIFICATION MUIM_NListtree_DoubleClick -- Called for every double click. (V1) SYNOPSIS DoMethodA(obj, MUIM_NListtree_DoubleClick, struct MUIP_NListtree_DoubleClick *doubleclickmsg); FUNCTION This method must not be called directly. It will be called by NListtree if an double click event occurs. This is an addition to MUIA_NListtree_DoubleClick INPUTS RESULT EXAMPLE NOTES BUGS MUIM_NListtree_DropDraw -- SYNOPSIS DoMethod(obj, MUIM_NListtree_DropDraw, LONG pos, LONG type, LONG minx, LONG maxx, LONG miny, LONG maxy); FUNCTION This method must not be called directly! It will be called by NListtree, and will draw the drop mark previously fixed (pos and type) by MUIM_NListtree_DropType within the minx, maxx, miny, maxy in the _rp(obj) rasport. For further information see method MUIM_NList_DropDraw. INPUTS RESULT EXAMPLE NOTES BUGS MUIM_NListtree_DropType -- SYNOPSIS DoMethod(obj, MUIM_NListtree_DropType, LONG *pos, LONG *type, LONG minx, LONG maxx, LONG miny, LONG maxy, LONG mousex, LONG mousey); FUNCTION This method MUST NOT be called directly ! It will be called by NListreet while the DragReport, with default *pos and *type values depending on the drag pointer position that you can modify as you want. For further information see method MUIM_NList_DropDraw. INPUTS RESULT EXAMPLE NOTES BUGS MUIM_NListtree_Exchange -- Exchanges two tree nodes. (V1) SYNOPSIS DoMethod(obj, MUIM_NListtree_Exchange, struct MUI_NListtree_TreeNode *listnode1, struct MUI_NListtree_TreeNode *treenode1, struct MUI_NListtree_TreeNode *listnode2, struct MUI_NListtree_TreeNode *treenode2, ULONG flags); FUNCTION Exchange two tree nodes. INPUTS listnode1 - Specify the list node of the entry which should be exchanged. MUIV_NListtree_Exchange_ListNode1_Root The root list is used. MUIV_NListtree_Exchange_ListNode1_Active The active list (the list of the active node) is used. treenode1 - Specify the node which should be exchanged. MUIV_NListtree_Exchange_TreeNode1_Head The head of the list defined in 'listnode1' is exchanged. MUIV_NListtree_Exchange_TreeNode1_Tail The tail of the list defined in 'listnode1' is exchanged. MUIV_NListtree_Exchange_TreeNode1_Active The active node is exchanged. listnode2 - Specify the second list node which is used for exchange. MUIV_NListtree_Exchange_ListNode2_Root The root list. MUIV_NListtree_Exchange_ListNode2_Active The list of the active node. treenode2 - This node is the second entry which is exchanged. MUIV_NListtree_Exchange_TreeNode2_Head The node 'treenode1' is exchanged with the head of the list defined in 'listnode2'. MUIV_NListtree_Exchange_TreeNode2_Tail The node 'treenode1' is exchanged with the tail of the list defined in 'ln2'. MUIV_NListtree_Exchange_TreeNode2_Active: The node 'treenode1' is exchanged with the active node. MUIV_NListtree_Exchange_TreeNode2_Up: The node 'treenode1' is exchanged with the entry previous to the one specified in 'treenode1'. MUIV_NListtree_Exchange_TreeNode2_Down: The node 'treenode1' is exchanged with the entry next (the successor) to the one specified in 'treenode1'. RESULT EXAMPLE // Exchange the active entry with the successor. DoMethod(obj, MUIV_NListtree_Exchange_ListNode1_Active, MUIV_NListtree_Exchange_TreeNode1_Active, MUIV_NListtree_Exchange_ListNode2_Active, MUIV_NListtree_Exchange_TreeNode2_Down, 0); NOTES BUGS MUIM_NListtree_FindName -- Find node using name match. (V1) SYNOPSIS struct MUI_NListtree_TreeNode *treenode = DoMethod(obj, MUIM_NListtree_FindName, struct MUI_NListtree_TreeNode *listnode, STRPTR name, ULONG flags); FUNCTION Find a node which name matches the specified one using the list node as start point.. INPUTS listnode - Specify the node which list is used to find the name. MUIV_NListtree_FindName_ListNode_Root Use the root list as the base list. MUIV_NListtree_FindName_ListNode_Active Use the list of the active node as the base. name - Specify the name of the node to find. But you can search for anything in tn_Name or tn_User field here by simply supplying the searched data and handling it in your own FindNameHook. flags: MUIV_NListtree_FindName_Flag_SameLevel Only nodes on the same level are affected. MUIV_NListtree_FindName_Flag_Visible The node is only returned if it is visible (only visible entries are checked). MUIV_NListtree_FindName_Flag_Activate If found, the entry will be activated. MUIV_NListtree_FindName_Flag_Selected Find only selected nodes. MUIV_NListtree_FindName_Flag_StartNode The specified entry in listnode is the start point for search and must not be a list node. It can also be a normal entry. RESULT Returns the found node if available, NULL otherwise. EXAMPLE // Find 2nd node by name. struct MUI_NListtree_TreeNode *treenode = DoMethod(obj, MUIM_NListtree_FindName, listnode, "2nd node", MUIV_NListtree_FindName_SameLevel| MUIV_NListtree_FindName_Visible); if ( treenode == NULL ) { PrintToUser( "No matching entry found." ); } NOTES MUIM_NListtree_FindUserData -- Find node upon user data. (V1) SYNOPSIS struct MUI_NListtree_TreeNode *treenode = DoMethod(obj, MUIM_NListtree_FindUserData, struct MUI_NListtree_TreeNode *listnode, APTR userdata, ULONG flags); FUNCTION Find a node which user data matches the specified one using the list node as start point.. This method is designed as a second possibility for searching. Because you are able to search for anything, you may set special hooks for searching two different fields in two different hooks with these two methods. INPUTS listnode - Specify the node which list is used to find the user data. MUIV_NListtree_FindUserData_ListNode_Root Use the root list as the base list. MUIV_NListtree_FindUserData_ListNode_Active Use the list of the active node as the base. userdata - Specify the user data of the node to find. You can search for anything in tn_Name or tn_User field here by simply supplying the searched data and handling it in your own FindUserDataHook. flags: MUIV_NListtree_FindUserData_Flag_SameLevel Only nodes on the same level are affected. MUIV_NListtree_FindUserData_Flag_Visible The node is only returned if it is visible (only visible entries are checked). MUIV_NListtree_FindUserData_Flag_Activate If found, the entry will be activated. MUIV_NListtree_FindUserData_Flag_Selected Find only selected nodes. MUIV_NListtree_FindUserData_Flag_StartNode The specified entry in listnode is the start point for search and must not be a list node. It can also be a normal entry. RESULT Returns the found node if available, NULL otherwise. EXAMPLE // Find node by user data. struct MUI_NListtree_TreeNode *treenode = DoMethod(obj, MUIM_NListtree_FindUserData, listnode, "my data", MUIV_NListtree_FindUserData_SameLevel| MUIV_NListtree_FindUserData_Visible); if ( treenode == NULL ) { PrintToUser( "No matching entry found." ); } NOTES BUGS MUIM_NListtree_GetEntry -- Get another node in relation to this. (V1) SYNOPSIS struct MUI_NListtree_TreeNode *rettreenode = DoMethod(obj, MUIM_NListtree_GetEntry, struct MUI_NListtree_TreeNode *treenode, LONG pos, ULONG flags); FUNCTION Get another node in relation to the specified list or node. INPUTS treenode - Define the node which is used to find another one. This can also be a list node, if the position is related to a list. MUIV_NListtree_GetEntry_ListNode_Root The root list is used. MUIV_NListtree_GetEntry_ListNode_Active: The list with the active entry is used. pos - The relative position of the node 'treenode'. MUIV_NListtree_GetEntry_Position_Head The head of the list is returned. MUIV_NListtree_GetEntry_Position_Tail The tail of the list is returned. MUIV_NListtree_GetEntry_Position_Active The active node is returned. If there is no active entry, NULL is returned. MUIV_NListtree_GetEntry_Position_Next The node next to the specified node is returned. Returns NULL if there is no next entry. MUIV_NListtree_GetEntry_Position_Previous The node right before the specified node is returned. Returns NULL if there is no previous entry (if 'treenode' is the head of the list. MUIV_NListtree_GetEntry_Position_Parent The list node of the specified 'treenode' is returned. flags: MUIV_NListtree_GetEntry_Flag_SameLevel: Only nodes in the same level are affected. MUIV_NListtree_GetEntry_Flag_Visible: The position is counted on visible entries only. RESULT Returns the requested node if available, NULL otherwise. EXAMPLE // Get the next entry. struct MUI_NListtree_TreeNode *treenode = DoMethod(obj, MUIM_NListtree_GetEntry, treenode, MUIV_NListtree_GetEntry_Position_Next, 0); if ( treenode != NULL ) { PrintToUser( "Next entry found!" ); } NOTES BUGS MUIM_NListtree_GetNr -- Get the position number of a tree node. (V1) SYNOPSIS ULONG number = DoMethod(obj, MUIM_NListtree_GetNr, struct MUI_NListtree_TreeNode *treenode, ULONG flags); FUNCTION Get the position number of the specified tree node. INPUTS treenode - Specify the node to count the position of. MUIV_NListtree_GetNr_TreeNode_Active: The position is counted related to the active node. flags: MUIV_NListtree_GetNr_Flag_CountAll Returns the number of all entries. MUIV_NListtree_GetNr_Flag_CountLevel Returns the number of entries of the list the specified node is in. MUIV_NListtree_GetNr_Flag_CountList Returns the number of the entries of the active list node (the specified node is in). MUIV_NListtree_GetNr_Flag_ListEmpty Returns TRUE if the specified list node is empty. MUIV_NListtree_GetNr_Flag_Visible Returns the position number of an visible entry. -1 if the entry is invisible. The position is counted on visible entries only. RESULT EXAMPLE // Check if the active (list) node is empty. ULONG empty = DoMethod(obj, MUIM_NListtree_GetNr, MUIV_NListtree_GetNr_TreeNode_Active, MUIV_NListtree_GetNr_Flag_ListEmpty); if ( empty == TRUE ) { AddThousandEntries(); } NOTES BUGS MUIM_NListtree_Insert -- Insert an entry at the specified position. (V1) SYNOPSIS struct MUI_NListtree_TreeNode *treenode = DoMethod(obj, MUIM_NListtree_Insert, STRPTR name, APTR userdata, struct MUI_NListtree_TreeNode *listnode, struct MUI_NListtree_TreeNode *prevtreenode, ULONG flags); FUNCTION Insert an entry at the position, which is defined in 'listnode' and 'prevtreenode'. The name contains the name of the entry as string which is buffered. The user entry can be used as you like. INPUTS name/userdata - What the names say ;-) listnode - Specify the node which list is used to insert the entry. MUIV_NListtree_Insert_ListNode_Root Use the root list. MUIV_NListtree_Insert_ListNode_Active Use the list of the active node. MUIV_NListtree_Insert_ListNode_ActiveFallback Use the list of the active node. If no list is active, an automatic fallback to the root list is done. MUIV_NListtree_Insert_ListNode_LastInserted Insert entry in the list the last entry was inserted. prevtreenode - The node which is the predecessor of the node to insert. MUIV_NListtree_Insert_PrevNode_Head The entry will be inserted at the head of the list. MUIV_NListtree_Insert_PrevNode_Tail The entry will be inserted at the tail of the list. MUIV_NListtree_Insert_PrevNode_Active The entry will be inserted after the active node of the list. If no entry is active, the entry will be inserted at the tail. MUIV_NListtree_Insert_PrevNode_Sorted: The entry will be inserted using the defined sort hook. flags: MUIV_NListtree_Insert_Flag_Active The inserted entry will be set to active. This means the cursor is moved to the newly inserted entry. If the entry was inserted into a closed node, it will be opened. MUIV_NListtree_Insert_Flag_NextNode 'prevtreenode' is the successor, not the predecessor. RESULT A pointer to the newly inserted entry. EXAMPLE // Insert an entry after the active one and make it active. DoMethod(obj, MUIM_NListtree_Insert, "Hello", NULL, MUIV_NListtree_Insert_ListNode_Active, MUIV_NListtree_Insert_PrevNode_Active, MUIV_NListtree_Insert_Flag_Active); NOTES BUGS Not implemented yet: MUIV_NListtree_Insert_Flag_NextNode MUIM_NListtree_InsertStruct -- Insert a structure such as a path using a delimiter. (V1) SYNOPSIS struct MUI_NListtree_TreeNode *treenode = DoMethod(obj, MUIM_NListtree_InsertStruct, STRPTR name, APTR userdata, STRPTR delimiter, ULONG flags); FUNCTION Insert a structure into the list such as a path or something similar (like ListtreeName.mcc does). The name is split using the supplied delimiter. For each name part a new tree entry is generated. If you have Images/aphaso/Image.mbr, the structure will be build as follows: + Images + aphaso - Image.mbr If a part of the structure is already present, it will be used to insert. INPUTS name - Data containing (must not) one or more delimiters as specified in delimiter (Images/aphaso/Image.mbr for example). userdata - Your personal data. delimiter - The delimiter(s) used in the name field (":/" or something). flags: Use normal insert flags here (see there). RESULT A pointer to the last instance of newly inserted entries. EXAMPLE // Insert a directory path. path = MyGetPath( lock ); DoMethod(obj, MUIM_NListtree_InsertStruct, path, NULL, ":/", 0); NOTES BUGS MUIM_NListtree_Move -- Move an entry to the specified position. (V1) SYNOPSIS DoMethod(obj, MUIM_NListtree_Move, struct MUI_NListtree_TreeNode *oldlistnode, struct MUI_NListtree_TreeNode *oldtreenode, struct MUI_NListtree_TreeNode *newlistnode, struct MUI_NListtree_TreeNode *newtreenode, ULONG flags); FUNCTION Move an entry to the position after a defined node. INPUTS oldlistnode - Specify the node which list is used to find the entry. The search is started at the head of this list. MUIV_NListtree_Move_OldListNode_Root The root list is used as the starting point. MUIV_NListtree_Move_OldListNode_Active The active list (the list of the active node) is used as the starting point. oldtreenode - Specify the node which should be moved. MUIV_NListtree_Move_OldTreeNode_Head The head of the list defined in 'oldlistnode' is moved. MUIV_NListtree_Move_OldTreeNode_Tail The tail of the list defined in 'oldlistnode' is moved. MUIV_NListtree_Move_OldTreeNode_Active The active node is moved. newlistnode - Specify the node which list is used to find the entry. The search is started at the head of this list. MUIV_NListtree_Move_NewListNode_Root The root list. MUIV_NListtree_Move_NewListNode_Active The list of the active node. newtreenode - This node is the predecessor of the entry which is inserted. MUIV_NListtree_Move_NewTreeNode_Head The node is moved to the head of the list defined in 'newlistnode'. MUIV_NListtree_Move_NewTreeNode_Tail The node is moved to the tail of the list defined in 'newlistnode'. MUIV_NListtree_Move_NewTreeNode_Active: The node is moved to one entry after the active node. MUIV_NListtree_Move_NewTreeNode_Sorted: The node is moved to the list using the sort hook. flags - Some flags to adjust moving. MUIV_NListtree_Move_Flag_KeepStructure The full tree structure from the selected entry to the root list is moved (created at destination). RESULT EXAMPLE // Move an entry to the head of another list-node. DoMethod(obj, MUIV_NListtree_Move_OldListNode_Active, MUIV_NListtree_Move_OldTreeNode_Active, somelistmode, MUIV_NListtree_Move_NewTreeNode_Head, 0); NOTES BUGS MUIM_NListtree_MultiTest -- Called for every selection. (V1) SYNOPSIS DoMethodA(obj, MUIM_NListtree_MultiTest, struct MUIP_NListtree_MultiTest *multimessage); FUNCTION This method must not be called directly. It will be called by NListtree just before multiselection. You can overload it and return TRUE or FALSE whether you want the entry to be multi- selectable or not. INPUTS RESULT EXAMPLE NOTES BUGS MUIM_NListtree_NextSelected -- Get next selected tree node. (V1) SYNOPSIS DoMethod(obj, MUIM_NListtree_NextSelected, struct MUI_NListtree_TreeNode **treenode); FUNCTION Iterate through the selected entries of a tree. This method steps through the contents of a (multi select) list tree and returns every entry that is currently selected. When no entry is selected but an entry is active, only the active entry will be returned. This behaviour will result in not returning the active entry when you have some other selected entries somewhere in your list. Since the active entry just acts as some kind of cursor mark, this seems to be the only sensible possibility to handle multi selection together with keyboard control. INPUTS treenode - A pointer to a pointer of struct MUI_NListtree_TreeNode that will hold the returned entry. Must be set to MUIV_NListtree_NextSelected_Start at start of iteration and is set to MUIV_NListtree_NextSelected_End when iteration is finished. MUIV_NListtree_NextSelected_Start Set this to start iteration. MUIV_NListtree_NextSelected_End Will be set to this, if last selected entry reached. RESULT EXAMPLE // Iterate through a list struct MUI_NListtree_TreeNode *treenode; treenode = MUIV_NListtree_NextSelected_Start; for (;;) { DoMethod(listtree, MUIM_NListtree_NextSelected, &treenode); if (treenode==MUIV_NListtree_NextSelected_End) break; printf("selected: %s\n", treenode->tn_Name); } NOTES BUGS MUIM_NListtree_Open -- Open the specified tree node. (V1) SYNOPSIS DoMethod(obj, MUIM_NListtree_Open, struct MUI_NListtree_TreeNode *listnode, struct MUI_NListtree_TreeNode *treenode, ULONG flags); FUNCTION Opens a node in the listtree. To open a child, which isn't displayed, use 'MUIV_NListtree_Open_ListNode_Parent' to open all its parents, too. Only nodes can be opened. INPUTS listnode - Specify the node which list is used to open the node. MUIV_NListtree_Open_ListNode_Root The root list is used. MUIV_NListtree_Open_ListNode_Parent Indicates, that all the parents of the node specified in 'treenode' should be opened too. MUIV_NListtree_Open_ListNode_Active The list of the active node is used. treenode - The node to open. MUIV_NListtree_Open_TreeNode_Head Opens the head node of the list. MUIV_NListtree_Open_TreeNode_Tail Opens the tail node of the list. MUIV_NListtree_Open_TreeNode_Active The active node will be opened. MUIV_NListtree_Open_TreeNode_All: All the nodes of the list are opened. RESULT EXAMPLE // Open the active list. DoMethod(obj, MUIM_NListtree_Open, MUIV_NListtree_Open_ListNode_Active, MUIV_NListtree_Open_TreeNode_Active, 0); NOTES BUGS MUIM_NListtree_PrevSelected -- Get previously selected tree node. (V1) SYNOPSIS DoMethod(obj, MUIM_NListtree_PrevSelected, struct MUI_NListtree_TreeNode **treenode); FUNCTION Iterate reverse through the selected entries of a tree. This method steps through the contents of a (multi-select) list tree and returns every entry that is currently selected. When no entry is selected but an entry is active, only the active entry will be returned. This behaviour will result in not returning the active entry when you have some other selected entries somewhere in your list. Since the active entry just acts as some kind of cursor mark, this seems to be the only sensible possibility to handle multi selection together with keyboard control. INPUTS treenode - A pointer to a pointer of struct MUI_NListtree_TreeNode that will hold the returned entry. Must be set to MUIV_NListtree_PrevSelected_Start at start of iteration an the end and is set to MUIV_NListtree_PrevSelected_End when first selected entry is reached and iteration is finished. MUIV_NListtree_PrevSelected_Start Set this to start iteration. MUIV_NListtree_PrevSelected_End Will be set to this, if last selected entry reached. RESULT EXAMPLE // Iterate through a list (reverse) struct MUI_NListtree_TreeNode *treenode; treenode = MUIV_NListtree_PrevSelected_Start; for (;;) { DoMethod(listtree, MUIM_NListtree_PrevSelected, &treenode); if (treenode==MUIV_NListtree_PrevSelected_End) break; printf("selected: %s\n", treenode->tn_Name); } NOTES BUGS MUIM_NListtree_Redraw -- Redraw the specified tree node. (V1) SYNOPSIS DoMethod(obj, MUIM_NListtree_Redraw, struct MUI_NListtree_TreeNode *treenode, ULONG flags); FUNCTION Redraw the specified entry. See special values for completeness. INPUTS treenode - The tree node to be redrawn. MUIV_NListtree_Redraw_Active Redraw the active entry. MUIV_NListtree_Redraw_All Redraw the complete visible tree. flags: MUIV_NListtree_Redraw_Flag_Nr The data specified in 'treenode' is the entry number, not the tree node itself. RESULT EXAMPLE // Redraw the active entry. DoMethod(obj, MUIM_NListtree_Redraw, MUIV_NListtree_Redraw_Active, 0); NOTES BUGS MUIM_NListtree_Remove -- Remove the specified entry(ies). (V1) SYNOPSIS DoMethod(obj, MUIM_NListtree_Remove, struct MUI_NListtree_TreeNode *listnode, struct MUI_NListtree_TreeNode *treenode, ULONG flags); FUNCTION Removes a node or nodes from the listtree. When the active entry is removed, the successor will become active. INPUTS listnode - Specify the node which list is used to find the entry which should be removed. The search is started at the begin of this list. MUIV_NListtree_Remove_ListNode_Root The root list is used. MUIV_NListtree_Remove_ListNode_Active The list of the active node is used. treenode - The node which should be removed. If there are children of this node, they are also removed. MUIV_NListtree_Remove_TreeNode_Head The head of the list defined in 'listnode' is removed. MUIV_NListtree_Remove_TreeNode_Tail The tail of the list defined in 'listnode' is removed. MUIV_NListtree_Remove_TreeNode_Active Removes the active node. MUIV_NListtree_Remove_TreeNode_All All nodes of the list which is specified in 'listnode', are removed. Other nodes of parent lists are not affected. MUIV_NListtree_Remove_TreeNode_Selected All selected nodes are removed. RESULT EXAMPLE // Remove the active entry if delete is pressed! DoMethod(bt_delete, MUIM_Notify, MUIA_Pressed, FALSE, lt_list, 4, MUIM_NListtree_Remove, MUIV_NListtree_Remove_ListNode_Active, MUIV_NListtree_Remove_TreeNode_Active, 0); NOTES BUGS MUIM_NListtree_Rename -- Rename the specified node. (V1) SYNOPSIS struct MUI_NListtree_TreeNode *treenode = DoMethod(obj, MUIM_NListtree_Rename, struct MUI_NListtree_TreeNode *treenode, STRPTR newname, ULONG flags); FUNCTION Rename the specified node. If you want to rename the tn_User field (see flags below), the construct and destruct hooks are used! If you have not specified these hooks, only the pointers will be copied. INPUTS treenode - Specifies the node which should be renamed. MUIV_NListtree_Rename_TreeNode_Active: Rename the active tree node. newname - The new name or pointer. flags: MUIV_NListtree_Rename_Flag_User The tn_User field is renamed. MUIV_NListtree_Rename_Flag_NoRefresh The list entry will not be refreshed. RESULT Returns the pointer of the renamed tree node. EXAMPLE // Rename the active tree node. DoMethod(obj, MUIM_NListtree_Rename, MUIV_NListtree_Rename_TreeNode_Active, "Very new name", 0); NOTES BUGS MUIM_NListtree_Select -- Select the specified tree node. (V1) SYNOPSIS DoMethod(obj, MUIM_NListtree_Select, struct MUI_NListtree_TreeNode *treenode, LONG seltype, LONG selflags, LONG *state); FUNCTION Select or unselect a tree entry or ask an entry about its state. See special values for completeness. INPUTS treenode - The tree node to be selected/unselected/asked. MUIV_NListtree_Select_Active For the active entry. MUIV_NListtree_Select_All For all entries. MUIV_NListtree_Select_Visible For all visible entries. seltype - Type of selection/unselection/ask MUIV_NListtree_Select_Off Unselect entry. MUIV_NListtree_Select_On Select entry. MUIV_NListtree_Select_Toggle Toggle entries state. MUIV_NListtree_Select_Ask Just ask about the state. selflags - Some kind of specials. MUIV_NListtree_Select_Flag_Force Adding this flag to seltype forces the selection by bypassing the multi test hook. state - Pointer to a longword. If not NULL, it will be filled with the current selection state of the entry. RESULT EXAMPLE // Select the active entry. LONG retstate; DoMethod(obj, MUIM_NListtree_Select, MUIV_NListtree_Select_Active, MUIV_NListtree_Select_On, 0, &retstate); // We must check this, because the multi-test hook may // cancel our selection. if (retstate == MUIV_NListtree_Select_On) { ... } NOTES If ( treenode == MUIV_NListtree_Select_All ) and ( seltype == MUIV_NListtree_Select_Ask ), state will be filled with the total number of selected entries. NEW for final 18.6: If (treenode == MUIV_NListtree_Select_Active ) and ( seltype == MUIV_NListtree_Select_Ask ), state will be the active entry, if any, or NULL. If only the active entry is selected, has a cursor mark (see MUIM_NListtree_NextSelected for that), you will receive 0 as the number of selected entries. BUGS MUIM_NListtree_Sort -- Sort the specified list node. (V1) SYNOPSIS DoMethod(obj, MUIM_NListtree_Sort, struct MUI_NListtree_TreeNode *listnode, ULONG flags); FUNCTION Sort the specified list node using the sort hook. INPUTS listnode - List node to sort. MUIV_NListtree_Sort_ListNode_Root Sort the root list. MUIV_NListtree_Sort_ListNode_Active Sort the list node of the active entry. MUIV_NListtree_Sort_TreeNode_Active Sorts the children of the active entry if a list. flags - Control the part where sorting is done. MUIV_NListtree_Sort_Flag_RecursiveOpen Sort the list recursive. All open child nodes of the node specified in 'listnode' will be sorted too. MUIV_NListtree_Sort_Flag_RecursiveAll Sort the list recursive with ALL child nodes of the node specified in 'listnode'. RESULT EXAMPLE // Sort the list of the active node. DoMethod(obj, MUIM_NListtree_Sort, MUIV_NListtree_Sort_ListNode_Active, 0); NOTES BUGS MUIM_NListtree_TestPos -- Get information about entry at x/y pos. (V1) SYNOPSIS DoMethod(obj, MUIM_NListtree_TestPos, LONG xpos, LONG ypos, struct MUI_NListtree_TestPos_Result *testposresult); FUNCTION Find out some information about the currently displayed entry at a certain position (x/y-pos). This is very useful for Drag&Drop operations. INPUTS xpos - X-position. ypos - Y-position. testposresult - Pointer to a valid MUI_NListtree_TestPos_Result structure. RESULT tpr_TreeNode - The tree node under the requested position or NULL if there is no entry displayed. The tpr_Type field contains detailed information about the relative position: MUIV_NListtree_TestPos_Result_Above MUIV_NListtree_TestPos_Result_Below MUIV_NListtree_TestPos_Result_Onto MUIV_NListtree_TestPos_Result_Sorted tpr_Column - The column unter the specified position or -1 if no valid column. EXAMPLE // Entry under the cursor? struct MUI_NListtree_TestPos_Result tpres; DoMethod(obj, MUIM_NListtree_TestPos, msg->imsg->MouseX, msg->imsg->MouseY, &tpres); if ( tpres.tpr_Entry != NULL ) { // Do something special here... } NOTES BUGS
/*************************************************************************** NListtree.mcc - New Listtree MUI Custom Class Copyright (C) 1999-2001 by Carsten Scholling Copyright (C) 2001-2006 by NList Open Source Team This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. NList classes Support Site: http://www.sf.net/projects/nlist-classes $Id: NListtree-Demo.c 43734 2012-01-28 14:26:37Z mazze $ ***************************************************************************/ #if defined(__AROS__) #define MUI_OBSOLETE 1 #endif /* ** Includes */ #include <proto/muimaster.h> #include <proto/exec.h> #include <proto/intuition.h> #include <proto/utility.h> #if !defined(__amigaos4__) #include <clib/alib_protos.h> #endif #include <exec/memory.h> #include <exec/types.h> #include <mui/NListtree_mcc.h> #include <mui/NListview_mcc.h> #include <mui/NList_mcc.h> #include <string.h> #include <stdio.h> #include <time.h> #ifdef MYDEBUG #define bug kprintf #define D(x) void kprintf( UBYTE *fmt, ... ); #else #define bug #define D(x) #endif #ifndef MAKE_ID #define MAKE_ID(a,b,c,d) ((ULONG) (a)<<24 | (ULONG) (b)<<16 | (ULONG) (c)<<8 | (ULONG) (d)) #endif #include "SDI_hook.h" #ifndef MUIA_Slider_Level #define MUIA_Slider_Level 0x8042ae3a /* V4 isg LONG */ #endif /* ** Do not use stack sizes below 8KB!! */ LONG __stack = 16384; /* ** MUI library base. */ struct Library *MUIMasterBase = NULL; #if defined(__amigaos4__) struct Library *IntuitionBase = NULL; #else struct IntuitionBase *IntuitionBase = NULL; #endif #if defined(__amigaos4__) struct IntuitionIFace *IIntuition = NULL; struct MUIMasterIFace *IMUIMaster = NULL; #endif struct MUI_NListtree_TreeNode *tntest; /* ** MUI objects. */ STATIC APTR app, window,lt_nodes, tx_info1, tx_info2, tx_info3, sl_treecol, st_string, bt_open, bt_close, bt_expand, bt_collapse, bt_insert, bt_remove, bt_exchange,bt_rename, bt_move, bt_copy, bt_moveks, bt_copyks, bt_find, bt_parent, bt_sort, bt_getnr, bt_redraw, bt_selected,bt_showtree,bt_seltogg, bt_test, bt_test2, bt_test3, bt_test4; /* ** Sample tree structure. */ struct SampleArray { const char *name; ULONG flags; }; STATIC const struct SampleArray sa[] = { { "comp", TNF_LIST | TNF_OPEN }, { "sys", TNF_LIST | TNF_OPEN }, { "amiga", TNF_LIST | TNF_OPEN }, { "misc", 0x8000 }, { "mac", TNF_LIST }, { "system", 0x8000 }, {"de", TNF_LIST | TNF_OPEN }, { "comm", TNF_LIST }, { "software", TNF_LIST }, { "ums", 0x8000 }, { "comp", TNF_LIST | TNF_OPEN }, { "sys", TNF_LIST | TNF_OPEN }, { "amiga", TNF_LIST }, { "misc", 0x8000 }, { "tech", 0x8000 }, { "amiga", 0x8000 }, {"sort test", TNF_LIST | TNF_OPEN }, { "a", 0 }, { "x", TNF_LIST }, { "v", 0 }, { "g", TNF_LIST }, { "h", 0 }, { "k", TNF_LIST }, { "u", 0 }, { "i", TNF_LIST }, { "t", 0 }, { "e", TNF_LIST }, { "q", 0 }, { "s", TNF_LIST }, { "c", 0 }, { "f", TNF_LIST }, { "p", 0 }, { "l", TNF_LIST }, { "z", 0 }, { "w", TNF_LIST }, { "b", 0 }, { "o", TNF_LIST }, { "d", 0 }, { "m", TNF_LIST }, { "r", 0 }, { "y", TNF_LIST }, { "n", 0 }, { "j", TNF_LIST }, {"m", TNF_LIST }, { "i", TNF_LIST }, { "c", TNF_LIST }, { "h", TNF_LIST }, { "e", TNF_LIST }, { "l", TNF_LIST }, { "a", TNF_LIST }, { "n", TNF_LIST }, { "g", TNF_LIST }, { "e", TNF_LIST }, { "l", TNF_LIST }, { "o", 0 }, {"end", TNF_LIST }, { "of", TNF_LIST }, { "tree", 0 }, { "Sort Test 2", TNF_LIST }, { NULL, 0 } }; /* ** This function draws the sample tree structure. */ STATIC VOID DrawSampleTree( Object *ltobj ) { struct MUI_NListtree_TreeNode *tn1, *tn2, *tn3; char txt[128]; WORD i = 0, j; tn1 = (struct MUI_NListtree_TreeNode *)DoMethod( ltobj, MUIM_NListtree_Insert, sa[i].name, (IPTR)sa[i].flags, MUIV_NListtree_Insert_ListNode_Root, MUIV_NListtree_Insert_PrevNode_Tail, sa[i].flags ); i++; tn2 = (struct MUI_NListtree_TreeNode *)DoMethod( ltobj, MUIM_NListtree_Insert, sa[i].name, (IPTR)sa[i].flags, tn1, MUIV_NListtree_Insert_PrevNode_Tail, sa[i].flags ); i++; tn1 = (struct MUI_NListtree_TreeNode *)DoMethod( ltobj, MUIM_NListtree_Insert, sa[i].name, (IPTR)sa[i].flags, tn2, MUIV_NListtree_Insert_PrevNode_Tail, sa[i].flags ); i++; tn1 = (struct MUI_NListtree_TreeNode *)DoMethod( ltobj, MUIM_NListtree_Insert, sa[i].name, (IPTR)sa[i].flags, tn1, MUIV_NListtree_Insert_PrevNode_Tail, sa[i].flags ); i++; tn1 = (struct MUI_NListtree_TreeNode *)DoMethod( ltobj, MUIM_NListtree_Insert, sa[i].name, (IPTR)sa[i].flags, tn2, MUIV_NListtree_Insert_PrevNode_Tail, sa[i].flags ); i++; tntest = tn1 = (struct MUI_NListtree_TreeNode *)DoMethod( ltobj, MUIM_NListtree_Insert, sa[i].name, (IPTR)sa[i].flags, tn1, MUIV_NListtree_Insert_PrevNode_Tail, sa[i].flags ); i++; tn1 = (struct MUI_NListtree_TreeNode *)DoMethod( ltobj, MUIM_NListtree_Insert, sa[i].name, (IPTR)sa[i].flags, MUIV_NListtree_Insert_ListNode_Root, MUIV_NListtree_Insert_PrevNode_Tail, sa[i].flags ); i++; tn2 = (struct MUI_NListtree_TreeNode *)DoMethod( ltobj, MUIM_NListtree_Insert, sa[i].name, (IPTR)sa[i].flags, tn1, MUIV_NListtree_Insert_PrevNode_Tail, sa[i].flags ); i++; tn2 = (struct MUI_NListtree_TreeNode *)DoMethod( ltobj, MUIM_NListtree_Insert, sa[i].name, (IPTR)sa[i].flags, tn2, MUIV_NListtree_Insert_PrevNode_Tail, sa[i].flags ); i++; tn2 = (struct MUI_NListtree_TreeNode *)DoMethod( ltobj, MUIM_NListtree_Insert, sa[i].name, (IPTR)sa[i].flags, tn2, MUIV_NListtree_Insert_PrevNode_Tail, sa[i].flags ); i++; tn3 = (struct MUI_NListtree_TreeNode *)DoMethod( ltobj, MUIM_NListtree_Insert, sa[i].name, (IPTR)sa[i].flags, tn1, MUIV_NListtree_Insert_PrevNode_Tail, sa[i].flags ); i++; tn1 = (struct MUI_NListtree_TreeNode *)DoMethod( ltobj, MUIM_NListtree_Insert, sa[i].name, (IPTR)sa[i].flags, tn3, MUIV_NListtree_Insert_PrevNode_Tail, sa[i].flags ); i++; tn2 = (struct MUI_NListtree_TreeNode *)DoMethod( ltobj, MUIM_NListtree_Insert, sa[i].name, (IPTR)sa[i].flags, tn1, MUIV_NListtree_Insert_PrevNode_Tail, sa[i].flags ); i++; tn3 = (struct MUI_NListtree_TreeNode *)DoMethod( ltobj, MUIM_NListtree_Insert, sa[i].name, (IPTR)sa[i].flags, tn2, MUIV_NListtree_Insert_PrevNode_Tail, sa[i].flags ); i++; tn3 = (struct MUI_NListtree_TreeNode *)DoMethod( ltobj, MUIM_NListtree_Insert, sa[i].name, (IPTR)sa[i].flags, tn2, MUIV_NListtree_Insert_PrevNode_Tail, sa[i].flags ); i++; tn3 = (struct MUI_NListtree_TreeNode *)DoMethod( ltobj, MUIM_NListtree_Insert, sa[i].name, (IPTR)sa[i].flags, tn1, MUIV_NListtree_Insert_PrevNode_Tail, sa[i].flags ); i++; tn1 = (struct MUI_NListtree_TreeNode *)DoMethod( ltobj, MUIM_NListtree_Insert, sa[i].name, (IPTR)sa[i].flags, MUIV_NListtree_Insert_ListNode_Root, MUIV_NListtree_Insert_PrevNode_Tail, sa[i].flags ); i++; for( j = 0; j < 26; j++ ) { DoMethod( ltobj, MUIM_NListtree_Insert, sa[i].name, (IPTR)sa[i].flags, tn1, MUIV_NListtree_Insert_PrevNode_Tail, sa[i].flags ); i++; } tn1 = (struct MUI_NListtree_TreeNode *)DoMethod( ltobj, MUIM_NListtree_Insert, sa[i].name, (IPTR)sa[i].flags, MUIV_NListtree_Insert_ListNode_Root, MUIV_NListtree_Insert_PrevNode_Tail, sa[i].flags ); i++; for( j = 0; j < 11; j++ ) { tn1 = (struct MUI_NListtree_TreeNode *)DoMethod( ltobj, MUIM_NListtree_Insert, sa[i].name, (IPTR)sa[i].flags, tn1, MUIV_NListtree_Insert_PrevNode_Tail, sa[i].flags ); i++; } tn1 = (struct MUI_NListtree_TreeNode *)DoMethod( ltobj, MUIM_NListtree_Insert, sa[i].name, (IPTR)sa[i].flags, MUIV_NListtree_Insert_ListNode_Root, MUIV_NListtree_Insert_PrevNode_Tail, sa[i].flags ); i++; tn1 = (struct MUI_NListtree_TreeNode *)DoMethod( ltobj, MUIM_NListtree_Insert, sa[i].name, (IPTR)sa[i].flags, tn1, MUIV_NListtree_Insert_PrevNode_Tail, sa[i].flags ); i++; tn1 = (struct MUI_NListtree_TreeNode *)DoMethod( ltobj, MUIM_NListtree_Insert, sa[i].name, (IPTR)sa[i].flags, tn1, MUIV_NListtree_Insert_PrevNode_Tail, sa[i].flags ); i++; tn1 = (struct MUI_NListtree_TreeNode *)DoMethod( ltobj, MUIM_NListtree_Insert, sa[i].name, (IPTR)sa[i].flags, MUIV_NListtree_Insert_ListNode_Root, MUIV_NListtree_Insert_PrevNode_Tail, sa[i].flags ); i++; for( i = 0; i < 2500; i++ ) { if ( i % 2 ) snprintf( txt, sizeof(txt), "Sort Entry %d", i + 1 ); else snprintf( txt, sizeof(txt), "Entry Sort %d", i + 1 ); tn2 = (struct MUI_NListtree_TreeNode *)DoMethod( ltobj, MUIM_NListtree_Insert, txt, 0, ( i % 5 ) ? tn2 : tn1, MUIV_NListtree_Insert_PrevNode_Tail, ( i % 5 ) ? TNF_LIST : 0 ); } DoMethod( ltobj, MUIM_NListtree_InsertStruct, "This/is/a/very/long/test/for/Blafasel_InsertStruct", 0, "/", 0 ); DoMethod( ltobj, MUIM_NListtree_InsertStruct, "This/is/another/very/long/test/for/Blafasel_InsertStruct", 0, "/", 0 ); } static struct MUI_NListtree_TreeNode *GetParent( Object *obj, struct MUI_NListtree_TreeNode *tn ) { if ( tn != NULL ) { return( (struct MUI_NListtree_TreeNode *)DoMethod( obj, MUIM_NListtree_GetEntry, MUIV_NListtree_GetEntry_ListNode_Root, MUIV_NListtree_GetEntry_Position_Parent, 0 ) ); } return( NULL ); } static struct MUI_NListtree_TreeNode *GetParentNotRoot( Object *obj, struct MUI_NListtree_TreeNode *tn ) { if((tn = GetParent( obj, tn))) { if ( GetParent( obj, tn ) ) { return( tn ); } } return( NULL ); } struct MUI_NListtree_TreeNode *IsXChildOfY( Object *obj, struct MUI_NListtree_TreeNode *x, struct MUI_NListtree_TreeNode *y ) { do { if ( y == x ) { return( y ); } } while((y = GetParentNotRoot( obj, y))); return( NULL ); } /* ** Allocates memory for each entry we create. */ HOOKPROTONHNO(confunc, SIPTR, struct MUIP_NListtree_ConstructMessage *msg) { struct SampleArray *sa; /* ** Allocate needed piece of memory for the new entry. */ if((sa = (struct SampleArray *)AllocVec( sizeof( struct SampleArray) + strlen( msg->Name ) + 1, MEMF_CLEAR))) { /* ** Save the user data field right after the ** array structure. */ strcpy( (STRPTR)&sa[1], msg->Name ); sa->name = (STRPTR)&sa[1]; sa->flags = (IPTR)msg->UserData; } return( (SIPTR)sa ); } MakeStaticHook(conhook, confunc); /* ** Free memory we just allocated above. */ HOOKPROTONHNO(desfunc, LONG, struct MUIP_NListtree_DestructMessage *msg) { if ( msg->UserData != NULL ) { FreeVec( msg->UserData ); msg->UserData = NULL; } return( 0 ); } MakeStaticHook(deshook, desfunc); /* ** Compare hook function. */ HOOKPROTONHNO(compfunc, LONG, struct MUIP_NListtree_CompareMessage *msg) { return( stricmp( msg->TreeNode1->tn_Name, msg->TreeNode2->tn_Name ) ); } MakeStaticHook(comphook, compfunc); /* ** MultiTest hook function. */ HOOKPROTONHNO(mtfunc, LONG, struct MUIP_NListtree_MultiTestMessage *msg) { if ( msg->TreeNode->tn_Flags & TNF_LIST ) return( FALSE ); return( TRUE ); } MakeStaticHook(mthook, mtfunc); /* ** Format the entry data for displaying. */ HOOKPROTONHNO(dspfunc, LONG, struct MUIP_NListtree_DisplayMessage *msg) { STATIC CONST_STRPTR t1 = "Newsgroups", t2 = "Flags", t3 = "subscribed", t4 = "\0", t5 = "Count"; STATIC char buf[10]; if ( msg->TreeNode != NULL ) { /* ** The user data is a pointer to a SampleArray struct. */ struct SampleArray *a = (struct SampleArray *)msg->TreeNode->tn_User; snprintf( buf, sizeof(buf), "%3d", (unsigned int)(IPTR)msg->Array[-1] ); *msg->Array++ = msg->TreeNode->tn_Name; *msg->Array++ = (STRPTR)(( a->flags & 0x8000 ) ? t3 : t4); *msg->Array++ = buf; } else { *msg->Array++ = (STRPTR)t1; *msg->Array++ = (STRPTR)t2; *msg->Array++ = (STRPTR)t5; *msg->Preparse++ = (STRPTR)"\033b\033u"; *msg->Preparse++ = (STRPTR)"\033b\033u"; *msg->Preparse++ = (STRPTR)"\033b\033u"; } return( 0 ); } MakeStaticHook(dsphook, dspfunc); /* ** Insert a new entry which name is given in ** the string gadget. */ HOOKPROTONHNP(insertfunc, LONG, Object *obj) { STRPTR x = NULL; /* ** Get user string. */ get( st_string, MUIA_String_Contents, &x ); /* ** Insert the new entry after ** the active entry. */ DoMethod( obj, MUIM_NListtree_Insert, x, 0, MUIV_NListtree_Insert_ListNode_Active, MUIV_NListtree_Insert_PrevNode_Active, MUIV_NListtree_Insert_Flag_Active ); return( 0 ); } MakeStaticHook(inserthook, insertfunc); /* ** Exchange two entries. */ HOOKPROTONH(exchangefunc, LONG, Object *obj, ULONG **para) { STATIC struct MUI_NListtree_TreeNode *tn1, *tn2; STATIC LONG exchcnt = 0; if ( ( exchcnt == 0 ) && ( (IPTR)*para == 42 ) ) { get( obj, MUIA_NListtree_Active, &tn1 ); if ( tn1 != MUIV_NListtree_Active_Off ) { nnset( tx_info3, MUIA_Text_Contents, "Select entry to exchange selected entry with." ); exchcnt++; } } else if ( exchcnt == 1 ) { get( obj, MUIA_NListtree_Active, &tn2 ); if ( ( tn2 != MUIV_NListtree_Active_Off ) && ( tn1 != tn2 ) ) { if ( !IsXChildOfY( obj, tn1, tn2 ) && !IsXChildOfY( obj, tn1, tn2 ) ) { struct MUI_NListtree_ListNode *ln1; if((ln1 = (struct MUI_NListtree_ListNode *)DoMethod( obj, MUIM_NListtree_GetEntry, tn1, MUIV_NListtree_GetEntry_Position_Parent, 0))) { DoMethod( obj, MUIM_NListtree_Exchange, ln1, tn1, MUIV_NListtree_Exchange_ListNode2_Active, MUIV_NListtree_Exchange_TreeNode2_Active, 0 ); nnset( tx_info3, MUIA_Text_Contents, "Entries successfully exchanged!" ); } else nnset( tx_info3, MUIA_Text_Contents, "Something went wrong! Try again to select." ); } else nnset( tx_info3, MUIA_Text_Contents, "You can not exchange with childs!" ); } else nnset( tx_info3, MUIA_Text_Contents, "You should not exchange an entry with itself!" ); exchcnt = 0; } return( 0 ); } MakeStaticHook(exchangehook, exchangefunc); /* ** Rename the selected entry with the name is given in ** the string gadget. */ HOOKPROTONHNP(renamefunc, LONG, Object *obj) { struct MUI_NListtree_TreeNode *tn = NULL; STRPTR x = NULL; /* ** Get user string. */ get( st_string, MUIA_String_Contents, &x ); get( obj, MUIA_NListtree_Active, &tn ); /* ** Insert the new entry sorted (compare hook) ** into the active list node. */ DoMethod( obj, MUIM_NListtree_Rename, tn, x, 0 ); return( 0 ); } MakeStaticHook(renamehook, renamefunc); /* ** Insert a new entry which name is given in ** the string gadget. */ HOOKPROTONH(movefunc, LONG, Object *obj, ULONG **para) { STATIC struct MUI_NListtree_TreeNode *tn1, *tn2; STATIC LONG movecnt = 0; if ( ( movecnt == 0 ) && ( (IPTR)*para == 42 ) ) { get( obj, MUIA_NListtree_Active, &tn1 ); if ( tn1 != MUIV_NListtree_Active_Off ) { nnset( tx_info3, MUIA_Text_Contents, "Select entry to insert after by simple click." ); movecnt++; } } else if ( movecnt == 1 ) { get( obj, MUIA_NListtree_Active, &tn2 ); if ( ( tn2 != MUIV_NListtree_Active_Off ) && ( tn1 != tn2 ) ) { if ( !IsXChildOfY( obj, tn1, tn2 ) && !IsXChildOfY( obj, tn1, tn2 ) ) { struct MUI_NListtree_ListNode *ln1; if((ln1 = (struct MUI_NListtree_ListNode *)DoMethod( obj, MUIM_NListtree_GetEntry, tn1, MUIV_NListtree_GetEntry_Position_Parent, 0))) { DoMethod( obj, MUIM_NListtree_Move, ln1, tn1, MUIV_NListtree_Move_NewListNode_Active, tn2, 0 ); nnset( tx_info3, MUIA_Text_Contents, "Entry successfully moved!" ); } else nnset( tx_info3, MUIA_Text_Contents, "Something went wrong! Try again to select destination." ); } else nnset( tx_info3, MUIA_Text_Contents, "You can not move childs!" ); } else nnset( tx_info3, MUIA_Text_Contents, "You should not move an entry to itself!" ); movecnt = 0; } return( 0 ); } MakeStaticHook(movehook, movefunc); /* ** Insert a new entry which name is given in ** the string gadget. */ HOOKPROTONH(copyfunc, LONG, Object *obj, ULONG **para) { STATIC struct MUI_NListtree_TreeNode *tn1, *tn2; STATIC LONG copycnt = 0; if ( ( copycnt == 0 ) && ( (IPTR)*para == 42 ) ) { get( obj, MUIA_NListtree_Active, &tn1 ); if ( tn1 != MUIV_NListtree_Active_Off ) { nnset( tx_info3, MUIA_Text_Contents, "Select entry to insert after by simple click." ); copycnt++; } } else if ( copycnt == 1 ) { get( obj, MUIA_NListtree_Active, &tn2 ); if ( ( tn2 != MUIV_NListtree_Active_Off ) && ( tn1 != tn2 ) ) { struct MUI_NListtree_ListNode *ln1; if((ln1 = (struct MUI_NListtree_ListNode *)DoMethod( obj, MUIM_NListtree_GetEntry, tn1, MUIV_NListtree_GetEntry_Position_Parent, 0))) { DoMethod( obj, MUIM_NListtree_Copy, ln1, tn1, MUIV_NListtree_Copy_DestListNode_Active, tn2, 0 ); nnset( tx_info3, MUIA_Text_Contents, "Entry successfully copied!" ); } else nnset( tx_info3, MUIA_Text_Contents, "Something went wrong! Try again to select destination." ); } else nnset( tx_info3, MUIA_Text_Contents, "You should not copy an entry to itself!" ); copycnt = 0; } return( 0 ); } MakeStaticHook(copyhook, copyfunc); /* ** Move KeepStructure */ HOOKPROTONH(moveksfunc, LONG, Object *obj, ULONG **para) { STATIC struct MUI_NListtree_TreeNode *tn1, *tn2; STATIC LONG movekscnt = 0; if ( ( movekscnt == 0 ) && ( (IPTR)*para == 42 ) ) { get( obj, MUIA_NListtree_Active, &tn1 ); if ( tn1 != MUIV_NListtree_Active_Off ) { nnset( tx_info3, MUIA_Text_Contents, "Select entry to make KeepStructure move with." ); movekscnt++; } } else if ( movekscnt == 1 ) { get( obj, MUIA_NListtree_Active, &tn2 ); if ( ( tn2 != MUIV_NListtree_Active_Off ) && ( tn1 != tn2 ) ) { struct MUI_NListtree_ListNode *ln1; if((ln1 = (struct MUI_NListtree_ListNode *)DoMethod( obj, MUIM_NListtree_GetEntry, tn1, MUIV_NListtree_GetEntry_Position_Parent, 0))) { DoMethod( obj, MUIM_NListtree_Move, ln1, tn1, MUIV_NListtree_Move_NewListNode_Active, tn2, MUIV_NListtree_Move_Flag_KeepStructure ); nnset( tx_info3, MUIA_Text_Contents, "Entry successfully moved (structure kept)" ); } else nnset( tx_info3, MUIA_Text_Contents, "Something went wrong! Try again to select destination." ); } else nnset( tx_info3, MUIA_Text_Contents, "You should not move an entry to itself!" ); movekscnt = 0; } return( 0 ); } MakeStaticHook(movekshook, moveksfunc); /* ** Copy KeepStructure */ HOOKPROTONH(copyksfunc, LONG, Object *obj, ULONG **para) { STATIC struct MUI_NListtree_TreeNode *tn1, *tn2; STATIC LONG copykscnt = 0; if ( ( copykscnt == 0 ) && ( (IPTR)*para == 42 ) ) { get( obj, MUIA_NListtree_Active, &tn1 ); if ( tn1 != MUIV_NListtree_Active_Off ) { nnset( tx_info3, MUIA_Text_Contents, "Select entry to make KeepStructure copy with." ); copykscnt++; } } else if ( copykscnt == 1 ) { get( obj, MUIA_NListtree_Active, &tn2 ); if ( ( tn2 != MUIV_NListtree_Active_Off ) && ( tn1 != tn2 ) ) { struct MUI_NListtree_ListNode *ln1; if((ln1 = (struct MUI_NListtree_ListNode *)DoMethod( obj, MUIM_NListtree_GetEntry, tn1, MUIV_NListtree_GetEntry_Position_Parent, 0))) { DoMethod( obj, MUIM_NListtree_Copy, ln1, tn1, MUIV_NListtree_Copy_DestListNode_Active, tn2, MUIV_NListtree_Copy_Flag_KeepStructure ); nnset( tx_info3, MUIA_Text_Contents, "Entry successfully copied (structure kept)" ); } else nnset( tx_info3, MUIA_Text_Contents, "Something went wrong! Try again to select destination." ); } else nnset( tx_info3, MUIA_Text_Contents, "You should not copy an entry to itself!" ); copykscnt = 0; } return( 0 ); } MakeStaticHook(copykshook, copyksfunc); HOOKPROTONHNO(fudf, LONG, struct MUIP_NListtree_FindUserDataMessage *msg) { nnset( tx_info1, MUIA_Text_Contents, "FindUserData Hook passed!" ); return( strncmp( (STRPTR)msg->User, (STRPTR)msg->UserData, strlen( (STRPTR)msg->User ) ) ); } MakeStaticHook(fudh, fudf); /* ** Find the specified tree node by name. */ HOOKPROTONHNP(findnamefunc, LONG, Object *obj) { struct MUI_NListtree_TreeNode *tn; STRPTR x = NULL; /* ** Let us see, which string the user wants to search for... */ get( st_string, MUIA_String_Contents, &x ); /* ** Is it somewhere in the tree? */ if((tn = (struct MUI_NListtree_TreeNode *)DoMethod(obj, MUIM_NListtree_FindUserData, MUIV_NListtree_FindUserData_ListNode_Root, x, MUIV_NListtree_FindUserData_Flag_Activate))) { /* ** Found! Inform the user. */ nnset( tx_info3, MUIA_Text_Contents, "Found your node!" ); } else { /* ** Not found. Inform the user. */ nnset( tx_info3, MUIA_Text_Contents, "NOT found specified node!" ); } return( 0 ); } MakeStaticHook(findnamehook, findnamefunc); /* ** Sort the active list. */ HOOKPROTONHNP(sortfunc, LONG, Object *obj) { clock_t start, end; LONG lastactive = 0; get( obj, MUIA_NListtree_Active, &lastactive ); set( obj, MUIA_NListtree_Active, MUIV_NListtree_Active_Off ); start = clock(); DoMethod( obj, MUIM_NListtree_Sort, lastactive, 0 ); end = clock(); set( obj, MUIA_NListtree_Active, lastactive ); DoMethod( tx_info3, MUIM_SetAsString, MUIA_Text_Contents, "Sort took %ld.%03lds", ( end - start ) / CLOCKS_PER_SEC, ( end - start ) % CLOCKS_PER_SEC ); return( 0 ); } MakeStaticHook(sorthook, sortfunc); /* ** Find the specified tree node by name. */ HOOKPROTONHNP(getnrfunc, LONG, Object *obj) { LONG temp, temp2; temp = DoMethod( obj, MUIM_NListtree_GetNr, MUIV_NListtree_GetNr_TreeNode_Active, MUIV_NListtree_GetNr_Flag_CountLevel ); if ( temp == 1 ) DoMethod( tx_info1, MUIM_SetAsString, MUIA_Text_Contents, "1 entry in parent node." ); else DoMethod( tx_info1, MUIM_SetAsString, MUIA_Text_Contents, "%ld entries in parent node.", temp ); temp = DoMethod( obj, MUIM_NListtree_GetNr, MUIV_NListtree_GetNr_TreeNode_Active, MUIV_NListtree_GetNr_Flag_CountAll ); if ( temp == 1 ) DoMethod( tx_info2, MUIM_SetAsString, MUIA_Text_Contents, "1 entry total." ); else DoMethod( tx_info2, MUIM_SetAsString, MUIA_Text_Contents, "%ld entries total.", temp ); temp = DoMethod( obj, MUIM_NListtree_GetNr, MUIV_NListtree_GetNr_TreeNode_Active, 0 ); temp2 = DoMethod( obj, MUIM_NListtree_GetNr, MUIV_NListtree_GetNr_TreeNode_Active, MUIV_NListtree_GetNr_Flag_Visible ); DoMethod( tx_info3, MUIM_SetAsString, MUIA_Text_Contents, "Active entry pos: %ld (visible: %ld).", temp, temp2 ); return( 0 ); } MakeStaticHook(getnrhook, getnrfunc); /* ** Find the specified tree node by name. */ HOOKPROTONHNP(numselfunc, LONG, Object *obj) { LONG temp = 0; DoMethod( obj, MUIM_NListtree_Select, MUIV_NListtree_Select_All, MUIV_NListtree_Select_Ask, 0, &temp ); if ( temp == 1 ) DoMethod( tx_info1, MUIM_SetAsString, MUIA_Text_Contents, "1 node selected." ); else DoMethod( tx_info1, MUIM_SetAsString, MUIA_Text_Contents, "%ld nodes selected.", temp ); { struct MUI_NListtree_TreeNode *tn; tn = (struct MUI_NListtree_TreeNode *)MUIV_NListtree_NextSelected_Start; for (;;) { DoMethod( obj, MUIM_NListtree_NextSelected, &tn ); if ( (IPTR)tn == (IPTR)MUIV_NListtree_NextSelected_End ) break; D(bug( "Next TreeNode: 0x%08lx - %s\n", tn, tn->tn_Name ) ); } D(bug( "\n" ) ); tn = (struct MUI_NListtree_TreeNode *)MUIV_NListtree_PrevSelected_Start; for (;;) { DoMethod( obj, MUIM_NListtree_PrevSelected, &tn ); if ( (IPTR)tn == (IPTR)MUIV_NListtree_PrevSelected_End ) break; D(bug( "Prev TreeNode: 0x%08lx - %s\n", tn, tn->tn_Name ) ); } } return( 0 ); } MakeStaticHook(numselhook, numselfunc); /* ** Test func */ HOOKPROTONHNP(testfunc, LONG, Object *obj) { SIPTR id; ULONG num; id = MUIV_NListtree_NextSelected_Start; for(;;) { DoMethod( obj, MUIM_NListtree_NextSelected, &id ); if(id == (SIPTR)MUIV_NListtree_NextSelected_End ) break; //GetAttr( MUIA_List_Entries, obj, &num ); num = DoMethod( obj, MUIM_NListtree_GetNr, MUIV_NListtree_GetNr_TreeNode_Active, MUIV_NListtree_GetNr_Flag_CountAll ); if ( num > 1 ) DoMethod( obj, MUIM_NListtree_Remove, MUIV_NListtree_Remove_ListNode_Active, id, 0 ); else break; } return( 0 ); } MakeStaticHook(testhook, testfunc); #if defined(__amigaos4__) #define GETINTERFACE(iface, base) (iface = (APTR)GetInterface((struct Library *)(base), "main", 1L, NULL)) #define DROPINTERFACE(iface) (DropInterface((struct Interface *)iface), iface = NULL) #else #define GETINTERFACE(iface, base) TRUE #define DROPINTERFACE(iface) #endif /* ** Main */ int main(UNUSED int argc, UNUSED char *argv[]) { ULONG signals; static const char *const UsedClasses[] = { "NList.mcc", "NListtree.mcc", "NListviews.mcc", NULL }; /* ** Is MUI V19 available? */ if((IntuitionBase = (APTR)OpenLibrary("intuition.library", 36)) && GETINTERFACE(IIntuition, IntuitionBase)) if((MUIMasterBase = OpenLibrary("muimaster.library", 19)) && GETINTERFACE(IMUIMaster, MUIMasterBase)) { /* ** Create application object. */ app = ApplicationObject, MUIA_Application_Title, "NListtree-Demo", MUIA_Application_Version, "$VER: NListtree-Demo 1.0 (" __DATE__ ")", MUIA_Application_Copyright, "Copyright (C) 2001-2006 by NList Open Source Team", MUIA_Application_Author, "NList Open Source Team", MUIA_Application_Description, "Demonstration program for MUI class NListtree.mcc", MUIA_Application_Base, "NLISTTREEDEMO", MUIA_Application_UsedClasses, UsedClasses, /* ** Build the window. */ SubWindow, window = WindowObject, MUIA_Window_Title, "NListtree-Demo", MUIA_Window_ID, MAKE_ID( 'N', 'L', 'T', 'R' ), MUIA_Window_AppWindow, TRUE, WindowContents, VGroup, /* ** Create a NListview embedded NListtree object */ Child, NListviewObject, MUIA_ShortHelp, "The NListtree object...", MUIA_NListview_NList, lt_nodes = NListtreeObject, InputListFrame, MUIA_CycleChain, TRUE, MUIA_NList_MinLineHeight, 18, MUIA_NListtree_MultiSelect, MUIV_NListtree_MultiSelect_Shifted, MUIA_NListtree_MultiTestHook, &mthook, MUIA_NListtree_DisplayHook, &dsphook, MUIA_NListtree_ConstructHook, &conhook, MUIA_NListtree_DestructHook, &deshook, /* This is the same as MUIV_NListtree_CompareHook_LeavesMixed. */ MUIA_NListtree_CompareHook, &comphook, MUIA_NListtree_DoubleClick, MUIV_NListtree_DoubleClick_Tree, MUIA_NListtree_EmptyNodes, FALSE, MUIA_NListtree_TreeColumn, 0, MUIA_NListtree_DragDropSort, TRUE, MUIA_NListtree_Title, TRUE, MUIA_NListtree_Format, ",,", MUIA_NListtree_FindUserDataHook,&fudh, //MUIA_NListtree_NoRootTree, TRUE, End, End, /* ** Build some controls. */ Child, tx_info1 = TextObject, MUIA_Background, MUII_TextBack, TextFrame, End, Child, tx_info2 = TextObject, MUIA_Background, MUII_TextBack, TextFrame, End, Child, tx_info3 = TextObject, MUIA_Background, MUII_TextBack, TextFrame, End, Child, ColGroup( 2 ), Child, FreeKeyLabel( "TreeCol:", 'c' ), Child, sl_treecol = Slider( 0, 2, 0 ), End, Child, HGroup, Child, st_string = StringObject, StringFrame, MUIA_String_MaxLen, 50, End, End, Child, ColGroup( 4 ), Child, bt_open = KeyButton( "Open", 'o' ), Child, bt_close = KeyButton( "Close", 'c' ), Child, bt_expand = KeyButton( "Expand", 'e' ), Child, bt_collapse = KeyButton( "Collapse", 'a' ), Child, bt_insert = KeyButton( "Insert", 'i' ), Child, bt_remove = KeyButton( "Remove", 'r' ), Child, bt_exchange = KeyButton( "Exchange", 'x' ), Child, bt_rename = KeyButton( "Rename", 'r' ), Child, bt_move = KeyButton( "Move", 'm' ), Child, bt_copy = KeyButton( "Copy", 'y' ), Child, bt_moveks = KeyButton( "Move KS", 'v' ), Child, bt_copyks = KeyButton( "Copy KS", 'k' ), Child, bt_find = KeyButton( "FindName", 'f' ), Child, bt_parent = KeyButton( "Parent", 'p' ), Child, bt_sort = KeyButton( "Sort", 's' ), Child, bt_getnr = KeyButton( "GetNr", 'n' ), Child, bt_redraw = KeyButton( "Redraw", 'w' ), Child, bt_selected = KeyButton( "Selected", 'd' ), Child, bt_seltogg = KeyButton( "Sel Togg", 't' ), Child, bt_showtree = KeyButton( "Show tree", 'h' ), Child, bt_test = KeyButton( "Test", ' ' ), Child, bt_test2 = KeyButton( "Test2", ' ' ), Child, bt_test3 = KeyButton( "Test3", ' ' ), Child, bt_test4 = KeyButton( "Test4", ' ' ), End, End, End, End; if( app ) { /* ** generate notifications */ DoMethod( window, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); /* ** open/close/expand/collapse */ DoMethod( bt_open, MUIM_Notify, MUIA_Pressed, FALSE, lt_nodes, 4, MUIM_NListtree_Open, MUIV_NListtree_Open_ListNode_Active, MUIV_NListtree_Open_TreeNode_Active, 0 ); DoMethod( bt_close, MUIM_Notify, MUIA_Pressed, FALSE, lt_nodes, 4, MUIM_NListtree_Close, MUIV_NListtree_Close_ListNode_Active, MUIV_NListtree_Close_TreeNode_Active, 0 ); DoMethod( bt_expand, MUIM_Notify, MUIA_Pressed, FALSE, lt_nodes, 4, MUIM_NListtree_Open, MUIV_NListtree_Open_ListNode_Root, MUIV_NListtree_Open_TreeNode_All, 0 ); DoMethod( bt_collapse, MUIM_Notify, MUIA_Pressed, FALSE, lt_nodes, 4, MUIM_NListtree_Close, MUIV_NListtree_Close_ListNode_Root, MUIV_NListtree_Close_TreeNode_All, 0 ); /* ** insert/remove/exchange/rename */ DoMethod( bt_insert, MUIM_Notify, MUIA_Pressed, FALSE, lt_nodes, 2, MUIM_CallHook, &inserthook ); DoMethod( bt_remove, MUIM_Notify, MUIA_Pressed, FALSE, lt_nodes, 4, MUIM_NListtree_Remove, MUIV_NListtree_Remove_ListNode_Root, MUIV_NListtree_Remove_TreeNode_Selected, 0 ); DoMethod( bt_exchange, MUIM_Notify, MUIA_Pressed, FALSE, lt_nodes, 3, MUIM_CallHook, &exchangehook, 42 ); DoMethod( lt_nodes, MUIM_Notify, MUIA_NListtree_Active, MUIV_EveryTime, lt_nodes, 3, MUIM_CallHook, &exchangehook, 0 ); DoMethod( bt_rename, MUIM_Notify, MUIA_Pressed, FALSE, lt_nodes, 2, MUIM_CallHook, &renamehook ); /* ** move/copy/moveks/copyks */ DoMethod( bt_move, MUIM_Notify, MUIA_Pressed, FALSE, lt_nodes, 3, MUIM_CallHook, &movehook, 42 ); DoMethod( lt_nodes, MUIM_Notify, MUIA_NListtree_Active, MUIV_EveryTime, lt_nodes, 3, MUIM_CallHook, &movehook, 0 ); DoMethod( bt_copy, MUIM_Notify, MUIA_Pressed, FALSE, lt_nodes, 3, MUIM_CallHook, ©hook, 42 ); DoMethod( lt_nodes, MUIM_Notify, MUIA_NListtree_Active, MUIV_EveryTime, lt_nodes, 3, MUIM_CallHook, ©hook, 0 ); DoMethod( bt_moveks, MUIM_Notify, MUIA_Pressed, FALSE, lt_nodes, 3, MUIM_CallHook, &movekshook, 42 ); DoMethod( lt_nodes, MUIM_Notify, MUIA_NListtree_Active, MUIV_EveryTime, lt_nodes, 3, MUIM_CallHook, &movekshook, 0 ); DoMethod( bt_copyks, MUIM_Notify, MUIA_Pressed, FALSE, lt_nodes, 3, MUIM_CallHook, ©kshook, 42 ); DoMethod( lt_nodes, MUIM_Notify, MUIA_NListtree_Active, MUIV_EveryTime, lt_nodes, 3, MUIM_CallHook, ©kshook, 0 ); /* ** find/parent/sort/getnr */ DoMethod( bt_find, MUIM_Notify, MUIA_Pressed, FALSE, lt_nodes, 2, MUIM_CallHook, &findnamehook ); DoMethod( bt_parent, MUIM_Notify, MUIA_Pressed, FALSE, lt_nodes, 3, MUIM_Set, MUIA_NListtree_Active, MUIV_NListtree_Active_Parent ); DoMethod( bt_sort, MUIM_Notify, MUIA_Pressed, FALSE, lt_nodes, 2, MUIM_CallHook, &sorthook ); /* DoMethod( bt_sort, MUIM_Notify, MUIA_Pressed, FALSE, lt_nodes, 3, MUIM_NListtree_Sort, MUIV_NListtree_Sort_TreeNode_Active, 0 ); */ DoMethod( bt_getnr, MUIM_Notify, MUIA_Pressed, FALSE, lt_nodes, 2, MUIM_CallHook, &getnrhook ); /* ** redraw/selected/seltogg/showtree */ DoMethod( bt_redraw, MUIM_Notify, MUIA_Pressed, FALSE, lt_nodes, 3, MUIM_NListtree_Redraw, MUIV_NListtree_Redraw_All ); DoMethod( bt_selected, MUIM_Notify, MUIA_Pressed, FALSE, lt_nodes, 2, MUIM_CallHook, &numselhook ); DoMethod( bt_seltogg, MUIM_Notify, MUIA_Pressed, FALSE, lt_nodes, 5, MUIM_NListtree_Select, MUIV_NListtree_Select_All, MUIV_NListtree_Select_Toggle, 0, NULL ); DoMethod( bt_showtree, MUIM_Notify, MUIA_Pressed, FALSE, lt_nodes, 3, MUIM_Set, MUIA_NListtree_ShowTree, MUIV_NListtree_ShowTree_Toggle ); /* ** misc */ DoMethod( sl_treecol, MUIM_Notify, MUIA_Slider_Level, MUIV_EveryTime, lt_nodes, 3, MUIM_Set, MUIA_NListtree_TreeColumn, MUIV_TriggerValue ); DoMethod( lt_nodes, MUIM_Notify, MUIA_NListtree_Active, MUIV_EveryTime, tx_info1, 4, MUIM_SetAsString, MUIA_Text_Contents, "Active node: 0x%08lx", MUIV_TriggerValue ); DoMethod( lt_nodes, MUIM_Notify, MUIA_NListtree_ActiveList, MUIV_EveryTime, tx_info2, 4, MUIM_SetAsString, MUIA_Text_Contents, "Active list: 0x%08lx", MUIV_TriggerValue ); DoMethod( lt_nodes, MUIM_Notify, MUIA_NListtree_DoubleClick, MUIV_EveryTime, tx_info3, 4, MUIM_SetAsString, MUIA_Text_Contents, "Double clicked on node: 0x%08lx", MUIV_TriggerValue ); DoMethod( lt_nodes, MUIM_Notify, MUIA_NListtree_SelectChange, TRUE, tx_info3, 3, MUIM_SetAsString, MUIA_Text_Contents, "Selection state changed" ); /* ** test */ DoMethod( bt_test, MUIM_Notify, MUIA_Pressed, FALSE, lt_nodes, 2, MUIM_CallHook, &testhook ); /* ** Open the window. ** */ set( window, MUIA_Window_Open, TRUE ); /* ** Set the tree into quiet state. */ set( lt_nodes, MUIA_NListtree_Quiet, TRUE ); /* ** Insert sample nodes. */ DrawSampleTree( lt_nodes ); /* ** Set the tree back to normal state. */ set( lt_nodes, MUIA_NListtree_Quiet, FALSE ); /* ** Minimal input loop. */ while((LONG)DoMethod( app, MUIM_Application_NewInput, &signals ) != (LONG)MUIV_Application_ReturnID_Quit ) { if ( signals ) { signals = Wait( signals | SIGBREAKF_CTRL_C ); if ( signals & SIGBREAKF_CTRL_C ) break; } } /* ** Clear the list. */ DoMethod( lt_nodes, MUIM_NListtree_Clear, NULL, 0 ); /* ** Close the window. */ set( window, MUIA_Window_Open, FALSE ); /* ** Shutdown */ MUI_DisposeObject( app ); } else printf( "Failed to create Application.\n" ); } if(MUIMasterBase) { DROPINTERFACE(IMUIMaster); CloseLibrary(MUIMasterBase); } if(IntuitionBase) { DROPINTERFACE(IIntuition); CloseLibrary((struct Library *)IntuitionBase); } return( 0 ); }
NListview
[edit | edit source]NListview.mcc/NListview.mcc NListview.mcc/MUIA_NListview_Horiz_ScrollBar NListview.mcc/MUIA_NListview_HSB_Height NListview.mcc/MUIA_NListview_NList NListview.mcc/MUIA_NListview_Vert_ScrollBar NListview.mcc/MUIA_NListview_VSB_Width
NListview.mcc/ That MCC public custom class give scrollers for a NList public custom class to make NList/NListview work near the same way as List/Listview. Most things that were handled by Listview are now handled by NList, so NListview is quite simple, anyway it's very easier to use NList with NListview than without. Anyway, use NList without NListview if you don't want to get attached scrollers (or want to attach your own scrollers to NList - see Demo). Note: NListview class can't use List as child but only NList, NFloattext, or a NList subclass, and NList class will not work with Listview without some conflict. MUIA_NListview_Horiz_ScrollBar -- [ISG], Object * SPECIAL INPUTS MUIV_NListview_HSB_Always 1 MUIV_NListview_HSB_Auto 2 MUIV_NListview_HSB_FullAuto 3 MUIV_NListview_HSB_None 4 MUIV_NListview_HSB_Default 5 SPECIAL SPECIAL INPUTS MUIV_NListview_HSB_On 0x0300 MUIV_NListview_HSB_Off 0x0100 FUNCTION With it you can tell if you want the scrollbar to be here always, never, automatic (not at start and appear forever if needed) or full automatic (appear and disappear when needed). Never is interesting if you want only one scrollbar of both or if you want to attach your own one only for one scrollbar. With Auto and FullAuto modes, scrollbars will not appear at first draw of the window. If you want it to appear when the window will be opened, you can set after creation time (not at init) MUIA_NListview_Horiz_ScrollBar to (MUIV_NListview_HSB_XXX|MUIV_NListview_HSB_On) where XXX is Default, FullAuto ... MUIV_NListview_HSB_On, MUIV_NListview_HSB_Off are used by the NList object to make scrollbars appear/disappear. The default is set by prefs. When prefs have not been set it is MUIV_NListview_HSB_Auto. MUIA_NListview_HSB_Height -- [..G], LONG FUNCTION Return the height of the horizontal scrollbar. Return 0 when no horizontal scrollbar is visible. MUIA_NListview_NList -- [I.G], Object * FUNCTION Same function as Listview.mui/MUIA_Listview_List. Every NListview needs a NList (or subclass) object as child. Specify it here. If none is specified, NListview will create a NList object as child, giving it the same taglist as itself. It's the only case where NList tags given to NListview will be taken into account. As every other child, it will be disposed of when its parent object is disposed. MUIA_NListview_Vert_ScrollBar -- [ISG], Object * SPECIAL INPUTS MUIV_NListview_VSB_Always 1 MUIV_NListview_VSB_Auto 2 MUIV_NListview_VSB_FullAuto 3 MUIV_NListview_VSB_None 4 MUIV_NListview_VSB_Default 5 MUIV_NListview_VSB_Left 6 SPECIAL SPECIAL INPUTS MUIV_NListview_VSB_On 0x0030 MUIV_NListview_VSB_Off 0x0010 FUNCTION Same as MUIA_NListview_Horiz_ScrollBar but for vertical scrollbar. The default is set by prefs. When prefs have not been set it is MUIV_NListview_VSB_Always. MUIA_NListview_VSB_Width -- [..G], LONG FUNCTION Return the width of the vertical scrollbar. Return 0 when no vertical scrollbar is visible. SEE ALSO MUIA_NListview_HSB_Height
NFloattext
[edit | edit source]NFloattext.mcc/NFloattext.mcc NFloattext.mcc/MUIA_NFloattext_Align NFloattext.mcc/MUIA_NFloattext_Justify NFloattext.mcc/MUIA_NFloattext_SkipChars NFloattext.mcc/MUIA_NFloattext_TabSize NFloattext.mcc/MUIA_NFloattext_Text NFloattext.mcc/MUIM_NFloattext_GetEntry
NFloattext class is a subclass of NList class that takes a big text string as input and splits it up into several lines to be displayed. Formatting capabilities include paragraphs an justified text with word wrap. That MCC public custom class work near the same way as Floattext. All you can do with NFloattext can be done directly using NList and its word wrap capabilities. NFloattext is here to give easy use and transition from Floattext. Now NList package provide a Floattext.mui replacement which use directly this class. Unfortunately the replacement Floattext.mui have to have the same major release number than original Floattext.mui to be accepted by MUI, so it will have to be update with each new MUI release. By default, MUIA_NList_Input is FALSE and MUIA_NList_TypeSelect is MUIV_NList_TypeSelect_Char, allowing char selection and copy to clipboard. If MUIA_NList_Input is set to TRUE, then MUIA_NList_TypeSelect default to MUIV_NList_TypeSelect_Line as usual. NFloattext does not copy the string text, so it needs to copy the string line to a buffer when you do a MUIM_NFloattext_GetEntry or MUIM_List_GetEntry, so the return pointer will be invalid after next GetEntry call (the new one will be valid of course). Using the old MUIA_Floattext_Text from standard Floatext class instead of MUIA_NFloattext_Text will make NFloattext copy the text like in Floattext class. Note that MUIM_NList_GetEntry work as describe in NList, so as NFloattext use word wrap entries, you should use better MUIM_NFloattext_GetEntry or MUIM_List_GetEntry. Or use MUIM_NList_GetEntryInfo and MUIM_NList_GetEntry. MUIA_NFloattext_Align -- [ISG], LONG SPECIAL INPUTS ALIGN_LEFT ALIGN_CENTER ALIGN_RIGHT ALIGN_JUSTIFY FUNCTION Indicate what alignment you want. It can be done with an escape alignment sequence in the Format preparse string or in the text string (for each linefeed separated lines) itself. setting it will set MUIA_NFloattext_Justify to TRUE if ALIGN_JUSTIFY, else to FALSE. MUIA_NFloattext_Justify -- [ISG], BOOL FUNCTION Same as Floattext.mui/MUIA_Floattext_Justify. if TRUE, MUIA_NFloattext_Align will be set to ALIGN_JUSTIFY, else to ALIGN_LEFT. MUIA_NFloattext_SkipChars -- [ISG], char * FUNCTION Same as NList.mcc/MUIA_NList_SkipChars and Floattext.mui/MUIA_Floattext_SkipChars. MUIA_NFloattext_TabSize -- [ISG], LONG FUNCTION Same as NList.mcc/MUIA_NList_TabSize and Floattext.mui/MUIA_Floattext_TabSize. Tab size defaults to 8. MUIA_NFloattext_Text -- [ISG], STRPTR FUNCTION Same as Floattext.mui/MUIA_Floattext_Text. String of characters to be displayed as floattext. This string may contain linefeeds or carriage returns to mark the end of paragraphs or tab characters for indention. NFloattext will automatically format the text according to the width of the NFloattext object. If a word won't fit into the current line, it will be wrapped. NFloattext don't copies the string into a private buffer as Floattext do it, so you need to keep your text in memory, but it uses less memory. If you want NFloattext to copy the text, just use MUIA_Floattext_Text which will do it for compatibility. Setting MUIA_NFloattext_Text to NULL means to clear the current text. Please note that justification and word wrap is a complicated operation and may take a considerable amount of time, especially with long texts on slow machines. MUIM_NFloattext_GetEntry -- SYNOPSIS DoMethod(obj,MUIM_NFloattext_GetEntry,LONG pos, APTR *entry); FUNCTION Same function as List.mui/MUIM_List_GetEntry. You'll get pointer to a null terminated string buffer which is a copy of the asked visible entry. Unlike with Floattext, the returned string will be valid only until next MUIM_NFloattext_GetEntry/MUIM_List_GetEntry call if the entry was word wrapped. I'll try to make it stay valid when using MUIM_List_GetEntry only if someone report me some compatibility problem because doing that will use more memory.
NBalance
[edit | edit source]NBalance.mcc/NBalance.mcc NBalance.mcc/MUIA_NBalance_Pointer
This MCC public custom class is derived from the MUI standard balance class which handles the dragging/resizing of vertical and horizontal groups. In contrast to the standard MUI balance class, however, it adds some features such as displaying a mouse pointer as soon as the mouse is above a dragable NBalance object. MUIA_NBalance_Pointer -- [ISG.], LONG INPUTS MUIV_NBalance_Pointer_Off MUIV_NBalance_Pointer_Standard (default) FUNCTION Allows to set the mouse pointer that should be displayed when the mouse is found to be above a NBalance object. Per default a standard horizontal or vertical size pointer is displayed as soon as the mouse is above a dragable NBalance object.
NBitmap
[edit | edit source]Creating a custom class
[edit | edit source]Most likely, when creating a custom class, the existing classes functionality will be extended, like providing a new appearance, handling keys, etc. Zune provides an interface to do so. The newly created class can be "private" to your application, or "public" and thus available to other applications like any existing (built-in or public custom) class.
To create you own custom class...
available on Aminet - look for DisKo
If you want to make your new custom class publicly available, e. g. to be included in AROS, it is necessary to register a class base address / class ID - to avoid conflicts with other developers developing a public custom class.
Typical MCC
[edit | edit source]#include "system.h" #include "MCCname_mcc.h" #include "MCCname_mcp.h" #include <proto/date.h> #include <proto/utility.h> #include <proto/intuition.h> #include <dos/dos.h> #include <proto/dos.h> #include <libraries/locale.h> #include <proto/locale.h> #include <libraries/mui.h> #include <proto/muimaster.h> #define CLASS MUIC_? #define SUPERCLASS MUIC_? #define VERSION number #define REVISION 0 #define VERSIONSTR "number" #define AUTHOR "name" #define COPYRIGHT "year" #define EXPORT_IMPORT_VERSION 1 /* further defines if needed */
Example
[edit | edit source]/*
** $Filename: ZuneARC.c $
** $Release: 1 $
** $Revision: 1.3 $
** $Date: 20/05/2010 $
**
** (C) Copyright 2009, 2010 Yannick Erb
** AROS Public License
*/
/*----------------------------------------------------------------------------*/
/* Main include */
/*----------------------------------------------------------------------------*/
#include "ZuneARC.h"
/*----------------------------------------------------------------------------*/
/* Menu */
/*----------------------------------------------------------------------------*/
#define NMABOUT_ID 200L
#define NMCONF_ID 201L
struct NewMenu Menu[] =
{
{NM_TITLE, "Project" , 0,0,0,(APTR)0},
{NM_ITEM , "About..." , "?",0,0,(APTR)NMABOUT_ID},
{NM_ITEM , "Edit Configuration", "C",0,0,(APTR)NMCONF_ID},
{NM_ITEM , NM_BARLABEL , 0,0,0,(APTR)0},
{NM_ITEM , "QUIT" , "Q",0,0,(APTR)MUIV_Application_ReturnID_Quit},
{NM_END , NULL , 0,0,0,(APTR)0},
};
/*----------------------------------------------------------------------------*/
/* Main program */
/*----------------------------------------------------------------------------*/
int main(int argc, char **argv)
{
BOOL Running = TRUE;
ULONG Signals;
char *CurrentArcName;
if (MUIMasterBase = OpenLibrary("muimaster.library", MUIMASTER_VMIN))
{
if (MakeMUIApp())
{
CurrentArcName = malloc(256+1);
strncpy(CurrentArcName,"",256);
set(Win, MUIA_Window_Open, TRUE);
strncpy(CurrentArcName,"",256);
set(Button2,MUIA_Disabled,TRUE);
set(Button3,MUIA_Disabled,TRUE);
set(Button4,MUIA_Disabled,TRUE);
set(Button5,MUIA_Disabled,TRUE);
// Read the configuration file
if (readconf())
{
MUI_Request(App,Win,0,"Error message","OK",
"Error in Configuration file",
TAG_DONE);
exit(1);
}
if (argc>1)
{
// started from Shell with an argument
strcpy(CurrentArcName,argv[1]);
}
else if(argc == 0)
{
// started from WB
struct WBStartup *wbmsg;
struct WBArg *wbarg;
wbmsg = (struct WBStartup *)argv;
wbarg = wbmsg->sm_ArgList;
wbarg++; // We only want to now the Name and Path of first parameter
if ( (wbmsg->sm_NumArgs>1) && (wbarg->wa_Lock) && (*wbarg->wa_Name) )
{
NameFromLock(wbarg->wa_Lock,CurrentArcName,256);
AddPart(CurrentArcName,wbarg->wa_Name,256);
}
}
if (strcmp(CurrentArcName,"")!=0)
{
set(ArcName,MUIA_Text_Contents,CurrentArcName);
DoMethod(ArcList,MUIM_NList_Clear);
if((ArcType = ArchiveType(CurrentArcName))<NbType)
{
ReadArchiveContent(CurrentArcName);
if (strncmp(archivers[arctypes[ArcType].Archiver].ExtractSingle,"#",1)==0)
set(Button2,MUIA_Disabled,TRUE);
else set(Button2,MUIA_Disabled,FALSE);
if (strncmp(archivers[arctypes[ArcType].Archiver].ExtractAll,"#",1)==0)
set(Button3,MUIA_Disabled,TRUE);
else set(Button3,MUIA_Disabled,FALSE);
if (strncmp(archivers[arctypes[ArcType].Archiver].Remove,"#",1)==0)
set(Button4,MUIA_Disabled,TRUE);
else set(Button4,MUIA_Disabled,FALSE);
if (strncmp(archivers[arctypes[ArcType].Archiver].Add,"#",1)==0)
set(Button5,MUIA_Disabled,TRUE);
else set(Button5,MUIA_Disabled,FALSE);
}
else
{
if (strcmp(CurrentArcName,"")!=0)
MUI_Request(App,Win,0,"Error message","OK",
strcat(CurrentArcName,"\nis not a known archive type"),
TAG_DONE);
set(ArcName,MUIA_Text_Contents,"");
set(Button2,MUIA_Disabled,TRUE);
set(Button3,MUIA_Disabled,TRUE);
set(Button4,MUIA_Disabled,TRUE);
set(Button5,MUIA_Disabled,TRUE);
}
}
while (Running)
{
switch(DoMethod(App, MUIM_Application_Input, &Signals))
{
case MUIV_Application_ReturnID_Quit:
Running = FALSE; /* break the loop */
break;
case NMCONF_ID:
Execute("SYS:Tools/Editor ZuneARC.cfg",NULL,NULL);
MUI_Request(App,Win,0,"Configuration file change","OK",
"In order to make the configuration change effective\nyou have to quit and restart ZuneARC",
TAG_DONE);
break;
case NMABOUT_ID:
MUI_Request(App,Win,0,"About...","OK",
"\33cZuneARC\nVersion 1.3\n\nYannick Erb\nMay. 2010",
TAG_DONE);
break;
case EXTSEL:
ExtractSelected(CurrentArcName);
break;
case EXTALL:
ExtractAll(CurrentArcName);
break;
case DELSEL:
RemoveSelected(CurrentArcName);
DoMethod(ArcList,MUIM_NList_Clear);
ReadArchiveContent(CurrentArcName);
break;
case ADDFIL:
AddFile(CurrentArcName);
DoMethod(ArcList,MUIM_NList_Clear);
ReadArchiveContent(CurrentArcName);
break;
case CREATE:
strcpy(CurrentArcName,CreateArchive());
set(ArcName,MUIA_Text_Contents,CurrentArcName);
DoMethod(ArcList,MUIM_NList_Clear);
if((ArcType = ArchiveType(CurrentArcName))<NbType)
{
ReadArchiveContent(CurrentArcName);
if (strncmp(archivers[arctypes[ArcType].Archiver].ExtractSingle,"#",1)==0)
set(Button2,MUIA_Disabled,TRUE);
else set(Button2,MUIA_Disabled,FALSE);
if (strncmp(archivers[arctypes[ArcType].Archiver].ExtractAll,"#",1)==0)
set(Button3,MUIA_Disabled,TRUE);
else set(Button3,MUIA_Disabled,FALSE);
if (strncmp(archivers[arctypes[ArcType].Archiver].Remove,"#",1)==0)
set(Button4,MUIA_Disabled,TRUE);
else set(Button4,MUIA_Disabled,FALSE);
if (strncmp(archivers[arctypes[ArcType].Archiver].Add,"#",1)==0)
set(Button5,MUIA_Disabled,TRUE);
else set(Button5,MUIA_Disabled,FALSE);
}
else
{
if (strcmp(CurrentArcName,"")!=0)
MUI_Request(App,Win,0,"Error message","OK",
strcat(CurrentArcName,"\nis not a known archive type"),
TAG_DONE);
set(ArcName,MUIA_String_Contents,"");
set(Button2,MUIA_Disabled,TRUE);
set(Button3,MUIA_Disabled,TRUE);
set(Button4,MUIA_Disabled,TRUE);
set(Button5,MUIA_Disabled,TRUE);
}
break;
case OPENID:
strcpy(CurrentArcName,getfilename(Win,"Select Archive to Open",FALSE,FALSE,"#?","SYS:"));
set(ArcName,MUIA_Text_Contents,CurrentArcName);
DoMethod(ArcList,MUIM_NList_Clear);
if((ArcType = ArchiveType(CurrentArcName))<NbType)
{
ReadArchiveContent(CurrentArcName);
if (strncmp(archivers[arctypes[ArcType].Archiver].ExtractSingle,"#",1)==0)
set(Button2,MUIA_Disabled,TRUE);
else set(Button2,MUIA_Disabled,FALSE);
if (strncmp(archivers[arctypes[ArcType].Archiver].ExtractAll,"#",1)==0)
set(Button3,MUIA_Disabled,TRUE);
else set(Button3,MUIA_Disabled,FALSE);
if (strncmp(archivers[arctypes[ArcType].Archiver].Remove,"#",1)==0)
set(Button4,MUIA_Disabled,TRUE);
else set(Button4,MUIA_Disabled,FALSE);
if (strncmp(archivers[arctypes[ArcType].Archiver].Add,"#",1)==0)
set(Button5,MUIA_Disabled,TRUE);
else set(Button5,MUIA_Disabled,FALSE);
}
else
{
if (strcmp(CurrentArcName,"")!=0)
MUI_Request(App,Win,0,"Error message","OK",
strcat(CurrentArcName,"\nis not a known archive type"),
TAG_DONE);
set(ArcName,MUIA_Text_Contents,"");
set(Button2,MUIA_Disabled,TRUE);
set(Button3,MUIA_Disabled,TRUE);
set(Button4,MUIA_Disabled,TRUE);
set(Button5,MUIA_Disabled,TRUE);
}
break;
default:
break;
}
if (Running && Signals) Wait(Signals);
}
set(Win, MUIA_Window_Open, FALSE);
MUI_DisposeObject(App);
}
CloseLibrary(MUIMasterBase);
}
return(0);
}
/*----------------------------------------------------------------------------*/
/* MakeMUIApp - creates the user interface */
/*----------------------------------------------------------------------------*/
static BOOL MakeMUIApp(void)
{
static struct Hook ListConstructHook;
static struct Hook ListDestructHook;
static struct Hook ListDisplayHook;
static struct Hook VListConstructHook;
static struct Hook VListDestructHook;
static struct Hook VListDisplayHook;
ListConstructHook.h_Entry = (HOOKFUNC)ListConst;
ListDestructHook.h_Entry = (HOOKFUNC)ListDest;
ListDisplayHook.h_Entry = (HOOKFUNC)ListDispl;
VListConstructHook.h_Entry = (HOOKFUNC)VListConst;
VListDestructHook.h_Entry = (HOOKFUNC)VListDest;
VListDisplayHook.h_Entry = (HOOKFUNC)VListDispl;
if (!(App = ApplicationObject,
MUIA_Application_Title, "ZuneARC",
MUIA_Application_Version, "$VER: ZuneARC 1.3 (20.05.10)",
MUIA_Application_Copyright, "© 2009 Yannick Erb",
MUIA_Application_Author, "Yannick Erb",
MUIA_Application_Description, "Zune Archivers Front-End",
MUIA_Application_Base, "ZARCC",
MUIA_Application_Menustrip, MUI_MakeObject(MUIO_MenustripNM,Menu,0),
SubWindow, Win = WindowObject,
MUIA_Window_Title, "ZuneARC",
MUIA_Window_ID, MAKEID('Z','A','R','C'),
MUIA_Window_Width , MUIV_Window_Width_Screen(50),
MUIA_Window_Height, MUIV_Window_Height_Screen(50),
WindowContents, VGroup,
Child, HGroup,
MUIA_Group_Spacing, 20,
MUIA_Group_SameWidth, TRUE,
Child, VGroup,
Child, Button0 = MakeButton("PROGDIR:Icons/Open.png", 'o', "\33uO\33npen Archive"),
Child, KeyLabel2("\33c\33uO\33npen",'\0'),
End,
Child, VGroup,
Child, Button1 = MakeButton("PROGDIR:Icons/Create.png", 'c', "\33uC\33nreate New Archive"),
Child, KeyLabel2("\33c\33uC\33nreate New",'\0'),
End,
Child, VGroup,
Child, Button2 = MakeButton("PROGDIR:Icons/ExtractSel.png", 's',"Extract \33uS\33nelected"),
Child, KeyLabel2("\33cExtract \33uS\33nel.",'\0'),
End,
Child, VGroup,
Child, Button3 = MakeButton("PROGDIR:Icons/ExtractALL.png", 'e',"\33uE\33nxtract All"),
Child, KeyLabel2("\33c\33uE\33nxtract All",'\0'),
End,
Child, VGroup,
Child, Button4 = MakeButton("PROGDIR:Icons/Remove.png", 'r',"\33uR\33nemove files from archive"),
Child, KeyLabel2("\33c\33uR\33nemove Sel.",'\0'),
End,
Child,VGroup,
Child, Button5 = MakeButton("PROGDIR:Icons/Add.png", 'a',"\33uA\33ndd files to archive"),
Child, KeyLabel2("\33c\33uA\33ndd files",'\0'),
End,
Child, RectangleObject, End,
End,
Child, BalanceObject, End,
Child, HGroup, MUIA_Group_SameHeight, TRUE,
Child, KeyLabel2(" Archive :",'\0'),
Child, ArcName = TextObject,
MUIA_Frame, MUIV_Frame_Text,
End,
End,
Child, NListviewObject,
MUIA_NListview_NList, ArcList = NListObject,
MUIA_NList_MultiSelect, MUIV_NList_MultiSelect_Default,
MUIA_NList_ConstructHook, (IPTR)&ListConstructHook,
MUIA_NList_DestructHook, (IPTR)&ListDestructHook,
MUIA_NList_DisplayHook, (IPTR)&ListDisplayHook,
MUIA_NList_Format, "BAR,P=\33r BAR,P=\33r BAR,BAR",
MUIA_NList_Title, TRUE,
End,
End,
Child, BalanceObject, End,
Child, cmdtext = GaugeObject,
MUIA_Gauge_Horiz, TRUE,
MUIA_FixHeightTxt, " ",
MUIA_Frame, MUIV_Frame_Gauge,
End,
End,
End,
SubWindow, SelAdd = WindowObject,
MUIA_Window_Title, "Select files to ADD",
MUIA_Window_ID, MAKEID('Z','A','R','1'),
MUIA_Window_Width , MUIV_Window_Width_Screen(50),
MUIA_Window_Height, MUIV_Window_Height_Screen(50),
WindowContents, VGroup,
Child, HGroup,
Child, VGroup,
Child, HGroup,
Child, KeyLabel2("Base Directory :",'\0'),
Child, SelAdd_CD = TextObject,
MUIA_Frame, MUIV_Frame_Text,
End,
End,
Child, HGroup,
Child, NListviewObject,
MUIA_Weight, 30,
MUIA_NListview_NList, SelAdd_VolList = NListObject,
MUIA_NList_ConstructHook, (IPTR)&VListConstructHook,
MUIA_NList_DestructHook, (IPTR)&VListDestructHook,
MUIA_NList_DisplayHook, (IPTR)&VListDisplayHook,
MUIA_Frame, MUIV_Frame_InputList,
End,
End,
Child, ListviewObject,
MUIA_Listview_List, SelAdd_DirList = DirlistObject,
MUIA_Dirlist_Directory, "",
MUIA_Dirlist_DrawersOnly, TRUE,
MUIA_Frame, MUIV_Frame_InputList,
End,
End,
End,
End,
Child, NListviewObject,
MUIA_NListview_NList, SelAdd_List = NListObject,
MUIA_NList_MultiSelect, MUIV_NList_MultiSelect_Default,
MUIA_NList_ConstructHook, (IPTR)&ListConstructHook,
MUIA_NList_DestructHook, (IPTR)&ListDestructHook,
MUIA_NList_DisplayHook, (IPTR)&ListDisplayHook,
MUIA_NList_Format, "COL=0 BAR,COL=1 P=\33r BAR,COL=3 BAR",
MUIA_NList_Title, TRUE,
End,
End,
End,
Child, HGroup,
MUIA_Group_Spacing, 50,
MUIA_Group_SameWidth, TRUE,
Child, SelAdd_OK = CoolImageIDButton("ARCHIVE",COOL_SAVEIMAGE_ID),
Child, SelAdd_PAR = CoolImageIDButton("PARENT",COOL_SWITCHIMAGE_ID),
Child, SelAdd_CANCEL = CoolImageIDButton("CANCEL",COOL_CANCELIMAGE_ID),
End,
End,
End,
End)) return(FALSE);
/* the 'end program' flag */
DoMethod(Win, MUIM_Notify, MUIA_Window_CloseRequest, TRUE,
App, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
/* Buttons that are handled by the main event loop */
DoMethod(Button0, MUIM_Notify, MUIA_Pressed, FALSE,
App, 2, MUIM_Application_ReturnID, OPENID);
DoMethod(Button1, MUIM_Notify, MUIA_Pressed, FALSE,
App, 2, MUIM_Application_ReturnID, CREATE);
DoMethod(Button2, MUIM_Notify, MUIA_Pressed, FALSE,
App, 2, MUIM_Application_ReturnID, EXTSEL);
DoMethod(Button3, MUIM_Notify, MUIA_Pressed, FALSE,
App, 2, MUIM_Application_ReturnID, EXTALL);
DoMethod(Button4, MUIM_Notify, MUIA_Pressed, FALSE,
App, 2, MUIM_Application_ReturnID, DELSEL);
DoMethod(Button5, MUIM_Notify, MUIA_Pressed, FALSE,
App, 2, MUIM_Application_ReturnID, ADDFIL);
/* PopASL, archive changed event.*/
DoMethod(ArcName, MUIM_Notify, MUIA_Popasl_Active, FALSE,
App, 2, MUIM_Application_ReturnID, NEWARC);
/* Events from the SelAdd window */
DoMethod(SelAdd, MUIM_Notify, MUIA_Window_CloseRequest, TRUE,
App, 2, MUIM_Application_ReturnID, QUITSELADD);
DoMethod(SelAdd_CANCEL, MUIM_Notify, MUIA_Pressed, FALSE,
App, 2, MUIM_Application_ReturnID, QUITSELADD);
DoMethod(SelAdd_OK, MUIM_Notify, MUIA_Pressed, FALSE,
App, 2, MUIM_Application_ReturnID, SELADDOK);
DoMethod(SelAdd_List, MUIM_Notify, MUIA_Listview_DoubleClick, TRUE,
App, 2, MUIM_Application_ReturnID, SELADDDC);
DoMethod(SelAdd_VolList, MUIM_Notify, MUIA_Listview_DoubleClick, TRUE,
App, 2, MUIM_Application_ReturnID, SELADDVOLL);
DoMethod(SelAdd_DirList, MUIM_Notify, MUIA_Listview_DoubleClick, TRUE,
App, 2, MUIM_Application_ReturnID, SELADDDIRL);
DoMethod(SelAdd_PAR, MUIM_Notify, MUIA_Pressed, FALSE,
App, 2, MUIM_Application_ReturnID, SELADDPAR);
return(TRUE);
}
/*----------------------------------------------------------------------------*/
/* MakeButton */
/*----------------------------------------------------------------------------*/
static APTR MakeButton(UBYTE *Image, UBYTE Key, UBYTE *Help)
{
return(MUI_NewObject("Dtpic.mui",
MUIA_Dtpic_Name,Image,
MUIA_InputMode, MUIV_InputMode_RelVerify,
MUIA_ControlChar, Key,
MUIA_Background, MUII_ButtonBack,
MUIA_ShortHelp, Help,
ImageButtonFrame,
TAG_DONE));
}
/*----------------------------------------------------------------------------*/
/* List construct Hook */
/*----------------------------------------------------------------------------*/
AROS_UFH3(APTR, ListConst,
AROS_UFHA(struct Hook *, h, A0),
AROS_UFHA(APTR, pool, A2),
AROS_UFHA(struct FileRecord *, entry, A1));
{
AROS_USERFUNC_INIT
struct FileRecord *new;
if (new=AllocPooled(pool,sizeof(struct FileRecord)))
{
*new = *entry;
}
return(new);
AROS_USERFUNC_EXIT
}
/*----------------------------------------------------------------------------*/
/* List destruct Hook */
/*----------------------------------------------------------------------------*/
AROS_UFH3(void, ListDest,
AROS_UFHA(struct Hook *, h, A0),
AROS_UFHA(APTR, pool, A2),
AROS_UFHA(struct FileRecord *, entry, A1));
{
AROS_USERFUNC_INIT
FreePooled(pool, entry, sizeof(struct FileRecord));
AROS_USERFUNC_EXIT
}
/*----------------------------------------------------------------------------*/
/* List display Hook */
/*----------------------------------------------------------------------------*/
AROS_UFH3(LONG, ListDispl,
AROS_UFHA(struct Hook *, h, A0),
AROS_UFHA(char **, array, A2),
AROS_UFHA(struct FileRecord *, entry, A1))
{
AROS_USERFUNC_INIT
static char buf1[256],buf2[16],buf3[16],buf4[64];
strcpy(buf1,"\33b");
strcpy(buf2,"\33b");
strcpy(buf3,"\33b");
strcpy(buf4,"\33b");
if(entry)
{
if (strcmp(entry->Size,"DIR")==0)
{
*array++ = strcat(buf1,entry->Name);
*array++ = strcat(buf2,entry->Size);
*array++ = strcat(buf3,entry->CSize);
*array = strcat(buf4,entry->Date);
}
else
{
*array++ = entry->Name;
*array++ = entry->Size;
*array++ = entry->CSize;
*array = entry->Date;
}
}
else
{
*array++ = "Name";
*array++ = "File Size";
*array++ = "Arch Size";
*array = "Date";
}
return(0);
AROS_USERFUNC_EXIT
}
/*----------------------------------------------------------------------------*/
/* VList construct Hook */
/*----------------------------------------------------------------------------*/
AROS_UFH3(APTR, VListConst,
AROS_UFHA(struct Hook *, h, A0),
AROS_UFHA(APTR, pool, A2),
AROS_UFHA(char *, entry, A1));
{
AROS_USERFUNC_INIT
char *new;
if (new=AllocPooled(pool,32))
{
strcpy(new,entry);
}
return(new);
AROS_USERFUNC_EXIT
}
/*----------------------------------------------------------------------------*/
/* VList destruct Hook */
/*----------------------------------------------------------------------------*/
AROS_UFH3(void, VListDest,
AROS_UFHA(struct Hook *, h, A0),
AROS_UFHA(APTR, pool, A2),
AROS_UFHA(char *, entry, A1));
{
AROS_USERFUNC_INIT
FreePooled(pool, entry, 32);
AROS_USERFUNC_EXIT
}
/*----------------------------------------------------------------------------*/
/* VList display Hook */
/*----------------------------------------------------------------------------*/
AROS_UFH3(LONG, VListDispl,
AROS_UFHA(struct Hook *, h, A0),
AROS_UFHA(char **, array, A2),
AROS_UFHA(char *, entry, A1))
{
AROS_USERFUNC_INIT
if (entry)
{
strcpy(*array,entry);
}
else
{
*array = "Volume";
}
return(0);
AROS_USERFUNC_EXIT
}
/*----------------------------------------------------------------------------*/
/* int ArchiveType(char *ArcFile) */
/* Returns the Archive type of the file */
/*----------------------------------------------------------------------------*/
int ArchiveType(char *ArcFile)
{
int extlen, i, type = 0;
while(type<NbType)
{
extlen = strlen(arctypes[type].Extension);
for(i=0;i<extlen;i++)
{
if (toupper(arctypes[type].Extension[i])!=toupper(ArcFile[strlen(ArcFile)-extlen+i])) break;
}
if (i==extlen) break;
type++;
}
return(type);
}
/*----------------------------------------------------------------------------*/
/* ReadArchiveContent(char *ArcFile) */
/* Reads the archive content and display it in the List */
/*----------------------------------------------------------------------------*/
void ReadArchiveContent(char *ArcFile)
{
struct FileRecord rec;
FILE *cf;
char line[1024];
char CurrentReading[512];
int EntryType[30];
int EntryMSpa[30];
int NbLine = 0,CurrentLine = 0, NbEntriesContentLine = 0, i = 0, j = 0, k = 0;
// clear display list
DoMethod(ArcList,MUIM_NList_Clear);
// generate tmp file containing the entries list
Runextcmd(archivers[arctypes[ArcType].Archiver].ListContent,ArcFile,"","","",TRUE);
// decode ContentFmt from config file (only first letter is kept)
while(archivers[arctypes[ArcType].Archiver].ContentFmt[i] != '\0')
{
if(archivers[arctypes[ArcType].Archiver].ContentFmt[i++] == ' ')
{
EntryType[NbEntriesContentLine] = (int)archivers[arctypes[ArcType].Archiver].ContentFmt[i-5];
EntryMSpa[NbEntriesContentLine] = atoi(&archivers[arctypes[ArcType].Archiver].ContentFmt[i-3]);
NbEntriesContentLine++;
}
}
EntryType[NbEntriesContentLine] = (int)archivers[arctypes[ArcType].Archiver].ContentFmt[i-4];
EntryMSpa[NbEntriesContentLine] = atoi(&archivers[arctypes[ArcType].Archiver].ContentFmt[i-2]);
// decode tmp file
if((cf = fopen("T:ZuneARC.tmp","r"))!=NULL)
{
// count total number of line in file
while(fgets(line,512,cf)!=NULL) NbLine++;
rewind(cf);
while(fgets(line,512,cf)!=NULL)
{
CurrentLine++;
if((CurrentLine > archivers[arctypes[ArcType].Archiver].ContentHeader) // skip header
&& (CurrentLine < NbLine-archivers[arctypes[ArcType].Archiver].ContentFooter+1)) // and footer
{
strcpy(rec.Name,"");
strcpy(rec.Size,"");
strcpy(rec.CSize,"");
strcpy(rec.Date,"");
// Read entries
j = 0;
for(i=0;i<NbEntriesContentLine+1;i++)
{
k = 0;
// skip initial spaces and tabs
while(line[j]==' ' || line[j]=='\t')
{
j++;
k++;
}
// if number of spaces (k) is bigger than the maximum allowed consecutive spaces than we're jumping to next entry
if (EntryMSpa[i] > 0 && k > EntryMSpa[i]) i++;
k = 0;
// read entry till space or tab or EOL encountered
while(line[j]!=' ' && line[j]!='\t' && line[j]!='\0' && line[j]!='\n')
{
CurrentReading[k++] = line[j++];
}
CurrentReading[k] = '\0';
switch(EntryType[i])
{
case 'N':
if(strcmp(rec.Name,"")!=0) strcat(rec.Name," ");
strcpy(rec.Name,strcat(rec.Name,CurrentReading));
break;
case 'C':
strcat(rec.CSize,CurrentReading);
break;
case 'S':
strcat(rec.Size,CurrentReading);
break;
case 'D':
if(strcmp(rec.Date,"")!=0) strcat(rec.Date," ");
strcat(rec.Date,CurrentReading);
break;
default:
break;
}
}
if ((atoi(rec.Size)==0) && (rec.Name[strlen(rec.Name)-1]=='/'))
{
strcpy(rec.Size,"DIR");
}
DoMethod(ArcList,MUIM_NList_InsertSingle,(IPTR)&rec, MUIV_NList_Insert_Bottom);
}
}
fclose(cf);
//DeleteFile("T:ZuneARC.tmp");
}
else
{
MUI_Request(App,Win,0,"Error message","OK",
"Temporary file was not created\nthere is either an error in the archive\nor in configuration file.",
TAG_DONE);
}
}
/*-------------------------------------------------------------------------------------*/
/* void Runextcmd(char * fmt,char *arch,char *file,char *dest, char *base,BOOL out) */
/* Formats and run the external command string */
/*-------------------------------------------------------------------------------------*/
void Runextcmd(char * fmt,char *arch,char *file,char *dest, char *base, BOOL out)
{
char cmd[1024];
char tmp[512];
char display[1024];
int i = 0,j = 0;
FILE *sf;
strncpy(display,"\0332",1024);
strncpy(cmd,"",1024);
strncpy(tmp,"",512);
sf = fopen("T:ZuneARC.script","w");
while (fmt[i]!='\0')
{
if(fmt[i]==';') // Command Section finished
{
i++;
cmd[j] = '\0';
if(out) strcat(cmd," >T:ZuneARC.tmp");
//printf("%s\n",cmd);
fprintf(sf,"%s\n",cmd);
j = 0;
strncpy(cmd,"",512);
}
if(fmt[i]!='%')
{
cmd[j++] = fmt[i++];
}
else
{
if (fmt[i+1]=='%') i++;
else strcpy(tmp,"\"");
if(strncmp(&fmt[i],"%arch",5)==0) strcat(tmp,arch);
if(strncmp(&fmt[i],"%file",5)==0) strcat(tmp,file);
if(strncmp(&fmt[i],"%dest",5)==0) strcat(tmp,dest);
if(strncmp(&fmt[i],"%base",5)==0) strcat(tmp,base);
if (fmt[i-1]!='%') strcat(tmp,"\"");
strcat(cmd,tmp);
j = j+strlen(tmp);
i = i+5;
}
}
cmd[j]='\0';
if(out) strcat(cmd," >T:ZuneARC.tmp");
//printf("%s\n",cmd);
fprintf(sf,"%s\n",cmd);
fclose(sf);
set(cmdtext,MUIA_Gauge_InfoText,strcat(display,cmd));
BPTR scriptfile = Open("T:ZuneARC.script",MODE_OLDFILE);
struct TagItem tags[] = {
{SYS_Input, (IPTR)NULL},
{SYS_Output, (IPTR)NULL},
{SYS_Error, (IPTR)NULL},
{SYS_ScriptInput, (IPTR)scriptfile},
{SYS_UserShell, TRUE},
{TAG_DONE, 0}
};
SystemTagList("",tags);
}
/*----------------------------------------------------------------------------*/
/* int readconf(void) */
/* Reads the configuration file and store the information */
/*----------------------------------------------------------------------------*/
int readconf(void)
{
FILE *cf;
char line[256];
char tmparc[10];
int i,j,k,l;
NbArc = 0;
NbType = 0;
if((cf=fopen("PROGDIR:ZuneARC.cfg","r")) == NULL)
{
MUI_Request(App,Win,0,"Error message","OK",
"Can't open configuration file\nZuneARC.cfg shall be placed in\nsame directpry as ZuneARC.",
TAG_DONE);
}
else
{
while(fgets(line,128,cf)!=NULL)
{
if(strncmp(line,"CmdName",7)==0) NbArc++;
if(strncmp(line,"ArcType",7)==0) NbType++;
}
}
archivers = malloc(NbArc * sizeof(struct Archivers));
arctypes = malloc(NbType * sizeof(struct ArcTypes));
rewind(cf);
j = 0;
while(fgets(line,256,cf)!=NULL)
{
if(strncmp(line,"CmdName",7)==0)
{
j++;
strcpy(archivers[j-1].CmdName,readconfline(line));
}
if(strncmp(line,"ExtractSingle",13)==0)
strcpy(archivers[j-1].ExtractSingle,readconfline(line));
if(strncmp(line,"ExtractAll",10)==0)
strcpy(archivers[j-1].ExtractAll,readconfline(line));
if(strncmp(line,"ListContent",11)==0)
strcpy(archivers[j-1].ListContent,readconfline(line));
if(strncmp(line,"ContentHeader",13)==0)
archivers[j-1].ContentHeader=atoi(readconfline(line));
if(strncmp(line,"ContentFooter",13)==0)
archivers[j-1].ContentFooter=atoi(readconfline(line));
if(strncmp(line,"ContentFmt",10)==0)
strcpy(archivers[j-1].ContentFmt,readconfline(line));
if(strncmp(line,"PreAdd",6)==0)
strcpy(archivers[j-1].PreAdd,readconfline(line));
if(strncmp(line,"Add",3)==0)
strcpy(archivers[j-1].Add,readconfline(line));
if(strncmp(line,"PostAdd",7)==0)
strcpy(archivers[j-1].PostAdd,readconfline(line));
if(strncmp(line,"PreRemove",9)==0)
strcpy(archivers[j-1].PreRemove,readconfline(line));
if(strncmp(line,"Remove",6)==0)
strcpy(archivers[j-1].Remove,readconfline(line));
if(strncmp(line,"PostRemove",10)==0)
strcpy(archivers[j-1].PostRemove,readconfline(line));
if(strncmp(line,"Create",6)==0)
strcpy(archivers[j-1].Create,readconfline(line));
}
rewind(cf);
j = 0;
while(fgets(line,256,cf)!=NULL)
{
if(strncmp(line,"ArcType",7)==0)
{
i = 0;
k = 0;
while(line[i++]!=',');
while(line[i++]==' ');
i--;
while(line[i++]!=',') arctypes[j].Extension[k++]=line[i-1];
arctypes[j].Extension[k] = '\0';
while(line[i++]==' ');
i--;
k = 0;
while(line[i++]!=',') tmparc[k++]=line[i-1];
tmparc[k] = '\0';
l = 0;
while((strcmp(tmparc,archivers[l].CmdName)!=0) && (l<NbArc)) l++;
arctypes[j].Archiver = l;
j++;
}
}
fclose(cf);
return(0);
}
/*----------------------------------------------------------------------------*/
/* char *readconfline(char *line) */
/* Reads one configuration file and sends back the content */
/*----------------------------------------------------------------------------*/
char *readconfline(char *line)
{
static char info[256];
int i = 0;
int k = 0;
while(line[i++]!=',');
while(line[i++]==' ');
i--;
while(line[i++]!=',') info[k++]=line[i-1];
info[k] = '\0';
return info;
}
/*----------------------------------------------------------------------------*/
/* char *CreateArchive() */
/* Creates a new archive file */
/*----------------------------------------------------------------------------*/
char *CreateArchive()
{
char *FileToAdd;
static char ArcName[128];
char *res = NULL;
char filter[16] = "#?.";
int extlen;
char arcsel[128]="";
int i,j = 0;
int TmpArcType[16];
strncpy(ArcName,"",128);
res = ArcName;
for(i=0;i<NbType;i++)
{
if(archivers[arctypes[i].Archiver].Create[0]!='#')
{
if (arcsel[0]!='\0') strcat(arcsel,"|");
strcat(arcsel,arctypes[i].Extension);
TmpArcType[j++] = i;
}
}
strcat(arcsel,"|CANCEL");
i = MUI_Request(App,Win,0,"Archive Type Selection",arcsel,
"Select the type of archive you want to create",
TAG_DONE);
if(i)
{
ArcType = TmpArcType[i-1];
extlen = strlen(arctypes[ArcType].Extension);
strcat(filter,arctypes[ArcType].Extension);
strcpy(ArcName,getfilename(Win,"New Archive Name",FALSE,FALSE,filter,"SYS:"));
// Append Extension if forgotten
if (strcmp(ArcName,"")!=0)
{
if (strcmp(arctypes[ArcType].Extension,&ArcName[strlen(ArcName)-extlen])!=0)
{
strcat(ArcName,".");
strcat(ArcName,arctypes[ArcType].Extension);
}
Runextcmd(archivers[arctypes[ArcType].Archiver].Create,ArcName,"","","",FALSE);
res = ArcName;
}
}
return(res);
}
/*----------------------------------------------------------------------------*/
/* void ExtractSelected(char *Archive) */
/* Extract Selected files from archive */
/*----------------------------------------------------------------------------*/
void ExtractSelected(char *Archive)
{
struct FileRecord *CurrentEntry;
LONG id = MUIV_NList_NextSelected_Start;
char *Destination;
Destination = getfilename(Win,"Select Destination directory",FALSE,TRUE,"#?",Archive);
if(strcmp(Destination,"")!=0)
{
for(;;)
{
DoMethod(ArcList,MUIM_NList_NextSelected,&id);
if(id==MUIV_NList_NextSelected_End) break;
DoMethod(ArcList,MUIM_NList_GetEntry,id,&CurrentEntry);
Runextcmd(archivers[arctypes[ArcType].Archiver].ExtractSingle,
Archive,CurrentEntry->Name,
Destination,"",FALSE);
}
}
else
{
MUI_Request(App,Win,0,"Error message","OK","No destination selected",TAG_DONE);
}
}
/*----------------------------------------------------------------------------*/
/* void ExtractAll(char *Archive) */
/* Extract All files from current Archive */
/*----------------------------------------------------------------------------*/
void ExtractAll(char *Archive)
{
char *Destination;
Destination = getfilename(Win,"Select Destination directory",FALSE,TRUE,"#?",Archive);
if(strcmp(Destination,"")!=0)
{
Runextcmd(archivers[arctypes[ArcType].Archiver].ExtractAll,
Archive,"",Destination,"",FALSE);
}
else
{
MUI_Request(App,Win,0,"Error message","OK","No destination selected",TAG_DONE);
}
}
/*----------------------------------------------------------------------------*/
/* void RemoveSelected(char *Archive) */
/* Delete Selected files from Archive */
/*----------------------------------------------------------------------------*/
void RemoveSelected(char *Archive)
{
struct FileRecord *CurrentEntry;
LONG id = MUIV_NList_NextSelected_Start;
int Nselect = 0,x = 0;
if(strcmp(Archive,"")!=0)
{
for(;;)
{
set(cmdtext,MUIA_Gauge_Current,++x);
DoMethod(ArcList,MUIM_NList_NextSelected,&id);
if(id==MUIV_NList_NextSelected_End) break;
Nselect++;
}
id = MUIV_NList_NextSelected_Start;
set(cmdtext,MUIA_Gauge_Max,Nselect);
// Remove pre command
if (strlen(archivers[arctypes[ArcType].Archiver].PreRemove)>0)
Runextcmd(archivers[arctypes[ArcType].Archiver].PreRemove,
Archive,"","","",FALSE);
// Remove command (loop)
for(;;)
{
set(cmdtext,MUIA_Gauge_Current,++x);
DoMethod(ArcList,MUIM_NList_NextSelected,&id);
if(id==MUIV_NList_NextSelected_End) break;
DoMethod(ArcList,MUIM_NList_GetEntry,id,&CurrentEntry);
Runextcmd(archivers[arctypes[ArcType].Archiver].Remove,
Archive,CurrentEntry->Name,"","",FALSE);
}
// Remove post command
if (strlen(archivers[arctypes[ArcType].Archiver].PostRemove)>0)
Runextcmd(archivers[arctypes[ArcType].Archiver].PostRemove,
Archive,"","","",FALSE);
set(cmdtext,MUIA_Gauge_Current,0);
}
else
{
MUI_Request(App,Win,0,"Error message","OK","No archive selected",TAG_DONE);
}
}
/*----------------------------------------------------------------------------*/
/* void AddFile(char *Archive) */
/* Add files to current Archive */
/*----------------------------------------------------------------------------*/
void AddFile(char *Archive)
{
static char Base[128] = "SYS:";
char vol[32];
char *tmp;
char test[32];
BOOL Running = TRUE;
ULONG Signals;
struct FileRecord *CurrentEntry;
LONG id = MUIV_NList_NextSelected_Start;
int Nselect = 0,x,y;
struct DosList *dl, *actdl;
// Get list of Volumes and file in VolList
DoMethod(SelAdd_VolList, MUIM_List_Clear);
dl = LockDosList(LDF_READ | LDF_VOLUMES | LDF_ASSIGNS | LDF_DEVICES);
actdl = dl;
while(actdl = NextDosEntry(actdl, LDF_DEVICES))
{
strncpy(vol, actdl->dol_Ext.dol_AROS.dol_DevName, sizeof(vol));
vol[sizeof(vol)-2] = '\0';
strcat(vol,":");
DoMethod(SelAdd_VolList,MUIM_List_InsertSingle, vol, MUIV_List_Insert_Bottom);
}
actdl = dl;
while(actdl = NextDosEntry(actdl, LDF_VOLUMES))
{
strncpy(vol, actdl->dol_Ext.dol_AROS.dol_DevName, sizeof(vol));
vol[sizeof(vol)-2] = '\0';
strcat(vol,":");
DoMethod(SelAdd_VolList,MUIM_List_InsertSingle, vol, MUIV_List_Insert_Bottom);
}
actdl = dl;
while(actdl = NextDosEntry(actdl, LDF_ASSIGNS))
{
strncpy(vol, actdl->dol_Ext.dol_AROS.dol_DevName, sizeof(vol));
vol[sizeof(vol)-2] = '\0';
strcat(vol,":");
DoMethod(SelAdd_VolList,MUIM_List_InsertSingle, vol, MUIV_List_Insert_Bottom);
}
UnLockDosList(LDF_READ | LDF_VOLUMES | LDF_ASSIGNS | LDF_DEVICES);
//strcpy(Base,"SYS:");
set(SelAdd_DirList,MUIA_Dirlist_Directory,Base);
set(SelAdd_CD,MUIA_Text_Contents,Base);
DoMethod(SelAdd_List,MUIM_NList_Clear);
AddInSelAddList(Base,"",MUIV_NList_Insert_Sorted);
set(SelAdd, MUIA_Window_Open, TRUE);
while (Running)
{
switch(DoMethod(App, MUIM_Application_Input, &Signals))
{
case QUITSELADD:
Running = FALSE; /* break the loop */
set(SelAdd, MUIA_Window_Open, FALSE);
break;
case SELADDVOLL:
DoMethod(SelAdd_VolList,MUIM_List_GetEntry,MUIV_List_GetEntry_Active,&tmp);
sprintf(Base,"%s",tmp);
set(SelAdd_DirList,MUIA_List_Quiet,TRUE);
set(SelAdd_DirList,MUIA_Dirlist_Directory,Base);
set(SelAdd_DirList,MUIA_List_Quiet,FALSE);
set(SelAdd_CD,MUIA_Text_Contents,Base);
DoMethod(SelAdd_List,MUIM_NList_Clear);
AddInSelAddList(Base,"",MUIV_NList_Insert_Sorted);
break;
case SELADDPAR:
x=0;
y=0;
while(Base[x++]!='\0') if((Base[x]=='/') || (Base[x]==':')) y=x;
if (Base[y]=='/') Base[y]='\0';
if (Base[y]==':') Base[y+1]='\0';
set(SelAdd_DirList,MUIA_List_Quiet,TRUE);
set(SelAdd_DirList,MUIA_Dirlist_Directory,Base);
set(SelAdd_DirList,MUIA_List_Quiet,FALSE);
set(SelAdd_CD,MUIA_Text_Contents,Base);
DoMethod(SelAdd_List,MUIM_NList_Clear);
AddInSelAddList(Base,"",MUIV_NList_Insert_Sorted);
break;
case SELADDDIRL:
strcpy(tmp,"");
strcpy(tmp,(APTR)XGET(SelAdd_DirList,MUIA_Dirlist_Path));
if (tmp) strcpy(Base,tmp);
set(SelAdd_DirList,MUIA_List_Quiet,TRUE);
set(SelAdd_DirList,MUIA_Dirlist_Directory,Base);
set(SelAdd_DirList,MUIA_List_Quiet,FALSE);
set(SelAdd_CD,MUIA_Text_Contents,Base);
DoMethod(SelAdd_List,MUIM_NList_Clear);
AddInSelAddList(Base,"",MUIV_NList_Insert_Sorted);
break;
case SELADDOK:
x = 0;
set(SelAdd, MUIA_Window_Open, FALSE);
for(;;)
{
set(cmdtext,MUIA_Gauge_Current,++x);
DoMethod(SelAdd_List,MUIM_NList_NextSelected,&id);
if(id==MUIV_NList_NextSelected_End) break;
Nselect++;
}
id = MUIV_NList_NextSelected_Start;
set(cmdtext,MUIA_Gauge_Max,Nselect);
// Add pre command
if (strlen(archivers[arctypes[ArcType].Archiver].PreAdd)>0)
Runextcmd(archivers[arctypes[ArcType].Archiver].PreAdd,
Archive,"","",Base,FALSE);
// Add command (loop)
for(;;)
{
set(cmdtext,MUIA_Gauge_Current,++x);
DoMethod(SelAdd_List,MUIM_NList_NextSelected,&id);
if(id==MUIV_NList_NextSelected_End) break;
DoMethod(SelAdd_List,MUIM_NList_GetEntry,id,&CurrentEntry);
Runextcmd(archivers[arctypes[ArcType].Archiver].Add,
Archive,CurrentEntry->Name,"",Base,FALSE);
}
// Add post command
if (strlen(archivers[arctypes[ArcType].Archiver].PostAdd)>0)
Runextcmd(archivers[arctypes[ArcType].Archiver].PostAdd,
Archive,"","",Base,FALSE);
set(cmdtext,MUIA_Gauge_Current,0);
Running = FALSE;
break;
case SELADDDC: /* Double click on an entry */
/*Get the active entry*/
DoMethod(SelAdd_List,MUIM_NList_GetEntry,MUIV_NList_GetEntry_Active,&CurrentEntry);
/*If active entry is a directory explode it*/
if (strncmp(CurrentEntry->Size,"DIR",3)==0)
{
char Dir[128];
char Path[128];
if(Base[(strlen(Base)-1)]==':')sprintf(Dir,"%s%s",Base,CurrentEntry->Name);
else sprintf(Dir,"%s/%s",Base,CurrentEntry->Name);
sprintf(Path,"%s/",CurrentEntry->Name);
AddInSelAddList(Dir,Path,MUIV_NList_Insert_Sorted);
DoMethod(SelAdd_List,MUIM_NList_Remove,MUIV_NList_Remove_Active);
}
break;
}
if (Running && Signals) Wait(Signals);
}
}
/*----------------------------------------------------------------------------*/
/* void AddInSelAddList(char *Dir,char *Path, LONG Position) */
/* Add files from DIR to Add List including Path in front of File Name */
/*----------------------------------------------------------------------------*/
void AddInSelAddList(char *Dir, char *Path, LONG Position)
{
BPTR BaseDirLock;
struct FileInfoBlock *fib;
BOOL success = FALSE;
struct DateTime dt;
char datebuffer[LEN_DATSTRING];
char timebuffer[LEN_DATSTRING];
struct FileRecord rec;
set(SelAdd_List,MUIA_NList_Quiet,TRUE);
BaseDirLock = Lock(Dir,ACCESS_READ);
if (BaseDirLock)
{
fib = AllocDosObject(DOS_FIB, NULL);
if (fib)
{
success = Examine(BaseDirLock, fib);
if (success && fib->fib_DirEntryType > 0)
{
for (;;)
{
BOOL ok;
ok = ExNext(BaseDirLock,fib);
if (!ok)
{
if (IoErr() == ERROR_NO_MORE_ENTRIES) break;
success = FALSE;
continue;
}
dt.dat_Stamp = fib->fib_Date;
dt.dat_Format = FORMAT_DOS;
dt.dat_Flags = 0;
dt.dat_StrDay = NULL;
dt.dat_StrDate = datebuffer;
dt.dat_StrTime = timebuffer;
DateToStr(&dt);
sprintf(rec.Name,"%s%s",Path,fib->fib_FileName);
if (fib->fib_DirEntryType>0) sprintf(rec.Size,"%s","DIR");
else sprintf(rec.Size,"%d",fib->fib_Size);
sprintf(rec.CSize,"");
sprintf(rec.Date,"%s %s",datebuffer,timebuffer);
DoMethod(SelAdd_List,MUIM_NList_InsertSingle,&rec, Position);
}
}
}
UnLock(BaseDirLock);
}
set(SelAdd_List,MUIA_NList_Quiet,FALSE);
}
/*----------------------------------------------------------------------------*/
/* char *getfilename(Object *win, char *title, BOOL save, */
/* BOOL drawers, char *pattern, char *inidrawer) */
/* open ASL FileRequester and get selection */
/*----------------------------------------------------------------------------*/
char *getfilename(Object *win, char *title, BOOL save, BOOL drawers, char *pattern, char *inidrawer)
{
char inipath[256], *eip;
static char buf[1024];
struct FileRequester *req;
struct Window *w;
Object *app = (Object *)XGET(win,MUIA_ApplicationObject);
char *res = NULL;
int x;
strcpy(inipath,inidrawer);
eip = PathPart(inipath);
eip[0]='\0';
strncpy(buf,"",1024);
res = buf;
get(win,MUIA_Window_Window,&w);
if(req=MUI_AllocAslRequestTags(ASL_FileRequest,
ASLFR_Window, w,
ASLFR_TitleText, title,
ASLFR_InitialPattern , pattern,
ASLFR_InitialDrawer , inipath,
ASLFR_DoSaveMode , save,
ASLFR_DoMultiSelect , FALSE,
ASLFR_DrawersOnly , drawers,
ASLFR_SetSortDrawers , ASLFRSORTDRAWERS_First,
ASLFR_DoPatterns , TRUE,
ASLFR_RejectIcons , TRUE,
ASLFR_UserData , app,
TAG_DONE))
{
set(app,MUIA_Application_Sleep,TRUE);
if (MUI_AslRequestTags(req,TAG_DONE))
{
res = buf;
stccpy(buf,req->fr_Drawer,sizeof(buf));
if(!drawers)
if (*req->fr_Drawer) AddPart(buf,req->fr_File,sizeof(buf));
else strcat(buf,req->fr_File);
}
MUI_FreeAslRequest(req);
set(app,MUIA_Application_Sleep,FALSE);
}
return(res);
}
fixed the bug in NFloattext.mcc which caused the class to ignore MUIA_Font (together with the rest of taglist). If you write your own varargs stub which uses AROS_SLOWSTACKTAGS macros inside itself, DO NOT declare it static!