GTK+ Forums

Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
It is currently Sun May 19, 2013 1:10 am

All times are UTC




Post new topic Reply to topic  [ 4 posts ] 
Author Message
 Post subject: Adding new stock items
PostPosted: Sun Oct 03, 2010 10:57 am 
Offline
GTK+ Guru

Joined: Sun Jan 17, 2010 6:48 pm
Posts: 100
Anyone got a simple code snippet that shows how to create new stockItems from within a program? I'm slowly piecing the bits together but I can tell that this is not a 'simple' process.

Will

_________________
"If you don't stand for something, then you'll fall for anything."


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 04, 2010 5:23 pm 
Offline
Never Seen the Sunlight

Joined: Wed Jul 23, 2008 10:31 am
Posts: 2406
Location: Slovenia
Hi.

Stock things are not the easiest concept to grasp. They are quite flexible and extendable, but learning curve can be quite steep.

First stock thing that you should know about is stock item, represented by GtkStockItem. This structure holds stock item's ID and all non-image data that one usually sees on widgets, created from stock. GtkMenuItem's label and accelerator come from this struct for example.

Second stock thing is stock icon, represented by GtkIconSet and associated ID. As the name of the main structure suggests, this is a set of one or more images that can be used in different situations (for example, icon set that represents "back" icon needs least 2 images: one for LTR locales and one for RTL ones).

The only connection between stock icons and items is their ID. But there is no rule that both stock item and icon must exist for given ID. It is completely valid to have only stock item or only stock icon.


Creating stock items is really simple. Just create GtkStockItem structure, fill it with proper data and call gtk_stock_add() or gtk_stock_add_static().

Creating stock icons can be really simple or quite complex, depending on the requirements. But in any case, you'll need to create your own GtkIconFactory, add it to default list of icon factories that is being searched by theme system and then add icon sets to this factory.

Last thing is to create actual icon set. This is where the bulk of complexity is hidden, because source of images in icon set can be:
  • file on disk that is read by icon factory
  • GdkPixbuf that is supplied by application
  • icon name, in which case image is loaded from icon theme

First two sources are quite easy to set up, but offer little flexibility. Last one would be the preferred way of creating new stock icons, because icon theme authors can override your default icon. (Of course, this is also the most complex way, since you need to work with theme system;)

To give you something to play with, I created simple application that demonstrates much of what I described above:

Code:
#include <gtk/gtk.h>

/* This is usually defined by build system */
#define GETTEXT_PACKAGE "my-sample-stock-app"

/* Define stock items */
static GtkStockItem stock_items[] =
{
    {"my-stock-sample1", "My Stock Sample 1", 0, 0, GETTEXT_PACKAGE},
    {"my-stock-sample2", "My Stock Sample 2", 0, 0, GETTEXT_PACKAGE},
    {"my-stock-sample3", "My Stock Sample 3", 0, 0, GETTEXT_PACKAGE}
};


static void
init_stocks (void)
{
  GtkIconFactory *factory;
  GtkIconSet     *iconset;
  GtkIconSource  *source;
  GdkPixbuf      *pixbuf;
  char           *path;

  /* Add our custom stock items */
  gtk_stock_add_static (stock_items, G_N_ELEMENTS (stock_items));


  /* Init icon factory */
  factory = gtk_icon_factory_new ();
  gtk_icon_factory_add_default (factory);


  /* Create stock icon for "my-stock-sample1" (from file) */
  path = g_build_filename (g_get_current_dir (), "night1.png", NULL);
  source = gtk_icon_source_new ();
  gtk_icon_source_set_filename (source, path);
  g_free (path);

  iconset = gtk_icon_set_new ();
  gtk_icon_set_add_source (iconset, source);
  gtk_icon_source_free (source);

  gtk_icon_factory_add (factory, "my-stock-sample1", iconset);
  gtk_icon_set_unref (iconset);


  /* Create stock icon for "my-stock-sample2" (from pixbuf) */
  path = g_build_filename (g_get_current_dir (), "night2.png", NULL);
  pixbuf = gdk_pixbuf_new_from_file (path, NULL);
  g_free (path);

  iconset = gtk_icon_set_new_from_pixbuf (pixbuf);
  g_object_unref (pixbuf);

  gtk_icon_factory_add (factory, "my-stock-sample2", iconset);
  gtk_icon_set_unref (iconset);


  /* Create stock icon for "my-stock-sample3" (from named icon) */
  source = gtk_icon_source_new ();
  gtk_icon_source_set_icon_name (source, "folder-music");

  iconset = gtk_icon_set_new ();
  gtk_icon_set_add_source (iconset, source);
  gtk_icon_source_free (source);

  gtk_icon_factory_add (factory, "my-stock-sample3", iconset);
  gtk_icon_set_unref (iconset);
}

int
main (int    argc,
      char **argv)
{
  GtkWidget *window,
            *vbox,
            *hbox,
            *button,
            *label;

  gtk_init (&argc, &argv);

  init_stocks();

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  g_signal_connect (window, "destroy", gtk_main_quit, NULL);

  vbox = gtk_vbox_new (FALSE, 5);
  gtk_container_add (GTK_CONTAINER (window), vbox);

  hbox = gtk_hbox_new (FALSE, 5);
  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);

  button = gtk_button_new_from_stock ("my-stock-sample1");
  gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);

  label = gtk_label_new ("From filename");
  gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);

  hbox = gtk_hbox_new (FALSE, 5);
  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);

  button = gtk_button_new_from_stock ("my-stock-sample2");
  gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);

  label = gtk_label_new ("From pixbuf");
  gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);

  hbox = gtk_hbox_new (FALSE, 5);
  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);

  button = gtk_button_new_from_stock ("my-stock-sample3");
  gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);

  label = gtk_label_new ("From named icon (theme)");
  gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);

  gtk_widget_show_all (window);

  gtk_main ();

  return 0;
}

Tadej


Top
 Profile  
 
 Post subject: Thanks
PostPosted: Tue Oct 05, 2010 8:05 am 
Offline
GTK+ Guru

Joined: Sun Jan 17, 2010 6:48 pm
Posts: 100
Tadej

Thanks for taking the time to make such a highly detailed reply. It is much appreciated.

WJG

_________________
"If you don't stand for something, then you'll fall for anything."


Top
 Profile  
 
 Post subject: Bindings Complete!
PostPosted: Thu Oct 07, 2010 10:18 am 
Offline
GTK+ Guru

Joined: Sun Jan 17, 2010 6:48 pm
Posts: 100
I've now wrapped up the code to create stockitems in to the Gnocl bindings. Here's how to add a stock item:

From a file:

[code=]gnocl::stockItem add -label News -icon "%/[pwd]/news.png"[/code]

From a pixbuf:

[code=]gnocl::stockItem add -label Georgie -icon "%?$pb1"[/code]

And, here's how to use them:

[code=]set but2 [gnocl::button -icon "%#News" -text White] [/code]

Job Done!

Will

_________________
"If you don't stand for something, then you'll fall for anything."


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

All times are UTC


Who is online

Users browsing this forum: Google [Bot] and 4 guests


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:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group