Cross-platform column justification of ListIconGadget

Just starting out? Need help? Post your questions and find answers here.
User avatar
Shardik
Addict
Addict
Posts: 2058
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Cross-platform column justification of ListIconGadget

Post by Shardik »

After countless hours of trying to find a Mac solution I finally
succeeded. I simply had declared the variable InitialSortOrder in
the structure DataBrowserListViewHeaderDesc wrongly as Long
Integer instead of Unsigned Word... :evil:

This is the final cross-platform code example (Windows, Linux and
MacOS X) to change the column justification in a ListIconGadget
during runtime.

Code: Select all

EnableExplicit

CompilerSelect #PB_Compiler_OS
  CompilerCase #PB_OS_Linux
    ImportC ""
      g_object_set_double(*Object, Property.P-ASCII, Value.D, Null) As "g_object_set"
    EndImport
  CompilerCase #PB_OS_MacOS
    #kControlUseJustMask = $0040
    #teCenter = 1
    #teFlushRight = -1
    #teFlushLeft = -2

    ImportC ""
      GetDataBrowserListViewHeaderDesc(DataBrowserRef, ColumnID, *HeaderDesc)
      GetDataBrowserTableViewColumnProperty(DataBrowserRef, Column, *ColumnID)
      HiliteControl(ControlRef, ControlPart)
      SetControlVisibility(ControlRef, IsVisible, DoDraw)
      SetDataBrowserListViewHeaderDesc(DataBrowserRef, ColumnID, *HeaderDesc)
    EndImport

    Structure RGBColor
      Red.U
      Green.U
      Blue.U
    EndStructure
    
    Structure ControlFontStyleRec
      Flags.W
      Font.W
      Size.W
      Style.W
      Mode.W
      Just.W
      ForeColor.RGBColor
      BackColor.RGBColor
    EndStructure

    Structure DataBrowserListViewHeaderDesc
      Version.L
      MinimumColumnWidth.U
      MaximumColumnWidth.U
      TitleOffset.W
      CFTitleString.L
      InitialSortOrder.U
      FontStyle.ControlFontStyleRec
      IconInfo.L
    EndStructure
CompilerEndSelect

Enumeration
  #PB_ListIcon_JustifyColumnLeft
  #PB_ListIcon_JustifyColumnCenter
  #PB_ListIcon_JustifyColumnRight
EndEnumeration

Procedure SetListIconColumnJustification(ListIconID, Column, Alignment)
  CompilerSelect #PB_Compiler_OS
    CompilerCase #PB_OS_Linux
      Protected AlignmentFactor.D
      Protected *CellRenderers
      Protected *Column
      Protected Count
      Protected i

      Select Alignment
        Case #PB_ListIcon_JustifyColumnLeft
          AlignmentFactor = 0.0
        Case #PB_ListIcon_JustifyColumnCenter
          AlignmentFactor = 0.5
        Case #PB_ListIcon_JustifyColumnRight
          AlignmentFactor = 1.0
      EndSelect

      *Column = gtk_tree_view_get_column_(GadgetID(ListIconID), Column)

      If *Column
        gtk_tree_view_column_set_alignment_(*Column, AlignmentFactor)
        *CellRenderers = gtk_tree_view_column_get_cell_renderers_(*Column)

        If *CellRenderers
          Count = g_list_length_(*CellRenderers)

          For i = 0 To Count - 1
            g_object_set_double(g_list_nth_data_(*CellRenderers, i), "xalign", AlignmentFactor, #Null)
          Next i         

          g_list_free_(*CellRenderers)
        EndIf
      EndIf
    CompilerCase #PB_OS_MacOS
      Protected ColumnID.L
      Protected HeaderDesc.DataBrowserListViewHeaderDesc

      If GetDataBrowserTableViewColumnProperty(GadgetID(0), Column, @ColumnID) = 0
        If GetDataBrowserListViewHeaderDesc(GadgetID(0), ColumnID, @HeaderDesc) = 0
          HeaderDesc\FontStyle\Flags = #kControlUseJustMask
          
          Select Alignment
            Case #PB_ListIcon_JustifyColumnLeft
              HeaderDesc\FontStyle\Just = #teFlushLeft
            Case #PB_ListIcon_JustifyColumnCenter
              HeaderDesc\FontStyle\Just = #teCenter
            Case #PB_ListIcon_JustifyColumnRight
              HeaderDesc\FontStyle\Just = #teFlushRight
          EndSelect
          
          SetDataBrowserListViewHeaderDesc(GadgetID(0), ColumnID, @HeaderDesc)
        EndIf
      EndIf
    CompilerCase #PB_OS_Windows
      Protected ListIconColumn.LV_COLUMN

      ListIconColumn\mask = #LVCF_FMT

      Select Alignment
        Case #PB_ListIcon_JustifyColumnLeft
          ListIconColumn\fmt = #LVCFMT_LEFT
        Case #PB_ListIcon_JustifyColumnCenter
          ListIconColumn\fmt = #LVCFMT_CENTER
        Case #PB_ListIcon_JustifyColumnRight
          ListIconColumn\fmt = #LVCFMT_RIGHT
      EndSelect

      SendMessage_(GadgetID(ListIconID), #LVM_SETCOLUMN, Column, @ListIconColumn)
  CompilerEndSelect
EndProcedure

OpenWindow(0, 200, 100, 445, 90, "Right justify 1st column")
ListIconGadget(0, 5, 5, 435, 80, "Name", 110)
AddGadgetColumn(0, 1, "Address", 300)
AddGadgetItem(0, -1, "Harry Rannit" + #LF$ + "12 Parliament Way, Battle Street, By the Bay")
AddGadgetItem(0, -1, "Ginger Brokeit" + #LF$ + "130 PureBasic Road, BigTown, CodeCity")

SetListIconColumnJustification(0, 0, #PB_ListIcon_JustifyColumnRight)

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
ozzie
Enthusiast
Enthusiast
Posts: 443
Joined: Sun Apr 06, 2008 12:54 pm
Location: Brisbane, Qld, Australia
Contact:

Re: Cross-platform column justification of ListIconGadget

Post by ozzie »

Many thanks, Shardik.
User avatar
Shardik
Addict
Addict
Posts: 2058
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Cross-platform column justification of ListIconGadget

Post by Shardik »

In my above cross-platform example the Mac part is for PB's carbon implementation (PB 4.61 and older or PB 5.00 with subsystem Carbon). Beginning with PB 5.00 PureBasic is based on the cocoa framework with a totally different API. Therefore I have programmed a separate solution for cocoa:
http://www.purebasic.fr/english/viewtop ... 5&start=28

To use this example code in your own cross-platform programs in PB 5.00 you have to download wilbert's CocoaMessage userlib (link in 1st posting of the above thread) and to save the lib (available for 32 and 64 bit) in your PB installation's userlib folder!
User avatar
CONVERT
Enthusiast
Enthusiast
Posts: 130
Joined: Fri May 02, 2003 12:19 pm
Location: France

Re: Cross-platform column justification of ListIconGadget

Post by CONVERT »

Shardik, you are so great!

Thank you very much.

Jean.
PureBasic 6.20 beta 2 (x64) | Windows 10 Pro x64 | Intel(R) Core(TM) i7-8700 CPU @ 3.20Ghz 16 GB RAM, SSD 500 GB, PC locally assembled.
Come back to 6.11 LTS 64 bits because of an issue with #PB_ComboBox_UpperCase in ComboBoxGadget() (Oct. 10, 2024).
Oma
Enthusiast
Enthusiast
Posts: 312
Joined: Thu Jun 26, 2014 9:17 am
Location: Germany

Re: Cross-platform column justification of ListIconGadget

Post by Oma »

After adding this line to shardiks code...

Code: Select all

CompilerSelect #PB_Compiler_OS
  CompilerCase #PB_OS_Linux
    ImportC ""
    	g_object_set_double(*Object, Property.P-ASCII, Value.D, Null) As "g_object_set"
       ;>>>
    	gtk_cell_layout_get_cells(*cell_layout)
       ;<<<
    EndImport
and replace the following disabled line with the following...

Code: Select all

;         *CellRenderers = gtk_tree_view_column_get_cell_renderers_(*Column)
        *CellRenderers = gtk_cell_layout_get_cells(*Column)
the code example still works on Linux with gtk2 and gtk3.

Regards, Charly
PureBasic 5.4-5.7, Linux: (X/L/K)Ubuntus+Mint - Windows XP (32Bit)
PureBasic Linux-API-Library & Viewer: http://www.chabba.de
User avatar
CONVERT
Enthusiast
Enthusiast
Posts: 130
Joined: Fri May 02, 2003 12:19 pm
Location: France

Re: Cross-platform column justification of ListIconGadget

Post by CONVERT »

Thanks a lot, Charly.
PureBasic 6.20 beta 2 (x64) | Windows 10 Pro x64 | Intel(R) Core(TM) i7-8700 CPU @ 3.20Ghz 16 GB RAM, SSD 500 GB, PC locally assembled.
Come back to 6.11 LTS 64 bits because of an issue with #PB_ComboBox_UpperCase in ComboBoxGadget() (Oct. 10, 2024).
User avatar
Keya
Addict
Addict
Posts: 1890
Joined: Thu Jun 04, 2015 7:10 am

Re: Cross-platform column justification of ListIconGadget

Post by Keya »

amazing work! I never would've thought this possible (especially cross-OS!) without a custom control :)
User avatar
CONVERT
Enthusiast
Enthusiast
Posts: 130
Joined: Fri May 02, 2003 12:19 pm
Location: France

Re: Cross-platform column justification of ListIconGadget

Post by CONVERT »

Image
PureBasic 6.20 beta 2 (x64) | Windows 10 Pro x64 | Intel(R) Core(TM) i7-8700 CPU @ 3.20Ghz 16 GB RAM, SSD 500 GB, PC locally assembled.
Come back to 6.11 LTS 64 bits because of an issue with #PB_ComboBox_UpperCase in ComboBoxGadget() (Oct. 10, 2024).
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Cross-platform column justification of ListIconGadget

Post by Kwai chang caine »

I have not see this code :shock:
Thanks SHARDIK for sharing 8)
A little bit late :oops:
ImageThe happiness is a road...
Not a destination
User avatar
Shardik
Addict
Addict
Posts: 2058
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Cross-platform column justification of ListIconGadget

Post by Shardik »

My last cross-platform code example is from 2012 and therefore still contains MacOS code for the Carbon framework. The last PureBasic version which is able to run this code example on MacOS is PB 5.11 with subsystem "Carbon". Although I already posted this link inside this thread to a Cocoa solution, for your convenience I have now replaced the Carbon part by the linked Cocoa part so that this example is now working with current PB versions on MacOS (tested successfully on MacOS 10.6.8 'Snow Leopard' with PB 5.44 x86 in both ASCII and Unicode mode and on MacOS 10.9.5 'Mavericks' with PB 5.44 x86 and x64 in both ASCII and Unicode mode).

Furthermore I have included Charly's suggested change in order to be able to run the example on Linux with both GTK2 and GTK3 (Thank you for that hint, Charly!).

Code: Select all

EnableExplicit

CompilerSelect #PB_Compiler_OS
  CompilerCase #PB_OS_Linux
    ImportC ""
      g_object_set_double(*Object, Property.P-ASCII, Value.D,
        Null) As "g_object_set"
      gtk_cell_layout_get_cells(*CellLayout)
      gtk_tree_view_column_set_alignment(*TreeColumn.GtkTreeViewColumn,
        Alignment.F)
    EndImport
CompilerEndSelect

Enumeration
  #PB_ListIcon_JustifyColumnLeft
  #PB_ListIcon_JustifyColumnCenter
  #PB_ListIcon_JustifyColumnRight
EndEnumeration

Procedure SetListIconColumnJustification(ListIconID.I, Column.I, Alignment.I)
  CompilerSelect #PB_Compiler_OS
    CompilerCase #PB_OS_Linux
      Protected AlignmentFactor.F
      Protected *CellRenderers
      Protected *Column
      Protected Count.I
      Protected i.I

      Select Alignment
        Case #PB_ListIcon_JustifyColumnLeft
          AlignmentFactor = 0.0
        Case #PB_ListIcon_JustifyColumnCenter
          AlignmentFactor = 0.5
        Case #PB_ListIcon_JustifyColumnRight
          AlignmentFactor = 1.0
      EndSelect

      *Column = gtk_tree_view_get_column_(GadgetID(ListIconID), Column)

      If *Column
        gtk_tree_view_column_set_alignment(*Column, AlignmentFactor)
        *CellRenderers = gtk_cell_layout_get_cells(*Column)

        If *CellRenderers
          Count = g_list_length_(*CellRenderers)

          For i = 0 To Count - 1
            g_object_set_double(g_list_nth_data_(*CellRenderers, i), "xalign",
              AlignmentFactor, #Null)
          Next i         

          g_list_free_(*CellRenderers)
        EndIf
      EndIf
    CompilerCase #PB_OS_MacOS
      Protected ColumnHeaderCell.I
      Protected ColumnObject.I
      Protected ColumnObjectArray.I

      Select Alignment
        Case #PB_ListIcon_JustifyColumnLeft
          Alignment = #NSLeftTextAlignment
        Case #PB_ListIcon_JustifyColumnCenter
          Alignment = #NSCenterTextAlignment
        Case #PB_ListIcon_JustifyColumnRight
          Alignment = #NSRightTextAlignment
      EndSelect

      ; ----- Justify text of column cells
      CocoaMessage(@ColumnObjectArray, GadgetID(ListIconID), "tableColumns")
      CocoaMessage(@ColumnObject, ColumnObjectArray, "objectAtIndex:", Column)
      CocoaMessage(0, CocoaMessage(0, ColumnObject, "dataCell"), "setAlignment:", Alignment)
      
      ; ----- Justify text of column header
      CocoaMessage(@ColumnHeaderCell, ColumnObject, "headerCell")
      CocoaMessage(0, ColumnHeaderCell, "setAlignment:", Alignment)
      
      ; ----- Redraw ListIcon contents to see change
      CocoaMessage(0, GadgetID(ListIconID), "reloadData")
    CompilerCase #PB_OS_Windows
      Protected ListIconColumn.LV_COLUMN

      ListIconColumn\mask = #LVCF_FMT

      Select Alignment
        Case #PB_ListIcon_JustifyColumnLeft
          ListIconColumn\fmt = #LVCFMT_LEFT
        Case #PB_ListIcon_JustifyColumnCenter
          ListIconColumn\fmt = #LVCFMT_CENTER
        Case #PB_ListIcon_JustifyColumnRight
          ListIconColumn\fmt = #LVCFMT_RIGHT
      EndSelect

      SendMessage_(GadgetID(ListIconID), #LVM_SETCOLUMN, Column, @ListIconColumn)
  CompilerEndSelect
EndProcedure

OpenWindow(0, 200, 100, 445, 90, "Right justify 1st column")
ListIconGadget(0, 5, 5, 435, 80, "Name", 110)
AddGadgetColumn(0, 1, "Address", 300)
AddGadgetItem(0, -1, "Harry Rannit" + #LF$ + "12 Parliament Way, Battle Street, By the Bay")
AddGadgetItem(0, -1, "Ginger Brokeit" + #LF$ + "130 PureBasic Road, BigTown, CodeCity")

SetListIconColumnJustification(0, 0, #PB_ListIcon_JustifyColumnRight)

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
Update: I have added the corrected GTK API function gtk_tree_view_column_set_alignment(*TreeColumn, Alignment.F) to the Linux ImportC block because the predefined PureBasic function declares incorrectly Alignment as Integer which resulted in missing header alignment when run on Linux. Thank you to eck49 for reporting the problem!
Last edited by Shardik on Fri Feb 26, 2021 9:40 pm, edited 2 times in total.
eck49
Enthusiast
Enthusiast
Posts: 153
Joined: Sat Nov 14, 2020 10:08 pm
Location: England

Re: Cross-platform column justification of ListIconGadget

Post by eck49 »

@Shardik
Thanks for this code, which is just what I want, except that the alignment of the headers seems to be displaced. Help!

Linux, Ubuntu 16.04 not sure which gtk flavour, PB 5.70.

Using the code from the 2/2/2017 post in this thread, but adapting the test code at the bottom to this

Code: Select all

OpenWindow(0, 200, 100, 999, 350, "Show Listicon justifications")
ListIconGadget(0, 5, 5, 835, 80, "Name", 110)
AddGadgetColumn(0, 1, "Address", 350)
AddGadgetColumn(0, 2, "Phone", 200)
AddGadgetColumn(0, 3, "--", 20)
AddGadgetItem(0, -1, "Harry Rannit" + #LF$ + "12 Parliament Way, Battle Street, By the Bay" + #LF$ + "45678")
AddGadgetItem(0, -1, "Ginger Brokeit" + #LF$ + "130 PureBasic Road, BigTown, CodeCity" + #LF$ + "678 998")

SetListIconColumnJustification(0, 0, #PB_ListIcon_JustifyColumnRight)
SetListIconColumnJustification(0, 1, #PB_ListIcon_JustifyColumnCenter)
SetListIconColumnJustification(0, 2, #PB_ListIcon_JustifyColumnLeft)

ListIconGadget(1, 5, 100, 835, 80, "Who", 110)
AddGadgetColumn(1, 1, "Where", 350)
AddGadgetColumn(1, 2, "Number", 200)
AddGadgetColumn(1, 3, "--", 20)
AddGadgetItem(1, -1, "Roger Bodgedit" + #LF$ + "999 Duff Place, Codswallop" + #LF$ + "07777 45678")
AddGadgetItem(1, -1, "Fred Fixedit" + #LF$ + "White House, NotThatOne, Gleeful" + #LF$ + "Fortify 245")

SetListIconColumnJustification(1, 2, #PB_ListIcon_JustifyColumnRight)
SetListIconColumnJustification(1, 1, #PB_ListIcon_JustifyColumnCenter)
SetListIconColumnJustification(1, 0, #PB_ListIcon_JustifyColumnLeft)

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
(In each case the last column, col3, is just a dummy to guarantee the whole of col2 is visible).

The listicon headers are justified thus:
Upper col0 Left, cols 1&2 Centre
Lower col0 Centre col1 Right and the header text for col2 is nowhere to be seen.

If I change the order of the second set of calls to the natural order, 0,1,2 instead of 2,1,0 both listicons are affected.
Upper col0 Left, col1 Right, col2 Centre
Lower col0 Left, col1 Left, col2 Centre

In every case the data items are aligned as intended, it is only the headers which are not.
The C importation is beyond my ken. Help!
Ubuntu 22.04 64-bit
Purebasic 6.00 (as of 5 Sep 2022)
(native tongue: English)
User avatar
Shardik
Addict
Addict
Posts: 2058
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Cross-platform column justification of ListIconGadget

Post by Shardik »

eck49 wrote:Thanks for this code, which is just what I want, except that the alignment of the headers seems to be displaced. Help!
You are right. The problem is a wrong internal declaration in PureBasic of the GTK API function gtk_tree_view_column_set_alignment_(*TreeColumn, xalign). Alignment has to be declared as Float in order to work correctly.

I have therefore changed my above code example from 02.02.2017 accordingly and added the corrected GTK API function gtk_tree_view_column_set_alignment(*TreeColumn, Alignment.F) to the ImportC block.
pierre2
New User
New User
Posts: 7
Joined: Fri Feb 21, 2020 4:40 pm

Re: Cross-platform column justification of ListIconGadget

Post by pierre2 »

Late to the party, but thank you Shardik for your cross-platform alignment code (both here, and elsewhere for TextGadgets) - exactly what I needed. Good work !
User avatar
Shardik
Addict
Addict
Posts: 2058
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Cross-platform column justification of ListIconGadget

Post by Shardik »

pierre2 wrote:Late to the party, but thank you Shardik for your cross-platform alignment code (both here, and elsewhere for TextGadgets) - exactly what I needed. Good work !
You are welcome!
pierre2
New User
New User
Posts: 7
Joined: Fri Feb 21, 2020 4:40 pm

Re: Cross-platform column justification of ListIconGadget

Post by pierre2 »

Using Linux Mint 21 Vannessa Mate, when I compile I get this message:

gtk_tree_view_column_set_alignment() is not a function, array, list, map or macro.

Is anyone able to point me in the right direction, please ?
Post Reply