It's very, very far away

It's very, very far away
You convinced me. I updated the code with your logic.ChrisR wrote: Tue Feb 25, 2025 6:40 pmYeah, it depends on how you see it:Zapman wrote: Tue Feb 25, 2025 6:04 pm I totally agree that the consequence (down arrow for ascending sorting) can seem inverted for certains. But an arrow pointing to the sky when values grow from up to down is too weird for me![]()
An arrow pointing to the sky.
Or an arrow smaller at top, larger at bottom for ascending sorting from smallest to largest value, as in Explorer
![]()
Code: Select all
;*****************************************************************************
;
; ColumnSortedListIconGadget.pbi
; Zapman - Feb 2025-7 - Windows Only
;
; This file must be saved under the name 'ColumnSortedListIconGadget.pbi'
;
; This library provides functionality to add sorting capabilities
; to a ListIconGadget, including sorting based on ascending or descending
; order, and displaying arrows for sorting in the header.
; The library can also be used to remove accents from text for proper sorting.
;
;*****************************************************************************
;
CompilerIf #PB_Compiler_IsMainFile
EnableExplicit
CompilerEndIf
;
; To sort items by date, the local date format is needed.
; Adapt the following if necessary:
;
Global DateFormat$ = Space(255) ; Create a buffer to get the local date format:
GetLocaleInfo_(#LOCALE_USER_DEFAULT, #LOCALE_SSHORTDATE, @DateFormat$, Len(DateFormat$))
Global DateSeparator$ = Space(4)
GetLocaleInfo_(#LOCALE_USER_DEFAULT, #LOCALE_SDATE, @DateSeparator$, Len(DateSeparator$))
DateFormat$ = "%" + LCase(ReplaceString(DateFormat$, DateSeparator$, DateSeparator$ + "%"))
DateFormat$ = ReplaceString(DateFormat$, "%d" + DateSeparator$, "%dd" + DateSeparator$)
DateFormat$ = ReplaceString(DateFormat$, "%m" + DateSeparator$, "%mm" + DateSeparator$)
;
; To sort items by floating numbers, the local decimal separator is needed.
; Adapt the following if necessary:
;
Global DecimalSeparator$ = Space(2) ; Create a buffer to get the local decimal separator
GetLocaleInfo_(#LOCALE_USER_DEFAULT, #LOCALE_SDECIMAL, @DecimalSeparator$, Len(DecimalSeparator$))
;
; You can also decide how you want the sorts to be done:
;
Global RemoveAccentsWhenSorting = #True
Global NoCaseSorting = #True
;
; ****************************************************************************************
;
;- 1--- FIRST PART: MISCELLANEOUS FUNCTIONS (possibly reusable for other needs) ---
;
CompilerIf Not(Defined(RemoveAccents, #PB_Procedure))
Procedure.s RemoveAccents(Text$)
; Function to remove accents from a string. By Zapman.
If Text$
Protected length = Len(Text$) * 2
Protected char$, ct, Result$
Protected NormalizedText$ = Space(Length)
;
Length = FoldString_(#MAP_COMPOSITE, @Text$, - 1, @NormalizedText$, Length) - 1
;
If Length > 0 And Length <> Len(Text$)
For ct = 1 To Length
char$ = Mid(NormalizedText$, ct, 1)
If Asc(char$) < 128
Result$ + char$
EndIf
Next
Else
Result$ = Text$
EndIf
;
ProcedureReturn Result$
EndIf
EndProcedure
CompilerEndIf
;
; ****************************************************************************************
;
;- 2--- SECOND PART: SPECIALIZED FUNCTIONS FOR THIS LIBRARY ---
;
; Enumeration to define the sort type:
Enumeration CSLI_SortType
#CSLI_Descent ; Ascending sort.
#CSLI_Ascent ; Descending sort.
#CSLI_Unsorted ; No sorting (default).
EndEnumeration
;
Procedure CSLI_CreateListIconArrows(ArrowType)
;
; Function to create sorting arrow images (Up, Down, and Up-Down arrows).
;
Protected TSize = 16
Protected ASize = TSize / 4
Protected SX = TSize / 2 - ASize
Protected SY = TSize / 2
Protected NewImage = CreateImage(#PB_Any, TSize, TSize, 32, #PB_Image_Transparent)
Protected VASize, Color
;
If NewImage
If ArrowType = #CSLI_Ascent ; UpArrow.
VASize = -ASize
ElseIf ArrowType = #CSLI_Descent ; DownArrow.
VASize = ASize
SY - ASize + 1
ElseIf ArrowType = #CSLI_Unsorted ; UpDownArrow.
VASize = ASize
SY = TSize / 2 + 1
EndIf
If StartDrawing(ImageOutput(NewImage))
;
DrawingMode(#PB_2DDrawing_AlphaBlend)
Box(0, 0, TSize, TSize, 0) ; Transparent background.
;
If ArrowType = #CSLI_Unsorted
Color = RGBA(192, 192, 192, 255) ; Gray for unsorted.
Else
Color = RGBA(1, 1, 1, 255) ; Quasi-Black for sorted arrows.
; A 'Full-Black' (0, 0, 0, 255) is not used because the FillArea()
; function doesn't work with full-black.
EndIf
;
Line(SX, SY, ASize * 2 + 1, 1, Color) ; Draw the arrow shape.
Line(SX, SY, ASize, VASize, Color)
Line(SX + ASize, SY + VASize, ASize, - VASize, Color)
FillArea(SX + ASize, SY + VASize / 2, Color, Color)
If ArrowType = #CSLI_Unsorted
; A double arrow (UpDown) is drawn for #CSLI_Unsorted.
SY - ASize + 1
VASize = -ASize
Line(SX, SY, ASize * 2 + 1, 1, Color)
Line(SX, SY, ASize, VASize, Color)
Line(SX + ASize, SY + VASize, ASize, - VASize, Color)
FillArea(SX + ASize, SY + VASize / 2, Color, Color)
EndIf
StopDrawing()
EndIf
ProcedureReturn NewImage
EndIf
EndProcedure
;
Procedure CSLI_CreateListIconImgList(LIHandle)
;
; Function to create an image list for the ListIcon header.
;
Protected hHeader, hImgL, ct, Img
;
If IsGadget(LIHandle)
LIHandle = GadgetID(LIHandle) ; Get the control handle from the gadget's num.
EndIf
;
hHeader = SendMessage_(LIHandle, #LVM_GETHEADER, 0, 0)
If SendMessage_(hHeader, #HDM_GETIMAGELIST, 0, 0) = 0
hImgL = ImageList_Create_(16, 16, #ILC_COLOR32 | #ILC_MASK, 0, 0)
For ct = #CSLI_Descent To #CSLI_Unsorted
Img = CSLI_CreateListIconArrows(ct)
ImageList_Add_(hImgL, ImageID(Img), 0)
; Microsoft doc says to free the original image after adding it to the image list.
FreeImage(Img)
Next
SendMessage_(hHeader, #HDM_SETIMAGELIST, 0, hImgL)
EndIf
EndProcedure
;
Procedure CSLI_FreeImageListFromGadget(LIHandle)
;
; Destroy both image lists of a ListIconGadget.
;
; Retrieve and destroy the ImageList for list items (row icons)
Protected hImageList, hHeader, hHeaderImageList
;
hImageList = SendMessage_(LIHandle, #LVM_GETIMAGELIST, #LVSIL_NORMAL, 0)
If hImageList
ImageList_Destroy_(hImageList)
SendMessage_(LIHandle, #LVM_SETIMAGELIST, #LVSIL_NORMAL, 0)
EndIf
;
; Retrieve the handle of the header control
hHeader = SendMessage_(LIHandle, #LVM_GETHEADER, 0, 0)
If hHeader
; Retrieve and destroy the ImageList for the header (column icons)
hHeaderImageList = SendMessage_(hHeader, #HDM_GETIMAGELIST, 0, 0)
If hHeaderImageList
ImageList_Destroy_(hHeaderImageList)
SendMessage_(hHeader, #HDM_SETIMAGELIST, 0, 0)
EndIf
EndIf
EndProcedure
; Define structure for sorting information.
Structure SortInfoStruct
GadgetHandle.i
Column.l
AscentDescent.l
EndStructure
;
Procedure CSLI_ListIconSortCallback(*item1.long, *item2.long, *SortInfo.SortInfoStruct)
;
; Sorting callback function used by the ListIcon to compare items.
;
Protected A$ = Space(200), B$ = Space(200), A2$, A.q = 0, B.q = 0, lvi.LV_ITEM
Protected result = 0, AscentDescent
;
lvi\iSubItem = *SortInfo\Column
lvi\pszText = @A$
lvi\cchTextMax = 200
SendMessage_(*SortInfo\GadgetHandle, #LVM_GETITEMTEXT, *item1\l, @lvi)
lvi\pszText = @B$
SendMessage_(*SortInfo\GadgetHandle, #LVM_GETITEMTEXT, *item2\l, @lvi)
;
If A$ = B$
ProcedureReturn 0 ; Items are equal.
EndIf
;
; Determine if sorting is ascending or descending.
If *SortInfo\AscentDescent = #CSLI_Descent : AscentDescent = -1 : Else : AscentDescent = 1 : EndIf
;
; Sorting based on numeric or alphabetical values.
A$ = ReplaceString(A$, DecimalSeparator$, ".")
B$ = ReplaceString(B$, DecimalSeparator$, ".")
;
If FindString(A$, "0")
A2$ = ReplaceString(A$, "0", "")
If A2$ = "" Or A2$ = "." Or A2$ = "$"
A$ = "0"
EndIf
EndIf
;
If A$ = "0" Or Val(A$) > 0 Or Val(B$) > 0
A = Val(A$)
B = Val(B$)
EndIf
If ValF(A$) > A Or ValF(B$) > B
A = ValF(A$)
B = ValF(B$)
EndIf
If ValD(A$) > A Or ValD(B$) > B
A = ValD(A$)
B = ValD(B$)
EndIf
;
If CountString(A$, DateSeparator$) > 1 Or CountString(B$, DateSeparator$) > 1
If ParseDate(DateFormat$, A$) > ParseDate(DateFormat$, B$)
Result = AscentDescent
Else
Result = -AscentDescent
EndIf
ElseIf Abs(A) > 0 Or A$ = "0"
If A > B Or ValF(A$) > ValF(B$)
Result = AscentDescent
Else
Result = -AscentDescent
EndIf
Else
If RemoveAccentsWhenSorting
A$ = RemoveAccents(A$)
B$ = RemoveAccents(B$)
EndIf
If NoCaseSorting
A$ = LCase(A$)
B$ = LCase(B$)
EndIf
If A$ > B$
Result = AscentDescent
Else
Result = -AscentDescent
EndIf
EndIf
;
ProcedureReturn result
EndProcedure
;
Procedure CSLI_ListIconHideHeaderImages(LIHandle)
;
; Function to hide images in the ListIcon header (useful when arrows are hidden).
; It will keep the value stored in the columns by #LVM_SETCOLUMN
; (index of the current image for each column), but no image will be shown.
;
Protected NColumn, LVC.LVCOLUMN
;
If IsGadget(LIHandle)
LIHandle = GadgetID(LIHandle) ; Get the control handle from the gadget's num.
EndIf
;
While SendMessage_(LIHandle, #LVM_GETCOLUMN, NColumn, @LVC)
; Hide images
LVC\mask = #LVCF_FMT
LVC\fmt = #LVCFMT_COL_HAS_IMAGES
LVC\iImage = 0
SendMessage_(LIHandle, #LVM_SETCOLUMN, NColumn, @LVC)
NColumn + 1
Wend
EndProcedure
; Declare SortListIcon procedure:
Declare SortListIcon(LIHandle, column, AscentDescent)
;
Procedure CSLI_WinLIProc(hWnd, uMsg, wParam, lParam)
;
; Window callback procedure to handle ListIcon sorting interaction.
;
Protected NColumn, LVC.LVCOLUMN, LIHandle, AscentDescent
Protected *NMHDR.NMHDR, *NMLV.NMLISTVIEW
;
Select uMsg
Case #WM_NOTIFY
*NMHDR = lParam
If GetProp_(*NMHDR\hWndFrom, "CSLI_Sort")
; Handle sort operations on column click:
If *NMHDR\code = #LVN_COLUMNCLICK
*NMLV = lParam
LIHandle = *NMHDR\hWndFrom
; Retrieve actual image-index:
LVC\mask = #LVCF_IMAGE
SendMessage_(LIHandle, #LVM_GETCOLUMN, *NMLV\iSubItem, @LVC)
AscentDescent = LVC\iImage
; Switch the index:
If AscentDescent = #CSLI_Ascent
AscentDescent = #CSLI_Descent
Else
AscentDescent = #CSLI_Ascent
EndIf
;
; Set image-index to UpDown for all columns:
While SendMessage_(LIHandle, #LVM_GETCOLUMN, NColumn, @LVC)
LVC\iImage = #CSLI_Unsorted
SendMessage_(LIHandle, #LVM_SETCOLUMN, NColumn, @LVC)
NColumn + 1
Wend
;
If GetProp_(LIHandle, "CSLI_ShowArrow") = 0
; If CSLI_ShowArrow is not set, hide the images:
CSLI_ListIconHideHeaderImages(LIHandle)
EndIf
;
; Sort and update image-index for the clicked column.
; If CSLI_ShowArrow is set, this will update the shown image
; for the clicked column:
SortListIcon(LIHandle, *NMLV\iSubItem, AscentDescent)
;
ElseIf *NMHDR\code = #LVN_DELETEALLITEMS
; The ListIcon gadget is being destroyed.
; Clean the memory from images:
CSLI_FreeImageListFromGadget(*NMHDR\hWndFrom)
EndIf
EndIf
EndSelect
;
Protected CSLI_OldCallBack = GetProp_(hWnd, "CSLI_OldCallBack")
ProcedureReturn CallWindowProc_(CSLI_OldCallBack, hWnd, uMsg, wParam, lParam)
EndProcedure
;
; ****************************************************************************************
;
;- 3--- THIRD PART: MAIN FUNCTIONS OF THIS LIBRARY ---
;
; ****************************************************************************************
;
Procedure MakeListIconSortable(GadgetNum, TrueFalse = #True)
;
; Initialyze all the needed values of 'LIHandle' to allow it
; to be sortable.
;
Protected i.l, GadgetID, LVC.LVCOLUMN, NColumn, NItems
;
If IsGadget(GadgetNum)
Protected LIHandle = GadgetID(GadgetNum) ; Get the control handle from the gadget's num.
Else
LIHandle = GadgetNum
GadgetNum = GetProp_(LIHandle, "PB_ID") ; Get the gadget's num from its handle.
EndIf
;
If IsGadget(GadgetNum) And GadgetType(GadgetNum) = #PB_GadgetType_ListIcon ; Ensure it's a valid ListIcon gadget.
If TrueFalse ; Check if sorting should be enabled.
NItems = SendMessage_(LIHandle, #LVM_GETITEMCOUNT, 0, 0) ; Get the number of items in the ListIcon.
For i = 0 To NItems - 1 ; Loop through all the items:
SetGadgetItemData(GadgetNum, i, i) ; Set the item data to its index for sorting purposes.
Next
SetProp_(LIHandle, "CSLI_Sort", 1) ; Store the sorting state in the ListIcon handle property.
; This will allow to know that this gadget had been made sortable.
CSLI_CreateListIconImgList(LIHandle); Create the image list for sorting icons.
If GetProp_(LIHandle, "CSLI_ShowArrow") ; If the sorting arrow is enabled...
NColumn = 0
While SendMessage_(LIHandle, #LVM_GETCOLUMN, NColumn, @LVC)
LVC\mask = #LVCF_IMAGE ; Set the column to use image (for sorting arrows).
LVC\iImage = #CSLI_Unsorted ; Set the initial sorting state as unsorted.
SendMessage_(LIHandle, #LVM_SETCOLUMN, NColumn, @LVC) ; Set the column information.
NColumn + 1
Wend
Else
CSLI_ListIconHideHeaderImages(LIHandle) ; If CSLI_ShowArrow is not set, hide the header images.
EndIf
;
Protected hWnd = GetAncestor_(LIHandle, #GA_ROOT) ; Get the root window handle for the ListIcon.
Protected CSLI_OldCallBack = GetProp_(hWnd, "CSLI_OldCallBack") ; Retrieve the CSLI_OldCallBack procedure if any.
If CSLI_OldCallBack = 0 ; If there's no existing CSLI_OldCallBack, set it:
CSLI_OldCallBack = SetWindowLongPtr_(hWnd, #GWL_WNDPROC, @CSLI_WinLIProc()) ; Set a custom window procedure.
SetProp_(hWnd, "CSLI_OldCallBack", CSLI_OldCallBack) ; Store the Oldcallback procedure address.
EndIf
Else ; If sorting is disabled
CSLI_ListIconHideHeaderImages(LIHandle) ; Hide any header images.
CSLI_FreeImageListFromGadget(LIHandle) ; Free the image list from the gadget.
hWnd = GetAncestor_(LIHandle, #GA_ROOT) ; Get the root window handle for the ListIcon.
CSLI_OldCallBack = GetProp_(hWnd, "CSLI_OldCallBack") ; Retrieve the old callback procedure.
If CSLI_OldCallBack ; If there was a custom callback set earlier...
; Reset to standard management:
SetWindowLongPtr_(hWnd, #GWL_WNDPROC, CSLI_OldCallBack) ; Restore the original window procedure.
RemoveProp_(hWnd, "CSLI_OldCallBack") ; Remove the stored callback address.
EndIf
EndIf
EndIf
EndProcedure
;
;https://www.purebasic.fr/english/viewtopic.php?t=55085
Procedure LIG_SetSortIcon(ListGadget.i, Column.i, SortOrder.i)
; http://stackoverflow.com/questions/254129/how-To-i-display-a-sort-arrow-in-the-header-of-a-List-view-column-using-c
Protected ColumnHeader.i
Protected ColumnCount.i
Protected hditem.HD_ITEM
Protected Cnt.i
#NoSort = 0
#AscSort = 1
#DescSort = 2
ColumnHeader = SendMessage_(GadgetID(ListGadget), #LVM_GETHEADER, 0, 0)
ColumnCount = SendMessage_(ColumnHeader, #HDM_GETITEMCOUNT, 0, 0)
For Cnt = 0 To ColumnCount - 1
hditem\mask = #HDI_FORMAT
If SendMessage_(ColumnHeader, #HDM_GETITEM, Cnt, @hditem) = 0
Debug "ERROR! LIG_SetSortIcon 1"
EndIf
hditem\mask = #HDI_FORMAT
If (Cnt = Column And SortOrder <> #NoSort)
Select SortOrder
Case #AscSort ; wenn aufsteigend sortiert werden soll
hditem\fmt & ~#HDF_SORTDOWN
hditem\fmt | #HDF_SORTUP
Debug "sortup"
Case #DescSort
hditem\fmt & ~#HDF_SORTUP
hditem\fmt | #HDF_SORTDOWN
Debug "sortdown"
EndSelect
Else
hditem\fmt & ~#HDF_SORTUP
hditem\fmt & ~#HDF_SORTDOWN
EndIf
If (SendMessage_(ColumnHeader, #HDM_SETITEM, Cnt, @hditem) = 0)
Debug "ERROR! LIG_SetSortIcon 2"
EndIf
Next
EndProcedure
Procedure.b LIG_GetSortOrder(ListGadget.i, Column.i)
Protected ColumnHeader.i
Protected hditem.HD_ITEM
Protected RetVal.b
ColumnHeader = SendMessage_(GadgetID(ListGadget), #LVM_GETHEADER, 0, 0)
hditem\mask = #HDI_FORMAT
If SendMessage_(ColumnHeader, #HDM_GETITEM, Column, @hditem)
If (hditem\fmt & #HDF_SORTUP) = #HDF_SORTUP
RetVal = #AscSort
ElseIf (hditem\fmt & #HDF_SORTDOWN) = #HDF_SORTDOWN
RetVal = #DescSort
Else
RetVal = #NoSort
EndIf
Else
Debug "ERROR! LIG_GetSortOrder"
RetVal = - 1
EndIf
ProcedureReturn RetVal
EndProcedure
Procedure SortListIcon(GadgetNum, column, AscentDescent)
;
; Sort the whole content of a ListIconGadget from one column values.
;
; column : from 0 to the last column number.
; AscentDescent : #CSLI_Descent for ascending, #CSLI_Ascent for descending.
;,,
Protected SortInfo.SortInfoStruct, LVC.LVCOLUMN, Order
;
If IsGadget(GadgetNum)
Protected LIHandle = GadgetID(GadgetNum) ; Get the control handle from the gadget's num.
Else
LIHandle = GadgetNum
GadgetNum = GetProp_(LIHandle, "PB_ID") ; Get the gadget's num from its handle.
EndIf
If IsGadget(GadgetNum) And GadgetType(GadgetNum) = #PB_GadgetType_ListIcon ; Ensure it's a ListIcon gadget
MakeListIconSortable(GadgetNum) ; Initialize the ListIcon gadget with sorting enabled.
If OSVersion() = #PB_OS_Windows_XP
#NoSort = 0
#AscSort = 1
#DescSort = 2
Select LIG_GetSortOrder(GadgetNum, column)
Case #NoSort, #DescSort
Order = #AscSort
Case #AscSort
Order = #DescSort
EndSelect
LIG_SetSortIcon(GadgetNum, column, Order)
EndIf
SortInfo\GadgetHandle = LIHandle ; Store the gadget handle in the sorting structure.
SortInfo\Column = column ; Store the column to be sorted in the sorting structure.
SortInfo\AscentDescent = AscentDescent ; Store the sorting order (ascending or descending).
SendMessage_(LIHandle, #LVM_SORTITEMS, @SortInfo, @CSLI_ListIconSortCallback()) ; Perform the sorting using the callback function.
;
; Update the image index for the column to reflect the sorting order.
LVC\mask = #LVCF_IMAGE ; Set the column to use an image (for the sorting arrow).
LVC\iImage = AscentDescent ; Set the image index based on the sorting order.
SendMessage_(LIHandle, #LVM_SETCOLUMN, column, @LVC) ; Set the updated column information.
;
If GetProp_(LIHandle, "CSLI_ShowArrow") = 0 ; If CSLI_ShowArrow is not enabled...
; Hide images in the columns.
; This will keep the value stored in the column by the preceeding #LVM_SETCOLUMN message
; (index of the current image for the column), but no image will be shown.
LVC\mask = #LVCF_FMT ; Set the column format to hide images:
LVC\fmt = #LVCFMT_COL_HAS_IMAGES
LVC\iImage = 0 ; Hide the image.
SendMessage_(LIHandle, #LVM_SETCOLUMN, column, @LVC) ; Apply the changes to the column.
EndIf
ProcedureReturn #True ; Return True to indicate success.
EndIf
EndProcedure
;
Procedure ShowListIconSortingArrows(LIHandle, ShowHide = #True)
;
; Hide or show the sorting arrows in the header of 'LIHandle'.
;
Protected Order, Column = 0
If IsGadget(LIHandle) ; Check if the provided handle is a valid gadget.
LIHandle = GadgetID(LIHandle) ; Get the control handle from the gadget's num.
EndIf
SetProp_(LIHandle, "CSLI_ShowArrow", ShowHide) ; Store whether the sorting arrows should be shown or hidden.
MakeListIconSortable(LIHandle) ; Re-initialize the ListIcon with the updated sorting arrows setting.
EndProcedure
;
; ****************************************************************************************
;
;- 4--- FORTH PART: DEMO PROCEDURE ---
;
; ****************************************************************************************
;
CompilerIf #PB_Compiler_IsMainFile
; The following won't run when this file is used as 'Included'.
Define HWindow = OpenWindow(#PB_Any, 0, 0, 485, 260, "Sortable ListIconGadget demo", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
;
Define SortListIconGagdetRef = ListIconGadget(#PB_Any, 0, 0, WindowWidth(HWindow), 225, "", 0, #PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection)
;
Define MakeListIconSortableCheckBox = CheckBoxGadget(#PB_Any, 10, WindowHeight(HWindow) - 30, 150, 22, "Make ListIcon Sortable")
SetGadgetState(MakeListIconSortableCheckBox, 1)
;
Define ShowListIconSortingArrowsCheckBox = CheckBoxGadget(#PB_Any, 200, WindowHeight(HWindow) - 30, 180, 22, "Show ListIcon Sorting Arrows")
SetGadgetState(ShowListIconSortingArrowsCheckBox, 1)
ShowListIconSortingArrows(SortListIconGagdetRef) ; <-- This will automatically set the ListIconGagdet to 'Sortable'.
; If you just want to make ListIconGagdet 'Sortable' without showing the arrows in the header,
; you can call 'MakeListIconSortable()' instead of ShowListIconSortingArrows().
;
AddGadgetColumn(SortListIconGagdetRef, 0, "Column 1", 150)
AddGadgetColumn(SortListIconGagdetRef, 1, "Column 2", 100)
AddGadgetColumn(SortListIconGagdetRef, 2, "Column 3", 100)
AddGadgetColumn(SortListIconGagdetRef, 3, "Column 4", 110)
;
Define mDate.q = Date()
Define a, A$, B$, C$, D$, x
;
For a = 0 To 8
A$ = "COLUMN 1, Row " + RSet(Str(a), 3, "0") + Chr(10)
If a = 0
A$ = "élève " + A$
EndIf
If a = 1
A$ = "devant " + A$
EndIf
If a = 2
A$ = "front " + A$
EndIf
If a = 3
A$ = "Absent " + A$
EndIf
If a = 4
A$ = "Final " + A$
EndIf
x = Random($FFFF)
B$ = RSet(Str(x), 5, "0") + Chr(10)
x = Random($7FFFFFFF)
C$ = "$" + RSet(Hex(x), 8, "0") + Chr(10)
D$ = FormatDate(DateFormat$, mDate)
mDate + 100000
AddGadgetItem(SortListIconGagdetRef, - 1, A$ + B$ + C$ + D$)
Next
;
SortListIcon(SortListIconGagdetRef, 0, #CSLI_Ascent)
;
Repeat
Define Event = WaitWindowEvent()
If Event = #PB_Event_Gadget
Select EventGadget()
Case MakeListIconSortableCheckBox
Define TrueFalse = GetGadgetState(MakeListIconSortableCheckBox)
SetGadgetState(ShowListIconSortingArrowsCheckBox, TrueFalse)
If TrueFalse
ShowListIconSortingArrows(SortListIconGagdetRef) ; <-- This will automatically call MakeListIconSortable(SortListIconGagdetRef, #True).
Else
MakeListIconSortable(SortListIconGagdetRef, #False)
EndIf
Case ShowListIconSortingArrowsCheckBox
TrueFalse = GetGadgetState(ShowListIconSortingArrowsCheckBox)
If TrueFalse
SetGadgetState(MakeListIconSortableCheckBox, #True)
EndIf
ShowListIconSortingArrows(SortListIconGagdetRef, TrueFalse)
EndSelect
EndIf
Until Event = #PB_Event_CloseWindow
CompilerEndIf
Very nice work, Mesa!
That's true.ebs wrote: Fri Feb 28, 2025 3:37 pm If "don't show arrows" is selected, the first click sorts in ascending order, but the second (and subsequent) clicks on the same header don't do anything.
You can relax
NopeLord wrote: Sat Mar 01, 2025 5:23 pm I'm just curios:
Why is "6:00 PM" greater than "16h30mn"?
Isn't "6:00PM" same as "16h00mn"?
So "6:00PM" should be lower than "16h30mn".
Of course.
Thanks again, Lord, for your accurate testing. This bug is fixed with the actual version.Lord wrote: Sat Mar 01, 2025 5:23 pmIf "Don't show arrows" is selected after arrows were allowed and sorting was used, the arrow remains visible.
Code: Select all
MakeListIconSortable(ListIconGadget, setting)