16

Im trying to use Image Buttons in GTK# (Xamarin Studio).I set the Image to the button and in the UI Builder the Image is coming up.

enter image description here

But when i run the program there is no image in the button

enter image description here

I tried this in Different versions of the IDE and on different platforms(Mac and Windows)

Please help

Update: MainWindow.cs

using System;
using Gtk;

public partial class MainWindow: Gtk.Window
{
    public MainWindow () : base (Gtk.WindowType.Toplevel)
    {
        Build ();
    }

    protected void OnDeleteEvent (object sender, DeleteEventArgs a)
    {
        Application.Quit ();
        a.RetVal = true;
    }
}

Within gtk-gui folder i can find these files

generated.cs

// This file has been generated by the GUI designer. Do not modify.
namespace Stetic
{
    internal class Gui
    {
        private static bool initialized;

        internal static void Initialize (Gtk.Widget iconRenderer)
        {
            if ((Stetic.Gui.initialized == false)) {
                Stetic.Gui.initialized = true;
            }
        }
    }

    internal class IconLoader
    {
        public static Gdk.Pixbuf LoadIcon (Gtk.Widget widget, string name, Gtk.IconSize size)
        {
            Gdk.Pixbuf res = widget.RenderIcon (name, size, null);
            if ((res != null)) {
                return res;
            } else {
                int sz;
                int sy;
                global::Gtk.Icon.SizeLookup (size, out  sz, out  sy);
                try {
                    return Gtk.IconTheme.Default.LoadIcon (name, sz, 0);
                } catch (System.Exception) {
                    if ((name != "gtk-missing-image")) {
                        return Stetic.IconLoader.LoadIcon (widget, "gtk-missing-image", size);
                    } else {
                        Gdk.Pixmap pmap = new Gdk.Pixmap (Gdk.Screen.Default.RootWindow, sz, sz);
                        Gdk.GC gc = new Gdk.GC (pmap);
                        gc.RgbFgColor = new Gdk.Color (255, 255, 255);
                        pmap.DrawRectangle (gc, true, 0, 0, sz, sz);
                        gc.RgbFgColor = new Gdk.Color (0, 0, 0);
                        pmap.DrawRectangle (gc, false, 0, 0, (sz - 1), (sz - 1));
                        gc.SetLineAttributes (3, Gdk.LineStyle.Solid, Gdk.CapStyle.Round, Gdk.JoinStyle.Round);
                        gc.RgbFgColor = new Gdk.Color (255, 0, 0);
                        pmap.DrawLine (gc, (sz / 4), (sz / 4), ((sz - 1) - (sz / 4)), ((sz - 1) - (sz / 4)));
                        pmap.DrawLine (gc, ((sz - 1) - (sz / 4)), (sz / 4), (sz / 4), ((sz - 1) - (sz / 4)));
                        return Gdk.Pixbuf.FromDrawable (pmap, pmap.Colormap, 0, 0, 0, 0, sz, sz);
                    }
                }
            }
        }
    }

    internal class ActionGroups
    {
        public static Gtk.ActionGroup GetActionGroup (System.Type type)
        {
            return Stetic.ActionGroups.GetActionGroup (type.FullName);
        }

        public static Gtk.ActionGroup GetActionGroup (string name)
        {
            return null;
        }
    }
}

Mainwindow.cs

// This file has been generated by the GUI designer. Do not modify.

public partial class MainWindow
{
    private global::Gtk.Fixed fixed1;

    private global::Gtk.Button button1;

    protected virtual void Build ()
    {
        global::Stetic.Gui.Initialize (this);
        // Widget MainWindow
        this.Name = "MainWindow";
        this.Title = global::Mono.Unix.Catalog.GetString ("MainWindow");
        this.WindowPosition = ((global::Gtk.WindowPosition)(4));
        // Container child MainWindow.Gtk.Container+ContainerChild
        this.fixed1 = new global::Gtk.Fixed ();
        this.fixed1.Name = "fixed1";
        this.fixed1.HasWindow = false;
        // Container child fixed1.Gtk.Fixed+FixedChild
        this.button1 = new global::Gtk.Button ();
        this.button1.CanFocus = true;
        this.button1.Name = "button1";
        this.button1.UseUnderline = true;
        this.button1.Label = global::Mono.Unix.Catalog.GetString ("GtkButton");
        global::Gtk.Image w1 = new global::Gtk.Image ();
        w1.Pixbuf = global::Stetic.IconLoader.LoadIcon (this, "gtk-delete", global::Gtk.IconSize.Menu);
        this.button1.Image = w1;
        this.fixed1.Add (this.button1);
        global::Gtk.Fixed.FixedChild w2 = ((global::Gtk.Fixed.FixedChild)(this.fixed1 [this.button1]));
        w2.X = 153;
        w2.Y = 137;
        this.Add (this.fixed1);
        if ((this.Child != null)) {
            this.Child.ShowAll ();
        }
        this.DefaultWidth = 400;
        this.DefaultHeight = 300;
        this.Show ();
        this.DeleteEvent += new global::Gtk.DeleteEventHandler (this.OnDeleteEvent);
    }
}
techno
  • 6,100
  • 16
  • 86
  • 192
  • Please post code. Is this GTK+ 2 or GTK+ 3? – andlabs Jun 05 '15 at 13:07
  • @andlabs Thanks for the reply.Its GTK+2.0.It will be hard to post all the code including the UI Auto Generated code on SO.I have uploaded the whole project here http://s000.tinyupload.com/?file_id=79475520923978214151 Please download and check – techno Jun 07 '15 at 09:02
  • We don't want your whole project. Please write a minimal example that demonstrates the problem, then we can try to solve that. – user12205 Jun 08 '15 at 01:45
  • @ace Its a minimal project with a single button.The thing is if i post the code here i will need to post the designer auto generated code too right? Anyway i will post it here – techno Jun 08 '15 at 04:30
  • @ace Please see the update – techno Jun 08 '15 at 05:41
  • @andlabs Please see the update – techno Jun 08 '15 at 05:41

2 Answers2

7

As far as I know, there's nothing wrong with the code. This is related to how Gtk theming.

Depending on how your themes are set, you might see the icon or not. By the way, the theme used by Xamarin is different from the one used by default, so running your application from within Xamarin Studio (F5) or from the command line might give different results.

If I remember well, under windows, there's a default Gtk theme and a Windows Theme. There's a tool to switch themes, but unfortunately, I can get my hands on it.

EDIT :

Here's how to get the themes running :

Here is a little software that will let you select a theme: http://sourceforge.net/projects/tumagcc/files/gtk2_prefs.exe/download

You'll also have to download a Gtk theme somewhere on the web (the first one I tried turned out to be ugly and unusable on windows, so you'll probably have to experiment a little bit here). Extract the theme (usually a tar.gz file) to your Gtk installation under share/themes. Make sure the directory structure, once the theme extracted is like :

{Gtk}/share/themes/MyFantasticTheme/Gtk-2.0

Then launch the little software as Administrator, select your theme in the list and click OK. Now run your app from outside Xamarin Studio.

EDIT #2:

After some fiddling I found out a way that displays icons and labels within buttons:

Application.Init ();
Gtk.Settings.Default.ThemeName = "Theme/gtk-2.0/gtkrc";
Gtk.Rc.Parse ("./Theme/gtk-2.0/gtkrc");

My theme consists of a single line inside Theme/gtk-2.0/gtkrc (documentation about the gtkrc file can be easily found, since it's not Gtk# specific):

gtk-button-images = 1

What I think happens is that a default theme is somehow set when your application starts, and this default theme can't be overriden. Why is it so? Maybe because the default theme runs with a specific Gtk engine for windows that doesn't allow icons in buttons. By overriding the default theme, I believe that you switch Gtk to the default engine.

Kristof
  • 435
  • 4
  • 16
  • Thanks for your answer.I tried from the command line there is nothing changed.This is the same thing that happens in Windows and Mac.How can i change the theme? – techno Jun 16 '15 at 11:49
  • There's an application bundled with the Gtk# installer for that purpose. But, oddly, I have the shortcut on my Windows computer, but the program itself is missing. It's called "Gtk Theme Selector". – Kristof Jun 17 '15 at 08:30
  • I tried searching the Entire Mono Folder.All i can find is the Folder named themes with entries Default & MS-Windows – techno Jun 17 '15 at 10:08
  • Thanks for the update.But when i distribute this software(Mainly for Mac) i need the software to take up the UI of the OS Automatically(this works currently) but will i need to distribute this theme or something.How will this work in Mac. – techno Jun 18 '15 at 05:12
  • I would suggest you to add the theme to your solution (set the property in the solution explorer to copy the files to the output folder) and add Gtk.Rc.Parse("/gtk-2.0/gtkrc") at the begining of your program. – Kristof Jun 18 '15 at 06:26
  • Thanks.I will try and get back tomorrow. – techno Jun 19 '15 at 17:41
  • Where can i set the property in the solution explorer to copy the themes locally? I can find a theme named gtkrc in the GTK# Folder,hope its the one you are referring to. – techno Jun 22 '15 at 10:09
  • When clicking the context menu on a file (or a set of files), there's a "Quick properties" menu, displaying: Copy to Ouput Directory and Scan for translations. Select the first item. When building, Xamarin will copy the files from your solution to the "bin" folder (where the .exe file is also copied). – Kristof Jun 22 '15 at 20:10
  • I added the file to the solution and added Gtk.Rc.Parse("/gtk-2.0/gtkrc") before Build(); also tried Gtk.Rc.Parse("gtkrc");.It did not work while running from Xamarin and from CMD. – techno Jun 23 '15 at 17:03
  • Did you verify that in your build path (bin/Release for example), that your theme is correctly copied to , and that the file bin/Release//gtk-2.0/gtkrc can be found? – Kristof Jun 24 '15 at 03:40
  • The theme is copied into the debug directory.What exactly is ? should i create a folder with the name ? I copied the gtkrc in the C:\Program Files (x86)\GtkSharp\2.12\share\themes\Default to the debug directory and put Gtk.Rc.Parse("gtkrc") – techno Jun 24 '15 at 04:40
  • is the name of your theme, sorry if it confused you. If the name of your theme is **Default**, in your solution, you should have a folder **Default** with the property set to _Copy to Output Direction_, and in your code, you should have `Gtk.Rc.Parse("Default/gtkrc")`. – Kristof Jun 24 '15 at 21:36
  • So far what I've been able to do is change my default Gtk Theme using the tool I mentionned before. I created my own gtkrc file, I added it to the Gtk distribution, this file contains one line : `gtk-button-images = 1`. Now when I run my program from outside Xamarin, it displays icons on buttons, as expected. But this doesn't work with `Rc.Parse(...)`. I'll push my investigations a little further. – Kristof Jun 27 '15 at 08:38
  • Ok, now I've got the `Rc.Parse` running. It seems that the .NET runtime you use has an effect on the themes. Running, within Xamarin Studio, with Microsoft .NET 4.5 or Mono 4.0.1 gives me the standard windows theme, but if I use Mono 3.3.0, my own theme is loaded and I see the pictures next to the buttons. – Kristof Jun 27 '15 at 09:58
  • Thanks for the effort.I will check and get back. – techno Jun 27 '15 at 13:28
  • Sorry for the late response,i was very busy with some other stuff other than coding.I cannot find mono 3.30 here http://www.mono-project.com/docs/about-mono/releases/ – techno Jul 03 '15 at 09:22
  • Ok, it seems it's more likely to be mono 3.2.3 (Xamarin studio says 3.3.0, but its installation path says 3.2.3). Have you seen my second edit on my answer? – Kristof Jul 03 '15 at 13:15
  • I have seen it now.I will try and get back tommorow.Thanks – techno Jul 03 '15 at 18:04
  • im sorry im really busy with some other stuff,will check and get back tomorrow. – techno Jul 08 '15 at 18:07
  • i was really busy with studies sorry.I tried adding the code you have mentioned to the program.cs file.It did not work.So i should download and install the old version of mono.Is there any workaround other than this.I can remember seeing the icons when i had used old version of mono.But it was way back – techno Jul 20 '15 at 04:34
  • I tried downloading Mono 3.2.3 and setting the default runtime to mono and adding the code you have suggested.Still does not work.But i have the default theme file and have not modified anything. – techno Jul 20 '15 at 05:24
  • I just tried it again. It my case, it works with .NET 4.5 and Mono 4.0.1, but only outside Xamarin Studio. If you launch it from within Xamarin Studio, it doesn't work. – Kristof Jul 23 '15 at 20:47
  • Thanks.I tried opening outside Xamarin from Command Line.It works :) the image buttons are all working,but the color of the window has completely changed.I will be distributing this app for Mac Only.So can you recommend me which theme to choose. – techno Jul 24 '15 at 05:59
  • I'm not a mac user, so it'll be difficult for me to give any advice on the choice of theme. This is much more a matter of taste than a technical decision. – Kristof Jul 24 '15 at 07:10
  • okay.I simply want the normal theme with the buttons with images on them.So will removing the GTk.parse.. code work? Long back it worked normally(when i was using older version of mono).I will try it out and get back. – techno Jul 24 '15 at 07:22
  • i changed this 'gtk-button-images = 1' in gtk theme file and added the parse code .It works with windows theme outside xamarin.If i press the run button i get the window without the theme and when i check back to see the theme file.Its content is replaced by this - > # # Default keybinding set. Empty because it is implemented inline in the code. # – techno Jul 24 '15 at 07:44
  • Yeah its indeed odd.Anyway i atleast got the image buttons to show up.Will check with mac and get back.Thanks a lot for your effort and help. – techno Jul 25 '15 at 10:59
4

You can achieve the same effect by putting the following after you initialize Gtk.

//Application.Init(); - insert after this line
Gtk.Settings.Default.SetLongProperty ("gtk-button-images", 1, "");
Paul
  • 41
  • 1