I'm a newbie to Gtk3 but I can't find how to do what I want anywhere. I'm trying to get a tree view representing article citations.
Desired outcome:
- columns are resizable
- no horizontal scrollbar
- columns take only as much space as needed, they don't expand the window if content is too long
- in case a cell's content is too long, either break the text over several lines (best) or trim it and add "..." (ok), just trim it (I could settle for that)
As an example of what I want, here's Zotero trimming columns with "..."
This is my widget hierarchy:
What I tried (using Glade + C):
- Default settings: a horizontal scrollbar appears
- Set ScrolledWindow horizontal scroll policy to "Never", auto sizing to column: window expands to fit content, e.g.
- Set ScrolledWindow horizontal scroll policy to "Never", fixed sizing columns, with maximum width: contents is trimmed (not "...", no text reflow), but I can only resize columns to the arbiratry size I've given them.
- Set ScrolledWindow horizontal scroll policy to "External", auto sizing columns, columns set to resizable: columns are not resizable, contents is not trimmed.
Here's variation 4 with source + XML file generated by Glade:
#include <gtk/gtk.h>
void on_window_main_destroy();
enum {
AUTHORS_COLUMN = 0,
TITLE_COLUMN,
N_COLUMNS
};
static void init_reference_list(GtkBuilder* builder)
{
GtkCellRenderer* renderer;
GtkWidget* tree_widget;
tree_widget = GTK_WIDGET(gtk_builder_get_object(builder, "tree_view"));
// -- Add attributes to Glade-generated columns
GtkTreeViewColumn* column;
renderer = gtk_cell_renderer_text_new();
column = GTK_TREE_VIEW_COLUMN(gtk_builder_get_object(builder, "title"));
gtk_tree_view_column_pack_start(column, renderer, FALSE);
gtk_tree_view_column_add_attribute(column, renderer, "text", TITLE_COLUMN );
column = GTK_TREE_VIEW_COLUMN(gtk_builder_get_object(builder, "authors"));
gtk_tree_view_column_pack_start(column, renderer, FALSE);
gtk_tree_view_column_add_attribute(column, renderer, "text", AUTHORS_COLUMN );
// -- Set up store and connect it to view
GtkListStore* store;
store = gtk_list_store_new(N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING );
gtk_tree_view_set_model(GTK_TREE_VIEW(tree_widget), GTK_TREE_MODEL(store));
// -- Placing fake data in store
char title[] = "A long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long title";
char authors[] = "Me You Us Them All of us";
GtkTreeIter iter;
int i;
for (int i = 0; i < 500; ++i)
{
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter, AUTHORS_COLUMN, authors, TITLE_COLUMN, title, -1 );
}
}
// called when window is closed
void on_window_main_destroy()
{
gtk_main_quit();
}
int main(int argc, char *argv[])
{
gtk_init(&argc, &argv);
// -- load builder
GtkBuilder* builder;
builder = gtk_builder_new();
gtk_builder_add_from_file (builder, "resources/ui/ref_search.glade", NULL);
gtk_builder_connect_signals(builder, NULL);
// -- Cell Renderer and fake data
init_reference_list(builder);
// -- Launch
GtkWidget *window;
window = GTK_WIDGET(gtk_builder_get_object(builder, "window_main"));
gtk_widget_show(window);
g_object_unref(builder);
gtk_main();
return 0;
}
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkEntryBuffer" id="search_buffer"/>
<object class="GtkWindow" id="window_main">
<property name="can_focus">False</property>
<property name="halign">baseline</property>
<property name="valign">baseline</property>
<property name="title" translatable="yes">Reference Manager</property>
<property name="resizable">False</property>
<property name="default_width">640</property>
<property name="default_height">480</property>
<signal name="destroy" handler="on_window_main_destroy" swapped="no"/>
<child type="titlebar">
<placeholder/>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkSearchEntry" id="search_bar">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="buffer">search_buffer</property>
<property name="primary_icon_name">edit-find-symbolic</property>
<property name="primary_icon_activatable">False</property>
<property name="primary_icon_sensitive">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">external</property>
<property name="shadow_type">in</property>
<property name="max_content_height">500</property>
<child>
<object class="GtkTreeView" id="tree_view">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="rules_hint">True</property>
<property name="enable_search">False</property>
<property name="show_expanders">False</property>
<property name="enable_grid_lines">horizontal</property>
<child internal-child="selection">
<object class="GtkTreeSelection"/>
</child>
<child>
<object class="GtkTreeViewColumn" id="authors">
<property name="resizable">True</property>
<property name="sizing">autosize</property>
<property name="title" translatable="yes">Author(s)</property>
<property name="expand">True</property>
<property name="clickable">True</property>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="title">
<property name="resizable">True</property>
<property name="sizing">autosize</property>
<property name="title" translatable="yes">Title</property>
<property name="expand">True</property>
<property name="clickable">True</property>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</interface>
Apologies if I'm missing the obvious!