Using default color for combo box cell layout renderer with GTK >=3.16 - combobox

I use a combobox whose items are dynamically created, the same goes for headlines inside the combobox in black which might or might not appear, depending on the current choice. It looks like this:
The code for the cell layout renderer is this (just for the concept, the details are not of interest for my following question):
void option_list_with_headlines
(G_GNUC_UNUSED GtkCellLayout *cell_layout,
GtkCellRenderer *action_option_combo_box_renderer,
GtkTreeModel *action_option_combo_box_model,
GtkTreeIter *action_option_combo_box_iter,
G_GNUC_UNUSED gpointer data) {
gchar *action_option_combo_item;
GdkRGBA normal_fg_color, normal_bg_color;
gboolean headline;
gtk_style_context_get_color (gtk_widget_get_style_context (action_option),
GTK_STATE_NORMAL, &normal_fg_color);
gtk_style_context_get_background_color (gtk_widget_get_style_context
(action_option), GTK_STATE_NORMAL, &normal_bg_color);
gtk_tree_model_get (action_option_combo_box_model,
action_option_combo_box_iter, ACTION_OPTION_COMBO_ITEM,
&action_option_combo_item, -1);
headline = g_regex_match_simple ("Add|Choose",
action_option_combo_item, G_REGEX_ANCHORED, 0);
g_object_set (action_option_combo_box_renderer,
"foreground-rgba", (headline) ? &((GdkRGBA) { 1.0, 1.0, 1.0, 1.0 }) :
&normal_fg_color, "background-rgba"
(g_str_has_prefix(action_option_combo_item, "Choose")) ?
&((GdkRGBA) { 0.31, 0.31, 0.79, 1.0 }) :
((g_str_has_prefix (action_option_combo_item, "Add")) ?
&((GdkRGBA) { 0.0, 0.0, 0.0, 1.0 }) : &normal_bg_color),
"sensitive", !headline, NULL);
// Cleanup
g_free (action_option_combo_item);
}
Now my question regarding this function:
From Gtk >=3.16 on I am no longer supposed to use gtk_style_context_get_background_color. But what can I do to set a color to default in a combo box item list then, like I do with "Name" and "Prompt" in the image above? Currently I use g_object_set together with the color I've gathered with gtk_style_context_get_background_color and GTK_STATE_NORMAL as a parameter.

The solution has turned out to be quite simple: I don't have to retrieve the default background color at all; it is enough to set the value for background-rgba to NULL when using g_object_set:
g_object_set (action_option_combo_box_renderer, "background-rgba", NULL, ...)
I didn't know that this is possible; I assumed that background-rgba always needs some kind of value.

Related

GtkTreeView C change individual text color for a specific row or cell and not the whole column

I'm racking my brain to figure out how to change text color in a GtkTreeView cell without having the whole column change color. I want to dynamically change from default color to to green or red depending on conditions. Like pass or fail a test and the individual cell text color turns red or green for instance in C programming.
if(strstr(string,"PASS"))
{
g_object_set(renderer_pass_fail,"foreground", "Green","foreground-set", TRUE,NULL);
}
else
{
g_object_set(renderer_pass_fail,"foreground", "Red","foreground-set", TRUE,NULL);
}
Yoh have to add one more column to your model and store color there.
enum
{
TEXT_COL,
COLOR_COL,
N_COLUMNS
};
/* TreeModel */
store = gtk_list_store_new (N_COLUMNS,
G_TYPE_STRING,
GDK_TYPE_RGBA);
/* Column */
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes (_("Name"),
renderer,
"text",
TEXT_COL,
"foreground-rgba",
COLOR_COL,
NULL);
/* Adding an element */
gtk_list_store_append (store, &ls_iter);
gtk_list_store_set (store, &ls_iter,
TEXT_COL, "hello",
COLOR_COL, gdk_rgba_copy (color),
-1);
With a few more googles and help from first answer above, and using keyword glade I found the answer in the following link how to accomplish the above using Glade.
Found Answer while using glade XML UI App
if(strstr(string,"PASS"))
{
gdk_color_parse ("green", &color);
gtk_list_store_set (get_gtk_list_store(), &iterr,COL, "PASS",COL_COLOR, &color,-1);
}
else if(strstr(string,"FAIL"))
{
gdk_color_parse ("red", &color);
gtk_list_store_set (get_gtk_list_store(), &iterr,COL, "FAIL",COL_COLOR, &color,-1);
}
else if(strstr(string,"ABORT"))
{
gdk_color_parse ("red", &color);
gtk_list_store_set (get_gtk_list_store(), &iterr,COL, "FAIL",COL_COLOR, &color,-1);
}
else
{
gdk_color_parse ("yellow", &color);
gtk_list_store_set (get_gtk_list_store(), &iterr,COL, "N / A",COL_COLOR, &color,-1);
}

Why is pango_cairo_show_layout drawing text at a slightly wrong location?

I have a Gtk app written in C running on Ubuntu Linux.
I'm confused about some behavior I'm seeing with the pango_cairo_show_layout function: I get the exact "ink" (not "logical") pixel size of a pango layout and draw the layout using pango_cairo_show_layout on a GtkDrawingArea widget. Right before drawing the layout, I draw a rectangle that should perfectly encompass the text that I'm about to draw, but the text always shows up a little below the bottom edge of the rectangle.
Here is my full code:
// The drawing area widget's "expose-event" callback handler
gboolean OnTestWindowExposeEvent(GtkWidget *pWidget, GdkEventExpose *pEvent, gpointer data)
{
// Note that this window is 365 x 449 pixels
double dEntireWindowWidth = pEvent->area.width; // This is 365.0
double dEntireWindowHeight = pEvent->area.height; // This is 449.0
// Create a cairo context with which to draw
cairo_t *cr = gdk_cairo_create(pWidget->window);
// Draw a red background
cairo_set_source_rgb(cr, 1.0, 0.0, 0.0);
cairo_rectangle(cr, 0.0, 0.0, dEntireWindowWidth, dEntireWindowHeight);
cairo_fill(cr);
// Calculate the padding inside the window which defines the text rectangle
double dPadding = 0.05 * ((dEntireWindowWidth < dEntireWindowHeight) ? dEntireWindowWidth : dEntireWindowHeight);
dPadding = round(dPadding); // This is 18.0
// The size of the text box in which to draw text
double dTextBoxSizeW = dEntireWindowWidth - (2.0 * dPadding);
double dTextBoxSizeH = dEntireWindowHeight - (2.0 * dPadding);
dTextBoxSizeW = round(dTextBoxSizeW); // This is 329.0
dTextBoxSizeH = round(dTextBoxSizeH); // This is 413.0
// Draw a black rectangle that defines the area in which text may be drawn
cairo_set_line_width(cr, 1.0);
cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
cairo_rectangle(cr, dPadding, dPadding, dTextBoxSizeW, dTextBoxSizeH);
cairo_stroke(cr);
// The text to draw
std::string szText("Erik");
// The font name to use
std::string szFontName("FreeSans");
// The font size to use
double dFontSize = 153.0;
// The font description string
char szFontDescription[64];
memset(&(szFontDescription[0]), 0, sizeof(szFontDescription));
snprintf(szFontDescription, sizeof(szFontDescription) - 1, "%s %.02f", szFontName.c_str(), dFontSize);
// Create a font description
PangoFontDescription *pFontDescription = pango_font_description_from_string(szFontDescription);
// Set up the font description
pango_font_description_set_weight(pFontDescription, PANGO_WEIGHT_NORMAL);
pango_font_description_set_style(pFontDescription, PANGO_STYLE_NORMAL);
pango_font_description_set_variant(pFontDescription, PANGO_VARIANT_NORMAL);
pango_font_description_set_stretch(pFontDescription, PANGO_STRETCH_NORMAL);
// Create a pango layout
PangoLayout *pLayout = gtk_widget_create_pango_layout(pWidget, szText.c_str());
// Set up the pango layout
pango_layout_set_alignment(pLayout, PANGO_ALIGN_LEFT);
pango_layout_set_width(pLayout, -1);
pango_layout_set_font_description(pLayout, pFontDescription);
pango_layout_set_auto_dir(pLayout, TRUE);
// Get the "ink" pixel size of the layout
PangoRectangle tRectangle;
pango_layout_get_pixel_extents(pLayout, &tRectangle, NULL);
double dRealTextSizeW = static_cast<double>(tRectangle.width);
double dRealTextSizeH = static_cast<double>(tRectangle.height);
// Calculate the top left corner coordinate at which to draw the text
double dTextLocX = dPadding + ((dTextBoxSizeW - dRealTextSizeW) / 2.0);
double dTextLocY = dPadding + ((dTextBoxSizeH - dRealTextSizeH) / 2.0);
// Draw a blue rectangle which should perfectly encompass the text we're about to draw
cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
cairo_set_source_rgb(cr, 0.0, 0.0, 1.0);
cairo_rectangle(cr, dTextLocX, dTextLocY, dRealTextSizeW, dRealTextSizeH);
cairo_stroke(cr);
// Set up the cairo context for drawing the text
cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
cairo_set_antialias(cr, CAIRO_ANTIALIAS_BEST);
// Move to the top left coordinate before drawing the text
cairo_move_to(cr, dTextLocX, dTextLocY);
// Draw the layout text
pango_cairo_show_layout(cr, pLayout);
// Clean up
cairo_destroy(cr);
g_object_unref(pLayout);
pango_font_description_free(pFontDescription);
return TRUE;
}
So, why is the text not being drawn exactly where I tell it to be drawn?
Thanks in advance for any help!
Look at the documentation for pango_layout_get_extents() (this is not mentioned in the docs for pango_layout_get_pixel_extents():
Note that both extents may have non-zero x and y. You may want to use
those to offset where you render the layout.
https://developer.gnome.org/pango/stable/pango-Layout-Objects.html#pango-layout-get-extents
This is because the position that you render the layout at is (as far as I remember) the position of the base line (so something logically related to the text) instead of the top-left corner of the layout (which would be some "arbitrary thing" not related to the actual text).
In the case of your code, I would suggest to add tRectangle.x to dTextLocX (or subtract? I'm not completely sure about the sign). The same should be done with the y coordinate.
TL;DR: Your PangoRectangle has a non-zero x/y position that you need to handle.
Edit: I am not completely sure, but I think Pango handles this just like cairo. For cairo, there is a nice description at http://cairographics.org/tutorial/#L1understandingtext. The reference point is the point you give to cairo. You want to look at the description of bearing.

GtkCellRendererPixbuf and signals

Could anyone please give me a hint on how to attach a "double clicked" signal
to the pixbuf that is in the GtkTreeView? GtkCellRendererPixbuf
doesn't have any signals?
I managed to set the GTK_CELL_RENDERER_MODE_ACTIVATABLE switch to the
renderer, but I don't know how to work.
I checked the header file and in fact there is the "activate" method; could you please
demonstrate how to use it?
renderer = gtk_cell_renderer_pixbuf_new();
g_object_set(renderer, "mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE, NULL);
column = gtk_tree_view_column_new_with_attributes(NULL,
renderer,
"pixbuf",
0,
NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
OK I try this:
Tree view's 'row-activated' will send the path and column as arguments
to the callback. With 'cursor-changed' just need to call
gtk_gtk_treeview_get_cursor to find out the path and column. With
gtk Widget's 'button-press-event' I get the event as an argument for
the callback and just need to call gtk_treeview_get_path_at_pos with
event x and event y to get the path and column.
A cell renderer is only supposed to draw the contents of the data model over a portion of the widget. Interaction with the user is in most cases realized using the widget itself.
In other words, simply connect to the button-press-event of the tree view and handle the case when the type is GDK_2BUTTON_PRESS. You can get the row/column under the mouse using gtk_tree_view_get_path_at_pos, as you do in your other question.
Check this:
void on_treeview_row_activated(GtkTreeView *treeview, GtkTreePath *path, GtkTreeViewColumn *col, gpointer data)
{
GtkTreeModel *model;
GtkTreeIter iter;
model = gtk_tree_view_get_model( treeview );
if ( gtk_tree_model_get_iter(model, &iter, path) )
{
gtk_tree_model_get(model, &iter,
ITEM, &dhd_contaItem2,
CODIGO, &dhd_G_CodProduto2 ,
DESCRICAO, &dhd_G_NomeProduto2 ,
QTD, &dhd_quantidade2,
VALOR, &dhd_valorItem2,
-1);
g_print( "Current row: %s %s %s %s %s\n", dhd_contaItem2, dhd_G_CodProduto2, dhd_G_NomeProduto2, dhd_quantidade2, dhd_valorItem2 );
}
}
I use that in one of my codes to print in terminal the selected row from a TreeView (with ListStore) when double clicked or when you press enter on it. On the gtk_tree_model_get notice that I'm using my own columns and variables, as i do in g_print. And I attach this function with row-activated signal on the TreeView. I don't know if is that what you want exactly but I hope it helps you out. Sorry for my bad english.

GtkListStore - how to center text?

I have included a brief snippet of code. I'm making a Tree View with 5 columns. I have pasted the last column with the for loop that generates the data to be stored in the GtkListStore. I can center the columns of the Tree View easily. I have looked online to find out how to center the text in the GtkListStore and I am not finding a solution. I have looked through the documentation:
http://developer.gnome.org/gtk3/3.4/GtkListStore.html
On the last link, I do not see an alignment property. Is there a way to align all of the objects through the GtkTreeModel? I haven't found any online examples using the GtkListStore and aligning text... really appreciate the help!
// Append Table Velocity column
column = gtk_tree_view_column_new();
gtk_tree_view_column_set_title(column, "Pressure");
gtk_tree_view_column_set_min_width(column, 60);
gtk_tree_view_column_set_alignment(column, 0.5); // 0.0 left, 0.5 center, 1.0 right
// Code Above center's the column title in the Tree View
renderer = gtk_cell_renderer_text_new();
g_object_set( G_OBJECT( renderer ), "xalign", 0.5 ); // xalign, 0.5
// Code above doesn't change alignment..
gtk_tree_view_column_pack_start(column, renderer, FALSE);
gtk_tree_view_column_set_attributes(column, renderer, "text", 4, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
// List Store
liststore = gtk_list_store_new(5, G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
gtk_tree_view_set_model(GTK_TREE_VIEW(treeview), GTK_TREE_MODEL(liststore));
int i;
for(i=1; i<=6; i++) {
// Append test data
gtk_list_store_append(liststore, &iter);
gtk_list_store_set(liststore, &iter, 0, i, 1, "5", 2, "0.2", 3, "123", 4, "0.5", -1);
// How do I center the text stored in the GtkListStore?
}
gtk_widget_show_all(window);
I was able to find a convenient function called gtk_tree_view_column_with_attributes(). Using this function and two more lines of code I can conveniently center the text in the header and the list store.
// Append Pressure column
column = gtk_tree_view_column_new_with_attributes("Pressure", renderer, "text", 4, NULL);
gtk_tree_view_column_set_alignment(column, 0.5);
gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
Try g_object_set (renderer, "xalign", 0.5, NULL); with the NULL at the end, g_object_set needs a sentinel. Actually leaving out the sentinel should have given you at least a compiler warning, or did you leave it out deliberately or by mistake?

GtkEntry transparent background without making the whole widget transparent?

I want to just make the background transparent not the whole widget, I know I can make a whole window transparent, but then the cursor fades out too? In essence for gtk_widget_modify_bg I would like to pass a transparent color. I tried using this:
GdkColor color;
gkd_color_parse(&color, "#000000000");
gtk_widget_modify_bg ...
The color comes out as black, or some random transparent color.
I tried doing this but still no result:
static gboolean on_expose(GtkWidget *widget, GdkEventExpose *event, gpointer data)
{
cairo_t *cr;
cr = gdk_cairo_create(gtk_widget_get_window(widget));
cairo_set_source_rgba(cr, 0, 0, 1, 0.1);
cairo_destroy(cr);
return FALSE;
}
I guess gdk_window_shape_combine_mask might be another direction.

Resources