Clarion 9's list box sorting
Clarion 9 appears to add support for list box sorting, so I decided to give it a whirl. '
The new bits I'm aware of are some properties:
PROPLIST:DefHdrTextColor EQUATE (7C2AH) ! integer: Text color in header PROPLIST:DefHdrBackColor EQUATE (7C2BH) ! integer: Background color in header PROPLIST:HdrSortTextColor EQUATE (7C2CH) ! integer: Text color in header of sort column PROPLIST:HdrSortBackColor EQUATE (7C2DH) ! integer: Background color in header of sort column PROPLIST:SortTextColor EQUATE (7C2EH) ! integer: Text color of sort column PROPLIST:SortBackColor EQUATE (7C2FH) ! integer: Background color of sort column PROPLIST:HasSortColumn EQUATE (7C30H) ! boolean: TRUE if sort column is supported PROPLIST:SortColumn EQUATE (7C31H) ! integer: Current sort column
and a new event:
EVENT:HeaderPressed EQUATE (1FH)
I put together a small demo app:
PROGRAM MAP END INCLUDE('equates.clw'),ONCE DataQ QUEUE Column1 string(20) Column2 long Column3 string(20) END x LONG MyWindow WINDOW('Caption'),AT(,,336,285),GRAY,FONT('MS Sans Serif',8,,FONT:regular) BUTTON('&Close'),AT(287,262,36,14),USE(?CancelButton),LEFT LIST,AT(15,8,307,243),USE(?LIST),VSCROLL,FROM(dataq),FORMAT('100L(2)|M~C' & | 'olumn 1~100L(2)|M~Column 2~100L(2)|M~Column 3~') END CODE Â ! Create some dummy data loop 100 TIMES loop x = 1 to 20 DataQ.Column1[x] = chr(random(65,122)) DataQ.Column3[x] = chr(random(65,122)) END Dataq.Column2 = random(1,10000) add(dataq) END OPEN(MyWindow) ACCEPT case event() of EVENT:HeaderPressed 0{prop:text} = 'Current sort column: ' & ?list{PROPLIST:SortColumn} END CASE FIELD() OF 0 CASE EVENT() OF EVENT:OpenWindow END OF ?CancelButton CASE EVENT() OF EVENT:Accepted POST(EVENT:CloseWindow) END END END
I ran the app, but I didn't notice anything different about the list box. It didn't sort on columns or produce any header pressed events. For a moment I thought maybe I needed an IMM attribute, but of course that removes all of the built in event handling including scrolling, so I took it right back off again.Â
Here's the sample app:
Then I realized that I was missing the PROPLIST assignments in my code. I added them to the OpenWindow event handling:
CASE EVENT() OF EVENT:OpenWindow ?list{PROPLIST:HasSortColumn,1} = true ?list{PROPLIST:HasSortColumn,2} = true ?list{PROPLIST:HasSortColumn,3} = true END
That triggered EVENT:HeaderPressed, but no automatic sorting. Well, that's not a big deal. I added this code:
case ?list{PROPLIST:SortColumn} of 1 sort(dataq,dataq.Column1) of 2 sort(dataq,dataq.Column2) of 3 sort(dataq,dataq.Column3) END
Presto - list box sorting:
I also added some code to set PROPLIST:HdrSortTextColor and PROPLIST:SortTextColor for visual clues.Â
But there are some oddities. Header coloring isn't always cleared when you select another column, and at the start all column headers are colored. Also the first click on a header changes the color, but the sorting doesn't happen until the second click, which can happen at any time after the first click (i.e. it's not a true double click). Here I've clicked on Column 2 but the sort order is still Column 3.Â
After playing around with this a bit more I realized that the problem is that PROPLIST:SortColumn doesn't return the column you just selected, it returns the column previously set as the sort column. Either there's a bug there or I'm handling the event wrong.Â
There doesn't seem to be any way internally to track the state of the sort order (i.e. if you want ascending/descending), so at present you'd need to do that in your own code. Also I don't see a means to add an image to indicate the sort order. There are ways to do that already, as Randy Rogers showed in ClarionMag, but they're non-trivial.Â
While not a complete solution to sorting list boxes, Clarion 9 offers a good if slightly buggy start. I'd love to see a property for a sort order indicator image and some internal toggle tracking to go with it,.Â
Here's the complete source for the sample Clarion 9 program:
PROGRAM MAP END INCLUDE('equates.clw'),ONCE DataQ QUEUE Column1 string(20) Column2 long Column3 string(20) END x LONG MyWindow WINDOW('Caption'),AT(,,336,285),GRAY,FONT('MS Sans Serif',8,,FONT:regular) BUTTON('&Close'),AT(287,262,36,14),USE(?CancelButton),LEFT LIST,AT(15,8,307,243),USE(?LIST),VSCROLL,FROM(dataq),FORMAT('100L(2)|M~C' & | 'olumn 1~100L(2)|M~Column 2~100L(2)|M~Column 3~') END CODE loop 100 TIMES loop x = 1 to 20 DataQ.Column1[x] = chr(random(65,122)) DataQ.Column3[x] = chr(random(65,122)) END Dataq.Column2 = random(1,10000) add(dataq) END OPEN(MyWindow) ACCEPT case event() of EVENT:HeaderPressed 0{prop:text} = 'Current sort column: ' & ?list{PROPLIST:SortColumn} case ?list{PROPLIST:SortColumn} of 1 sort(dataq,dataq.Column1) of 2 sort(dataq,dataq.Column2) of 3 sort(dataq,dataq.Column3) END END CASE FIELD() OF 0 CASE EVENT() OF EVENT:OpenWindow ?list{PROPLIST:HasSortColumn,1} = true ?list{PROPLIST:HasSortColumn,2} = true ?list{PROPLIST:HasSortColumn,3} = true ?list{PROPLIST:HdrSortTextColor} = color:blue !?list{PROPLIST:HdrSortBackColor} = color:yellow ?list{PROPLIST:SortTextColor} = color:blue !?list{PROPLIST:SortBackColor} = color:yellow END OF ?CancelButton CASE EVENT() OF EVENT:Accepted POST(EVENT:CloseWindow) END END END