Custom TreeGadget with column support, cross-platform
Custom TreeGadget with column support, cross-platform
Hello,
[UPDATE, 13 Jul 2018]
You can find the most recent module version here:
http://www.inspirant.de/download/treeViewEx.pbi
The initial code here in the top post is not updated any more and therefore was removed.
[/UPDATE]
I like to share my current version of my custom tree gadget. This are the features:
* unlimited number of root and child elements
* up to 50 columns
* support multi select (#tree_flags_multiSelect)
* support auto-size (#tree_flags_autoSize)
* supporting icon/image for every entry, column entry and column header
* build-in sort function ct_Sort()
* cross-platform
* built in optional search function
I know that this is not finished and by far not a complete replacement of a regular tree gadget. This are the currently open bugs and problems:
* Multi-Select does not support SHIFT key (range selection)
* Scrollbars somehow do not work as normal (don't know the reason for now)
* Missing functions to set/get the top position
* If the first column is resized to be very small, the tree-lines may be overlaying the second column
* Some more customization options
* On MacOS, the cursor pointer does not change during resize yet
* Not aware of different DPI settings
Would be nice if people who extend, enhance or fix this will share their extensions here
[UPDATE, 13 Jul 2018]
You can find the most recent module version here:
http://www.inspirant.de/download/treeViewEx.pbi
The initial code here in the top post is not updated any more and therefore was removed.
[/UPDATE]
I like to share my current version of my custom tree gadget. This are the features:
* unlimited number of root and child elements
* up to 50 columns
* support multi select (#tree_flags_multiSelect)
* support auto-size (#tree_flags_autoSize)
* supporting icon/image for every entry, column entry and column header
* build-in sort function ct_Sort()
* cross-platform
* built in optional search function
I know that this is not finished and by far not a complete replacement of a regular tree gadget. This are the currently open bugs and problems:
* Multi-Select does not support SHIFT key (range selection)
* Scrollbars somehow do not work as normal (don't know the reason for now)
* Missing functions to set/get the top position
* If the first column is resized to be very small, the tree-lines may be overlaying the second column
* Some more customization options
* On MacOS, the cursor pointer does not change during resize yet
* Not aware of different DPI settings
Would be nice if people who extend, enhance or fix this will share their extensions here
Last edited by Kukulkan on Fri Jul 13, 2018 10:42 am, edited 4 times in total.
Re: Custom TreeGadget with column support, cross-platform
Nice work
To set a cursor on OS X, you can use the NSCursor class.Kukulkan wrote:* On MacOS, the cursor pointer does not change during resize yet
Code: Select all
CocoaMessage(0, CocoaMessage(0, 0, "NSCursor pointingHandCursor"), "set")
Windows (x64)
Raspberry Pi OS (Arm64)
Raspberry Pi OS (Arm64)
Re: Custom TreeGadget with column support, cross-platform
thanks for sharing!
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
- Kwai chang caine
- Always Here
- Posts: 5357
- Joined: Sun Nov 05, 2006 11:42 pm
- Location: Lyon - France
Re: Custom TreeGadget with column support, cross-platform
Really nice and usefull
Thanks
Thanks
The happiness is a road...
Not a destination
Not a destination
-
- Always Here
- Posts: 6425
- Joined: Fri Oct 23, 2009 2:33 am
- Location: Wales, UK
- Contact:
Re: Custom TreeGadget with column support, cross-platform
Very nice work Kukulkan, the Test is very fast. I'm struggling to understand the code though - how would I create a tree for, say, my drive C?
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
If it sounds simple, you have not grasped the complexity.
Re: Custom TreeGadget with column support, cross-platform
Fill a tree with filesystem info like this:
Copy this code to replace the test code in the first post.
Set path in this line:
Define Path.s = "c:\git\apps\"
The respective ItemDataStr field contains the full path
Code: Select all
; #######################################################################
; TEST
;{ #######################################################################
Procedure ScanDir(Path.s, *treeId.ct_main, *parent.ct_entry, IconId.i = 0)
If Right(Path.s, 1) <> "\" And Right(Path.s, 1) <> "/"
Path.s = Path.s + "/"
EndIf
Protected Dir.i = ExamineDirectory(#PB_Any, Path.s, "*.*")
Protected *new.ct_entry
Protected Text.s
If Dir.i
While NextDirectoryEntry(Dir.i)
If DirectoryEntryType(Dir.i) = #PB_DirectoryEntry_File
Text.s = DirectoryEntryName(Dir.i) + #TAB$ + Str(DirectoryEntrySize(Dir.i) / 1024)+" KB"
ct_addItem(*treeId, *parent, Text.s, 0, Path.s + DirectoryEntryName(Dir.i))
ElseIf DirectoryEntryName(Dir.i) = "." Or DirectoryEntryName(Dir.i) = ".."
; ignore
Else
*new = ct_addItem(*treeId, *parent, DirectoryEntryName(Dir.i), IconId.i, Path.s + DirectoryEntryName(Dir.i))
*new\status = #tree_collapsed
ScanDir(Path.s + DirectoryEntryName(Dir.i), *treeId, *new, IconId.i)
EndIf
Wend
FinishDirectory(Dir.i)
EndIf
EndProcedure
DataSection
folderyellow_png:
Data.q $0A1A0A0D474E5089,$524448490D000000,$3000000030000000,$F902570000000608,$4752730100000087
Data.q $0000E91CCEAE0042,$FF0044474B620600,$93A7BDA0FF00FF00,$7359487009000000,$C3140000C3140000
Data.q $000000424D701501,$04DB07454D497407,$E5DE7EDB000B0B16,$54414449B8070000,$575C8F4999EDDE68
Data.q $3ABAA1BEE77FC715,$445890B1831019C4,$04A26C3624604688,$43E4B0592C483163,$C22241B22C160904
Data.q $31002C166B023E7B,$98C0885020589158,$50F6EC83B638A090,$78B0F7BA6F0D7774,$AA2C11B9EA77BEF7
Data.q $7ABD5552A4FC2465,$3C14F73FFCCF7FF7,$F57D52F78F5C9EB9,$FD7D7F0FA79FEEB1,$DBC680AFE738AFCB
Data.q $FFD0501DAFE24401,$BECC5E4273210016,$4902A71FF7EAF227,$2F67E82F93FF7E42,$F01E0D0EFF5F077F
Data.q $51D414E0668F3380,$BF7FBB88E0F961CE,$3C27FE46FD2EA7CE,$93EA55C5EA4B3610,$7756887C28B880BF
Data.q $3F98CCD6501CA151,$2F57EB7D5B4419F3,$D01DF1273E2C93AA,$184C1E8DB40459F8,$B8DD579367C6500D
Data.q $4AB3E2F1BD0AEB76,$1BFE7CAF8B172D59,$9B0D9B00A5BEBC6F,$885C424146F87BC5,$AAE86D01AC3924D9
Data.q $C5908B8FE1FB3C6B,$17DC317824A369FB,$183358651033F749,$E421C541442C634A,$45B5411455165108
Data.q $37873F3BD5F3315C,$AC9CD0DA640A5BE6,$4AAD47B99B89BE08,$25B543200BA2BD18,$66FD742103E08C84
Data.q $0EA02A0A2126BD1A,$CAF48A032C219068,$0057B45497A22DD8,$CB9CA28444798A8D,$A1C84247BDCB5B83
Data.q $090C2409F51AAB34,$0777479931E7BFDB,$D54D15EBA8EF04F5,$CDBD08077C1034D2,$BB4B26028D1485E8
Data.q $0292A342C5338BF8,$C511154045F7A3A2,$7BEDE372DFB7B089,$A8371CD2A880E68F,$626E80B4610A137A
Data.q $AAA841085704C458,$47158B4735272735,$7D43AA094E842747,$CBEF199C9788BA10,$B6EAD170404A1EA0
Data.q $FD8CB2C94851A8BE,$42A94EAEEF9B92FD,$8BA50C7F9288FA3F,$AC667CB459B0930B,$E1AAF59EF3A1401F
Data.q $072AFE5E2E13FDDE,$9D0A53E9F4097E2F,$876114EBF2674E4D,$21684803BC37FBBC,$F06D7ADF7395DF54
Data.q $B8C49D5E3969BD40,$C3709460D0156E4B,$59E37AC77DE28A86,$1D53AFA5E0E23FDC,$C72D98227AD119FE
Data.q $7EF1F21549DA4F89,$964B40218B614538,$BC007E776FF373EF,$BE5E0E6DFABF5F96,$12C7FCDC87C3C3C2
Data.q $BA49BD8231710047,$66C95411C1A6D2ED,$4B5668D7E2FC5C7B,$05128C9332541B54,$AC1A5FBC59F85175
Data.q $863A73EC9B36D8C2,$381CFB0EB7BB9E73,$DB95ECFE6F0AF978,$BA72B5DAA4BD2F17,$5DA1A5D464754F4B
Data.q $8F45D446DEAFC03F,$091F3C5A3E39B231,$72A24DFC65102871,$36723863A703C4F5,$2EF7C3E3E24C6EEB
Data.q $53AD5AD74B7FF774,$64C2F592FB8CE9D5,$572D63F14A4FAC93,$0A9388D2D246520F,$3EC30FC0C3843143
Data.q $51DB2D59444319FF,$020C239D41B2F581,$4C6A564AF333C110,$2B1EAD62DC91874C,$60E133A8B0DAC007
Data.q $99431AFFBAC19231,$20BAF7A0547E75D1,$6571A99B33B00C1A,$FCA2DD0DE26E810A,$1A68D0F5A0F0C3B3
Data.q $DC6B42B58D71F01E,$8AC98B293157932E,$0C85E48C0B3C371A,$690494A8A2A028C1,$A802D005CBA30023
Data.q $011AB022F607A80C,$A30CEE828C37934B,$9B192E4424A5570F,$6A9903D31A443A39,$F1376629D3A99D22
Data.q $6AD63061187844D9,$24458C888B118876,$9D9F6D8F7DB41F1F,$72E26168C4CEC989,$BA312EF6EA6A3E4A
Data.q $D0769D88842B6301,$6C95A2EA37526554,$08CAAF8F2B58C015,$99AA18367B313339,$3CA6D61170860F8D
Data.q $3BA365826C589116,$84CDA5FA4F51CA87,$56C609B2308EFCEC,$0128433323CAC40E,$309BDF789DA74FD8
Data.q $62CB607C332E65B0,$2275FBAC615D8EE2,$F04215501AA039DB,$6F34951C634F99DB,$E16393F3D25AAB0D
Data.q $D68F436754386159,$3A6E488B481C407B,$253380E69655D4C3,$927E721373DE609B,$B067608D48C0BBA0
Data.q $8EBF7EDA82A94652,$6CBCB498F253738B,$EF5C4CE0BB76CB11,$E2DB10868C1CC30A,$D2C5AD8B33B40C81
Data.q $53E83ED955899563,$118577D184DD611A,$2751440784C87F0C,$3221958E4CD1D0E6,$6C20D6C342AA6367
Data.q $6D558CC1186EDD88,$F56D4F222CF11817,$A67B2BDF238564C2,$28DAA2553E686713,$6656AA4FEE971855
Data.q $C798C0BBDEB6C708,$3C665C1BCC52ACA3,$FBE1E9F8378FE370,$60D3BB4CA51D3F78,$F56D9FB5EE30A848
Data.q $F77833C8E2863DD8,$C73FCEE78151BDFA,$B329DCEF873B9F0B,$32CD9A9E6194EED0,$AF46059D6E1D9823
Data.q $3CB6B3BDDC665E50,$AF71A80F23EF04A0,$0A89CCA9564D589A,$57CD4D000118B0A3,$681CC042F04639D8
Data.q $72756BA3AEF8F782,$6D6243484FB628F0,$D872A6B4386DDB8C,$1D1C257A30AECB03,$734FC9FF3E2619DA
Data.q $948D37AD7413F970,$C2FEEA6B58D6A84D,$76EF9F6CD793B81C,$BFBC66516287D188,$787CB02BD5BC06B8
Data.q $849B5EA6867AAE9B,$62ABF23F6C6186C9,$F1ED2669C213F025,$4B8488C2BB4E4266,$F47B707939A7F883
Data.q $EAD27CE4538D3880,$06126A99E49478C6,$77DF3333E44C33B6,$5EFF86A93B1B118D,$D306825B415894F2
Data.q $249CB03EDDE3A6BE,$3B57899D91693162,$CD040625DD164B4D,$B40D34038929ACA2,$78C561699D0EED8D
Data.q $DD22E9328B293666,$D6F8A9FBC7A46219,$7F14BA1152736558,$2701EFB3DB112185,$D70D4F3663611193
Data.q $10E28619D96FD4DA,$2E8CA6738E7A84F1,$9C17F9CD64EF168E,$55E08BDE2E24E00F,$CB5836D8DC4506AC
Data.q $5853CEC66B88BDF8,$D8E94890FB532145,$0B53F78A3814BE9C,$8C24328CB58A9B9F,$FAC26C16E90F651A
Data.q $B801730FC5FEBF0F,$96DA9739966F9174,$63F68845FF8B8219,$FEF78657A4FDA730,$BFA3FA8D3EF81BB3
Data.q $FDD9869FF87173D3,$40545145DBFC6704,$19FE9393BE915055,$BCBB12A0E77D2080,$7F572F5BA9CCB6B4
Data.q $46BD42A078FEA6F9,$906F1C29504FE0F6,$1EDEC1915F0BEB3C,$7F6566463DDC1994,$EB7B967ECFFFB872
Data.q $63FDC35AA42B2C0E,$A1AAA405D211CEE4,$959D0C8A26BFFA6E,$907C2E0CFEE8E650,$47C2E0CB2007ECF0
Data.q $8E7CC1DC829FE7D1,$5D0665A25FB22DD6,$9B9C8F18C78AAA80,$C45C801FCF0773A3,$FAE4FF51FC9E87C3
Data.q $78C25AC505FEBFBF,$00000000F7457727,$826042AE444E4549
EndDataSection
If OpenWindow(0, 10, 10, 800, 480, "Custom TreeGadget", #PB_Window_SystemMenu)
; PREPARE SOME CUSTOMIZING
Define Path.s = "c:\git\apps\"
Define FolderGadget.i = CatchImage(#PB_Any, ?folderyellow_png)
Define Config.ct_customizing
With Config
\fontId = LoadFont(#PB_Any, "Arial", 10)
\foregroundColor = RGB(0,0,0)
\backgroundColor = RGB(255,255,255)
\selForegroundColor = RGB(255,255,255)
\selBackgroundColor = RGB(160,160,160)
\lineColor = #PB_Ignore
\headerBackroundColor = #PB_Ignore
\headerForegroundColor = #PB_Ignore
EndWith
;{ CREATE TREEGADGET #1
Define *Tree1.ct_main = ct_TreeGadget(10, 10, 780, 460, #tree_flags_autoSize)
ct_TreeGadgetCustomize(*Tree1, Config)
ScanDir(Path.s, *Tree1, 0, FolderGadget.i)
;}
*Tree1\header(1)\text = "Size"
ct_redraw(*Tree1)
Define Event.i, Quit.i
Repeat
Event = WaitWindowEvent()
If Event = #PB_Event_CloseWindow ; If the user has pressed on the close button
Quit = 1
EndIf
Until Quit = 1
EndIf
Set path in this line:
Define Path.s = "c:\git\apps\"
The respective ItemDataStr field contains the full path
Re: Custom TreeGadget with column support, cross-platform
Very good.
Thank you for sharing.
Thank you for sharing.
DE AA EB
-
- Enthusiast
- Posts: 108
- Joined: Wed May 13, 2009 8:38 am
- Location: Arizona, USA
Re: Custom TreeGadget with column support, cross-platform
Awesome code and very fast.
Thank You
Thank You
Re: Custom TreeGadget with column support, cross-platform
Nice thanks for sharing
Re: Custom TreeGadget with column support, cross-platform
Updated version! This is now re-designed to run as a module. This brings much more comfort in usage...
I keep the initial post and code, as someone might be more interested in the original version.
[UPDATE, 15 Sept 2015] Added some extra margin left from the line and left from the Icon to look better [/UPDATE]
[UPDATE, 18 Dec 2015] Added clear function to cleanup a tree (eg for next usage)[/UPDATE]
[UPDATE, 18 Dec 2015] Added sortColumn() function, added mouseOnHeader() function, added sort by header click to example code[/UPDATE]
[UPDATE, 02 Feb 2018] On MacOS High Sierra, Apple changed the behavior of NSDeviceResolution. Due to the fact that PB is still not DPI aware, on Retina Displays it now does no longer work. I removed DPI awareness for MacOS because of this (check _cust_tree_DetermineSystemDPIFactor() function).
[UPDATE, 13 Jul 2018] Added optional search functionality (see example on bottom of the source). Exchanged the icons.
I had to remove the code from here because the maximum size of 60K was exceed. Please download the PBI include here:
http://www.inspirant.de/download/treeViewEx.pbi
If you enhance this, I'd be happy to see it here Maybe someone is happy to enhance the MacOS usage and the column header size cursor?
I keep the initial post and code, as someone might be more interested in the original version.
[UPDATE, 15 Sept 2015] Added some extra margin left from the line and left from the Icon to look better [/UPDATE]
[UPDATE, 18 Dec 2015] Added clear function to cleanup a tree (eg for next usage)[/UPDATE]
[UPDATE, 18 Dec 2015] Added sortColumn() function, added mouseOnHeader() function, added sort by header click to example code[/UPDATE]
[UPDATE, 02 Feb 2018] On MacOS High Sierra, Apple changed the behavior of NSDeviceResolution. Due to the fact that PB is still not DPI aware, on Retina Displays it now does no longer work. I removed DPI awareness for MacOS because of this (check _cust_tree_DetermineSystemDPIFactor() function).
[UPDATE, 13 Jul 2018] Added optional search functionality (see example on bottom of the source). Exchanged the icons.
I had to remove the code from here because the maximum size of 60K was exceed. Please download the PBI include here:
http://www.inspirant.de/download/treeViewEx.pbi
If you enhance this, I'd be happy to see it here Maybe someone is happy to enhance the MacOS usage and the column header size cursor?
Last edited by Kukulkan on Fri Jul 13, 2018 10:37 am, edited 7 times in total.
Re: Custom TreeGadget with column support, cross-platform
Kukulkan that is excellent! And really clean code that gives high performance too, it worked really well on my Win+Mac+Linux VMs
DPI-aware too! you should write a book on creating custom controls, id buy it
DPI-aware too! you should write a book on creating custom controls, id buy it
Re: Custom TreeGadget with column support, cross-platform
Thank you Keya, highly appreciated But I do not plan to write a book
Re: Custom TreeGadget with column support, cross-platform
I updated the source three threads above. The module version now also having a clear() function to cleanup the tree if needed.
BTW, the initial code (no module) is no longer continued by me. I will add a hint in the initial entry.
BTW, the initial code (no module) is no longer continued by me. I will add a hint in the initial entry.
Re: Custom TreeGadget with column support, cross-platform
{edit} disregard, finally figured out how to read a column! i prefer SelectElement over ForEach as theres only a couple columns
also I added this to see the full "Parent1\Child1\Child2" path of the selected item
ps. you mention in the Features "up to 50 columns", but it seems easy to make that configurable to supporting infinite columns by changing "Array header.ct_header(50)" to "#MaxColumns = 50: Array header.ct_header(#MaxColumns)"? I dont know if it's wasting memory if set to 50 when only 3 are being used, but it was an easy change heehee
This really is a fantastic control!! it's also really the only control suitable for the information i want to display, I think if i didnt have this option i would have to use a non-combined tree + list sort of like Explorer in Details mode, which would be messy and nowhere near as effective for my type of data, so thankyou very much again for sharing your excellent work, but im sad to read you've discontinued it! although did you mean you're still continuing, but only the module version?
Ive never made custom controls before and this seems like it makes a great template to learn from too... and cross-platform! stunning
Code: Select all
If SelectElement(*Selected\columns(), 0)
Debug "Column 0 text of the selected item = " + *Selected\columns()\text
EndIf
Code: Select all
Protected sFullText.s = *Selected\text
While *Selected\parent <> 0
*Selected = *Selected\parent
sFullText = *Selected\text + "\" + sFullText
Wend
Debug "Full text = " + sFullText
This really is a fantastic control!! it's also really the only control suitable for the information i want to display, I think if i didnt have this option i would have to use a non-combined tree + list sort of like Explorer in Details mode, which would be messy and nowhere near as effective for my type of data, so thankyou very much again for sharing your excellent work, but im sad to read you've discontinued it! although did you mean you're still continuing, but only the module version?
Ive never made custom controls before and this seems like it makes a great template to learn from too... and cross-platform! stunning
Last edited by Keya on Fri Dec 18, 2015 12:51 pm, edited 1 time in total.