TreeView - set border on individual cells

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

TreeView - set border on individual cells

Gtk+ - Apps Dev mailing list
Is this possible?

I did originally plan to have certain cells have a background colour to
emphasize that there is a value to change. However as soon as the row is
selected this is all wiped out by the highlight from selected row

So is it possible to set the borders on a cell by cell basis, all I can
find is overall properties for the trreview

Mike
_______________________________________________
gtk-app-devel-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Reply | Threaded
Open this post in threaded view
|

Re: TreeView - set border on individual cells

Gtk+ - Apps Dev mailing list
Am Donnerstag, den 04.04.2019, 23:04 +0100 schrieb Mike Martin via gtk-
app-devel-list:

> Is this possible?
>
> I did originally plan to have certain cells have a background colour
> to
> emphasize that there is a value to change. However as soon as the row
> is
> selected this is all wiped out by the highlight from selected row
>
> So is it possible to set the borders on a cell by cell basis, all I
> can
> find is overall properties for the trreview
>
> Mike

I don't have a definitive answer for you. But just as a headsup: you
can inspect every GTK component's CSS properties interactively while
running the program. You can even live edit the properties.

Here's a guide:

https://blog.gtk.org/2017/04/05/the-gtk-inspector/

_______________________________________________
gtk-app-devel-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Reply | Threaded
Open this post in threaded view
|

Re: TreeView - set border on individual cells

Mike Martin
Update, I worked out how to get rid of highlight

1 treeview->set selection mode(none)
2 treeview->signal_connect(row_activated =>sub{
Treeview->set_cursor_on_cell(path,column,cell,true)
}
)

Not exact code, but this is process that worked for me

Would still be useful if I could find out about borders though



On Fri, 5 Apr 2019, 08:03 , <[hidden email]> wrote:

> Am Donnerstag, den 04.04.2019, 23:04 +0100 schrieb Mike Martin via gtk-
> app-devel-list:
> > Is this possible?
> >
> > I did originally plan to have certain cells have a background colour
> > to
> > emphasize that there is a value to change. However as soon as the row
> > is
> > selected this is all wiped out by the highlight from selected row
> >
> > So is it possible to set the borders on a cell by cell basis, all I
> > can
> > find is overall properties for the trreview
> >
> > Mike
>
> I don't have a definitive answer for you. But just as a headsup: you
> can inspect every GTK component's CSS properties interactively while
> running the program. You can even live edit the properties.
>
> Here's a guide:
>
> https://blog.gtk.org/2017/04/05/the-gtk-inspector/
>
>
_______________________________________________
gtk-app-devel-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Reply | Threaded
Open this post in threaded view
|

Re: TreeView - set border on individual cells

Gtk+ - Apps Dev mailing list
On Fri, 5 Apr 2019, 12:36 Mike Martin, <[hidden email]> wrote:

> Update, I worked out how to get rid of highlight
>
> 1 treeview->set selection mode(none)
> 2 treeview->signal_connect(row_activated =>sub{
> Treeview->set_cursor_on_cell(path,column,cell,true)
> }
> )
>
> Not exact code, but this is process that worked for me
>
> Would still be useful if I could find out about borders though
>
>
>
> On Fri, 5 Apr 2019, 08:03 , <[hidden email]> wrote:
>
>> Am Donnerstag, den 04.04.2019, 23:04 +0100 schrieb Mike Martin via gtk-
>> app-devel-list:
>> > Is this possible?
>> >
>> > I did originally plan to have certain cells have a background colour
>> > to
>> > emphasize that there is a value to change. However as soon as the row
>> > is
>> > selected this is all wiped out by the highlight from selected row
>> >
>> > So is it possible to set the borders on a cell by cell basis, all I
>> > can
>> > find is overall properties for the trreview
>> >
>> > Mike
>>
>> I don't have a definitive answer for you. But just as a headsup: you
>> can inspect every GTK component's CSS properties interactively while
>> running the program. You can even live edit the properties.
>>
>> Here's a guide:
>>
>> https://blog.gtk.org/2017/04/05/the-gtk-inspector/
>>
>>
_______________________________________________
gtk-app-devel-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Reply | Threaded
Open this post in threaded view
|

Re: TreeView - set border on individual cells

Gtk+ - Apps Dev mailing list
In reply to this post by Gtk+ - Apps Dev mailing list
 
Hi Mike,

I gave what you said a try and it looks to work well enough. Then, how do you get a box around a selected cell. It seems to me if you let the built in renderer do it's thing and then get a cairo_t to just draw a rectangle after, it should work, right? OK, a bit of a hack but it works on my computer. GTK3.18. On a newer version of GTK I get a deprecated warning about gdk_cairo_create() but it still works.

Eric
  
//gcc -Wall stripe_list2.c -o stripe_list2 `pkg-config --cflags --libs gtk+-3.0`

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

enum
{
   ID,
   PROGRAM,
   COLOR,
   COLOR2,
   COLUMNS
};

static gint row_g=0;
static gint column_g=0;

static void get_path(GtkTreeView *tree_view, GtkTreePath *path, GtkTreeViewColumn *column, gpointer renderer1)
  {
    g_print("Get Path\n");
    gchar *string=gtk_tree_path_to_string(path);
    g_print("%s %s\n", string, gtk_tree_view_column_get_title(column));
    row_g=atoi(string);
    g_free(string);

    gint c1=0;
    if(g_strcmp0("ID", gtk_tree_view_column_get_title(column))==0) c1=2;
    if(g_strcmp0("Program", gtk_tree_view_column_get_title(column))==0) c1=3;
    column_g=c1-2;

    GtkTreeIter iter;
    GtkTreeModel *tree_model=gtk_tree_view_get_model(tree_view);
    gtk_tree_model_get_iter(tree_model, &iter, path);
    gtk_list_store_set(GTK_LIST_STORE(tree_model), &iter, c1, "SpringGreen", -1);
    gtk_widget_queue_draw(GTK_WIDGET(tree_view));
  }
static gboolean draw_rectangle(GtkWidget *tree_view, cairo_t *cr, gpointer data)
  {
    GtkTreePath *path=gtk_tree_path_new_from_indices(row_g, -1);

    g_print("Draw Rectangle %i %i\n", row_g, column_g);
    GdkWindow *win=gtk_tree_view_get_bin_window(GTK_TREE_VIEW(tree_view));
    cairo_t *cr2=gdk_cairo_create(win);
    GdkRectangle rect;
    cairo_set_line_width(cr2, 4.0);
    cairo_set_source_rgba(cr2, 1.0, 1.0, 1.0, 1.0);
    GtkTreeViewColumn *column=gtk_tree_view_get_column(GTK_TREE_VIEW(tree_view), column_g);
    gtk_tree_view_get_cell_area(GTK_TREE_VIEW(tree_view), path, column, &rect);
    cairo_rectangle(cr2, rect.x+2, rect.y+2, rect.width-2, rect.height-2);
    cairo_stroke(cr2);
    
    cairo_destroy(cr2);  
    gtk_tree_path_free(path);

    return TRUE;
  }
int main(int argc, char *argv[])
  {
    gtk_init(&argc, &argv);

    GtkWidget *window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "Stripes");
    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
    gtk_window_set_default_size(GTK_WINDOW(window), 300, 300);
    gtk_widget_set_name(window, "main_window");
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

    GtkTreeIter iter;
    GtkListStore *store=gtk_list_store_new(COLUMNS, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
    gtk_list_store_append(store, &iter);
    gtk_list_store_set(store, &iter, ID, 0, PROGRAM, "Gedit", COLOR, "cyan", COLOR2, "chartreuse", -1);
    gtk_list_store_append(store, &iter);
    gtk_list_store_set(store, &iter, ID, 1, PROGRAM, "Gimp", COLOR,  "yellow", COLOR2, "chartreuse", -1);
    gtk_list_store_append(store, &iter);
    gtk_list_store_set(store, &iter, ID, 2, PROGRAM, "Inkscape", COLOR, "cyan", COLOR2, "chartreuse", -1);
    gtk_list_store_append(store, &iter);
    gtk_list_store_set(store, &iter, ID, 3, PROGRAM, "Firefox", COLOR, "yellow", COLOR2, "fuchsia", -1);
    gtk_list_store_append(store, &iter);
    gtk_list_store_set(store, &iter, ID, 4, PROGRAM, "Calculator", COLOR, "cyan", COLOR2, "chartreuse", -1);
    gtk_list_store_append(store, &iter);
    gtk_list_store_set(store, &iter, ID, 5, PROGRAM, "Devhelp", COLOR, "yellow", COLOR2, "chartreuse", -1);

    GtkWidget *tree=gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
    gtk_widget_set_name(tree, "test_tree");
    gtk_widget_set_hexpand(tree, TRUE);
    gtk_widget_set_vexpand(tree, FALSE);
    g_object_set(tree, "activate-on-single-click", TRUE, NULL);
    g_signal_connect_after(tree, "draw", G_CALLBACK(draw_rectangle), NULL);

    GtkTreeSelection *selection=gtk_tree_view_get_selection(GTK_TREE_VIEW(tree));
    gtk_tree_selection_set_mode(selection, GTK_SELECTION_NONE);

    GtkCellRenderer *renderer1=gtk_cell_renderer_text_new();
    g_object_set(renderer1, "editable", FALSE, NULL);

    g_signal_connect(tree, "row-activated", G_CALLBACK(get_path), renderer1);
  
    //Bind the COLOR column to the "cell-background" property.
    GtkTreeViewColumn *column1 = gtk_tree_view_column_new_with_attributes("ID", renderer1, "text", ID, "cell-background", COLOR, NULL);
    gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column1);   
    GtkTreeViewColumn *column2 = gtk_tree_view_column_new_with_attributes("Program", renderer1, "text", PROGRAM, "cell-background", COLOR2, NULL);
    gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column2);

    GtkWidget *label=gtk_label_new("Test Label");
    gtk_widget_set_name(label, "test_label");
    gtk_widget_set_hexpand(label, TRUE);
  
    GtkWidget *grid=gtk_grid_new();
    gtk_grid_set_row_homogeneous(GTK_GRID(grid), TRUE);
    gtk_widget_set_name(grid, "test_grid");
    gtk_grid_attach(GTK_GRID(grid), tree, 0, 0, 1, 9);
    gtk_grid_attach(GTK_GRID(grid), label, 0, 10, 1, 1);

    gtk_container_add(GTK_CONTAINER(window), grid);
  
    gtk_widget_show_all(window);

    gtk_main();    return 0;  
  }

 
 

_______________________________________________
gtk-app-devel-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Reply | Threaded
Open this post in threaded view
|

Re: TreeView - set border on individual cells

Gtk+ - Apps Dev mailing list
On Sat, 6 Apr 2019 at 19:05, Eric Cashon via gtk-app-devel-list <
[hidden email]> wrote:



> static gboolean draw_rectangle(GtkWidget *tree_view, cairo_t *cr, gpointer
> data)
>   {
>     GtkTreePath *path=gtk_tree_path_new_from_indices(row_g, -1);
>
>     g_print("Draw Rectangle %i %i\n", row_g, column_g);
>     GdkWindow *win=gtk_tree_view_get_bin_window(GTK_TREE_VIEW(tree_view));
>     cairo_t *cr2=gdk_cairo_create(win);
>

Don't ever do this.

There's a reason why you're getting a deprecation warning: you're already
getting a Cairo context from the "draw" signal; use that to draw. There's
no reason whatsoever to create a new Cairo context for a GdkWindow in GTK3.

Ciao,
 Emmanuele.

--
https://www.bassi.io
[@] ebassi [@gmail.com]
_______________________________________________
gtk-app-devel-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Reply | Threaded
Open this post in threaded view
|

Re: TreeView - set border on individual cells

Gtk+ - Apps Dev mailing list
In reply to this post by Gtk+ - Apps Dev mailing list
 
Hi Emmanuele,

The second cairo_t is used so that the rectangle can be lined up to the cell. If I use the cairo_t in the "draw" callback then the rectangle doesn't line up.

Eric

_______________________________________________
gtk-app-devel-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Reply | Threaded
Open this post in threaded view
|

Re: TreeView - set border on individual cells

Gtk+ - Apps Dev mailing list
On Sat, 6 Apr 2019 at 20:15, <[hidden email]> wrote:


> The second cairo_t is used so that the rectangle can be lined up to the
> cell. If I use the cairo_t in the "draw" callback then the rectangle
> doesn't line up.
>

You're still using:

 1. the wrong window to draw on
 2. deprecated API
 3. a slow rendering path

In general, though drawing *on top* of widgets is not encouraged; you're
either going to break things inside GTK, or your own code will break
because GTK may change something in how widgets are drawn.

If you want to change how a cell is rendered, you can subclass the cell
renderer into your own class and override its own draw function; this way,
you're guaranteed you'll be rendering at the right position.

Ciao,
 Emmanuele.

--
https://www.bassi.io
[@] ebassi [@gmail.com]
_______________________________________________
gtk-app-devel-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Reply | Threaded
Open this post in threaded view
|

Re: TreeView - set border on individual cells

Gtk+ - Apps Dev mailing list
In reply to this post by Gtk+ - Apps Dev mailing list

I see gtk_cell_renderer_render() in the documentation and it has a cairo_t to draw with. I haven't tried to subclass from a treeview and override the rendering. Something I should probably figure out. Do you know of an example of doing something like this in C? Maybe I can put together a better example.

Eric
_______________________________________________
gtk-app-devel-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Reply | Threaded
Open this post in threaded view
|

Re: TreeView - set border on individual cells

Gtk+ - Apps Dev mailing list
In reply to this post by Gtk+ - Apps Dev mailing list
 
I looked into this a little more. It looks like using an overlay is the easiest solution that I could find. You can override the render function of the cell renderer but then you will probably need all the code in the text cell renderer. This isn't too bad since the text cell renderer is modular and you don't have to deal with a tangle of header files. Or you can just make changes to the text cell renderer and compile the changes in GTK. Changing the cell renderer has the advantage that you can order what you want to draw from back to front. A little more flexible than drawing a rectangle over the top.

This does seem something to be useful to be able to do.

Eric
  
//gcc -Wall stripe_list3.c -o stripe_list3 `pkg-config --cflags --libs gtk+-3.0`

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

enum
{
   ID,
   PROGRAM,
   COLOR,
   COLOR2,
   COLUMNS
};

static gint row_g=0;
static gint column_g=0;

static void get_path(GtkTreeView *tree_view, GtkTreePath *path, GtkTreeViewColumn *column, gpointer renderer1)
  {
    g_print("Get Path\n");
    gchar *string=gtk_tree_path_to_string(path);
    g_print("%s %s\n", string, gtk_tree_view_column_get_title(column));
    row_g=atoi(string);
    g_free(string);

    gint c1=0;
    if(g_strcmp0("ID", gtk_tree_view_column_get_title(column))==0) c1=2;
    if(g_strcmp0("Program", gtk_tree_view_column_get_title(column))==0) c1=3;
    column_g=c1-2;

    GtkTreeIter iter;
    GtkTreeModel *tree_model=gtk_tree_view_get_model(tree_view);
    gtk_tree_model_get_iter(tree_model, &iter, path);
    gtk_list_store_set(GTK_LIST_STORE(tree_model), &iter, c1, "SpringGreen", -1);
    gtk_widget_queue_draw(GTK_WIDGET(tree_view));
  }
static gboolean draw_rectangle(GtkWidget *overlay, cairo_t *cr, GtkWidget *tree_view)
  {
    g_print("Draw Rectangle %i %i\n", row_g, column_g);
    GtkTreePath *path=gtk_tree_path_new_from_indices(row_g, -1);
    GtkTreeViewColumn *column=gtk_tree_view_get_column(GTK_TREE_VIEW(tree_view), column_g);

    GdkRectangle rect;
    gint x=0;
    gint y=0;
    gtk_tree_view_convert_bin_window_to_widget_coords(GTK_TREE_VIEW(tree_view), 0, 0, &x, &y);

    cairo_save(cr);
    cairo_translate(cr, x, y);
    cairo_set_line_width(cr, 2.0);
    cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
   
    gtk_tree_view_get_cell_area(GTK_TREE_VIEW(tree_view), path, column, &rect);
    cairo_rectangle(cr, rect.x+1, rect.y+1, rect.width-1, rect.height-1);
    cairo_stroke(cr);
    cairo_restore(cr);
       
    gtk_tree_path_free(path);

    return FALSE;
  }
int main(int argc, char *argv[])
  {
    gtk_init(&argc, &argv);

    GtkWidget *window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "Stripes");
    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
    gtk_window_set_default_size(GTK_WINDOW(window), 300, 300);
    gtk_widget_set_name(window, "main_window");
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

    GtkTreeIter iter;
    GtkListStore *store=gtk_list_store_new(COLUMNS, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
    gtk_list_store_append(store, &iter);
    gtk_list_store_set(store, &iter, ID, 0, PROGRAM, "Gedit", COLOR, "cyan", COLOR2, "chartreuse", -1);
    gtk_list_store_append(store, &iter);
    gtk_list_store_set(store, &iter, ID, 1, PROGRAM, "Gimp", COLOR,  "yellow", COLOR2, "chartreuse", -1);
    gtk_list_store_append(store, &iter);
    gtk_list_store_set(store, &iter, ID, 2, PROGRAM, "Inkscape", COLOR, "cyan", COLOR2, "chartreuse", -1);
    gtk_list_store_append(store, &iter);
    gtk_list_store_set(store, &iter, ID, 3, PROGRAM, "Firefox", COLOR, "yellow", COLOR2, "fuchsia", -1);
    gtk_list_store_append(store, &iter);
    gtk_list_store_set(store, &iter, ID, 4, PROGRAM, "Calculator", COLOR, "cyan", COLOR2, "chartreuse", -1);
    gtk_list_store_append(store, &iter);
    gtk_list_store_set(store, &iter, ID, 5, PROGRAM, "Devhelp", COLOR, "yellow", COLOR2, "chartreuse", -1);

    GtkWidget *tree=gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
    gtk_widget_set_name(tree, "test_tree");
    gtk_widget_set_hexpand(tree, TRUE);
    gtk_widget_set_vexpand(tree, FALSE);
    g_object_set(tree, "activate-on-single-click", TRUE, NULL);

    GtkTreeSelection *selection=gtk_tree_view_get_selection(GTK_TREE_VIEW(tree));
    gtk_tree_selection_set_mode(selection, GTK_SELECTION_NONE);

    GtkCellRenderer *renderer1=gtk_cell_renderer_text_new();
    g_object_set(renderer1, "editable", FALSE, NULL);

    g_signal_connect(tree, "row-activated", G_CALLBACK(get_path), renderer1);
  
    //Bind the COLOR column to the "cell-background" property.
    GtkTreeViewColumn *column1 = gtk_tree_view_column_new_with_attributes("ID", renderer1, "text", ID, "cell-background", COLOR, NULL);
    gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column1);   
    GtkTreeViewColumn *column2 = gtk_tree_view_column_new_with_attributes("Program", renderer1, "text", PROGRAM, "cell-background", COLOR2, NULL);
    gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column2);

    GtkWidget *overlay=gtk_overlay_new();
    gtk_overlay_add_overlay(GTK_OVERLAY(overlay), tree);
    gtk_overlay_set_overlay_pass_through(GTK_OVERLAY(overlay), tree, TRUE);
    g_signal_connect_after(overlay, "draw", G_CALLBACK(draw_rectangle), tree);

    GtkWidget *label=gtk_label_new("Test Label");
    gtk_widget_set_name(label, "test_label");
    gtk_widget_set_hexpand(label, TRUE);
  
    GtkWidget *grid=gtk_grid_new();
    gtk_grid_set_row_homogeneous(GTK_GRID(grid), TRUE);
    gtk_widget_set_name(grid, "test_grid");
    gtk_grid_attach(GTK_GRID(grid), overlay, 0, 0, 1, 9);
    gtk_grid_attach(GTK_GRID(grid), label, 0, 10, 1, 1);

    gtk_container_add(GTK_CONTAINER(window), grid);
  
    gtk_widget_show_all(window);

    gtk_main();
    return 0;  
  }

 

_______________________________________________
gtk-app-devel-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list