ListIconGadget (GtkTreeView) - row height

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: ListIconGadget (GtkTreeView) - row height

Post by Shardik »

Previously I already demonstrated how to get and set a ListIconGadget's row height on MacOS X with Cocoa framework.

srod already demonstrated how to get and set a ListIconGadget's row height on Windows.

So I combined all these solutions together with my Linux example from above to a cross-platform example which contains - as a further goodie - a cross-platform procedure to place the labels of a TrackbarGadget under their corresponding tick marks. I have tested this code example successfully on these operating systems with PB 5.11 in ASCII and Unicode mode:

- Windows XP SP3 x86
- Windows 7 SP1 x64 with PB 5.11 x86 and x64
- MacOS X 10.6.8 (Snow Leopard) with PB 5.11 x86 and x64
- MacOS X 10.8.3 (Mountain Lion) with PB 5.11 x86 and x64
- Lubuntu 12.10 x86
- Ubuntu 12.04 x64 with KDE
- Ubuntu 12.04 x64 with Unity

But nevertheless there remain subtle differences between the different operating systems:

- On MacOS X it's possible to decrease the row height beyond the initial default value (the text then may become partially hidden!). On Windows and Linux it's only possible to increase the row height!
- On MacOS X on increasing row height the text will stay in the upper part of the row while on Windows and Linux the text always remains centered!

Code: Select all

EnableExplicit

CompilerSelect #PB_Compiler_OS
  CompilerCase #PB_OS_Linux
    ImportC ""
      gtk_scale_add_mark(*TrackBar.GtkScale, Value.D, Position.I, *MarkupText)
      gtk_tree_view_column_get_cell_renderers(*Column.GtkTreeViewColumn)
    EndImport
    
    Define OldRowHeight.L
    Define RowHeight.L
    Define TrackBarHeight.I = 55

    Procedure DrawTickMarkLabels(TrackBarID.I)
      Protected i.I
      Protected Label.S
      Protected *LabelBuffer = AllocateMemory(8)
      Protected Maximum.I = GetGadgetAttribute(TrackBarID, #PB_TrackBar_Maximum)
      Protected Minimum.I = GetGadgetAttribute(TrackBarID, #PB_TrackBar_Minimum)

      For i = Minimum To Maximum
        Label = Str(i)
        PokeS(*LabelBuffer, Label, MemorySize(*LabelBuffer), #PB_Ascii)
        gtk_scale_add_mark(GadgetID(TrackBarID), i, #GTK_POS_BOTTOM, *LabelBuffer)
      Next i

      FreeMemory(*LabelBuffer)
    EndProcedure

    Procedure.I GetCellRenderer(ListIconID.I, CellRendererID.I)
      Static    *CellRenderer0.GtkCellRenderer
      Static    *CellRenderer1.GtkCellRenderer
      Protected CellRendererList.I
      Protected Column.I
      Protected i.I
      
      If *CellRenderer0 = 0
        ; ----- Get column 0
        Column = gtk_tree_view_get_column_(GadgetID(ListIconID), 0)
        
        If Column
          ; ----- Get list of cell renderers for column 0
          CellRendererList = gtk_tree_view_column_get_cell_renderers(Column)
          
          If CellRendererList
            ; ----- Get 1st cell renderer from list for changing row height
            *CellRenderer0 = g_list_nth_data_(CellRendererList, 0)
            ; ----- Get 2nd cell renderer from list to obtain current row height
            *CellRenderer1 = g_list_nth_data_(CellRendererList, 1)
          EndIf
        EndIf
      EndIf

      If CellRendererID = 0
        ProcedureReturn *CellRenderer0
      Else
        ProcedureReturn *CellRenderer1
      EndIf
    EndProcedure

    Procedure.L GetRowHeight(ListIconID.I)
      Protected *CellRenderer.GtkCellRenderer
      Protected RowHeight.L
      Protected RowWidth.L
      Protected xOffset.L
      Protected yOffset.L

      *CellRenderer = GetCellRenderer(ListIconID, 1)
      gtk_cell_renderer_get_size_(*CellRenderer, GadgetID(ListIconID), 0, @xOffset, @yOffset, @RowWidth, @RowHeight)
      ProcedureReturn RowHeight
    EndProcedure

    Procedure SetRowHeight(ListIconID.I, RowHeight.L)
      Protected *CellRenderer.GtkCellRenderer
      Protected Column.I

      Column = gtk_tree_view_get_column_(GadgetID(ListIconID), 0)
        
      If Column
        *CellRenderer = GetCellRenderer(ListIconID, 0)
        *CellRenderer\height = RowHeight
        gtk_tree_view_column_clear_attributes_(Column, *CellRenderer)
      EndIf
    EndProcedure
  CompilerCase #PB_OS_MacOS
    Define RowHeight.CGFloat
    Define OldRowHeight.CGFloat
    Define TrackBarHeight.I = 24
    
    Procedure DrawTickMarkLabels(TrackBarID.I)
      Protected i.I
      Protected Label.S
      Protected LabelWidth.I
      Protected Maximum.I = GetGadgetAttribute(TrackBarID, #PB_TrackBar_Maximum)
      Protected Minimum.I = GetGadgetAttribute(TrackBarID, #PB_TrackBar_Minimum)
      Protected Rectangle.NSRect
      Protected TickHeight.I
      Protected TickX.I
      Protected TickY.I
      
      For i = Minimum To Maximum
        CocoaMessage(@Rectangle, GadgetID(TrackBarID), "rectOfTickMarkAtIndex:", i - Minimum)
        TickX = Rectangle\origin\x
        TickY = Rectangle\origin\y
        TickHeight = Rectangle\size\height
        
        StartDrawing(WindowOutput(0))
          Label = Str(i)
          LabelWidth = TextWidth(Label)
        StopDrawing()
        
        TextGadget(#PB_Any, GadgetX(TrackBarID) + TickX - LabelWidth / 2 - 2, GadgetY(TrackBarID) + TickY + TickHeight, LabelWidth + 8, 15, Label)
      Next i
    EndProcedure
    
    Procedure.I GetRowHeight(ListIconID.I)
      Protected RowHeight.CGFloat
      
      CocoaMessage(@RowHeight, GadgetID(ListIconID), "rowHeight")
      ProcedureReturn Int(RowHeight)
    EndProcedure
    
    Procedure SetRowHeight(ListIconID.I, RowHeight.CGFloat)
      CocoaMessage(0, GadgetID(0), "setRowHeight:@", @RowHeight)
    EndProcedure
  CompilerCase #PB_OS_Windows
    Define OldRowHeight.I
    Define RowHeight.I
    Define TrackBarHeight.I = 30

    Procedure DrawTickMarkLabels(TrackBarID.I)
      Protected i.I
      Protected Label.S
      Protected LabelWidth.I
      Protected Maximum.I = GetGadgetAttribute(TrackBarID, #PB_TrackBar_Maximum)
      Protected Minimum.I = GetGadgetAttribute(TrackBarID, #PB_TrackBar_Minimum)
      Protected TickX.I
      Protected TickXDelta.I
      Protected TickXFirst.I

      For i = 0 To Maximum - Minimum - 2
        TickX = SendMessage_(GadgetID(TrackBarID), #TBM_GETTICPOS, i, 0)

        Select i
          Case 0
            TickXFirst = TickX
          Case 1
            TickXDelta = TickX - TickXFirst
        EndSelect

        StartDrawing(WindowOutput(0))
          Label = Str(i + Minimum + 1)
          LabelWidth = TextWidth(Label)
        StopDrawing()

        TextGadget(#PB_Any, GadgetX(TrackBarID) + TickX - LabelWidth / 2 - 2 + 4, GadgetY(TrackBarID) + GadgetHeight(TrackBarID) + 2, LabelWidth, 15, Label)
      Next i

      StartDrawing(WindowOutput(0))
        Label = Str(Minimum)
        LabelWidth = TextWidth(Label)
      StopDrawing()

      TextGadget(#PB_Any, GadgetX(TrackBarID) + LabelWidth / 2 - 2, GadgetY(TrackBarID) + GadgetHeight(TrackBarID) + 2, LabelWidth, 15, Label)

      StartDrawing(WindowOutput(0))
        Label = Str(Maximum)
        LabelWidth = TextWidth(Label)
      StopDrawing()

      TextGadget(#PB_Any, GadgetX(TrackBarID) + TickX + TickXDelta - LabelWidth / 2 - 2 + 4, GadgetY(TrackBarID) + GadgetHeight(TrackBarID) + 2, LabelWidth, 15, Label)
    EndProcedure
    
    Procedure.I GetRowHeight(ListIconID.I)
      Protected Rectangle.RECT
      
      Rectangle\left = #LVIR_BOUNDS
      SendMessage_(GadgetID(ListIconID), #LVM_GETITEMRECT, 0, Rectangle)
      ProcedureReturn Rectangle\bottom - Rectangle\top - 1
    EndProcedure
    
    Procedure SetRowHeight(ListIconID.I, RowHeight.I)
      Protected ImageHandle.I
      
      ImageHandle = ImageList_Create_(1, RowHeight, #ILC_COLORDDB, 0, 0)
      SendMessage_(GadgetID(ListIconID), #LVM_SETIMAGELIST, #LVSIL_SMALL, ImageHandle)
      ImageList_Destroy_(ImageHandle)
    EndProcedure
CompilerEndSelect

Define i.I
Define TickLabelList.S

OpenWindow(0, 200, 100, 470, 210, "Change ListIcon's row height")

ListIconGadget(0, 10, 10, WindowWidth(0) - 20, 94, "Name", 110, #PB_ListIcon_GridLines)
AddGadgetColumn(0, 1, "Address", GadgetWidth(0) - GetGadgetItemAttribute(0, 0, #PB_ListIcon_ColumnWidth) - 30)
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")
AddGadgetItem(0, -1, "Didi Foundit" + #LF$ + "321 Logo Drive, Mouse House, Downtown")

Frame3DGadget(1, 10, GadgetY(0) + GadgetHeight(0) + 10, WindowWidth(0) - 20, 80, "Row height:")
TrackBarGadget(2, GadgetX(1) + 10, GadgetY(1) + 20, GadgetWidth(1) - 20, TrackBarHeight, 10, 30, #PB_TrackBar_Ticks)
DrawTickMarkLabels(2)

RowHeight = GetRowHeight(0)
OldRowHeight = RowHeight
SetGadgetState(2, RowHeight)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      If EventGadget() = 2
        RowHeight = GetGadgetState(2)

        If RowHeight <> OldRowHeight
          SetRowHeight(0, RowHeight)
          OldRowHeight = RowHeight
        EndIf
      EndIf
  EndSelect
ForEver
mdp
Enthusiast
Enthusiast
Posts: 115
Joined: Mon Apr 18, 2005 8:28 pm

Re: ListIconGadget (GtkTreeView) - row height

Post by mdp »

Sorry, I just re-emerged...
I checked your code, Shardik, but it would still take me a while and some extra study of GTK+ (I really am a newby at it) to get clearer ideas and experiment... I cannot believe the TreeView rows cannot be shrunk below that value.

By the way: you mention that It's not possible to reduce a row's height below a specific minimum value (19 pixels in Ubuntu 12.04 x64 with KDE) - did you have the chance to test on other distributions (maybe 32bit, considering that in your tests the x64 distros return a wrong value for the vertical-separator)?
Post Reply