Vala StatusIcon Example

This example was copied from http://pomozok.wordpress.com/2011/03/10/gtk-tray-example-written-in-vala/. It shows a basic tray icon, created from the HOME stock icon.

using Gtk;

public class Main {

  class AppStatusIcon : Window {
    private StatusIcon trayicon;
    private Menu menuSystem;

    public AppStatusIcon() {
      /* Create tray icon */
      trayicon = new StatusIcon.from_stock(Stock.HOME);
      trayicon.set_tooltip_text ("Tray");
      trayicon.set_visible(true);

      trayicon.activate.connect(about_clicked);

      create_menuSystem();
      trayicon.popup_menu.connect(menuSystem_popup);
    }

    /* Create menu for right button */
    public void create_menuSystem() {
      menuSystem = new Menu();
      var menuAbout = new ImageMenuItem.from_stock(Stock.ABOUT, null);
      menuAbout.activate.connect(about_clicked);
      menuSystem.append(menuAbout);
      var menuQuit = new ImageMenuItem.from_stock(Stock.QUIT, null);
      menuQuit.activate.connect(Gtk.main_quit);
      menuSystem.append(menuQuit);
      menuSystem.show_all();
    }

    /* Show popup menu on right button */
    private void menuSystem_popup(uint button, uint time) {
      menuSystem.popup(null, null, null, button, time);
    }

    private void about_clicked() {
      var about = new AboutDialog();
      about.set_version("0.0.0");
      about.set_program_name("Tray");
      about.set_comments("Tray utility");
      about.set_copyright("vala");
      about.run();
      about.hide();
    }
  }

  public static int main (string[] args) {
    Gtk.init(ref args);
    var App = new AppStatusIcon();
    App.hide();
    Gtk.main();
    return 0;
  }
}

Compile and Run

$ valac --pkg=gtk+-2.0 tray.vala
$ ./tray

Vala StatusIcon and Cairo Example

This example shows how to create a systray element and paint into it using Cairo. This allows to do animations or change the picture displayed to show the current status.

using GLib;
using Gtk;
using Gdk;
using Cairo;

public class test: GLib.Object {

        private StatusIcon trayicon;
        private int old_size;

        // Pixbuf callback to destroy the pixel buffer
        public void PixbufDestroyNotify (uint8* pixels) {
        
                GLib.stdout.printf("delete buffer\n");
                delete pixels;
        
        }

        public bool timer() {

                // This callback repaints the systray canvas
                GLib.stdout.printf("repaint\n");
                repaint(this.old_size);
                return false;
                
        }

        public bool repaint(int size) {
        
                // First, let's paint something in a Cairo Surface
        
                var canvas = new Cairo.ImageSurface(Cairo.Format.ARGB32,size,size);
                var ctx = new Cairo.Context(canvas);
                
                // This makes easier to scale the picture
                ctx.scale(size,size);

                if (size!=old_size) {
                        
                        // When the size changes, paint a red circle
                        ctx.set_source_rgb(1,0,0);

                        // and set a timer to repaint the circle in green after one second
                        Timeout.add(1000,timer);
                } else {
                        
                        // When just repainting, paint a green circle
                        ctx.set_source_rgb(0,1,0);
                }
                ctx.arc(0.5,0.5,0.3,0,6.283184);
                ctx.set_line_width(0.2);
                ctx.stroke();
                
                this.old_size=size;
                
                // the pixel buffer must remain after being created, so manual memory management is used here
                uint8* pixel_data=new uint8[size*size*4];
                
                // create a new Pixbuf using the previous pixel_data memory as buffer
                // it is 8bit per pixel, RGB, with alpha, and the callback to free the pixel data is PixbufDestroyNotify()
                var pix=new Pixbuf.from_data((uint8[])pixel_data,Gdk.Colorspace.RGB,true,8,size,size,size*4,this.PixbufDestroyNotify);
                        
                uint8 *p1=pixel_data;
                uint8 *p2=canvas.get_data();
                int counter;
                int max=size*size;;
                
                // Copy the surface to the pixbuf
                // (Format in surface is BGRA, but in Pixbuf is RGBA)
                for(counter=0;counter<max;counter++) {
                        *p1    =*(p2+2);
                        *(p1+1)=*(p2+1);
                        *(p1+2)=*p2;
                        *(p1+3)=*(p2+3);
                        p1+=4;
                        p2+=4;
                }
                
                // Set pixmap in the systray
                this.trayicon.set_from_pixbuf(pix);
                
                // Return true because the function had in account the new size, so the pannel has not to scale it
                return true;
        }


        public test() {
        
                this.old_size=0;
                this.trayicon = new StatusIcon();
                this.trayicon.set_visible(true);
                
                // This event is called when the user modifies the height of the pannel
                this.trayicon.size_changed.connect(this.repaint);
                
                // This event is called when the user clicks on the icon.
                // Assigned with an anonymous method to main_quit.
                this.trayicon.activate.connect( () => { Gtk.main_quit(); } );
        
        }
}

public static int main (string[] args) {

        Gtk.init (ref args);

        var testclass = new test();
        Gtk.main ();
        return 0;
}

Compile and Run

$ valac --pkg=gtk+-2.0 tray2.vala
$ ./tray2

Projects/Vala/StatusIcon (last edited 2013-11-22 16:48:30 by WilliamJonMcCann)