Page 2 of 2

Re: ListIconGadget sort on column

Posted: Sat Oct 02, 2010 2:00 pm
by Shardik
Andre wrote:Anyone already adapted such an example code (for sorting by listicon header) to MacOS?

Code: Select all

EnableExplicit

ImportC ""
  DisposeDataBrowserItemCompareUPP(*DataBrowserItemCompareCallback)
  GetDataBrowserCallbacks(DataBrowser.L, *DataBrowserCallbacks)
  GetDataBrowserPropertyFlags(DataBrowser.L, ColumnPropertyID.L, ColumnPropertyFlags.L)
  GetDataBrowserTableViewColumnPosition(DataBrowser.L, ColumnPropertyID, *ColumnIndex.L)
  GetDataBrowserTableViewColumnProperty(DataBrowser.L, ColumnIndex.L, *ColumnPropertyID)
  InitDataBrowserCallbacks(*DataBrowserCallbacks)
  NewDataBrowserItemCompareUPP(*DataBrowserItemCompareCallback)
  SetDataBrowserCallbacks(DataBrowser.L, *DataBrowserCallbacks)
  SetDataBrowserHasScrollBars(DataBrowser.L, HasHorizontalScrollbar.L, HasVerticalScrollbar.L)
  SetDataBrowserPropertyFlags(DataBrowser.L, ColumnPropertyID.L, ColumnPropertyFlags.L)
  SetDataBrowserSortOrder(DataBrowser.L, SortOrder.L)
  SetDataBrowserSortProperty(DataBrowser.L, ColumnPropertyID.L)
EndImport

#kDataBrowserLatestCallbacks = 0
#kDataBrowserViewSpecificFlagsOffset = 16
#kDataBrowserListViewSortableColumn = 1 << (#kDataBrowserViewSpecificFlagsOffset + 2)
#kDataBrowserOrderIncreasing = 1
#kDataBrowserOrderDecreasing = 2
#noErr = 0

Structure DataBrowserCallbacks
  Version.L
  DataBrowserItemDataUPP.L
  DataBrowserItemCompareUPP.L
  DataBrowserItemNotificationUPP.L
  DataBrowserAddDragItemUPP.L
  DataBrowserAcceptDragUPP.L
  DataBrowserReceiveDragUPP.L
  DataBrowserPostProcessDragUPP.L
  DataBrowserItemHelpContentUPP.L
  DataBrowserGetContextualMenuUPP.L
  DataBrowserSelectContextualMenuUPP.L
EndStructure

Define ColumnPropertyFlags.L
Define ColumnPropertyID.L
Define DataBrowserCallbacks.DataBrowserCallbacks
Define *DataBrowserItemCompareUPP
Define i.I

; ----- Item-comparison callback for row sort

Procedure DataBrowserItemCompareCallback(DataBrowser.L, Item1ID.L, Item2ID.L, ColumnPropertyID.L)
  Protected ColumnIndex.L

  If GetDataBrowserTableViewColumnPosition(DataBrowser, ColumnPropertyID, @ColumnIndex) = #noErr
    If GetGadgetItemText(0, Item1ID - 1, ColumnIndex) < GetGadgetItemText(0, Item2ID - 1, ColumnIndex)
      ProcedureReturn #True
    Else
      ProcedureReturn #False
    EndIf
  EndIf
EndProcedure

OpenWindow(0, 100, 100, 422, 90, "Sort ListIcon on column click", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ListIconGadget(0, 5, 5, 412, 80, "Name", 115)
AddGadgetColumn(0, 1, "Address", 290)
AddGadgetItem(0, -1, "Harry Rannit" + #LF$ + "22 Parliament Way, Battle Street, By the Bay")
AddGadgetItem(0, -1, "Didi Foundit"+ #LF$ + "321 Logo Drive, Mouse House, Downtown")
AddGadgetItem(0, -1, "Ginger Brokeit" + #LF$ + "130 PureBasic Road, BigTown, CodeCity")

Delay(10)

While WindowEvent()
Wend

; ----- Switch off horizontal and vertical scrollbars
SetDataBrowserHasScrollBars(GadgetID(0), #False, #False)

; ----- Initialize new item-comparison callback
DataBrowserCallbacks\version = #kDataBrowserLatestCallbacks

If InitDataBrowserCallbacks(@DataBrowserCallbacks) = #noErr
  *DataBrowserItemCompareUPP = NewDataBrowserItemCompareUPP(@DataBrowserItemCompareCallback())
  DataBrowserCallbacks\DataBrowserItemCompareUPP = *DataBrowserItemCompareUPP

  If SetDataBrowserCallbacks(GadgetID(0), @DataBrowserCallbacks) = #noErr
    ; ----- Set Sortable Flag for column 0 and 1
    For i = 1 To 0 Step -1
      GetDataBrowserTableViewColumnProperty(GadgetID(0), i, @ColumnPropertyID)
      GetDataBrowserPropertyFlags(GadgetID(0), ColumnPropertyID, @ColumnPropertyFlags)
      ColumnPropertyFlags ! #kDataBrowserListViewSortableColumn
      SetDataBrowserPropertyFlags(GadgetID(0), ColumnPropertyID, ColumnPropertyFlags)
    Next i

    ; ----- Designate column 0 for sorting
    SetDataBrowserSortProperty(GadgetID(0), ColumnPropertyID)
    ; ----- Set sorting order to increasing
    SetDataBrowserSortOrder(GadgetID(0), #kDataBrowserOrderIncreasing)

    Repeat
      Select WaitWindowEvent()
        Case #PB_Event_CloseWindow
          Break
      EndSelect
    ForEver

    ; ----- Dispose procedure pointer to item-comparison callback
    DisposeDataBrowserItemCompareUPP(*DataBrowserItemCompareUPP)
  EndIf
EndIf

Re: ListIconGadget sort on column

Posted: Sun May 08, 2011 9:49 am
by jesperbrannmark
That is beatiful, but what happens if you add more items after the first sort? I cant get that to work - it all disappears - ie:

Code: Select all

;EnableExplicit

ImportC ""
  DisposeDataBrowserItemCompareUPP(*DataBrowserItemCompareCallback)
  GetDataBrowserCallbacks(DataBrowser.L, *DataBrowserCallbacks)
  GetDataBrowserPropertyFlags(DataBrowser.L, ColumnPropertyID.L, ColumnPropertyFlags.L)
  GetDataBrowserTableViewColumnPosition(DataBrowser.L, ColumnPropertyID, *ColumnIndex.L)
  GetDataBrowserTableViewColumnProperty(DataBrowser.L, ColumnIndex.L, *ColumnPropertyID)
  InitDataBrowserCallbacks(*DataBrowserCallbacks)
  NewDataBrowserItemCompareUPP(*DataBrowserItemCompareCallback)
  SetDataBrowserCallbacks(DataBrowser.L, *DataBrowserCallbacks)
  SetDataBrowserHasScrollBars(DataBrowser.L, HasHorizontalScrollbar.L, HasVerticalScrollbar.L)
  SetDataBrowserPropertyFlags(DataBrowser.L, ColumnPropertyID.L, ColumnPropertyFlags.L)
  SetDataBrowserSortOrder(DataBrowser.L, SortOrder.L)
  SetDataBrowserSortProperty(DataBrowser.L, ColumnPropertyID.L)
EndImport

#kDataBrowserLatestCallbacks = 0
#kDataBrowserViewSpecificFlagsOffset = 16
#kDataBrowserListViewSortableColumn = 1 << (#kDataBrowserViewSpecificFlagsOffset + 2)
#kDataBrowserOrderIncreasing = 1
#kDataBrowserOrderDecreasing = 2
#noErr = 0

Structure DataBrowserCallbacks
  Version.L
  DataBrowserItemDataUPP.L
  DataBrowserItemCompareUPP.L
  DataBrowserItemNotificationUPP.L
  DataBrowserAddDragItemUPP.L
  DataBrowserAcceptDragUPP.L
  DataBrowserReceiveDragUPP.L
  DataBrowserPostProcessDragUPP.L
  DataBrowserItemHelpContentUPP.L
  DataBrowserGetContextualMenuUPP.L
  DataBrowserSelectContextualMenuUPP.L
EndStructure

Define ColumnPropertyFlags.L
Define ColumnPropertyID.L
Define DataBrowserCallbacks.DataBrowserCallbacks
Define *DataBrowserItemCompareUPP
Define i.I

; ----- Item-comparison callback for row sort

Procedure DataBrowserItemCompareCallback(DataBrowser.L, Item1ID.L, Item2ID.L, ColumnPropertyID.L)
  Protected ColumnIndex.L
  
  If GetDataBrowserTableViewColumnPosition(DataBrowser, ColumnPropertyID, @ColumnIndex) = #noErr
    If GetGadgetItemText(0, Item1ID - 1, ColumnIndex) < GetGadgetItemText(0, Item2ID - 1, ColumnIndex)
      ProcedureReturn #True
    Else
      ProcedureReturn #False
    EndIf
  EndIf
EndProcedure

OpenWindow(0, 100, 100, 422, 90, "Sort ListIcon on column click", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ListIconGadget(0, 5, 5, 412, 80, "Name", 115)
AddGadgetColumn(0, 1, "Address", 290)
AddGadgetItem(0, -1, "Harry Rannit" + #LF$ + "22 Parliament Way, Battle Street, By the Bay")
AddGadgetItem(0, -1, "Didi Foundit"+ #LF$ + "321 Logo Drive, Mouse House, Downtown")
AddGadgetItem(0, -1, "Ginger Brokeit" + #LF$ + "130 PureBasic Road, BigTown, CodeCity")

Delay(10)

While WindowEvent()
Wend

; ----- Switch off horizontal and vertical scrollbars
SetDataBrowserHasScrollBars(GadgetID(0), #False, #False)

; ----- Initialize new item-comparison callback
DataBrowserCallbacks\version = #kDataBrowserLatestCallbacks

If InitDataBrowserCallbacks(@DataBrowserCallbacks) = #noErr
  *DataBrowserItemCompareUPP = NewDataBrowserItemCompareUPP(@DataBrowserItemCompareCallback())
  DataBrowserCallbacks\DataBrowserItemCompareUPP = *DataBrowserItemCompareUPP
  
  If SetDataBrowserCallbacks(GadgetID(0), @DataBrowserCallbacks) = #noErr
    ; ----- Set Sortable Flag for column 0 and 1
    For i = 1 To 0 Step -1
      GetDataBrowserTableViewColumnProperty(GadgetID(0), i, @ColumnPropertyID)
      GetDataBrowserPropertyFlags(GadgetID(0), ColumnPropertyID, @ColumnPropertyFlags)
      ColumnPropertyFlags ! #kDataBrowserListViewSortableColumn
      SetDataBrowserPropertyFlags(GadgetID(0), ColumnPropertyID, ColumnPropertyFlags)
    Next i
    
    ; ----- Designate column 0 for sorting
    SetDataBrowserSortProperty(GadgetID(0), ColumnPropertyID)
    ; ----- Set sorting order to increasing
    SetDataBrowserSortOrder(GadgetID(0), #kDataBrowserOrderIncreasing)
  EndIf
EndIf

; Add in some more shit - this is what I've added to the old code
AddGadgetItem(0, -1, "Monty Richi" + #LF$ + "trailer")
AddGadgetItem(0, -1, "Jakob Degree"+ #LF$ + "hotel")
AddGadgetItem(0, -1, "Mary Subaru" + #LF$ + "homeless")

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
  EndSelect
ForEver

; ----- Dispose procedure pointer to item-comparison callback
DisposeDataBrowserItemCompareUPP(*DataBrowserItemCompareUPP)

Re: ListIconGadget sort on column

Posted: Mon May 09, 2011 9:05 pm
by Shardik
jesperbrannmark wrote:That is beatiful, but what happens if you add more items after the first sort? I cant get that to work - it all disappears
Replace the line

Code: Select all

If InitDataBrowserCallbacks(@DataBrowserCallbacks) = #noErr
by

Code: Select all

If GetDataBrowserCallbacks(GadgetID(0), @DataBrowserCallbacks) = #noErr
In my original posting I initialized a complete new structure of DataBrowser
(= ListIcon) callbacks. But apparently PureBasic utilizes one or several of these
callbacks for its own purposes. If you request the callback structure by the API
call GetDataBrowserCallbacks() and change only the item comparison callback
for your sorting needs, your above mentioned problem will disappear... :wink:

This is your complete modified example with the above change:

Code: Select all

EnableExplicit

ImportC ""
  DisposeDataBrowserItemCompareUPP(*DataBrowserItemCompareCallback)
  GetDataBrowserCallbacks(DataBrowser.L, *DataBrowserCallbacks)
  GetDataBrowserPropertyFlags(DataBrowser.L, ColumnPropertyID.L, ColumnPropertyFlags.L)
  GetDataBrowserTableViewColumnPosition(DataBrowser.L, ColumnPropertyID, *ColumnIndex.L)
  GetDataBrowserTableViewColumnProperty(DataBrowser.L, ColumnIndex.L, *ColumnPropertyID)
  NewDataBrowserItemCompareUPP(*DataBrowserItemCompareCallback)
  SetDataBrowserCallbacks(DataBrowser.L, *DataBrowserCallbacks)
  SetDataBrowserHasScrollBars(DataBrowser.L, HasHorizontalScrollbar.L, HasVerticalScrollbar.L)
  SetDataBrowserPropertyFlags(DataBrowser.L, ColumnPropertyID.L, ColumnPropertyFlags.L)
  SetDataBrowserSortOrder(DataBrowser.L, SortOrder.L)
  SetDataBrowserSortProperty(DataBrowser.L, ColumnPropertyID.L)
EndImport

#kDataBrowserLatestCallbacks = 0
#kDataBrowserViewSpecificFlagsOffset = 16
#kDataBrowserListViewSortableColumn = 1 << (#kDataBrowserViewSpecificFlagsOffset + 2)
#kDataBrowserOrderIncreasing = 1
#noErr = 0

Structure DataBrowserCallbacks
  Version.L
  DataBrowserItemDataUPP.L
  DataBrowserItemCompareUPP.L
  DataBrowserItemNotificationUPP.L
  DataBrowserAddDragItemUPP.L
  DataBrowserAcceptDragUPP.L
  DataBrowserReceiveDragUPP.L
  DataBrowserPostProcessDragUPP.L
  DataBrowserItemHelpContentUPP.L
  DataBrowserGetContextualMenuUPP.L
  DataBrowserSelectContextualMenuUPP.L
EndStructure

Define ColumnPropertyFlags.L
Define ColumnPropertyID.L
Define DataBrowserCallbacks.DataBrowserCallbacks
Define *DataBrowserItemCompareUPP
Define i.I

; ----- Item-comparison callback for row sort

Procedure DataBrowserItemCompareCallback(DataBrowser.L, Item1ID.L, Item2ID.L, ColumnPropertyID.L)
  Protected ColumnIndex.L
 
  If GetDataBrowserTableViewColumnPosition(DataBrowser, ColumnPropertyID, @ColumnIndex) = #noErr
    If GetGadgetItemText(0, Item1ID - 1, ColumnIndex) < GetGadgetItemText(0, Item2ID - 1, ColumnIndex)
      ProcedureReturn #True
    Else
      ProcedureReturn #False
    EndIf
  EndIf
EndProcedure

OpenWindow(0, 100, 100, 422, 150, "Sort ListIcon on column click", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ListIconGadget(0, 5, 5, 412, 140, "Name", 115)
AddGadgetColumn(0, 1, "Address", 290)
AddGadgetItem(0, -1, "Harry Rannit" + #LF$ + "22 Parliament Way, Battle Street, By the Bay")
AddGadgetItem(0, -1, "Didi Foundit"+ #LF$ + "321 Logo Drive, Mouse House, Downtown")
AddGadgetItem(0, -1, "Ginger Brokeit" + #LF$ + "130 PureBasic Road, BigTown, CodeCity")

Delay(10)

While WindowEvent()
Wend

; ----- Switch off horizontal and vertical scrollbars
SetDataBrowserHasScrollBars(GadgetID(0), #False, #False)

; ----- Initialize new item-comparison callback
DataBrowserCallbacks\version = #kDataBrowserLatestCallbacks

If GetDataBrowserCallbacks(GadgetID(0), @DataBrowserCallbacks) = #noErr
  *DataBrowserItemCompareUPP = NewDataBrowserItemCompareUPP(@DataBrowserItemCompareCallback())
  DataBrowserCallbacks\DataBrowserItemCompareUPP = *DataBrowserItemCompareUPP
 
  If SetDataBrowserCallbacks(GadgetID(0), @DataBrowserCallbacks) = #noErr
    ; ----- Set Sortable Flag for column 0 and 1
    For i = 1 To 0 Step -1
      GetDataBrowserTableViewColumnProperty(GadgetID(0), i, @ColumnPropertyID)
      GetDataBrowserPropertyFlags(GadgetID(0), ColumnPropertyID, @ColumnPropertyFlags)
      ColumnPropertyFlags ! #kDataBrowserListViewSortableColumn
      SetDataBrowserPropertyFlags(GadgetID(0), ColumnPropertyID, ColumnPropertyFlags)
    Next i
   
    ; ----- Designate column 0 for sorting
    SetDataBrowserSortProperty(GadgetID(0), ColumnPropertyID)
    ; ----- Set sorting order to increasing
    SetDataBrowserSortOrder(GadgetID(0), #kDataBrowserOrderIncreasing)
  EndIf
EndIf

; Add in some more shit - this is what I've added to the old code
AddGadgetItem(0, -1, "Monty Richi" + #LF$ + "trailer")
AddGadgetItem(0, -1, "Jakob Degree"+ #LF$ + "hotel")
AddGadgetItem(0, -1, "Mary Subaru" + #LF$ + "homeless")

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
  EndSelect
ForEver

; ----- Dispose procedure pointer to item-comparison callback
DisposeDataBrowserItemCompareUPP(*DataBrowserItemCompareUPP)

Re: ListIconGadget sort on column

Posted: Thu Jun 16, 2011 1:48 pm
by jesperbrannmark
Hi all.
The mac version of listicongadget sort on column works extremely good for me.
The PC version keeps doing bad stuff (crash). It took me weeks before i realised it was this function making all that fuss. A simple procedurereturn 0 at the beginning of comparefunc solved the issue but also left me without sorting.
Here is a old fashion alternative that actually works. I dont aim to win the speed competition or best code... just to get a function that sorts:

Code: Select all

Global updown.l = 1, lastcol.l = 0
Global cols=3
Procedure sort(gadget,col)
  Global Dim ss.s(CountGadgetItems(gadget))  
  For i=0 To CountGadgetItems(gadget)-1
    ss.s(i)=GetGadgetItemText(gadget,i,lastcol)
    ss.s(i)+Space(100-Len(ss.s(i)))
    For o=0 To cols
      ss.s(i)+GetGadgetItemText(gadget,i,o)+Chr(10)
    Next
  Next
  i-1 
  SortArray(ss.s(),updown,0,i)
  ClearGadgetItems(gadget)
  For o=0 To i
    AddGadgetItem(gadget,-1,Right(ss.s(o),Len(ss.s(o))-100))  
  Next
  Global Dim ss.s(0)
EndProcedure
Procedure ColumnClickCallback(hwnd, msg, wParam, lParam) 
  result = #PB_ProcessPureBasicEvents 
  Select msg 
    Case #WM_NOTIFY 
      *msg.NMHDR = lParam 
      If *msg\hwndFrom = GadgetID(0) And *msg\code = #LVN_COLUMNCLICK 
        *pnmv.NM_LISTVIEW = lParam 
        If lastcol<>*pnmv\iSubItem And updown=0
          updown = 1 
        ElseIf lastcol<>*pnmv\iSubItem And updown=1
          updown=0
        EndIf
        lastcol = *pnmv\iSubItem 
        sort(0,lastcol)
        updown = 1
      EndIf 
  EndSelect
  ProcedureReturn result 
EndProcedure 

If OpenWindow(0, 384, 288, 640, 480, "ListIconGadget sort example", #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_SizeGadget) 
  ListIconGadget(0, 0, 0, 530, WindowHeight(0), "Column 0", 300, #PB_ListIcon_GridLines | #PB_ListIcon_FullRowSelect) 
  AddGadgetColumn(0, 1, "Column 1", 100) 
  AddGadgetColumn(0, 2, "Column 2", 100) 
  AddGadgetColumn(0, 3, "Column 3", 100) 
  AddGadgetItem(0, 0, "Aaa 1"+Chr(10)+"Bcc 3"+Chr(10)+"Cdd 2"+Chr(10)+"Eee 3"+Chr(10), 0) 
  AddGadgetItem(0, 1, "Aab 2"+Chr(10)+"Bbc 2"+Chr(10)+"Ddd 3"+Chr(10)+"Dde 1"+Chr(10), 0) 
  AddGadgetItem(0, 2, "Abb 3"+Chr(10)+"Baa 1"+Chr(10)+"Ccd 1"+Chr(10)+"Dee 2"+Chr(10), 0) 
  SetWindowCallback(@ColumnClickCallback()) 
  Repeat 
    EventID = WaitWindowEvent() 
  Until EventID = #PB_Event_CloseWindow 
EndIf 

End 

Re: ListIconGadget sort on column

Posted: Sun Aug 21, 2011 12:32 pm
by jesperbrannmark
Updated the code above.
Mac OS X Lion doesnt allow eventhandler as "procedure" but it need to be "procedurec" otherwise it crashes.

Code: Select all

EnableExplicit

ImportC ""
  DisposeDataBrowserItemCompareUPP(*DataBrowserItemCompareCallback)
  GetDataBrowserCallbacks(DataBrowser.L, *DataBrowserCallbacks)
  GetDataBrowserPropertyFlags(DataBrowser.L, ColumnPropertyID.L, ColumnPropertyFlags.L)
  GetDataBrowserTableViewColumnPosition(DataBrowser.L, ColumnPropertyID, *ColumnIndex.L)
  GetDataBrowserTableViewColumnProperty(DataBrowser.L, ColumnIndex.L, *ColumnPropertyID)
  NewDataBrowserItemCompareUPP(*DataBrowserItemCompareCallback)
  SetDataBrowserCallbacks(DataBrowser.L, *DataBrowserCallbacks)
  SetDataBrowserHasScrollBars(DataBrowser.L, HasHorizontalScrollbar.L, HasVerticalScrollbar.L)
  SetDataBrowserPropertyFlags(DataBrowser.L, ColumnPropertyID.L, ColumnPropertyFlags.L)
  SetDataBrowserSortOrder(DataBrowser.L, SortOrder.L)
  SetDataBrowserSortProperty(DataBrowser.L, ColumnPropertyID.L)
EndImport

#kDataBrowserLatestCallbacks = 0
#kDataBrowserViewSpecificFlagsOffset = 16
#kDataBrowserListViewSortableColumn = 1 << (#kDataBrowserViewSpecificFlagsOffset + 2)
#kDataBrowserOrderIncreasing = 1
#noErr = 0

Structure DataBrowserCallbacks
  Version.L
  DataBrowserItemDataUPP.L
  DataBrowserItemCompareUPP.L
  DataBrowserItemNotificationUPP.L
  DataBrowserAddDragItemUPP.L
  DataBrowserAcceptDragUPP.L
  DataBrowserReceiveDragUPP.L
  DataBrowserPostProcessDragUPP.L
  DataBrowserItemHelpContentUPP.L
  DataBrowserGetContextualMenuUPP.L
  DataBrowserSelectContextualMenuUPP.L
EndStructure

Define ColumnPropertyFlags.L
Define ColumnPropertyID.L
Define DataBrowserCallbacks.DataBrowserCallbacks
Define *DataBrowserItemCompareUPP
Define i.I

; ----- Item-comparison callback for row sort

Procedurec DataBrowserItemCompareCallback(DataBrowser.L, Item1ID.L, Item2ID.L, ColumnPropertyID.L)
  Protected ColumnIndex.L

  If GetDataBrowserTableViewColumnPosition(DataBrowser, ColumnPropertyID, @ColumnIndex) = #noErr
    If GetGadgetItemText(0, Item1ID - 1, ColumnIndex) < GetGadgetItemText(0, Item2ID - 1, ColumnIndex)
      ProcedureReturn #True
    Else
      ProcedureReturn #False
    EndIf
  EndIf
EndProcedure

OpenWindow(0, 100, 100, 422, 150, "Sort ListIcon on column click", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ListIconGadget(0, 5, 5, 412, 140, "Name", 115)
AddGadgetColumn(0, 1, "Address", 290)
AddGadgetItem(0, -1, "Harry Rannit" + #LF$ + "22 Parliament Way, Battle Street, By the Bay")
AddGadgetItem(0, -1, "Didi Foundit"+ #LF$ + "321 Logo Drive, Mouse House, Downtown")
AddGadgetItem(0, -1, "Ginger Brokeit" + #LF$ + "130 PureBasic Road, BigTown, CodeCity")

Delay(10)

While WindowEvent()
Wend

; ----- Switch off horizontal and vertical scrollbars
SetDataBrowserHasScrollBars(GadgetID(0), #False, #False)

; ----- Initialize new item-comparison callback
DataBrowserCallbacks\version = #kDataBrowserLatestCallbacks

If GetDataBrowserCallbacks(GadgetID(0), @DataBrowserCallbacks) = #noErr
  *DataBrowserItemCompareUPP = NewDataBrowserItemCompareUPP(@DataBrowserItemCompareCallback())
  DataBrowserCallbacks\DataBrowserItemCompareUPP = *DataBrowserItemCompareUPP

  If SetDataBrowserCallbacks(GadgetID(0), @DataBrowserCallbacks) = #noErr
    ; ----- Set Sortable Flag for column 0 and 1
    For i = 1 To 0 Step -1
      GetDataBrowserTableViewColumnProperty(GadgetID(0), i, @ColumnPropertyID)
      GetDataBrowserPropertyFlags(GadgetID(0), ColumnPropertyID, @ColumnPropertyFlags)
      ColumnPropertyFlags ! #kDataBrowserListViewSortableColumn
      SetDataBrowserPropertyFlags(GadgetID(0), ColumnPropertyID, ColumnPropertyFlags)
    Next i
   
    ; ----- Designate column 0 for sorting
    SetDataBrowserSortProperty(GadgetID(0), ColumnPropertyID)
    ; ----- Set sorting order to increasing
    SetDataBrowserSortOrder(GadgetID(0), #kDataBrowserOrderIncreasing)
  EndIf
EndIf

; Add in some more shit - this is what I've added to the old code
AddGadgetItem(0, -1, "Monty Richi" + #LF$ + "trailer")
AddGadgetItem(0, -1, "Jakob Degree"+ #LF$ + "hotel")
AddGadgetItem(0, -1, "Mary Subaru" + #LF$ + "homeless")

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
  EndSelect
ForEver

; ----- Dispose procedure pointer to item-comparison callback
DisposeDataBrowserItemCompareUPP(*DataBrowserItemCompareUPP)

Re: ListIconGadget sort on column

Posted: Thu Aug 02, 2012 1:34 pm
by jesperbrannmark
Is there any way of knowing the order that is presented on screen - ie if I would like to print this list or save it or something ?
I have included a "click" button that just debugs the gadgetitems in order, but the order is different to what is in the listicon.

Code: Select all

EnableExplicit

ImportC ""
  DisposeDataBrowserItemCompareUPP(*DataBrowserItemCompareCallback)
  GetDataBrowserCallbacks(DataBrowser.L, *DataBrowserCallbacks)
  GetDataBrowserPropertyFlags(DataBrowser.L, ColumnPropertyID.L, ColumnPropertyFlags.L)
  GetDataBrowserTableViewColumnPosition(DataBrowser.L, ColumnPropertyID, *ColumnIndex.L)
  GetDataBrowserTableViewColumnProperty(DataBrowser.L, ColumnIndex.L, *ColumnPropertyID)
  NewDataBrowserItemCompareUPP(*DataBrowserItemCompareCallback)
  SetDataBrowserCallbacks(DataBrowser.L, *DataBrowserCallbacks)
  SetDataBrowserHasScrollBars(DataBrowser.L, HasHorizontalScrollbar.L, HasVerticalScrollbar.L)
  SetDataBrowserPropertyFlags(DataBrowser.L, ColumnPropertyID.L, ColumnPropertyFlags.L)
  SetDataBrowserSortOrder(DataBrowser.L, SortOrder.L)
  SetDataBrowserSortProperty(DataBrowser.L, ColumnPropertyID.L)
EndImport

#kDataBrowserLatestCallbacks = 0
#kDataBrowserViewSpecificFlagsOffset = 16
#kDataBrowserListViewSortableColumn = 1 << (#kDataBrowserViewSpecificFlagsOffset + 2)
#kDataBrowserOrderIncreasing = 1
#noErr = 0

Structure DataBrowserCallbacks
  Version.L
  DataBrowserItemDataUPP.L
  DataBrowserItemCompareUPP.L
  DataBrowserItemNotificationUPP.L
  DataBrowserAddDragItemUPP.L
  DataBrowserAcceptDragUPP.L
  DataBrowserReceiveDragUPP.L
  DataBrowserPostProcessDragUPP.L
  DataBrowserItemHelpContentUPP.L
  DataBrowserGetContextualMenuUPP.L
  DataBrowserSelectContextualMenuUPP.L
EndStructure

Define ColumnPropertyFlags.L
Define ColumnPropertyID.L
Define DataBrowserCallbacks.DataBrowserCallbacks
Define *DataBrowserItemCompareUPP
Define i.I

; ----- Item-comparison callback for row sort

ProcedureC DataBrowserItemCompareCallback(DataBrowser.L, Item1ID.L, Item2ID.L, ColumnPropertyID.L)
  Protected ColumnIndex.L
  
  If GetDataBrowserTableViewColumnPosition(DataBrowser, ColumnPropertyID, @ColumnIndex) = #noErr
    If GetGadgetItemText(0, Item1ID - 1, ColumnIndex) < GetGadgetItemText(0, Item2ID - 1, ColumnIndex)
      ProcedureReturn #True
    Else
      ProcedureReturn #False
    EndIf
  EndIf
EndProcedure

OpenWindow(0, 100, 100, 422, 250, "Sort ListIcon on column click", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ListIconGadget(0, 5, 25, 412, 200, "Name", 115)
AddGadgetColumn(0, 1, "Address", 290)
AddGadgetItem(0, -1, "Harry Rannit" + #LF$ + "22 Parliament Way, Battle Street, By the Bay")
AddGadgetItem(0, -1, "Didi Foundit"+ #LF$ + "321 Logo Drive, Mouse House, Downtown")
AddGadgetItem(0, -1, "Ginger Brokeit" + #LF$ + "130 PureBasic Road, BigTown, CodeCity")


; ----- Switch off horizontal and vertical scrollbars
SetDataBrowserHasScrollBars(GadgetID(0), #False, #False)

; ----- Initialize new item-comparison callback
DataBrowserCallbacks\version = #kDataBrowserLatestCallbacks

If GetDataBrowserCallbacks(GadgetID(0), @DataBrowserCallbacks) = #noErr
  *DataBrowserItemCompareUPP = NewDataBrowserItemCompareUPP(@DataBrowserItemCompareCallback())
  DataBrowserCallbacks\DataBrowserItemCompareUPP = *DataBrowserItemCompareUPP
  
  If SetDataBrowserCallbacks(GadgetID(0), @DataBrowserCallbacks) = #noErr
    ; ----- Set Sortable Flag for column 0 and 1
    For i = 1 To 0 Step -1
      GetDataBrowserTableViewColumnProperty(GadgetID(0), i, @ColumnPropertyID)
      GetDataBrowserPropertyFlags(GadgetID(0), ColumnPropertyID, @ColumnPropertyFlags)
      ColumnPropertyFlags ! #kDataBrowserListViewSortableColumn
      SetDataBrowserPropertyFlags(GadgetID(0), ColumnPropertyID, ColumnPropertyFlags)
    Next i
    
    ; ----- Designate column 0 for sorting
    SetDataBrowserSortProperty(GadgetID(0), ColumnPropertyID)
    ; ----- Set sorting order to increasing
    SetDataBrowserSortOrder(GadgetID(0), #kDataBrowserOrderIncreasing)
  EndIf
EndIf
ButtonGadget(1,0,0,WindowWidth(0),24,"CLICK")
; Add in some more shit - this is what I've added to the old code
AddGadgetItem(0, -1, "Monty Richi" + #LF$ + "trailer")
AddGadgetItem(0, -1, "Jakob Degree"+ #LF$ + "hotel")
AddGadgetItem(0, -1, "Mary Subaru" + #LF$ + "homeless")

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      If EventGadget()=1
        For i=0 To CountGadgetItems(0)
          Debug GetGadgetItemText(0,i,0)+" / "+GetGadgetItemText(0,i,1)
        Next
      EndIf
  EndSelect
ForEver

; ----- Dispose procedure pointer to item-comparison callback
DisposeDataBrowserItemCompareUPP(*DataBrowserItemCompareUPP)

Re: ListIconGadget sort on column

Posted: Mon Aug 20, 2012 9:16 pm
by Shardik
jesperbrannmark wrote:I have included a "click" button that just debugs the gadgetitems in order, but the order is different to what is in the listicon.
Yes, unfortunately the sorted column items have a different order internally as displayed in the ListIconGadget. In fact they keep the same order as entered with AddGadgetItem() and the DataBrowser only works with pointers to the items.
jesperbrannmark wrote:Is there any way of knowing the order that is presented on screen - ie if I would like to print this list or save it or something ?
Yes, there is. I have implemented procedures to obtain the index of the currently sorted column and the current sort order (increasing or decreasing). I have taken a somewhat unelegant approach by reading the items of the current sorted column into an array, sorting its contents and displaying the items of the array instead of the items of the ListIconGadget. A more elegant (and performant) approach would be to modify the DataBrowserItemCompareCallback() and using SetGadgetItemData() to keep track of the sorted index of each item... :wink:

Code: Select all

EnableExplicit

ImportC ""
  DisposeDataBrowserItemCompareUPP(*DataBrowserItemCompareCallback)
  GetDataBrowserCallbacks(DataBrowser.L, *DataBrowserCallbacks)
  GetDataBrowserPropertyFlags(DataBrowser.L, ColumnPropertyID.L, ColumnPropertyFlags.L)
  GetDataBrowserSortOrder(DataBrowser.L, *SortOrder)
  GetDataBrowserSortProperty(DataBrowser.L, *SortColumnID)
  GetDataBrowserTableViewColumnPosition(DataBrowser.L, ColumnPropertyID, *ColumnIndex.L)
  GetDataBrowserTableViewColumnProperty(DataBrowser.L, ColumnIndex.L, *ColumnPropertyID)
  GetDataBrowserItemDataText(ItemDataRef.L, StringRef.L)
  NewDataBrowserItemCompareUPP(*DataBrowserItemCompareCallback)
  SetDataBrowserCallbacks(DataBrowser.L, *DataBrowserCallbacks)
  SetDataBrowserHasScrollBars(DataBrowser.L, HasHorizontalScrollbar.L, HasVerticalScrollbar.L)
  SetDataBrowserPropertyFlags(DataBrowser.L, ColumnPropertyID.L, ColumnPropertyFlags.L)
  SetDataBrowserSortOrder(DataBrowser.L, SortOrder.L)
  SetDataBrowserSortProperty(DataBrowser.L, ColumnPropertyID.L)
EndImport

#kDataBrowserLatestCallbacks = 0
#kDataBrowserViewSpecificFlagsOffset = 16
#kDataBrowserListViewSortableColumn = 1 << (#kDataBrowserViewSpecificFlagsOffset + 2)
#kDataBrowserOrderDecreasing = 2
#kDataBrowserOrderIncreasing = 1

Structure DataBrowserCallbacks
  Version.L
  DataBrowserItemDataUPP.L
  DataBrowserItemCompareUPP.L
  DataBrowserItemNotificationUPP.L
  DataBrowserAddDragItemUPP.L
  DataBrowserAcceptDragUPP.L
  DataBrowserReceiveDragUPP.L
  DataBrowserPostProcessDragUPP.L
  DataBrowserItemHelpContentUPP.L
  DataBrowserGetContextualMenuUPP.L
  DataBrowserSelectContextualMenuUPP.L
EndStructure

Define ColumnPropertyFlags.L
Define ColumnPropertyID.L
Define DataBrowserCallbacks.DataBrowserCallbacks
Define *DataBrowserItemCompareUPP
Define i.I
Define SortColumn.L

; ----- Item-comparison callback for row sort

Procedure DataBrowserItemCompareCallback(DataBrowser.L, Item1ID.L, Item2ID.L, ColumnPropertyID.L)
  Protected ColumnIndex.L
 
  If GetDataBrowserTableViewColumnPosition(DataBrowser, ColumnPropertyID, @ColumnIndex) = 0
    If GetGadgetItemText(0, Item1ID - 1, ColumnIndex) < GetGadgetItemText(0, Item2ID - 1, ColumnIndex)
      ProcedureReturn #True
    Else
      ProcedureReturn #False
    EndIf
  EndIf
EndProcedure

Procedure.L GetCurrentSortOrder(DataBrowserRef.L)
  Protected SortOrder.L
  Protected SortOrderText.S
  
  If GetDataBrowserSortOrder(DataBrowserRef, @SortOrder) = 0
    If SortOrder = #kDataBrowserOrderIncreasing
      SortOrderText = "increasing"
    Else
      SortOrderText = "decreasing"
    EndIf

    Debug "Sorting order: " + SortOrderText
    ProcedureReturn SortOrder
  EndIf
EndProcedure

Procedure.L GetCurrentSortColumn(DataBrowserRef.L)
  Protected SortColumnID.L
  Protected SortColumnIndex.L

  If GetDataBrowserSortProperty(DataBrowserRef, @SortColumnID) = 0
    If GetDataBrowserTableViewColumnPosition(DataBrowserRef, SortColumnID, @SortColumnIndex) = 0
      Debug "Current sort column: " + Str(SortColumnIndex)
      ProcedureReturn SortColumnIndex
    EndIf
  EndIf

  ProcedureReturn -1
EndProcedure

OpenWindow(0, 270, 100, 422, 120, "Sort ListIcon on column click")
ListIconGadget(0, 5, 5, 412, WindowHeight(0) - 40, "Name", 115)
AddGadgetColumn(0, 1, "Address", 290)
AddGadgetItem(0, -1, "Harry Rannit" + #LF$ + "22 Parliament Way, Battle Street, By the Bay")
AddGadgetItem(0, -1, "Didi Foundit"+ #LF$ + "321 Logo Drive, Mouse House, Downtown")
AddGadgetItem(0, -1, "Ginger Brokeit" + #LF$ + "130 PureBasic Road, BigTown, CodeCity")
ButtonGadget(1, 130, WindowHeight(0) - 30, WindowWidth(0) - 260, 20, "Display sorted column")

; ----- Switch off horizontal and vertical scrollbars
SetDataBrowserHasScrollBars(GadgetID(0), #False, #False)

; ----- Initialize new item-comparison callback
DataBrowserCallbacks\version = #kDataBrowserLatestCallbacks

If GetDataBrowserCallbacks(GadgetID(0), @DataBrowserCallbacks) = 0
  *DataBrowserItemCompareUPP = NewDataBrowserItemCompareUPP(@DataBrowserItemCompareCallback())
  DataBrowserCallbacks\DataBrowserItemCompareUPP = *DataBrowserItemCompareUPP
 
  If SetDataBrowserCallbacks(GadgetID(0), @DataBrowserCallbacks) = 0
    ; ----- Set Sortable Flag for column 0 and 1
    For i = 1 To 0 Step -1
      GetDataBrowserTableViewColumnProperty(GadgetID(0), i, @ColumnPropertyID)
      GetDataBrowserPropertyFlags(GadgetID(0), ColumnPropertyID, @ColumnPropertyFlags)
      ColumnPropertyFlags ! #kDataBrowserListViewSortableColumn
      SetDataBrowserPropertyFlags(GadgetID(0), ColumnPropertyID, ColumnPropertyFlags)
    Next i
   
    ; ----- Designate column 0 for sorting
    SetDataBrowserSortProperty(GadgetID(0), ColumnPropertyID)
    ; ----- Set sorting order to increasing
    SetDataBrowserSortOrder(GadgetID(0), #kDataBrowserOrderIncreasing)
  EndIf
EndIf

Dim ColumnItem.S(CountGadgetItems(0) - 1)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case  #PB_Event_Gadget
      If EventGadget() = 1
        If EventType() = #PB_EventType_LeftClick
          SortColumn = GetCurrentSortColumn(GadgetID(0))

          If SortColumn <> -1
            For i = 0 To CountGadgetItems(0) - 1
              ColumnItem(i) = GetGadgetItemText(0, i, SortColumn)
            Next i

            Select GetCurrentSortOrder(GadgetID(0))
              Case #kDataBrowserOrderIncreasing
                SortArray(ColumnItem(), #PB_Sort_Ascending)
              Case #kDataBrowserOrderDecreasing
                SortArray(ColumnItem(), #PB_Sort_Descending)
            EndSelect

            For i = 0 To CountGadgetItems(0) - 1
              Debug ColumnItem(i)
            Next i
            
            Debug ""
          EndIf
        EndIf
      EndIf
  EndSelect
ForEver

; ----- Dispose procedure pointer to item-comparison callback
DisposeDataBrowserItemCompareUPP(*DataBrowserItemCompareUPP)