GtkTreeView Example Partially working

Linux specific forum
User avatar
StarBootics
Addict
Addict
Posts: 984
Joined: Sun Jul 07, 2013 11:35 am
Location: Canada

GtkTreeView Example Partially working

Post by StarBootics »

Hello everyone,

I'm struggling very hard on the GtkTreeView Widget with a GtkListStore model in order to create a ListView.
I have try many things but I can't add any row to the GtkListStore.

Thanks in advance.
StarBootics

Code: Select all

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Project name : Gtk List View Example
; File Name : Gtk List View Example.pb
; File version: 1.0.0
; Programming : Partially working
; Programmed by : StarBootics
; Date : 08-04-2022
; Last Update : 08-04-2022
; PureBasic code : V6.00 Beta 6
; Platform : Linux
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Programming Notes
;
; I can't figure out what I'm doing wrong. The columns are 
; created but I can't add any row to the GtkListStore. See 
; GtkListView -> AppendItem() method.
;
; There is some references tutorials I have found but they are
; not very useful.
;
; https://docs.gtk.org/gtk3/treeview-tutorial.html
; https://zetcode.com/gui/gtk2/gtktreeview/
;
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

DeclareModule GtkWindow
  
  Interface Window
    
    GetID.i()
    GetPosition(*PosX, *PosY)
    SetPosition(Position.i = #GTK_WIN_POS_NONE)
    SetSize(Width.l, Height.l)
    SetTitle(Title.s)
    SetResizable(Resizable.i)
    SetBorderWidth(BorderWidth.l)
    SetTransientFor(*Parent)
    SetKeepAbove(Setting.i)
    Move(X.l, Y.l)
    Show()
    SignalConnect(SignalName.s, *CallBack, UserData.i)
    AddWidget(*Widget)
    Free()
    
  EndInterface
  
  Declare.i New()
  
EndDeclareModule

Module GtkWindow
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Déclaration de la Structure <<<<<

  Structure Private_Members
    
    VirtualTable.i
    *WindowID
    
  EndStructure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Les observateurs <<<<<

  Procedure.i GetID(*This.Private_Members)
    
    ProcedureReturn *This\WindowID
  EndProcedure
  
  Procedure GetPosition(*This.Private_Members, *PosX, *PosY)
    
    gtk_window_get_position_(*This\WindowID, *PosX, *PosY)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Les mutateurs <<<<<
  
  Procedure SetPosition(*This.Private_Members, Position.i = #GTK_WIN_POS_NONE)
    
    gtk_window_set_position_(*This\WindowID, Position)
    
  EndProcedure
  
  Procedure SetSize(*This.Private_Members, Width.l, Height.l)
    
    gtk_window_set_default_size_(*This\WindowID, Width, Height)
    
  EndProcedure
  
  Procedure SetTitle(*This.Private_Members, Title.s)
    
    gtk_window_set_title_(*This\WindowID, Title)
    
  EndProcedure
  
  Procedure SetResizable(*This.Private_Members, Resizable.i)
    
    gtk_window_set_resizable_(*This\WindowID, Resizable)
    
  EndProcedure
  
  Procedure SetBorderWidth(*This.Private_Members, BorderWidth.l)
    
    gtk_container_set_border_width_(*This\WindowID, BorderWidth)
    
  EndProcedure
  
  Procedure SetTransientFor(*This.Private_Members, *Parent)
    
    gtk_window_set_transient_for_(*This\WindowID, *Parent)
    
  EndProcedure

  Procedure SetKeepAbove(*This.Private_Members, Setting.i)
    
    gtk_window_set_keep_above_(*This\WindowID, Setting)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< L'opérateur Move <<<<<
  
  Procedure Move(*This.Private_Members, X.l, Y.l)
    
    gtk_window_move_(*This\WindowID, X, Y)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< L'opérateur Show <<<<<
  
  Procedure Show(*This.Private_Members)
    
     gtk_widget_show_all_(*This\WindowID)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Nom de la procédure <<<<<
  
  Procedure SignalConnect(*This.Private_Members, SignalName.s, *CallBack, UserData.i)
    
    g_signal_connect_(*This\WindowID, SignalName, *CallBack, UserData)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Nom de la procédure <<<<<
  
  Procedure AddWidget(*This.Private_Members, *Widget)
    
    gtk_container_add_(*This\WindowID, *Widget)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Le Destructeur <<<<<

  Procedure Free(*This.Private_Members)
    
    FreeStructure(*This)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Le Constructeur <<<<<

  Procedure.i New()
    
    *This.Private_Members = AllocateStructure(Private_Members)
    *This\VirtualTable = ?START_METHODS
    
    *This\WindowID = gtk_window_new_(#GTK_WINDOW_TOPLEVEL)
    
    ProcedureReturn *This
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Les entrées de la table virtuelle <<<<<

  DataSection
    START_METHODS:
    Data.i @GetID()
    Data.i @GetPosition()
    Data.i @SetPosition()
    Data.i @SetSize()
    Data.i @SetTitle()
    Data.i @SetResizable()
    Data.i @SetBorderWidth()
    Data.i @SetTransientFor()
    Data.i @SetKeepAbove()
    Data.i @Move()
    Data.i @Show()
    Data.i @SignalConnect()
    Data.i @AddWidget()
    Data.i @Free()
    END_METHODS:
  EndDataSection
  
EndModule

DeclareModule GtkListView
  
  Interface ListView
    
    GetID.i()
    AppendItem(Definition.s)
    Free()
    
  EndInterface
  
  Declare.i New(ColumnNames.s)
  
EndDeclareModule

Module GtkListView
  
  ImportC ""
    
    gtk_tree_view_set_grid_lines(*Widget, Flag.i)
    
  EndImport
  
  
  Macro G_TYPE_MAKE_FUNDAMENTAL(x)
    
    x << 2
    
  EndMacro
  
  #G_TYPE_INVALID = G_TYPE_MAKE_FUNDAMENTAL(0)
  #G_TYPE_NONE = G_TYPE_MAKE_FUNDAMENTAL(1)
  #G_TYPE_INTERFACE = G_TYPE_MAKE_FUNDAMENTAL(2)
  #G_TYPE_CHAR = G_TYPE_MAKE_FUNDAMENTAL(3)
  #G_TYPE_UCHAR = G_TYPE_MAKE_FUNDAMENTAL(4)
  #G_TYPE_BOOLEAN = G_TYPE_MAKE_FUNDAMENTAL(5)
  #G_TYPE_INT = G_TYPE_MAKE_FUNDAMENTAL(6)
  #G_TYPE_UINT = G_TYPE_MAKE_FUNDAMENTAL(7)
  #G_TYPE_LONG = G_TYPE_MAKE_FUNDAMENTAL(8)
  #G_TYPE_ULONG = G_TYPE_MAKE_FUNDAMENTAL(9)
  #G_TYPE_INT64 = G_TYPE_MAKE_FUNDAMENTAL(10)
  #G_TYPE_UINT64 = G_TYPE_MAKE_FUNDAMENTAL(11)
  #G_TYPE_ENUM = G_TYPE_MAKE_FUNDAMENTAL(12)
  #G_TYPE_FLAGS = G_TYPE_MAKE_FUNDAMENTAL(13)
  #G_TYPE_FLOAT = G_TYPE_MAKE_FUNDAMENTAL(14)
  #G_TYPE_DOUBLE = G_TYPE_MAKE_FUNDAMENTAL(15)
  #G_TYPE_STRING = G_TYPE_MAKE_FUNDAMENTAL(16)
  #G_TYPE_POINTER = G_TYPE_MAKE_FUNDAMENTAL(17)
  #G_TYPE_BOXED = G_TYPE_MAKE_FUNDAMENTAL(18)
  #G_TYPE_PARAM = G_TYPE_MAKE_FUNDAMENTAL(19)
  #G_TYPE_OBJECT = G_TYPE_MAKE_FUNDAMENTAL(20)
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Déclaration des Structures <<<<<
  
  Structure Private_Members
    
    VirtualTable.i
    *ListViewID
    *ScrolledWindowID
    
  EndStructure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Les observateurs <<<<<

  Procedure.i GetID(*This.Private_Members)
    
    ProcedureReturn *This\ScrolledWindowID
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< L'opérateur AppendColumn <<<<<

  Procedure AppendItem(*This.Private_Members, Definition.s)
    
    Protected Iter.GtkTreeIter, Value.GValue
    
    *ListStore = gtk_tree_view_get_model_(*This\ListViewID)
    
    gtk_list_store_append_(*ListStore, @Iter)
;     Debug Iter\stamp
;     Debug Iter\user_data
;     Debug Iter\user_data2
;     Debug Iter\user_data3
    
;     Debug Iter\stamp
;     gtk_list_store_insert_(*ListStore, @Iter, -1)
;     Debug Iter\stamp
    
    ColumnMax.l = CountString(Definition, Chr(10))
    
    For ColumnID = 0 To ColumnMax 
      CellValue.s = StringField(Definition, ColumnID+1, Chr(10))
      g_value_set_string_(@Value, CellValue)
      gtk_list_store_set_value_(*ListStore, Iter, ColumnID, @Value)
    Next
    
    
  EndProcedure
 
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Le Destructeur <<<<<

  Procedure Free(*This.Private_Members)
    
    FreeStructure(*This)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Le Constructeur <<<<<

  Procedure.i New(ColumnNames.s)
    
    *This.Private_Members = AllocateStructure(Private_Members)
    *This\VirtualTable = ?START_METHODS
    
    *This\ScrolledWindowID = gtk_scrolled_window_new_(#Null, #Null)
    
    gtk_scrolled_window_set_shadow_type_(*This\ScrolledWindowID, #GTK_SHADOW_IN)
    
    *This\ListViewID = gtk_tree_view_new_()
    gtk_container_add_(*This\ScrolledWindowID, *This\ListViewID)
    
    
    ColumnMax.l = CountString(ColumnNames, Chr(10))
    
   *GTYPE = AllocateMemory((ColumnMax+1) * SizeOf(Integer))
   FillMemory(*GTYPE, (ColumnMax+1) * SizeOf(Integer), #G_TYPE_STRING, #PB_Integer)
;     *Cursor = *GTYPE
    
    For ColumnID = 0 To ColumnMax
      
      *CellRenderer = gtk_cell_renderer_text_new_()
      *TreeViewColumnID = gtk_tree_view_column_new_()
      gtk_tree_view_column_add_attribute_(*TreeViewColumnID, *CellRenderer, "text", ColumnID)
      gtk_tree_view_append_column_(*This\ListViewID, *TreeViewColumnID)
      gtk_tree_view_column_set_title_(*TreeViewColumnID, StringField(ColumnNames, ColumnID+1, Chr(10)))
      
      gtk_tree_view_append_column_(*This\ListViewID, *TreeViewColumnID) 
      
;       Debug Str(PeekI(*Cursor)) + " vs #G_TYPE_STRING (" + Str(#G_TYPE_STRING) + ")"
;       *Cursor + SizeOf(Integer)
      
    Next

    *ListStore = gtk_list_store_newv_(ColumnMax, *GTYPE)
    FreeMemory(*GTYPE)
    
    gtk_tree_view_set_model_(*This\ListViewID, *ListStore)
    
    g_object_unref_(*ListStore)
    
;     gtk_tree_view_set_headers_clickable_(*This\ListViewID, #True)
;     gtk_tree_view_columns_autosize_(*This\ListViewID)
    gtk_tree_view_set_grid_lines(*This\ListViewID, 3)
    
    ProcedureReturn *This
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Les entrées de la table virtuelle <<<<<

  DataSection
    START_METHODS:
    Data.i @GetID()
    Data.i @AppendItem()
    Data.i @Free()
    END_METHODS:
  EndDataSection
  
EndModule

CompilerIf #PB_Compiler_IsMainFile
  
  ProcedureC WindowDeleteEventHandler(*Widget.GtkWidget, *Event.GdkEventAny, UserData.I)
    
    ;Debug "WindowDeleteEventHandler"
    gtk_window_get_position_(*Widget, @X.l, @Y.l)
    
    ;Debug "Position (x,y) = (" + Str(X) + "," + Str(Y) + ")"
    
  EndProcedure
  
  ProcedureC WindowCloseHandler(*Widget.GtkWidget, *Event.GdkEventAny, UserData.I)
    
    ;Debug "WindowCloseHandler"
    gtk_window_get_position_(*Widget, @X.l, @Y.l)
    
    ;Debug "Position (x,y) = (" + Str(X) + "," + Str(Y) + ")"
    
    gtk_main_quit_()
    
  EndProcedure

  gtk_init_(0, 0)
  
  MainWin.GtkWindow::Window = GtkWindow::New()
  MainWin\SetSize(400, 300)
  MainWin\SetTitle("GtkListView Example")
  MainWin\SetPosition(#GTK_WIN_POS_CENTER)
  MainWin\SetResizable(#False)
  MainWin\SetBorderWidth(5)
  
  MainWin\SignalConnect("delete-event", @WindowDeleteEventHandler(), 25)
  MainWin\SignalConnect("destroy", @WindowCloseHandler(), 0)
  
  ListView.GtkListView::ListView = GtkListView::New("File Name" + Chr(10) + "Status")
  
  ListView\AppendItem("Vector2f - OOP.pb" + Chr(10) + "OK")
  ListView\AppendItem("Vector3f - OOP.pb" + Chr(10) + "OK")
  ListView\AppendItem("Vector4f - OOP.pb" + Chr(10) + "OK")
  
  
  MainWin\AddWidget(ListView\GetID())
  
  MainWin\Show()
  
  gtk_main_()
  
  MainWin\Free()
  
CompilerEndIf

; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< END OF FILE <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<
The Stone Age did not end due to a shortage of stones !
User avatar
StarBootics
Addict
Addict
Posts: 984
Joined: Sun Jul 07, 2013 11:35 am
Location: Canada

Re: GtkTreeView Example Partially working

Post by StarBootics »

Hello everyone,

I have made some progress but still unable to populate the ListStore with some strings. It look like the gtk_list_store_set_value_() don't work properly even if the GValue I gave to this instruction is properly set. I mean I'm putting and extracting the right string every time so it should work.

My investigation continues, meanwhile if someone find what I'm doing wrong please let me know.

Best regards
StarBootics

Code: Select all

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Project name : Gtk List View Example
; File Name : Gtk List View Example.pb
; File version: 1.0.1
; Programming : Partially working
; Programmed by : StarBootics
; Date : 08-04-2022
; Last Update : 09-04-2022
; PureBasic code : V6.00 Beta 6
; Platform : Linux
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Programming Notes
;
; I can't figure out what I'm doing wrong. The columns are 
; created, the rows are also created but a problem remain. They
; are empty. 
;
; It look like the gtk_list_store_set_value() don't work 
; properly, see GtkListView -> AppendItem() method.
;
; There is some references tutorials I have found but they are
; not very useful.
;
; https://docs.gtk.org/gtk3/treeview-tutorial.html
; https://zetcode.com/gui/gtk2/gtktreeview/
;
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

DeclareModule GtkWindow
  
  Interface Window
    
    GetID.i()
    GetPosition(*PosX, *PosY)
    SetPosition(Position.i = #GTK_WIN_POS_NONE)
    SetSize(Width.l, Height.l)
    SetTitle(Title.s)
    SetResizable(Resizable.i)
    SetBorderWidth(BorderWidth.l)
    SetTransientFor(*Parent)
    SetKeepAbove(Setting.i)
    Move(X.l, Y.l)
    Show()
    SignalConnect(SignalName.s, *CallBack, UserData.i)
    AddWidget(*Widget)
    Free()
    
  EndInterface
  
  Declare.i New()
  
EndDeclareModule

Module GtkWindow
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Déclaration de la Structure <<<<<

  Structure Private_Members
    
    VirtualTable.i
    *WindowID
    
  EndStructure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Les observateurs <<<<<

  Procedure.i GetID(*This.Private_Members)
    
    ProcedureReturn *This\WindowID
  EndProcedure
  
  Procedure GetPosition(*This.Private_Members, *PosX, *PosY)
    
    gtk_window_get_position_(*This\WindowID, *PosX, *PosY)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Les mutateurs <<<<<
  
  Procedure SetPosition(*This.Private_Members, Position.i = #GTK_WIN_POS_NONE)
    
    gtk_window_set_position_(*This\WindowID, Position)
    
  EndProcedure
  
  Procedure SetSize(*This.Private_Members, Width.l, Height.l)
    
    gtk_window_set_default_size_(*This\WindowID, Width, Height)
    
  EndProcedure
  
  Procedure SetTitle(*This.Private_Members, Title.s)
    
    gtk_window_set_title_(*This\WindowID, Title)
    
  EndProcedure
  
  Procedure SetResizable(*This.Private_Members, Resizable.i)
    
    gtk_window_set_resizable_(*This\WindowID, Resizable)
    
  EndProcedure
  
  Procedure SetBorderWidth(*This.Private_Members, BorderWidth.l)
    
    gtk_container_set_border_width_(*This\WindowID, BorderWidth)
    
  EndProcedure
  
  Procedure SetTransientFor(*This.Private_Members, *Parent)
    
    gtk_window_set_transient_for_(*This\WindowID, *Parent)
    
  EndProcedure

  Procedure SetKeepAbove(*This.Private_Members, Setting.i)
    
    gtk_window_set_keep_above_(*This\WindowID, Setting)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< L'opérateur Move <<<<<
  
  Procedure Move(*This.Private_Members, X.l, Y.l)
    
    gtk_window_move_(*This\WindowID, X, Y)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< L'opérateur Show <<<<<
  
  Procedure Show(*This.Private_Members)
    
     gtk_widget_show_all_(*This\WindowID)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Nom de la procédure <<<<<
  
  Procedure SignalConnect(*This.Private_Members, SignalName.s, *CallBack, UserData.i)
    
    g_signal_connect_(*This\WindowID, SignalName, *CallBack, UserData)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Nom de la procédure <<<<<
  
  Procedure AddWidget(*This.Private_Members, *Widget)
    
    gtk_container_add_(*This\WindowID, *Widget)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Le Destructeur <<<<<

  Procedure Free(*This.Private_Members)
    
    FreeStructure(*This)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Le Constructeur <<<<<

  Procedure.i New()
    
    *This.Private_Members = AllocateStructure(Private_Members)
    *This\VirtualTable = ?START_METHODS
    
    *This\WindowID = gtk_window_new_(#GTK_WINDOW_TOPLEVEL)
    
    ProcedureReturn *This
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Les entrées de la table virtuelle <<<<<

  DataSection
    START_METHODS:
    Data.i @GetID()
    Data.i @GetPosition()
    Data.i @SetPosition()
    Data.i @SetSize()
    Data.i @SetTitle()
    Data.i @SetResizable()
    Data.i @SetBorderWidth()
    Data.i @SetTransientFor()
    Data.i @SetKeepAbove()
    Data.i @Move()
    Data.i @Show()
    Data.i @SignalConnect()
    Data.i @AddWidget()
    Data.i @Free()
    END_METHODS:
  EndDataSection
  
EndModule

DeclareModule GtkListView
  
  Interface ListView
    
    GetID.i()
    AppendItem(Definition.s)
    Free()
    
  EndInterface
  
  Declare.i New(ColumnNames.s)
  
EndDeclareModule

Module GtkListView
  
  ImportC ""
    
    gtk_tree_view_set_grid_lines(*Widget, Flag.i)
    
  EndImport
  
  
  Macro G_TYPE_MAKE_FUNDAMENTAL(x)
    
    x << 2
    
  EndMacro
  
  #G_TYPE_INVALID = G_TYPE_MAKE_FUNDAMENTAL(0)
  #G_TYPE_NONE = G_TYPE_MAKE_FUNDAMENTAL(1)
  #G_TYPE_INTERFACE = G_TYPE_MAKE_FUNDAMENTAL(2)
  #G_TYPE_CHAR = G_TYPE_MAKE_FUNDAMENTAL(3)
  #G_TYPE_UCHAR = G_TYPE_MAKE_FUNDAMENTAL(4)
  #G_TYPE_BOOLEAN = G_TYPE_MAKE_FUNDAMENTAL(5)
  #G_TYPE_INT = G_TYPE_MAKE_FUNDAMENTAL(6)
  #G_TYPE_UINT = G_TYPE_MAKE_FUNDAMENTAL(7)
  #G_TYPE_LONG = G_TYPE_MAKE_FUNDAMENTAL(8)
  #G_TYPE_ULONG = G_TYPE_MAKE_FUNDAMENTAL(9)
  #G_TYPE_INT64 = G_TYPE_MAKE_FUNDAMENTAL(10)
  #G_TYPE_UINT64 = G_TYPE_MAKE_FUNDAMENTAL(11)
  #G_TYPE_ENUM = G_TYPE_MAKE_FUNDAMENTAL(12)
  #G_TYPE_FLAGS = G_TYPE_MAKE_FUNDAMENTAL(13)
  #G_TYPE_FLOAT = G_TYPE_MAKE_FUNDAMENTAL(14)
  #G_TYPE_DOUBLE = G_TYPE_MAKE_FUNDAMENTAL(15)
  #G_TYPE_STRING = G_TYPE_MAKE_FUNDAMENTAL(16)
  #G_TYPE_POINTER = G_TYPE_MAKE_FUNDAMENTAL(17)
  #G_TYPE_BOXED = G_TYPE_MAKE_FUNDAMENTAL(18)
  #G_TYPE_PARAM = G_TYPE_MAKE_FUNDAMENTAL(19)
  #G_TYPE_OBJECT = G_TYPE_MAKE_FUNDAMENTAL(20)
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Déclaration des Structures <<<<<
  
  Structure Private_Members
    
    VirtualTable.i
    *ListViewID
    *ScrolledWindowID
    
  EndStructure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Les observateurs <<<<<

  Procedure.i GetID(*This.Private_Members)
    
    ProcedureReturn *This\ScrolledWindowID
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< L'opérateur AppendColumn <<<<<

  Procedure AppendItem(*This.Private_Members, Definition.s)
    
    Protected Iter.GtkTreeIter, Value.GValue
    
    *ListStore = gtk_tree_view_get_model_(*This\ListViewID)
    
    gtk_list_store_append_(*ListStore, @Iter)
    
    If gtk_list_store_iter_is_valid_(*ListStore, @Iter)
      
      ColumnMax.l = CountString(Definition, Chr(10))
      
      For ColumnID = 0 To ColumnMax 
        
        CellValue.s = StringField(Definition, ColumnID+1, Chr(10))
        g_value_init_(@Value, #G_TYPE_STRING)
        g_value_set_string_(@Value, CellValue)
        
        *ExtractedValue = g_value_get_string_(@Value)
        
        If *ExtractedValue <> #Null
          Debug CellValue + " vs " + PeekS(*ExtractedValue, -1, #PB_UTF8)
        Else
          Debug CellValue + " vs NUll Pointer"
        EndIf
        
        gtk_list_store_set_value_(*ListStore, @Iter, ColumnID, @Value)
        
      Next
      
    EndIf
    
  EndProcedure
 
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Le Destructeur <<<<<

  Procedure Free(*This.Private_Members)
    
    FreeStructure(*This)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Le Constructeur <<<<<

  Procedure.i New(ColumnNames.s)
    
    *This.Private_Members = AllocateStructure(Private_Members)
    *This\VirtualTable = ?START_METHODS
    
    *This\ScrolledWindowID = gtk_scrolled_window_new_(#Null, #Null)
    
    gtk_scrolled_window_set_shadow_type_(*This\ScrolledWindowID, #GTK_SHADOW_IN)
    
    *This\ListViewID = gtk_tree_view_new_()
    gtk_container_add_(*This\ScrolledWindowID, *This\ListViewID)
    
    
    ColumnMax.l = CountString(ColumnNames, Chr(10))
    
   *GTYPE = AllocateMemory((ColumnMax+1) * SizeOf(Integer))
   FillMemory(*GTYPE, (ColumnMax+1) * SizeOf(Integer), #G_TYPE_STRING, #PB_Integer)
;     *Cursor = *GTYPE
    
    For ColumnID = 0 To ColumnMax
      
      *CellRenderer = gtk_cell_renderer_text_new_()
      *TreeViewColumnID = gtk_tree_view_column_new_()
      gtk_tree_view_column_add_attribute_(*TreeViewColumnID, *CellRenderer, "text", ColumnID)
      gtk_tree_view_append_column_(*This\ListViewID, *TreeViewColumnID)
      gtk_tree_view_column_set_title_(*TreeViewColumnID, StringField(ColumnNames, ColumnID+1, Chr(10)))
      
      gtk_tree_view_append_column_(*This\ListViewID, *TreeViewColumnID) 
      
;       Debug Str(PeekI(*Cursor)) + " vs #G_TYPE_STRING (" + Str(#G_TYPE_STRING) + ")"
;       *Cursor + SizeOf(Integer)
      
    Next

    *ListStore = gtk_list_store_newv_(ColumnMax, *GTYPE)
    FreeMemory(*GTYPE)
    
    gtk_tree_view_set_model_(*This\ListViewID, *ListStore)
    
    g_object_unref_(*ListStore)
    
;     gtk_tree_view_set_headers_clickable_(*This\ListViewID, #True)
;     gtk_tree_view_columns_autosize_(*This\ListViewID)
    gtk_tree_view_set_grid_lines(*This\ListViewID, 3)
    
    ProcedureReturn *This
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Les entrées de la table virtuelle <<<<<

  DataSection
    START_METHODS:
    Data.i @GetID()
    Data.i @AppendItem()
    Data.i @Free()
    END_METHODS:
  EndDataSection
  
EndModule

CompilerIf #PB_Compiler_IsMainFile
  
  ProcedureC WindowDeleteEventHandler(*Widget.GtkWidget, *Event.GdkEventAny, UserData.I)
    
    ;Debug "WindowDeleteEventHandler"
    gtk_window_get_position_(*Widget, @X.l, @Y.l)
    
    ;Debug "Position (x,y) = (" + Str(X) + "," + Str(Y) + ")"
    
  EndProcedure
  
  ProcedureC WindowCloseHandler(*Widget.GtkWidget, *Event.GdkEventAny, UserData.I)
    
    ;Debug "WindowCloseHandler"
    gtk_window_get_position_(*Widget, @X.l, @Y.l)
    
    ;Debug "Position (x,y) = (" + Str(X) + "," + Str(Y) + ")"
    
    gtk_main_quit_()
    
  EndProcedure

  gtk_init_(0, 0)
  
  MainWin.GtkWindow::Window = GtkWindow::New()
  MainWin\SetSize(400, 300)
  MainWin\SetTitle("GtkListView Example")
  MainWin\SetPosition(#GTK_WIN_POS_CENTER)
  MainWin\SetResizable(#False)
  MainWin\SetBorderWidth(5)
  
  MainWin\SignalConnect("delete-event", @WindowDeleteEventHandler(), 25)
  MainWin\SignalConnect("destroy", @WindowCloseHandler(), 0)
  
  ListView.GtkListView::ListView = GtkListView::New("File Name" + Chr(10) + "Status")
  
  ListView\AppendItem("Vector2f - OOP.pb" + Chr(10) + "OK")
  ListView\AppendItem("Vector3f - OOP.pb" + Chr(10) + "OK")
  ListView\AppendItem("Vector4f - OOP.pb" + Chr(10) + "OK")
  
  
  MainWin\AddWidget(ListView\GetID())
  
  MainWin\Show()
  
  gtk_main_()
  
  MainWin\Free()
  
CompilerEndIf

; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< END OF FILE <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<
The Stone Age did not end due to a shortage of stones !
User avatar
StarBootics
Addict
Addict
Posts: 984
Joined: Sun Jul 07, 2013 11:35 am
Location: Canada

Re: GtkTreeView Example Partially working

Post by StarBootics »

Hello everyone,

I definitively need to investigate more about GTK 3. I have spent some time re-writing my previous example in C using the same function I have used in PureBasic. I have some Gtk-CRITICAL**: gtl_cell_area_attribute_connect : assertion ‘gtk_cell_area_has_renderer (area, renderer)’ failed.

I'm making some progress but ...

Best regards
StarBootics

Code: Select all

#include <stdlib.h>
#include <gtk/gtk.h>
#include <glib.h>

int main (int argc, char *argv[])
{

    enum {
        COLUMN_FILENAME,
        COLUMN_STATUS,
        N_COLUMNS
    };

    GtkWidget *win = NULL;
    GtkWidget *Scrollwin = NULL;
    GtkWidget *ListView = NULL;
    GtkCellRenderer *CellRenderer = NULL;
    GtkTreeViewColumn *TreeViewColumnID = NULL;
    GtkTreeModel *list_store = NULL;

    /* Initialize GTK+ */
    /*g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING, (GLogFunc) gtk_false, NULL);*/
    gtk_init (&argc, &argv);
    /*g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING, g_log_default_handler, NULL);*/

    /* Create the main window */
    win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_container_set_border_width (GTK_CONTAINER (win), 8);
    gtk_window_set_title (GTK_WINDOW (win), "Hello World");
    gtk_window_set_position (GTK_WINDOW (win), GTK_WIN_POS_CENTER);
    gtk_window_set_default_size(GTK_WINDOW (win), 400, 300);
    gtk_container_set_border_width(win, 5);
    //gtk_widget_realize (win);

    g_signal_connect (win, "destroy", gtk_main_quit, NULL);

    Scrollwin = gtk_scrolled_window_new(NULL, NULL);
    gtk_scrolled_window_set_shadow_type(Scrollwin, GTK_SHADOW_IN);

    gint64 GTYPES[N_COLUMNS];
    GTYPES[COLUMN_FILENAME] = G_TYPE_STRING;
    GTYPES[COLUMN_STATUS] = G_TYPE_STRING;

    list_store = gtk_list_store_newv(N_COLUMNS, GTYPES);

    GValue Value;
    g_value_init(&Value, G_TYPE_STRING);

    GtkTreeIter Iter;

    gtk_list_store_append(GTK_LIST_STORE(list_store), &Iter);

    if(gtk_list_store_iter_is_valid(GTK_LIST_STORE(list_store), &Iter))
    {

        g_value_set_string(&Value, "Vector2f - OOP.pb");
        gtk_list_store_set_value(GTK_LIST_STORE(list_store), &Iter, COLUMN_FILENAME, &Value);

        g_value_set_string(&Value, "OK");
        gtk_list_store_set_value(GTK_LIST_STORE(list_store), &Iter, COLUMN_STATUS, &Value);

    }

    gtk_list_store_append(GTK_LIST_STORE(list_store), &Iter);

    if(gtk_list_store_iter_is_valid(GTK_LIST_STORE(list_store), &Iter))
    {

        g_value_set_string(&Value, "Vector3f - OOP.pb");
        gtk_list_store_set_value(GTK_LIST_STORE(list_store), &Iter, COLUMN_FILENAME, &Value);

        g_value_set_string(&Value, "OK");
        gtk_list_store_set_value(GTK_LIST_STORE(list_store), &Iter, COLUMN_STATUS, &Value);

    }

    gtk_list_store_append(GTK_LIST_STORE(list_store), &Iter);

    if(gtk_list_store_iter_is_valid(GTK_LIST_STORE(list_store), &Iter))
    {
        g_value_set_string(&Value, "Vector4f - OOP.pb");
        gtk_list_store_set_value(GTK_LIST_STORE(list_store), &Iter, COLUMN_FILENAME, &Value);

        g_value_set_string(&Value, "OK");
        gtk_list_store_set_value(GTK_LIST_STORE(list_store), &Iter, COLUMN_STATUS, &Value);

    }

    ListView = gtk_tree_view_new();
    gtk_tree_view_set_model(ListView, list_store);
    gtk_tree_view_set_grid_lines(ListView, 3);

    gtk_container_add(Scrollwin, ListView);

    CellRenderer = gtk_cell_renderer_text_new();
    TreeViewColumnID = gtk_tree_view_column_new();
    gtk_tree_view_column_add_attribute(TreeViewColumnID, CellRenderer, "text", 0);
    gtk_tree_view_append_column(ListView, TreeViewColumnID);
    gtk_tree_view_column_set_title(TreeViewColumnID, "FileName");

    CellRenderer = gtk_cell_renderer_text_new();
    TreeViewColumnID = gtk_tree_view_column_new();
    gtk_tree_view_column_add_attribute(TreeViewColumnID, CellRenderer, "text", 1);
    gtk_tree_view_append_column(ListView, TreeViewColumnID);
    gtk_tree_view_column_set_title(TreeViewColumnID, "Status");

    gtk_container_add(win, Scrollwin);

    /* Enter the main loop */
    gtk_widget_show_all (win);
    gtk_main ();
    return 0;
}
The Stone Age did not end due to a shortage of stones !
User avatar
Shardik
Addict
Addict
Posts: 1991
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: GtkTreeView Example Partially working

Post by Shardik »

In your second PureBasic example you have definitely two bugs:
  1. In GtkListView::New you have forgotten to pack your column. So you should change

    Code: Select all

          *CellRenderer = gtk_cell_renderer_text_new_()
          *TreeViewColumnID = gtk_tree_view_column_new_()
          gtk_tree_view_column_add_attribute_(*TreeViewColumnID, *CellRenderer, "text", ColumnID)
          gtk_tree_view_append_column_(*This\ListViewID, *TreeViewColumnID)
          gtk_tree_view_column_set_title_(*TreeViewColumnID, StringField(ColumnNames, ColumnID+1, Chr(10)))
    
    to

    Code: Select all

          *CellRenderer = gtk_cell_renderer_text_new_()
          *TreeViewColumnID = gtk_tree_view_column_new_()
    
          ; ----- Pack new column
          gtk_tree_view_column_pack_start_(*TreeViewColumnID, *CellRenderer, ColumnID + 1)
          ; ---------------------
    
          gtk_tree_view_column_add_attribute_(*TreeViewColumnID, *CellRenderer, "text", ColumnID)
          gtk_tree_view_append_column_(*This\ListViewID, *TreeViewColumnID)
          gtk_tree_view_column_set_title_(*TreeViewColumnID, StringField(ColumnNames, ColumnID+1, Chr(10)))
    
  2. In GtkListView::AppendItem you have to convert your cell text from Unicode to UTF8. Furthermore I had to change g_value_set_string_() into directly setting the pointer Value\data\v_pointer. So you should change

    Code: Select all

          For ColumnID = 0 To ColumnMax 
            
            CellValue.s = StringField(Definition, ColumnID+1, Chr(10))
            g_value_init_(@Value, #G_TYPE_STRING)
            g_value_set_string_(@Value, CellValue)
            
            *ExtractedValue = g_value_get_string_(@Value)
            
            If *ExtractedValue <> #Null
              Debug CellValue + " vs " + PeekS(*ExtractedValue, -1, #PB_UTF8)
            Else
              Debug CellValue + " vs NUll Pointer"
            EndIf
            
            gtk_list_store_set_value_(*ListStore, @Iter, ColumnID, @Value)
            
          Next
    
    to

    Code: Select all

          For ColumnID = 0 To ColumnMax 
    
            CellValue.s = StringField(Definition, ColumnID+1, Chr(10))
            g_value_init_(@Value, #G_TYPE_STRING)
    ;         g_value_set_string_(@Value, CellValue)
    
            ; ----- Convert CellValue to UTF8
            CellValueUTF8.s = Space(StringByteLength(CellValue, #PB_UTF8))
            PokeS(@CellValueUTF8, CellValue, -1, #PB_UTF8)
    
            ; ----- Change   
            ; g_value_set_string_(@Value, CellValue)
            ; to
            Value\data\v_pointer = @CellValueUTF8
    ;         Debug PeekS(g_value_get_string_(@Value), -1, #PB_UTF8)
    
    ;         *ExtractedValue = g_value_get_string_(@Value)
    ;         
    ;         If *ExtractedValue <> #Null
    ;           Debug CellValue + " vs " + PeekS(*ExtractedValue, -1, #PB_UTF8)
    ;         Else
    ;           Debug CellValue + " vs NUll Pointer"
    ;         EndIf
    
            gtk_list_store_set_value_(*ListStore, @Iter, ColumnID, @Value)
    
After applying these two changes, the values in the first column will be displayed. Unfortunately the values in the second column are still missing. I did a lot of tests but I still haven't been successful in displaying also the values in the second column.

Therefore I have written my own much more simple test code with a PureBasic window and an API ListStore and API ListView and it works like a charm:

Code: Select all

EnableExplicit

#ColumnCount = 2
#ColumnNameList = "Item #" + #LF$ + "Status"

#G_TYPE_STRING = 16 << 2

Define *CellRenderer.GtkCellRenderer
Define *Column.GtkTreeViewColumn
Define ColumnTypeString.I = #G_TYPE_STRING
Define i.I
Define *ListView.GtkWidget
Define *ListStore.GtkListStore
Define *Window.GtkWindow

Dim TypeArray.I(#ColumnCount - 1)

Procedure GetChildContainer(WindowID.I)
  Protected Container.I

  Container = g_list_nth_data_(gtk_container_get_children_(0 +
    gtk_bin_get_child_(WindowID(0))), 0)
  
  ProcedureReturn Container
EndProcedure

Procedure AddRow(*ListStore, RowText.S)
  Protected CellValue.GValue
  Protected Iter.GtkTreeIter
  Protected i.I
  Protected ItemText.S
  Protected ItemTextUTF8.S
  
  g_value_init_(@CellValue, #G_TYPE_STRING)
  gtk_list_store_append_(*ListStore, @Iter)

  For i = 0 To #ColumnCount - 1  
    ItemText = StringField(RowText, i + 1, #LF$)
    ItemTextUTF8 = Space(StringByteLength(ItemText, #PB_UTF8))
    PokeS(@ItemTextUTF8, ItemText, -1, #PB_UTF8)
    CellValue\data\v_pointer = @ItemTextUTF8
    gtk_list_store_set_value_(*ListStore, @Iter, i, @CellValue)
  Next i
EndProcedure

*Window = OpenWindow(0, 140, 100, 240, 140, "API ListView",
  #PB_Window_SizeGadget)

For i = 0 To #ColumnCount - 1
  TypeArray(i) = #G_TYPE_STRING
Next i

*ListStore = gtk_list_store_newv_(#ColumnCount, @TypeArray())
*ListView = gtk_tree_view_new_with_model_(*ListStore)

For i = 0 To #ColumnCount - 1
  *CellRenderer = gtk_cell_renderer_text_new_()
  *Column = gtk_tree_view_column_new_()
  gtk_tree_view_column_pack_start_(*Column, *CellRenderer, i + 1)
  gtk_tree_view_column_add_attribute_(*Column, *CellRenderer, "text", i)
  gtk_tree_view_append_column_(*ListView, *Column)
  gtk_tree_view_column_set_title_(*Column, StringField(#ColumnNameList,
    i + 1, #LF$))
Next i

If Subsystem("gtk2")
  gtk_fixed_put_(GetChildContainer(0), *ListView, 10, 10)
Else
  gtk_layout_put_(GetChildContainer(0), *ListView, 10, 10)
EndIf

gtk_widget_set_size_request_(*ListView, WindowWidth(0) - 20,
  WindowHeight(0) - 20)

For i = 1 To 4
  AddRow(*ListStore, "Item " + Str(i) + #LF$ + "OK")
Next i 

gtk_widget_show_all_(*Window)

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
I have done all my tests on Linux Mint 19.3 x64 'Tricia' with Cinnamon and GTK3 using PB 5.73 x64 and PB 6.00 Beta 6 x64 with Asm and C backend. My own example is working with both GTK2 and GTK3.
User avatar
StarBootics
Addict
Addict
Posts: 984
Joined: Sun Jul 07, 2013 11:35 am
Location: Canada

Re: GtkTreeView Example Partially working

Post by StarBootics »

Hello Shardik,

Many thanks for your input to the problem I have experienced, very appreciated. :D
Shardik wrote: Tue Apr 12, 2022 3:49 pm After applying these two changes, the values in the first column will be displayed. Unfortunately the values in the second column are still missing. I did a lot of tests but I still haven't been successful in displaying also the values in the second column.
This is strange because here on my computer (Ubuntu 21.10) after your suggested modification I have the text showing in both columns. I can see the "Vector2f - OOP.pb" in the first column and "OK" in the second column and so on for the other rows.

Oh, by the way, the g_value_init_(@Value, #G_TYPE_STRING) should be done only once and not at every loop. I have discovered this during the pure C code testing session.

Thanks again.

Best regards
StarBootics
The Stone Age did not end due to a shortage of stones !
User avatar
Shardik
Addict
Addict
Posts: 1991
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: GtkTreeView Example Partially working

Post by Shardik »

StarBootics wrote: Tue Apr 12, 2022 4:31 pm
Shardik wrote: Tue Apr 12, 2022 3:49 pm After applying these two changes, the values in the first column will be displayed. Unfortunately the values in the second column are still missing. I did a lot of tests but I still haven't been successful in displaying also the values in the second column.
This is strange because here on my computer (Ubuntu 21.10) after your suggested modification I have the text showing in both columns. I can see the "Vector2f - OOP.pb" in the first column and "OK" in the second column and so on for the other rows.
I am glad that my two suggested modifications have solved your problem on your Ubuntu 21.10.

StarBootics wrote: Oh, by the way, the g_value_init_(@Value, #G_TYPE_STRING) should be done only once and not at every loop. I have discovered this during the pure C code testing session.
I was aware of this bug but moving g_value_init_() before the loop didn't solve the problem of only displaying the values of the first column on my Linux Mint 19.3 Cinnamon. As you may have seen in my own example in procedure AddRow() I had already placed g_value_init_() before the loop.
User avatar
StarBootics
Addict
Addict
Posts: 984
Joined: Sun Jul 07, 2013 11:35 am
Location: Canada

Re: GtkTreeView Example Partially working

Post by StarBootics »

Hello Shardik,

If you launch trough a terminal the "gtk-launch --version" what do you get as GTK version.

On Ubuntu 21.10, I get 3.24.30

Best regards
StarBootics
The Stone Age did not end due to a shortage of stones !
User avatar
Shardik
Addict
Addict
Posts: 1991
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: GtkTreeView Example Partially working

Post by Shardik »

My GTK version is 3.22.20. I also considered a different GTK version for causing my problem of the empty text cells in the second column but that can't be the case because my posted example with a PB window and API ListView works like a charm and displays the text in both the first and second column.
User avatar
StarBootics
Addict
Addict
Posts: 984
Joined: Sun Jul 07, 2013 11:35 am
Location: Canada

Re: GtkTreeView Example Partially working

Post by StarBootics »

Hello everyone,

@Shardik : I have re-worked your example a little bit, my guess it's no longer working :

Code: Select all

EnableExplicit

#ColumnCount = 2
#ColumnNameList = "Item #" + #LF$ + "Status"

#G_TYPE_STRING = 16 << 2

Define *CellRenderer.GtkCellRenderer
Define *Column.GtkTreeViewColumn
Define ColumnTypeString.I = #G_TYPE_STRING
Define i.I
Define *ListView.GtkWidget
Define *ListStore.GtkListStore
Define *Window.GtkWindow

Dim TypeArray.I(#ColumnCount - 1)

; Procedure GetChildContainer(WindowID.I)
;   Protected Container.I
; 
;   Container = g_list_nth_data_(gtk_container_get_children_(0 + gtk_bin_get_child_(WindowID(WindowID))), 0)
;   
;   ProcedureReturn Container
; EndProcedure

ProcedureC WindowCloseHandler(*Widget.GtkWidget, *Event.GdkEventAny, UserData.I)
  
  Protected X.l, Y.l
  
  Debug "WindowCloseHandler"
  gtk_window_get_position_(*Widget, @X, @Y)
  
  Debug "Position (x,y) = (" + Str(X) + "," + Str(Y) + ")"
  
  gtk_main_quit_()
  
EndProcedure
  
Procedure AddRow(*ListStore, RowText.S)
  Protected CellValue.GValue
  Protected Iter.GtkTreeIter
  Protected i.I
  Protected ItemText.S
  Protected ItemTextUTF8.S
  
  g_value_init_(@CellValue, #G_TYPE_STRING)
  gtk_list_store_append_(*ListStore, @Iter)

  For i = 0 To #ColumnCount - 1  
    ItemText = StringField(RowText, i + 1, #LF$)
    ItemTextUTF8 = Space(StringByteLength(ItemText, #PB_UTF8))
    PokeS(@ItemTextUTF8, ItemText, -1, #PB_UTF8)
    CellValue\data\v_pointer = @ItemTextUTF8
    gtk_list_store_set_value_(*ListStore, @Iter, i, @CellValue)
  Next i
  
EndProcedure

gtk_init_(0, 0)

*Window = gtk_window_new_(#GTK_WINDOW_TOPLEVEL)
gtk_window_set_title_(*Window, "API ListView")
gtk_container_set_border_width_(*Window, 5)
g_signal_connect_(*Window, "destroy", @WindowCloseHandler(), 0)

; OpenWindow(0, 140, 100, 240, 140, "API ListView", #PB_Window_SizeGadget)

For i = 0 To #ColumnCount - 1
  TypeArray(i) = #G_TYPE_STRING
Next i

*ListStore = gtk_list_store_newv_(#ColumnCount, @TypeArray())
*ListView = gtk_tree_view_new_with_model_(*ListStore)

For i = 0 To #ColumnCount - 1
  *CellRenderer = gtk_cell_renderer_text_new_()
  *Column = gtk_tree_view_column_new_()
  gtk_tree_view_column_pack_start_(*Column, *CellRenderer, i + 1)
  gtk_tree_view_column_add_attribute_(*Column, *CellRenderer, "text", i)
  gtk_tree_view_append_column_(*ListView, *Column)
  gtk_tree_view_column_set_title_(*Column, StringField(#ColumnNameList, i + 1, #LF$))
Next i

; If Subsystem("gtk2")
;   gtk_fixed_put_(GetChildContainer(0), *ListView, 10, 10)
; Else
;   gtk_layout_put_(GetChildContainer(0), *ListView, 10, 10)
; EndIf

gtk_container_add_(*Window, *ListView)
; gtk_container_add_(GetChildContainer(0), *ListView)

; gtk_widget_set_size_request_(*ListView, WindowWidth(0) - 20,
;   WindowHeight(0) - 20)

For i = 1 To 4
  AddRow(*ListStore, "Item " + Str(i) + #LF$ + "OK")
Next i 

gtk_widget_show_all_(*Window)

gtk_main_()

; Repeat
; Until WaitWindowEvent() = #PB_Event_CloseWindow
On my computer it work.

Best regards
StarBootics
The Stone Age did not end due to a shortage of stones !
User avatar
Shardik
Addict
Addict
Posts: 1991
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: GtkTreeView Example Partially working

Post by Shardik »

StarBootics wrote: Wed Apr 13, 2022 11:00 pm @Shardik : I have re-worked your example a little bit, my guess it's no longer working :
Your modified version of my example with an API window is also working like a charm on my Linux Mint 19.3 x64 'Tricia' with Cinnamon and GTK 3.22.20 displaying both columns with text.
User avatar
StarBootics
Addict
Addict
Posts: 984
Joined: Sun Jul 07, 2013 11:35 am
Location: Canada

Re: GtkTreeView Example Partially working

Post by StarBootics »

Shardik wrote: Thu Apr 14, 2022 9:30 am Your modified version of my example with an API window is also working like a charm on my Linux Mint 19.3 x64 'Tricia' with Cinnamon and GTK 3.22.20 displaying both columns with text.
Little bit more modifications, I have replaced the TypeArray() with an allocated memory block. (After code review it's the only difference between your code and mine.)

Code: Select all

EnableExplicit

#ColumnCount = 2
#ColumnNameList = "Item #" + #LF$ + "Status"

#G_TYPE_STRING = 16 << 2

Define *CellRenderer.GtkCellRenderer
Define *Column.GtkTreeViewColumn
Define ColumnTypeString.I = #G_TYPE_STRING
Define i.I
Define *ListView.GtkWidget
Define *ListStore.GtkListStore
Define *Window.GtkWindow
Define *GTYPE

; Dim TypeArray.I(#ColumnCount - 1)

; Procedure GetChildContainer(WindowID.I)
;   Protected Container.I
; 
;   Container = g_list_nth_data_(gtk_container_get_children_(0 + gtk_bin_get_child_(WindowID(WindowID))), 0)
;   
;   ProcedureReturn Container
; EndProcedure

ProcedureC WindowCloseHandler(*Widget.GtkWidget, *Event.GdkEventAny, UserData.I)
  
  Protected X.l, Y.l
  
  Debug "WindowCloseHandler"
  gtk_window_get_position_(*Widget, @X, @Y)
  
  Debug "Position (x,y) = (" + Str(X) + "," + Str(Y) + ")"
  
  gtk_main_quit_()
  
EndProcedure
  
Procedure AddRow(*ListStore, RowText.S)
  
  Protected CellValue.GValue
  Protected Iter.GtkTreeIter
  Protected i.I
  Protected ItemText.S
  Protected ItemTextUTF8.S
  
  g_value_init_(@CellValue, #G_TYPE_STRING)
  gtk_list_store_append_(*ListStore, @Iter)

  For i = 0 To #ColumnCount - 1  
    ItemText = StringField(RowText, i + 1, #LF$)
    ItemTextUTF8 = Space(StringByteLength(ItemText, #PB_UTF8))
    PokeS(@ItemTextUTF8, ItemText, -1, #PB_UTF8)
    CellValue\data\v_pointer = @ItemTextUTF8
    gtk_list_store_set_value_(*ListStore, @Iter, i, @CellValue)
  Next i
  
EndProcedure

gtk_init_(0, 0)

*Window = gtk_window_new_(#GTK_WINDOW_TOPLEVEL)
gtk_window_set_title_(*Window, "API ListView")
gtk_container_set_border_width_(*Window, 5)
g_signal_connect_(*Window, "destroy", @WindowCloseHandler(), 0)

; OpenWindow(0, 140, 100, 240, 140, "API ListView", #PB_Window_SizeGadget)

; For i = 0 To #ColumnCount - 1
;   TypeArray(i) = #G_TYPE_STRING
; Next i

*GTYPE = AllocateMemory((#ColumnCount) * SizeOf(Integer))

FillMemory(*GTYPE, (#ColumnCount) * SizeOf(Integer), #G_TYPE_STRING, #PB_Integer)
*ListStore = gtk_list_store_newv_(#ColumnCount, *GTYPE)
FreeMemory(*GTYPE)

; *ListStore = gtk_list_store_newv_(#ColumnCount, @TypeArray())
*ListView = gtk_tree_view_new_with_model_(*ListStore)

For i = 0 To #ColumnCount - 1
  *CellRenderer = gtk_cell_renderer_text_new_()
  *Column = gtk_tree_view_column_new_()
  gtk_tree_view_column_pack_start_(*Column, *CellRenderer, i + 1)
  gtk_tree_view_column_add_attribute_(*Column, *CellRenderer, "text", i)
  gtk_tree_view_append_column_(*ListView, *Column)
  gtk_tree_view_column_set_title_(*Column, StringField(#ColumnNameList, i + 1, #LF$))
Next i

; If Subsystem("gtk2")
;   gtk_fixed_put_(GetChildContainer(0), *ListView, 10, 10)
; Else
;   gtk_layout_put_(GetChildContainer(0), *ListView, 10, 10)
; EndIf

gtk_container_add_(*Window, *ListView)
; gtk_container_add_(GetChildContainer(0), *ListView)

; gtk_widget_set_size_request_(*ListView, WindowWidth(0) - 20,
;   WindowHeight(0) - 20)

For i = 1 To 4
  AddRow(*ListStore, "Item " + Str(i) + #LF$ + "OK")
Next i 

gtk_widget_show_all_(*Window)

gtk_main_()

; Repeat
; Until WaitWindowEvent() = #PB_Event_CloseWindow
Still working ?

Another version with the AddRow() procedure modified :

Code: Select all

EnableExplicit

#ColumnCount = 2
#ColumnNameList = "Item #" + #LF$ + "Status"

#G_TYPE_STRING = 16 << 2

Define *CellRenderer.GtkCellRenderer
Define *Column.GtkTreeViewColumn
Define ColumnTypeString.I = #G_TYPE_STRING
Define i.I
Define *ListView.GtkWidget
Define *ListStore.GtkListStore
Define *Window.GtkWindow
Define *GTYPE

; Dim TypeArray.I(#ColumnCount - 1)

; Procedure GetChildContainer(WindowID.I)
;   Protected Container.I
; 
;   Container = g_list_nth_data_(gtk_container_get_children_(0 + gtk_bin_get_child_(WindowID(WindowID))), 0)
;   
;   ProcedureReturn Container
; EndProcedure

ProcedureC WindowCloseHandler(*Widget.GtkWidget, *Event.GdkEventAny, UserData.I)
  
  Protected X.l, Y.l
  
  Debug "WindowCloseHandler"
  gtk_window_get_position_(*Widget, @X, @Y)
  
  Debug "Position (x,y) = (" + Str(X) + "," + Str(Y) + ")"
  
  gtk_main_quit_()
  
EndProcedure
  
Procedure AddRow(*ListStore, RowText.S)
  
  Protected CellValue.GValue
  Protected Iter.GtkTreeIter
  Protected i.I
  
  g_value_init_(@CellValue, #G_TYPE_STRING)
  gtk_list_store_append_(*ListStore, @Iter)

;   For i = 0 To #ColumnCount - 1  
;     ItemText = StringField(RowText, i + 1, #LF$)
;     ItemTextUTF8 = Space(StringByteLength(ItemText, #PB_UTF8))
;     PokeS(@ItemTextUTF8, ItemText, -1, #PB_UTF8)
;     CellValue\data\v_pointer = @ItemTextUTF8
;     gtk_list_store_set_value_(*ListStore, @Iter, i, @CellValue)
;   Next i
  
  For i = 0 To #ColumnCount - 1  

    CellValue\data\v_pointer = UTF8(StringField(RowText, i + 1, #LF$))
    gtk_list_store_set_value_(*ListStore, @Iter, i, @CellValue)
    FreeMemory(CellValue\data\v_pointer)
    
  Next i
  
EndProcedure

gtk_init_(0, 0)

*Window = gtk_window_new_(#GTK_WINDOW_TOPLEVEL)
gtk_window_set_title_(*Window, "API ListView")
gtk_container_set_border_width_(*Window, 5)
g_signal_connect_(*Window, "destroy", @WindowCloseHandler(), 0)

; OpenWindow(0, 140, 100, 240, 140, "API ListView", #PB_Window_SizeGadget)

; For i = 0 To #ColumnCount - 1
;   TypeArray(i) = #G_TYPE_STRING
; Next i

*GTYPE = AllocateMemory((#ColumnCount) * SizeOf(Integer))

FillMemory(*GTYPE, (#ColumnCount) * SizeOf(Integer), #G_TYPE_STRING, #PB_Integer)
*ListStore = gtk_list_store_newv_(#ColumnCount, *GTYPE)
FreeMemory(*GTYPE)

; *ListStore = gtk_list_store_newv_(#ColumnCount, @TypeArray())
*ListView = gtk_tree_view_new_with_model_(*ListStore)

For i = 0 To #ColumnCount - 1
  *CellRenderer = gtk_cell_renderer_text_new_()
  *Column = gtk_tree_view_column_new_()
  gtk_tree_view_column_pack_start_(*Column, *CellRenderer, i + 1)
  gtk_tree_view_column_add_attribute_(*Column, *CellRenderer, "text", i)
  gtk_tree_view_append_column_(*ListView, *Column)
  gtk_tree_view_column_set_title_(*Column, StringField(#ColumnNameList, i + 1, #LF$))
Next i

; If Subsystem("gtk2")
;   gtk_fixed_put_(GetChildContainer(0), *ListView, 10, 10)
; Else
;   gtk_layout_put_(GetChildContainer(0), *ListView, 10, 10)
; EndIf

gtk_container_add_(*Window, *ListView)
; gtk_container_add_(GetChildContainer(0), *ListView)

; gtk_widget_set_size_request_(*ListView, WindowWidth(0) - 20,
;   WindowHeight(0) - 20)

For i = 1 To 4
  AddRow(*ListStore, "Item " + Str(i) + #LF$ + "OK")
Next i 

gtk_widget_show_all_(*Window)

gtk_main_()

; Repeat
; Until WaitWindowEvent() = #PB_Event_CloseWindow
What about this one ?

Best regards
StarBootics
The Stone Age did not end due to a shortage of stones !
User avatar
Shardik
Addict
Addict
Posts: 1991
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: GtkTreeView Example Partially working

Post by Shardik »

Both examples from your last posting are displaying the text correctly in both columns.
User avatar
StarBootics
Addict
Addict
Posts: 984
Joined: Sun Jul 07, 2013 11:35 am
Location: Canada

Re: GtkTreeView Example Partially working

Post by StarBootics »

OK final test :

Code: Select all

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Project name : Gtk List View Example
; File Name : Gtk List View Example.pb
; File version: 1.1.1
; Programming : Testing in progress
; Programmed by : StarBootics
; Date : April 8th, 2022
; Last Update : April 14th, 2022
; PureBasic code : V6.00 Beta 6
; Platform : Linux Only
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Programming Notes 
;
; This code is still experimental. Work fine on :
; 
; Ubuntu 21.10 (GTK V3.24.30)
;
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

DeclareModule GtkWindow
  
  Interface Window
    
    GetID.i()
    GetPosition(*PosX, *PosY)
    SetPosition(Position.i = #GTK_WIN_POS_NONE)
    SetSize(Width.l, Height.l)
    SetTitle(Title.s)
    SetResizable(Resizable.i)
    SetBorderWidth(BorderWidth.l)
    SetTransientFor(*Parent)
    SetKeepAbove(Setting.i)
    Move(X.l, Y.l)
    Show()
    SignalConnect(SignalName.s, *CallBack, UserData.i)
    AddWidget(*Widget)
    Free()
    
  EndInterface
  
  Declare.i New()
  
EndDeclareModule

Module GtkWindow
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Déclaration de la Structure <<<<<

  Structure Private_Members
    
    VirtualTable.i
    *WindowID
    
  EndStructure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Les observateurs <<<<<

  Procedure.i GetID(*This.Private_Members)
    
    ProcedureReturn *This\WindowID
  EndProcedure
  
  Procedure GetPosition(*This.Private_Members, *PosX, *PosY)
    
    gtk_window_get_position_(*This\WindowID, *PosX, *PosY)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Les mutateurs <<<<<
  
  Procedure SetPosition(*This.Private_Members, Position.i = #GTK_WIN_POS_NONE)
    
    gtk_window_set_position_(*This\WindowID, Position)
    
  EndProcedure
  
  Procedure SetSize(*This.Private_Members, Width.l, Height.l)
    
    gtk_window_set_default_size_(*This\WindowID, Width, Height)
    
  EndProcedure
  
  Procedure SetTitle(*This.Private_Members, Title.s)
    
    gtk_window_set_title_(*This\WindowID, Title)
    
  EndProcedure
  
  Procedure SetResizable(*This.Private_Members, Resizable.i)
    
    gtk_window_set_resizable_(*This\WindowID, Resizable)
    
  EndProcedure
  
  Procedure SetBorderWidth(*This.Private_Members, BorderWidth.l)
    
    gtk_container_set_border_width_(*This\WindowID, BorderWidth)
    
  EndProcedure
  
  Procedure SetTransientFor(*This.Private_Members, *Parent)
    
    gtk_window_set_transient_for_(*This\WindowID, *Parent)
    
  EndProcedure

  Procedure SetKeepAbove(*This.Private_Members, Setting.i)
    
    gtk_window_set_keep_above_(*This\WindowID, Setting)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< L'opérateur Move <<<<<
  
  Procedure Move(*This.Private_Members, X.l, Y.l)
    
    gtk_window_move_(*This\WindowID, X, Y)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< L'opérateur Show <<<<<
  
  Procedure Show(*This.Private_Members)
    
     gtk_widget_show_all_(*This\WindowID)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Nom de la procédure <<<<<
  
  Procedure SignalConnect(*This.Private_Members, SignalName.s, *CallBack, UserData.i)
    
    g_signal_connect_(*This\WindowID, SignalName, *CallBack, UserData)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Nom de la procédure <<<<<
  
  Procedure AddWidget(*This.Private_Members, *Widget)
    
    gtk_container_add_(*This\WindowID, *Widget)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Le Destructeur <<<<<

  Procedure Free(*This.Private_Members)
    
    FreeStructure(*This)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Le Constructeur <<<<<

  Procedure.i New()
    
    *This.Private_Members = AllocateStructure(Private_Members)
    *This\VirtualTable = ?START_METHODS
    
    *This\WindowID = gtk_window_new_(#GTK_WINDOW_TOPLEVEL)
    
    ProcedureReturn *This
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Les entrées de la table virtuelle <<<<<

  DataSection
    START_METHODS:
    Data.i @GetID()
    Data.i @GetPosition()
    Data.i @SetPosition()
    Data.i @SetSize()
    Data.i @SetTitle()
    Data.i @SetResizable()
    Data.i @SetBorderWidth()
    Data.i @SetTransientFor()
    Data.i @SetKeepAbove()
    Data.i @Move()
    Data.i @Show()
    Data.i @SignalConnect()
    Data.i @AddWidget()
    Data.i @Free()
    END_METHODS:
  EndDataSection
  
EndModule

DeclareModule GtkListView
  
  Interface ListView
    
    GetID.i()
    GetActiveRow.l()
    GetRowUserData.i()
    SetActiveRow(ActiveRowID.l)
    SetColumnsNames(ColumnNames.s)
    DetachModel()
    AppendRow(Definition.s, UserData.i = 0)
    ReAttachModel()
    ClearRows()
    RemoveRow(RowID.l)
    SignalConnect(SignalName.s, *CallBack, UserData.i)
    Free()
    
  EndInterface
  
  Declare.i New(ColumnNames.s)
  
EndDeclareModule

Module GtkListView
  
  ImportC ""
    
    gtk_tree_view_set_grid_lines(*Widget, Flag.i)
    gtk_list_store_set_value(*ListStore, *Iter.GtkTreeIter, ColumnID.l, *Value.GValue)
    
  EndImport
  
  Macro IsBetween(Value, Lower, Upper)
    
    ((Value) >= (Lower) And (Value) <= (Upper))
    
  EndMacro
  
  ;   Macro G_TYPE_MAKE_FUNDAMENTAL(x)
  ;     
  ;     x << 2
  ;     
  ;   EndMacro
  ;
  ;   #G_TYPE_INVALID = G_TYPE_MAKE_FUNDAMENTAL(0)
  ;   #G_TYPE_NONE = G_TYPE_MAKE_FUNDAMENTAL(1)
  ;   #G_TYPE_INTERFACE = G_TYPE_MAKE_FUNDAMENTAL(2)
  ;   #G_TYPE_CHAR = G_TYPE_MAKE_FUNDAMENTAL(3)
  ;   #G_TYPE_UCHAR = G_TYPE_MAKE_FUNDAMENTAL(4)
  ;   #G_TYPE_BOOLEAN = G_TYPE_MAKE_FUNDAMENTAL(5)
  ;   #G_TYPE_INT = G_TYPE_MAKE_FUNDAMENTAL(6)
  ;   #G_TYPE_UINT = G_TYPE_MAKE_FUNDAMENTAL(7)
  ;   #G_TYPE_LONG = G_TYPE_MAKE_FUNDAMENTAL(8)
  ;   #G_TYPE_ULONG = G_TYPE_MAKE_FUNDAMENTAL(9)
  ;   #G_TYPE_INT64 = G_TYPE_MAKE_FUNDAMENTAL(10)
  ;   #G_TYPE_UINT64 = G_TYPE_MAKE_FUNDAMENTAL(11)
  ;   #G_TYPE_ENUM = G_TYPE_MAKE_FUNDAMENTAL(12)
  ;   #G_TYPE_FLAGS = G_TYPE_MAKE_FUNDAMENTAL(13)
  ;   #G_TYPE_FLOAT = G_TYPE_MAKE_FUNDAMENTAL(14)
  ;   #G_TYPE_DOUBLE = G_TYPE_MAKE_FUNDAMENTAL(15)
  
  #G_TYPE_STRING = 16 << 2 ; G_TYPE_MAKE_FUNDAMENTAL(16)
  
  ;   #G_TYPE_POINTER = G_TYPE_MAKE_FUNDAMENTAL(17)
  ;   #G_TYPE_BOXED = G_TYPE_MAKE_FUNDAMENTAL(18)
  ;   #G_TYPE_PARAM = G_TYPE_MAKE_FUNDAMENTAL(19)
  ;   #G_TYPE_OBJECT = G_TYPE_MAKE_FUNDAMENTAL(20)
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Déclaration des Structures <<<<<
  
  Structure Row
    
    UserData.i
    Iter.GtkTreeIter
    
  EndStructure
  
  Structure Private_Members
    
    VirtualTable.i
    *ListViewID
    *ScrolledWindowID
    *ListStoreID
    List Rows.Row()
    
  EndStructure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Les observateurs <<<<<
  
  Procedure.i GetID(*This.Private_Members)
    
    ProcedureReturn *This\ScrolledWindowID
  EndProcedure
  
  Procedure.l GetActiveRow(*This.Private_Members)
    
    Protected Iter.GtkTreeIter
    
    ActiveRowID.l = -1
    *Selection.GtkTreeSelection = gtk_tree_view_get_selection_(*This\ListViewID)
    
    If gtk_tree_selection_count_selected_rows_(*Selection) = 1
      
      gtk_tree_selection_get_selected_(*Selection, #Null, @Iter)
      
      ForEach *This\Rows()
        
        If *This\Rows()\Iter\stamp = Iter\stamp And *This\Rows()\Iter\user_data = Iter\user_data And *This\Rows()\Iter\user_data2 = Iter\user_data2 And *This\Rows()\Iter\user_data3 = Iter\user_data3
          ActiveRowID = ListIndex(*This\Rows())
          Break
        EndIf
        
      Next
      
    EndIf
    
    ProcedureReturn ActiveRowID
  EndProcedure
  
  Procedure.i GetRowUserData(*This.Private_Members)
  
    ProcedureReturn *This\Rows()\UserData
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Les mutateurs <<<<<
  
  Procedure SetActiveRow(*This.Private_Members, ActiveRowID.l)

    If IsBetween(ActiveRowID, 0, ListSize(*This\Rows()) - 1)
      
      *Selection.GtkTreeSelection = gtk_tree_view_get_selection_(*This\ListViewID)
      
      SelectElement(*This\Rows(), ActiveRowID)
      gtk_tree_selection_select_iter_(*Selection, @*This\Rows()\Iter)
      
    EndIf
    
  EndProcedure
  
  Procedure SetColumnsNames(*This.Private_Members, ColumnNames.s)
    
    ColumnMax.l = CountString(ColumnNames, Chr(10))
    
    For ColumnID = 0 To ColumnMax
      *TreeViewColumnID = gtk_tree_view_get_column_(*This\ListViewID, ColumnID)
      gtk_tree_view_column_set_title_(*TreeViewColumnID, StringField(ColumnNames, ColumnID+1, Chr(10)))
    Next
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< L'opérateur DetachModel <<<<<
  
  Procedure DetachModel(*This.Private_Members)
    
    *This\ListStoreID = gtk_tree_view_get_model_(*This\ListViewID)
    g_object_ref_(*This\ListStoreID)
    gtk_tree_view_set_model_(*This\ListViewID, #Null)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< L'opérateur AppendRow <<<<<
  
  Procedure AppendRow(*This.Private_Members, Definition.s, UserData.i = 0)
    
    Protected Value.GValue
    
    If *This\ListStoreID <> 0
      
      g_value_init_(@Value, #G_TYPE_STRING)
      
      AddElement(*This\Rows())
      *This\Rows()\UserData = UserData
      
      gtk_list_store_append_(*This\ListStoreID, @*This\Rows()\Iter)
      
      If gtk_list_store_iter_is_valid_(*This\ListStoreID, @*This\Rows()\Iter)
        
        ColumnMax.l = CountString(Definition, Chr(10))
        
        For ColumnID = 0 To ColumnMax 
          
          Value\data\v_pointer = UTF8(StringField(Definition, ColumnID+1, Chr(10)))
          gtk_list_store_set_value(*This\ListStoreID, @*This\Rows()\Iter, ColumnID, @Value)
          FreeMemory(Value\data\v_pointer)
          
        Next
        
      EndIf
      
    EndIf
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< L'opérateur ReattachModel <<<<<
  
  Procedure ReAttachModel(*This.Private_Members)
    
    gtk_tree_view_set_model_(*This\ListViewID, *This\ListStoreID)
    g_object_unref_(*This\ListStoreID)
    *This\ListStoreID = 0
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< L'opérateur ClearRows <<<<<
  
  Procedure ClearRows(*This.Private_Members)
    
    DetachModel(*This)
    gtk_list_store_clear_(*This\ListStoreID)
    ClearList(*This\Rows())
    ReAttachModel(*This)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< L'opérateur RemoveRow <<<<<
  
  Procedure RemoveRow(*This.Private_Members, RowID.l)
    
    If IsBetween(RowID, 0, ListSize(*This\Rows()) - 1)
      
      SelectElement(*This\Rows(), RowID)
      DetachModel(*This)
      gtk_list_store_remove_(*This\ListStoreID, @*This\Rows()\Iter)
      ReAttachModel(*This)
      DeleteElement(*This\Rows(), 1)
      
    EndIf
    
  EndProcedure
    
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Nom de la procédure <<<<<
  
  Procedure SignalConnect(*This.Private_Members, SignalName.s, *CallBack, UserData.i)
    
    g_signal_connect_(*This\ListViewID, SignalName, *CallBack, UserData)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Le Destructeur <<<<<
  
  Procedure Free(*This.Private_Members)
    
    FreeStructure(*This)
    
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Le Constructeur <<<<<
  
  Procedure.i New(ColumnNames.s)
    
    *This.Private_Members = AllocateStructure(Private_Members)
    *This\VirtualTable = ?START_METHODS
    
    *This\ScrolledWindowID = gtk_scrolled_window_new_(#Null, #Null)
    
    gtk_scrolled_window_set_shadow_type_(*This\ScrolledWindowID, #GTK_SHADOW_IN)
    
    ColumnMax.l = CountString(ColumnNames, Chr(10))
    
;     Dim TypeArray.i(ColumnMax)
;     
;     For Index = 0 To ColumnMax
;       TypeArray(Index) = #G_TYPE_STRING
;     Next
;     
;     *ListStore = gtk_list_store_newv_(ColumnMax+1, @TypeArray())
;     
;     FreeArray(TypeArray())
    
    *GTYPE = AllocateMemory((ColumnMax+1) * SizeOf(Integer))
    
    FillMemory(*GTYPE, (ColumnMax+1) * SizeOf(Integer), #G_TYPE_STRING, #PB_Integer)
    *ListStore = gtk_list_store_newv_(ColumnMax+1, *GTYPE)
    FreeMemory(*GTYPE)
    
    *This\ListViewID = gtk_tree_view_new_with_model_(*ListStore)
    g_object_unref_(*ListStore)
    
    gtk_container_add_(*This\ScrolledWindowID, *This\ListViewID)
    
    For ColumnID = 0 To ColumnMax
      
      *CellRenderer.GtkCellRenderer = gtk_cell_renderer_text_new_()
      *TreeViewColumnID.GtkTreeViewColumn = gtk_tree_view_column_new_()
      
      gtk_tree_view_column_pack_start_(*TreeViewColumnID, *CellRenderer, ColumnID+1)
      gtk_tree_view_column_add_attribute_(*TreeViewColumnID, *CellRenderer, "text", ColumnID)
      gtk_tree_view_append_column_(*This\ListViewID, *TreeViewColumnID)
      gtk_tree_view_column_set_title_(*TreeViewColumnID, StringField(ColumnNames, ColumnID+1, Chr(10)))
      
    Next
   
    gtk_tree_view_set_grid_lines(*This\ListViewID, 3)
    
    ProcedureReturn *This
  EndProcedure
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Les entrées de la table virtuelle <<<<<
  
  DataSection
    START_METHODS:
    Data.i @GetID()
    Data.i @GetActiveRow()
    Data.i @GetRowUserData()
    Data.i @SetActiveRow()
    Data.i @SetColumnsNames()
    Data.i @DetachModel()
    Data.i @AppendRow()
    Data.i @ReAttachModel()
    Data.i @ClearRows()
    Data.i @RemoveRow()
    Data.i @SignalConnect()
    Data.i @Free()
    END_METHODS:
  EndDataSection
  
EndModule

CompilerIf #PB_Compiler_IsMainFile
  
  ProcedureC WindowDeleteEventHandler(*Widget.GtkWidget, *Event.GdkEventAny, UserData.I)
    
    ;Debug "WindowDeleteEventHandler"
    gtk_window_get_position_(*Widget, @X.l, @Y.l)
    
    ;Debug "Position (x,y) = (" + Str(X) + "," + Str(Y) + ")"
    
  EndProcedure
  
  ProcedureC WindowCloseHandler(*Widget.GtkWidget, UserData.I)
    
    ;Debug "WindowCloseHandler"
    gtk_window_get_position_(*Widget, @X.l, @Y.l)
    
    ;Debug "Position (x,y) = (" + Str(X) + "," + Str(Y) + ")"
    
    gtk_main_quit_()
    
  EndProcedure

  gtk_init_(0, 0)
  
  MainWin.GtkWindow::Window = GtkWindow::New()
  MainWin\SetSize(400, 300)
  MainWin\SetTitle("GtkListView Example")
  MainWin\SetPosition(#GTK_WIN_POS_CENTER)
  MainWin\SetResizable(#False)
  MainWin\SetBorderWidth(5)
  
  MainWin\SignalConnect("delete-event", @WindowDeleteEventHandler(), 25)
  MainWin\SignalConnect("destroy", @WindowCloseHandler(), 0)
  
  ListView.GtkListView::ListView = GtkListView::New("File Name" + Chr(10) + "Status")
  
  ListView\DetachModel()
  ListView\AppendRow("Vector2f - OOP.pb" + Chr(10) + "OK")
  ListView\AppendRow("Vector3f - OOP.pb" + Chr(10) + "OK")
  ListView\AppendRow("Vector4f - OOP.pb" + Chr(10) + "OK")
  ListView\ReAttachModel()
  
  MainWin\AddWidget(ListView\GetID())
  
  MainWin\Show()
  
  gtk_main_()
  
  MainWin\Free()
  ListView\Free()
  
CompilerEndIf

; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< END OF FILE <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<
Best regards
StarBootics
The Stone Age did not end due to a shortage of stones !
User avatar
Shardik
Addict
Addict
Posts: 1991
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: GtkTreeView Example Partially working

Post by Shardik »

Your final test was successful on my Linux Mint 19.3 'Tricia' x64 Cinnamon with GTK3 and PB 6.00 Beta 6 (Asm and C backend).

Thank you for your persistence. I only did a quick test and still have to analyse which one of your changes did finally eliminate the bug of only displaying the text in the first column in my distribution.
User avatar
StarBootics
Addict
Addict
Posts: 984
Joined: Sun Jul 07, 2013 11:35 am
Location: Canada

Re: GtkTreeView Example Partially working

Post by StarBootics »

Shardik wrote: Fri Apr 15, 2022 2:19 pm Thank you for your persistence.
And thanks to you for taking time to test my codes.

Best regards
StarBootics
The Stone Age did not end due to a shortage of stones !
Post Reply