#include #include #include #include #include #include #include #include #include #include #include struct Library *MUIMasterBase = NULL; struct Library *IntuitionBase = NULL; struct MUI_CustomClass *mylistclass = NULL; static const char *titles[] = {"Header 1", "Header 2", "Header 3", "Header 4", NULL}; struct mylistinfo { struct Hook DisplayHook; struct Hook CompareHook; Object *obj; }; #define MYREG(x) register __ ## x #define ASM __asm #define SAVEDS __saveds #define FUNC_HOOK(ret, name, htype, hook, dtype, data, mtype, msg) \ __asm __interrupt __saveds static ret name (register __a0 htype hook, register __a2 dtype data, register __a1 mtype msg) #define DISPATCHER_ENTRY(name) #define ENTRY(name) name #define HOOKENTRY(name) (HOOKFUNC)##name #define PROCGATE(name) #define GETNPENTRY(name) (ULONG)##name #define HOOK_INIT #define HOOK_EXIT #ifndef MUIA_List_TitleClick #define MUIA_List_TitleClick 0x80422fd9 /* V20 ..g LONG */ #endif #ifndef MUIA_List_SortColumn #define MUIA_List_SortColumn 0x8042cafb // V21 #endif FUNC_HOOK(APTR, MyList_ConstructFunc, struct Hook *, hook, APTR, pool, STRPTR *, entry) { STRPTR *dest; STRPTR ptr; int c, len = 0; for(c = 0; entry[c]; c++) len += strlen(entry[c]) + 1; if(!(dest = AllocVec((c + 1) * sizeof(STRPTR) + len, MEMF_ANY))) return NULL; ptr = ((UBYTE *) dest) + (c + 1) * sizeof(STRPTR); for(c = 0; entry[c]; c++) { dest[c] = ptr; strcpy(dest[c], entry[c]); ptr += strlen(entry[c]) + 1; } dest[c] = NULL; return dest; } FUNC_HOOK(VOID, MyList_DestructFunc, struct Hook *, hook, APTR, pool, STRPTR, entry) { FreeVec(entry); } FUNC_HOOK(LONG, MyList_DisplayFunc, struct Hook *, hook, char **, array, STRPTR *, entry) { HOOK_INIT if(entry) { int c; for(c = 0; entry[c]; c++) *array++ = entry[c]; } else { int k; for(k = 0; k < 4; k++) *array++ = (STRPTR) titles[k]; } return 0; HOOK_EXIT } FUNC_HOOK(LONG, MyList_CompareFunc, struct Hook *, hook, STRPTR *, entry2, STRPTR *, entry1) { HOOK_INIT struct mylistinfo *data = (struct mylistinfo *) hook->h_Data; int sortcolumn = 0; get(data->obj, MUIA_List_SortColumn, &sortcolumn); return strcmp(entry1[sortcolumn], entry2[sortcolumn]); HOOK_EXIT } static ULONG MyList_New(struct IClass *cl, Object *obj, struct opSet *msg) { static struct Hook MyList_ConstructHook = { { 0,0 }, HOOKENTRY(MyList_ConstructFunc), NULL, NULL }; static struct Hook MyList_DestructHook = { { 0,0 }, HOOKENTRY(MyList_DestructFunc) , NULL, NULL }; ULONG tags[] = {MUIA_List_ConstructHook, (ULONG) &MyList_ConstructHook, MUIA_List_DestructHook , (ULONG) &MyList_DestructHook, TAG_MORE, 0}; tags[5] = (ULONG) msg->ops_AttrList; obj = (Object *) DoSuperMethod(cl, obj, OM_NEW, tags, NULL); if(obj) { struct mylistinfo *data = INST_DATA(cl, obj); data->obj = obj; data->DisplayHook.h_Entry = HOOKENTRY(MyList_DisplayFunc); data->DisplayHook.h_Data = (APTR) data; set(obj, MUIA_List_DisplayHook, &data->DisplayHook); data->CompareHook.h_Entry = HOOKENTRY(MyList_CompareFunc); data->CompareHook.h_Data = (APTR) data; set(obj, MUIA_List_CompareHook, &data->CompareHook); } return (ULONG) obj; } SAVEDS ASM ULONG MyListDispatcher(MYREG(a0) struct IClass *cl, MYREG(a2) Object *obj, MYREG(a1) Msg msg) { switch(msg->MethodID) { case OM_NEW: return MyList_New(cl, obj, (APTR) msg); } return DoSuperMethodA(cl, obj, msg); } int main(int argc, char *argv[]) { Object *win, *app, *lv, *but; ULONG sigs = 0; ULONG id; STRPTR entry0[] = {"A", "H", "Z", "Vier", NULL}; STRPTR entry1[] = {"B", "G", "Y", "Vier", NULL}; STRPTR entry2[] = {"C", "F", "X", "Vier", NULL}; STRPTR entry3[] = {"D", "E", "W", "Vier", NULL}; int k; IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 0); MUIMasterBase = OpenLibrary("muimaster.library", 0); mylistclass = MUI_CreateCustomClass(NULL, MUIC_List, NULL, sizeof(struct mylistinfo), (APTR) ENTRY(MyListDispatcher)); app = ApplicationObject, MUIA_Application_Title, "Foo", MUIA_Application_Base, "xxxxx", SubWindow, win = WindowObject, MUIA_Window_Title, "Bar", WindowContents, VGroup, Child, VGroup, GroupFrameT("hmm"), Child, lv = ListviewObject, MUIA_Listview_List, NewObject(mylistclass->mcc_Class, NULL, InputListFrame, MUIA_List_Format, "MINWIDTH=100px,MINWIDTH=100px,,", // MUIA_List_Title, 1, MUIA_List_SortColumn, 2, End, End, Child, but = SimpleButton("Click"), End, End, End, End; DoMethod(win, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); DoMethod(but, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, 1000); DoMethod(lv, MUIM_List_InsertSingle, entry0, MUIV_List_Insert_Sorted); DoMethod(lv, MUIM_List_InsertSingle, entry1, MUIV_List_Insert_Sorted); DoMethod(lv, MUIM_List_InsertSingle, entry2, MUIV_List_Insert_Sorted); DoMethod(lv, MUIM_List_InsertSingle, entry3, MUIV_List_Insert_Sorted); // set(lv, MUIA_List_SortColumn, 2); set(win, MUIA_Window_Open, TRUE); while((id = DoMethod(app,MUIM_Application_NewInput,&sigs)) != MUIV_Application_ReturnID_Quit) { if(id == 1000) set(lv, MUIA_List_SortColumn, 2); if(sigs) { sigs = Wait(sigs | SIGBREAKF_CTRL_C); if (sigs & SIGBREAKF_CTRL_C) break; } } MUI_DisposeObject(app); MUI_DeleteCustomClass(mylistclass); if(MUIMasterBase) CloseLibrary(MUIMasterBase); if(IntuitionBase) CloseLibrary((struct Library *) IntuitionBase); return 0; }