GTK+ Forums

Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
It is currently Sat Oct 25, 2014 7:44 pm

All times are UTC




Post new topic Reply to topic  [ 8 posts ] 
Author Message
 Post subject: A little help with CssProvider in gtkmm (C++)
PostPosted: Mon Aug 27, 2012 3:44 pm 
Offline
Familiar Face

Joined: Mon Aug 27, 2012 3:39 pm
Posts: 6
I'm using:
Ubuntu 12.04 (Unico)
Gtkmm

I'm interfacing with a few different systems. If I lose comms to X system, I need a Gtk::Entry that holds the status message for that comm link to not only go from 'connected' to 'disconnected', but I also want the background of the entry widget to go from green to red. Then, if the comms link comes back, it should go back from red to green.


Last edited by jasonmclose on Mon Aug 27, 2012 8:03 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re:A little help with CssProvider in gtkmm (C++)
PostPosted: Fri Aug 31, 2012 4:03 pm 
Offline
GTK+ Guru

Joined: Fri Mar 25, 2011 5:16 pm
Posts: 177
Location: USA
Once you change the background color the window manager changes the text highlight-color for you.
This is weather you use CSS or functions to do it. So you must change it back if you want the stock look.

For Ubuntu 12.04 with Unico use background not background-color.
If you want to use CSS I found this on the gtk-devel-list which may be of use.
https://mail.gnome.org/archives/gtk-app-devel-list/2012-August/msg00086.html

You cound use g_io_add_watch () to watch for comm changes then execute that code.

But I would not use CSS. Use g_io_add_watch () with these functions:
gtk_widget_override_background_color()
gtk_widget_override_color() (with GTK_STATE_FLAG_SELECTED)

As far a the actual serial code I'am not familiar with that or gtkmm.


Top
 Profile  
 
 Post subject: Re: A little help with CssProvider in gtkmm (C++)
PostPosted: Fri Aug 31, 2012 4:13 pm 
Offline
Familiar Face

Joined: Mon Aug 27, 2012 3:39 pm
Posts: 6
That solution will not work.

gtk_widget_override_background_color() only overrides the highlight color. gtk_widget_override_color() will override the color of the font/text. If I use gtk_widget_override_background_color(), and set it to red, use the GTK_STATE_FLAG_SELECTED flag, that will give me a text entry with the text highlighted with a red highlight, but beyond the text, the rest of the text entry will be white.

As far as I can see, there is no way to change the background color (not the highlight color) of a Gtk::Entry through API calls. the ONLY way I see it done is via the CSS (background attribute).

The issue is, there doesn't seem to be an easy way to manipulate that linked css file during runtime, and have the GUI reapply the changes.


Top
 Profile  
 
 Post subject: Re: A little help with CssProvider in gtkmm (C++)
PostPosted: Sat Sep 01, 2012 4:39 am 
Offline
GTK+ Guru

Joined: Fri Mar 25, 2011 5:16 pm
Posts: 177
Location: USA
Here's an example in C code that simulates the serial connection with two buttons. This works for me on Ubuntu Natty (classic no effects and Unico)
Attachment:
serial1.png
serial1.png [ 11.27 KiB | Viewed 1305 times ]

Code:
/*  Compile with:   
      gcc -Wall -o ser2 `pkg-config --cflags --libs gtk+-3.0` ser2.c
*/

#include <gtk/gtk.h>

typedef struct
{
   GtkWidget *window;
   GtkWidget *grid;
   GtkWidget *entry;
   GtkWidget *com_enable_btn;
   GtkWidget *com_disable_btn;
}WIDGETS;

static void comm_enable (GtkButton *button,  gpointer data)
{
  WIDGETS *widget = (WIDGETS*) data;

  GdkRGBA entry_bg_highlight_color = {0, 0, 0, 1.0};
  GdkRGBA entry_bg_color = {0, 1.0, 0, 1.0};
  GdkRGBA entry_cursor_color = {0, 1.0, 0, 1.0};
  gtk_entry_set_text (GTK_ENTRY(widget->entry), "connected");
  gtk_widget_override_color (GTK_WIDGET(widget->entry), GTK_STATE_FLAG_SELECTED, &entry_bg_highlight_color);
  gtk_widget_override_background_color (GTK_WIDGET(widget->entry), GTK_STATE_FLAG_NORMAL, &entry_bg_color);
  gtk_widget_override_cursor (GTK_WIDGET(widget->entry), &entry_cursor_color, &entry_cursor_color);
}

static void comm_disable (GtkToggleButton *togglebutton,  gpointer data)
{
  WIDGETS *widget = (WIDGETS*) data;

  gtk_entry_set_text (GTK_ENTRY(widget->entry), "disconnected");
  GdkRGBA entry_bg_highlight_color = {0, 0, 0, 1.0};
  GdkRGBA entry_bg_color = {1.0, 0, 0, 1.0};
  GdkRGBA entry_cursor_color = {1.0, 0, 0, 1.0};

  gtk_widget_override_color (GTK_WIDGET(widget->entry), GTK_STATE_FLAG_SELECTED, &entry_bg_highlight_color);
  gtk_widget_override_background_color (GTK_WIDGET(widget->entry), GTK_STATE_FLAG_NORMAL, &entry_bg_color);
  gtk_widget_override_cursor (GTK_WIDGET(widget->entry), &entry_cursor_color, &entry_cursor_color);
}

int main(int argc, char *argv[] )
{
  WIDGETS *widget = g_slice_new (WIDGETS);

  gtk_init (&argc, &argv);
 
  widget->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  g_signal_connect (GTK_WIDGET (widget->window), "destroy", G_CALLBACK (gtk_main_quit), NULL);

  widget->entry = gtk_entry_new ();
  gtk_entry_set_text (GTK_ENTRY(widget->entry), "connected");
  gtk_entry_set_alignment (GTK_ENTRY(widget->entry), 0.50);
  gtk_editable_set_editable( GTK_EDITABLE(widget->entry), FALSE);
  gtk_entry_set_width_chars (GTK_ENTRY(widget->entry), 13);
  gtk_entry_set_max_length (GTK_ENTRY(widget->entry), 13);

  GdkRGBA entry_bg_highlight_color = {0, 0, 0, 1.0};
  GdkRGBA entry_bg_color = {0, 1.0, 0, 1.0};
  GdkRGBA entry_cursor_color = {0, 1.0, 0, 1.0};

  gtk_widget_override_background_color (GTK_WIDGET(widget->entry), GTK_STATE_FLAG_NORMAL, &entry_bg_color);
  gtk_widget_override_color (GTK_WIDGET(widget->entry), GTK_STATE_FLAG_SELECTED, &entry_bg_highlight_color);
  gtk_widget_override_cursor (GTK_WIDGET(widget->entry), &entry_cursor_color, &entry_cursor_color);

  widget->com_enable_btn = gtk_button_new_with_label ("enable");
  widget->com_disable_btn = gtk_button_new_with_label ("disable");

  g_signal_connect (widget->com_enable_btn, "clicked", G_CALLBACK (comm_enable), widget);
  g_signal_connect (widget->com_disable_btn, "clicked", G_CALLBACK (comm_disable), widget);

  widget->grid = gtk_grid_new ();
  gtk_grid_attach (GTK_GRID(widget->grid), GTK_WIDGET(widget->entry), 0, 0, 1, 1);

  gtk_grid_attach (GTK_GRID(widget->grid), GTK_WIDGET(widget->com_enable_btn), 1, 0,1, 1);

  gtk_grid_attach (GTK_GRID(widget->grid), GTK_WIDGET(widget->com_disable_btn), 2, 0, 1, 1);

  gtk_widget_set_margin_top (widget->grid, 20);
  gtk_widget_set_margin_bottom (widget->grid, 20);
  gtk_widget_set_margin_left (widget->grid, 20);
  gtk_widget_set_margin_right (widget->grid, 20);

  gtk_container_add (GTK_CONTAINER(widget->window), GTK_WIDGET(widget->grid));
  gtk_widget_show_all(widget->window);
  gtk_main();
  g_slice_free (WIDGETS, widget);
  return(0);
}


Top
 Profile  
 
 Post subject: Re: A little help with CssProvider in gtkmm (C++)
PostPosted: Tue Sep 04, 2012 12:36 pm 
Offline
Familiar Face

Joined: Mon Aug 27, 2012 3:39 pm
Posts: 6
did you try to compile this?

i'm getting all sorts of errors.
Code:
gtk_entry_get_type
isn't in the gtk3 API.

this wouldn't compile for me (Ubuntu 12.04). it worked for you?


Top
 Profile  
 
 Post subject: Re: A little help with CssProvider in gtkmm (C++)
PostPosted: Tue Sep 04, 2012 3:02 pm 
Offline
Familiar Face

Joined: Mon Aug 27, 2012 3:39 pm
Posts: 6
Attachment:
File comment: this is what i see when i start up my program
gtk_ss_start.png
gtk_ss_start.png [ 7.1 KiB | Viewed 1286 times ]
Attachment:
File comment: as you can see, the green only shows up when you highlight the text
gtk_ss_green.png
gtk_ss_green.png [ 8.61 KiB | Viewed 1286 times ]
Attachment:
File comment: red only shows up once you hit 'disconnect' and highlight the text.
gtk_ss_red.png
gtk_ss_red.png [ 8.79 KiB | Viewed 1286 times ]


ok. i converted your C code to C++ (gtkmm) so that you can see what is going on. here are the screenshots.

as you can see, the override_background functionality does not seem to be consistent between your code and mine. i don't know if your code is entirely GTK3 though, as i couldn't get it to compile quickly. but regardless, the override_background only changes the highlight color, not the actual background color of the widget.

if you have any more suggestions, i'm all ears. but either the GNOME people changed the way the override_background functionality works in GTK3 in respect to the text entry (Gtk::Entry), or it doesn't work the way you thought it did (i assumed the same thing you did until i went in and tried it and i crashed and burned. so i was in the same boat...).

below is my code:
Code:
/*  Compile with:   
    g++ -g -Wall testgtk.cpp `pkg-config --cflags --libs gtkmm-3.0` -o testgtk
*/
#include <gtkmm.h>

// Convenience function, so we don't have to enter this in more than once.
void set_entry_attr(Gtk::Entry* entry, double r, double g, double b, Glib::ustring text)
{
    // Create colors
    Gdk::RGBA entry_bg_highlight_color;
    Gdk::RGBA entry_bg_color;
    Gdk::RGBA entry_cursor_color;

    // Pick our colors
    entry_bg_highlight_color.set_rgba(0, 0, 0, 1.0);
    entry_bg_color.set_rgba(r, g, b, 1.0);
    entry_cursor_color.set_rgba(r, g, b, 1.0);

    entry->set_text(text);

    // Set entry's colors
    entry->override_background_color(entry_bg_color, Gtk::STATE_FLAG_NORMAL);
    entry->override_color(entry_bg_highlight_color, Gtk::STATE_FLAG_SELECTED);
    entry->override_cursor(entry_cursor_color, entry_cursor_color);
} // end set_entry_attr

// When the user hits the enable button
static void comm_enable(Gtk::Entry* entry)
{
    set_entry_attr(entry, 0, 1.0, 0, "connected");
} // end comm_enable

// When the user hits the disable button
static void comm_disable(Gtk::Entry* entry)
{
    set_entry_attr(entry, 1.0, 0, 0, "disconnected");
} // end com_disable

int main (int argc, char *argv[])
{
    //gtk_init(&argc, &argv);

    Glib::RefPtr<Gtk::Application> app = Gtk::Application::create(argc, argv, "example.org");

    // Create the window
    Gtk::Window* window = new Gtk::Window(Gtk::WINDOW_TOPLEVEL);

    // Create the grid
    Gtk::Grid* grid = new Gtk::Grid();

    // Create buttons
    Gtk::Button* com_enable_btn = new Gtk::Button("enable");
    Gtk::Button* com_disable_btn = new Gtk::Button("disable");

    // New entry
    Gtk::Entry* entry = new Gtk::Entry();

    // Configure entry
    entry->set_text("connected");
    entry->set_alignment(0.50);
    entry->set_editable(false);
    entry->set_width_chars(13);
    entry->set_max_length(13);

    // Initialize the entry's stuff
    set_entry_attr(entry, 0, 1.0, 0, "connected");

    // Connect button click signals, and pass the entry
    com_enable_btn->signal_clicked().connect(sigc::bind<Gtk::Entry*>(sigc::ptr_fun(&comm_enable), entry));
    com_disable_btn->signal_clicked().connect(sigc::bind<Gtk::Entry*>(sigc::ptr_fun(&comm_disable), entry));

    // Attach widgets to grid
    grid->attach(*entry, 0, 0, 1, 1);
    grid->attach(*com_enable_btn, 1, 0, 1, 1);
    grid->attach(*com_disable_btn, 2, 0, 1, 1);

    // Grid stuff
    grid->set_margin_top(20);
    grid->set_margin_bottom(20);
    grid->set_margin_left(20);
    grid->set_margin_right(20);

    // Add the grid
    window->add(*grid);

    // Show everything
    window->show_all();

    // Run the app
    app->run(*window);

    // Housecleaning
    delete window;
    delete grid;
    delete com_enable_btn;
    delete com_disable_btn;
    delete entry;

    // Return
    return 0;
} // end main


Top
 Profile  
 
 Post subject: Re: A little help with CssProvider in gtkmm (C++)
PostPosted: Tue Sep 04, 2012 3:46 pm 
Offline
GTK+ Guru

Joined: Fri Mar 25, 2011 5:16 pm
Posts: 177
Location: USA
Yes, it compiled just fine without any warnings. The screen shot is of the program running.

gtk_entry_get_type() isn't in my code or your's.

All the code I'm using is GTK+3.
http://developer.gnome.org/gtk3/3.2/GtkEntry.html
http://developer.gnome.org/gtk3/3.2/GtkWidget.html

Perhaps gtk_widget_override_color () is the problem when using Gtkmm. There are warnings in the documentation about using it.
Quote:
Note that for complex widgets this may bring in undesired results (such as uniform background color everywhere), in these cases it is better to fully style such widgets through a GtkCssProvider with the GTK_STYLE_PROVIDER_PRIORITY_APPLICATION priority.

http://developer.gnome.org/gtk3/3.2/GtkWidget.html#gtk-widget-override-color

Whether GtkEntry qualifies as a "complex widgets" I'm not sure.

Maybe someone who's more familiar with Gtkmm can help out here.


Top
 Profile  
 
 Post subject: Re: A little help with CssProvider in gtkmm (C++)
PostPosted: Tue Sep 04, 2012 3:54 pm 
Offline
Familiar Face

Joined: Mon Aug 27, 2012 3:39 pm
Posts: 6
You're right. I don't know where the code I got came from. sorry about that. I thought I copied it directly off of the page. Weird, I apologise.

It's so odd that it works differently between C and C++.

Unfortunately, all I need to know is how to change the CSS Properties in mid exectution, and get the GUI to reapply them.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group