HowTo: Pack Gtk CellRenderers vertically in a Gtk TreeView

[...]
var treeview = Gtk.TreeView();
var column = new Gtk.TreeViewColumn();

var cellrenderer_1 = Gtk.CellRendererPixbuf();
var cellrenderer_2 = Gtk.CellRendererText();

column.add_attribute(cellrenderer_1, "pixbuf", 0);
column.add_attribute(cellrenderer_2, "markup", 1);

(column.get_area() as Gtk.Orientable).set_orientation(Gtk.Orientation.VERTICAL);

column.pack_start(cellrenderer_1, false);
column.pack_start(cellrenderer_2, false);

treeview.append_column(column);
[...] 

Ubuntu 11.10 – Windows lose titlebar

Just a quick fix, if you find that all of your windows in Ubuntu lose their titlebar’s when maximised and want the previous behaviour back, just modify the gconf key that lives under:

/apps/metacity/general/show_maximized_titlebars

 

That is all ๐Ÿ™‚

nVidia GeForce 210 on Ubuntu 11.04

Recently I bought a nVidia Corporation GT218 (GeForce 210) graphics card however I was surprised to find that it didn’t actually work straight away after installing it into the motherboard in Ubuntu 11.04 (Natty).

the reason this happens is that Ubuntu doesn’t ship the latest version of the nVidia binary driver (for stability reasons). This is an issue as the version that Ubuntu ships does not work with the GeForce 210.

However this is not a reason to worry, it is very easy to fix ๐Ÿ™‚

Step 1 : Remove Nouveau Drivers

In order to install the newer nVidia drivers without issue, it is wise to remove the free Nouveau drivers. To do this, open a terminal and type:

sudo apt-get --purge remove xserver-xorg-video-nouveau

And then reboot to make sure everything goes smoothly ๐Ÿ™‚

 

Step 2 : Install new nVidia Drivers

You can download the new nVidia drivers direct from nVidia, however one issue is that the driver kernel modules won’t be rebuilt when your Linux kernel is updated.

Instead, install them from the Ubuntu X Swat PPA (fancy name for the team that manage all things graphical in Ubuntu) and you get the latest stable drivers, and additionally they are rebuilt with every kernel update.

To do this, open a terminal and type:

sudo add-apt-repository ppa:ubuntu-x-swat/x-updates

sudo apt-get update

And then:

sudo apt-get install nvidia-current nvidia-settings

Once this is complete, restart your computer and all should work! You can configure any specific graphics settings with nVidia X Server Settings found in Applications > System > Administration.

 

Help something went wrong!

If anything goes wrong, don’t worry. Boot up your computer and hold down the SHIFT key so that the GRUB Boot Menu appears. Then choose the top-most entry that contains “(recovery mode)” using the arrow keys and click ENTER.

Then using the dialog that appears, select Reconfigure graphics, and then select the entry to reset the graphics configuration to default. Then you should be able to boot correctly again ๐Ÿ™‚

 

References

http://askubuntu.com/questions/4954/how-to-get-nvidia-geforce-gt-210-drivers-working-on-lucid-lynx

http://askubuntu.com/questions/3024/good-nvidia-drivers-for-ubuntu/3027#3027

A Better Firefox Menu

With the release of Firefox 4, a change was the addition of a new ‘compact’ menu.

While the aim of this was to be useful, I can say I have never found it intuitive and prefer the old menu system. In fact, the only reason why I kept it, was that I appreciated the screen space it saved me.

Recently I came across the Firefox Add-on Personal Menu, an extension which allows you to customise which menu items appear in this compact menu.

Using this extension I was able to add the previous menu system (File, Edit, View etc.) into this compact menu. I could have the best of both worlds – saving screen space but the familiarity of the old menu system.

HowTo

After installing Personal Menu from Firefox Add-ons, open Firefox’s Add-ons Manager and then click the Preferences button in the Personal Menu item.

Remove all current menu items in the compact menu by clicking the Remove () button.

Then add the ‘old’ menus into the compact menu by selecting each menu under ‘Menu Bar’ in the left sidebar and clicking the Add (+) button.

Once you have done this, click ‘Apply’ and it should be done!

To restore the compact menu to its previous state, either disable/remove the Personal Menu add-on, or In the ‘Advanced’ tab, (within the Personal Menu preferences) click Restore…

GtkAction – HowTo and Why

About

A problem that recently arose when I was developing a GTK application was I had a set of actions (New, Save, Open etc.) which needed to be in a ToolBar and a MenuBar.

The issue was keeping all these actions in sync, and it becomes even tricker when certain action are only enabled in certain scenarios.

However Gtk has an easy way to deal with this.

GtkAction

A GtkAction simply represents an action and it gives the opportunity for many widgets to make this action happen.

For example if I had a Save action, I would want my Save item in my Menubar and Toolbar do activate this action.

GtkAction also provides many more useful properties, besides just making the action happen. It can also store a label, tooltip, icon and more, so that each widget that uses the action simply ‘picks up’ this information.

In practice this means there is no need to set the label twice etc.

As well as the normal GtkAction class, there is also GtkToggleAction and GtkRadioAction (to represent actions that can be toggled, or a selection out of one) and GtkActionGroup so you can group together similar actions (i.e. actions that modify a document)

Howto use it

Glade

Create actions by clicking on the buttons under Actions

To set widgets to use them, configure the Related Action field

Code (Vala)


var action_clickme = new Gtk.Action("clickme", "Click Me!", "Why don't you click me?", Gtk.Stock.ABOUT);

// This widget can be anything that implement GtkActivatable
var button = new Gtk.Button();
button.set_related_action(action_clickme);
button.set_use_action_appearance(true);

action_clickme.activate.connect(() => {
stdout.printf("You activated the action!\n");
});

 

HowTo: Gtk.Scrollbars and Floating Widgets

Hi All,

So recently with a little project I have been working on, I found myself with a problem.

As shown by the illustration below, I wanted to have a widget (in this case a Gtk.InfoBar) be ‘inside’ the scrollbars of a TreeView I had, so it appeared as though it ‘floated’ on top of the TreeView.

The issue I had

Luckily GTK has widgets to achieve this purpose, however unluckily, there seemed to be a lack of documentation for them :/

However I managed to get my head around them so I thought I’d put this HowTo up for any others who struggle with this in the future (and for me in case I forget :P)

HowTo

The layout of the widgets

To the right you can see the layout needed for this ‘effect’.

Inside a toplevel Gtk.Table (of two columns and two rows), there is a Gtk.VBox, a Gtk.VScrollbar on the right and a Gtk.HScrollbar at the bottom. Inside the Gtk.VBox, there the ‘floating widget’, the widget we want to stay ‘on top’ and a scrollable widget (i.e. Gtk.TreeView, Gtk.IconView).

Essentially what we will do is:

  1. Pack all our widgets into the right places
  2. Synchronise the adjustments for the scrollbars and the scrollable widget
  3. Connect some signals
  4. Done!

NB: All code below is in Vala, however the methods and processes used are the same regardless of language

Okay so first we will create our custom containerย  ‘ScrolledWindowWithFloatingWidget’.


class ScrolledWindowWithFloatingWidget : Gtk.Table {

    private Gtk.HScrollbar hscrollbar;
    private Gtk.VScrollbar vscrollbar;

    private Gtk.Adjustment hadjustment = new Gtk.Adjustment(0, 0, 0, 0, 0, 0);
    private Gtk.Adjustment vadjustment = new Gtk.Adjustment(0, 0, 0, 0, 0, 0);

    private Gtk.VBox vbox;

As you can see above, this container widget is subclassed from the Gtk.Table that we will use to store all of the widgets. We have made the scrollbars fields of this class, as we are going to use them throughout the code, the same with the VBox. Also we have created two new Gtk.Adjustments which we will use to synchronise the scrolling of our scrollable widget and our scrolbars.

The adjustments simply hold values which will be used by the scrollbars and the scrollable widgets, to show how much has been scrolled, how much is currently showing, the boundaries for scrolling etc.

    
public ScrolledWindowWithFloatingWidget() {
        this.vbox = new Gtk.VBox(false, 0);

        this.hadjustment.changed.connect(this.on_hadjustment_changed);
        this.vadjustment.changed.connect(this.on_vadjustment_changed);

        this.hscrollbar = new Gtk.HScrollbar(this.hadjustment);
        this.vscrollbar = new Gtk.VScrollbar(this.vadjustment);

        this.attach(this.vbox, 0, 1, 0, 1, Gtk.AttachOptions.EXPAND|Gtk.AttachOptions.FILL, Gtk.AttachOptions.EXPAND|Gtk.AttachOptions.FILL, 0, 0);
        this.attach(hscrollbar, 0, 1, 1, 2, Gtk.AttachOptions.EXPAND|Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0);
        this.attach(vscrollbar, 1, 2, 0, 1, Gtk.AttachOptions.FILL, Gtk.AttachOptions.EXPAND|Gtk.AttachOptions.FILL, 0, 0);
    }

Above, in the construct method of this class, we create the VBox to store our two widgets, create the two scrollbars (using the adjustments we have already created) and pack these widgets into our container. Also we connect some signals to callbacks, which I shall explain later.


    public void add_scrollable_widget(Gtk.Widget widget) {
        widget.set_scroll_adjustments(this.hadjustment, this.vadjustment);
        widget.scroll_event.connect(this.on_widget_scroll_event);
        widget.set_size_request(1, 1);
        this.vbox.pack_start(widget, true, true);
    }

Next we have a public function of this class. This should be called to add the scrollable widget to the container. What it does is set the scroll adjustments of the widget (i.e. the adjustment which the widget to look for so it knows how much to show at any given time), connect a signal to a callback which shall come up later and also packs the widget into the VBox.

(The size request thing is needed for the widget to grow to fit the vbox, but I don’t really know why, all I know is that it doesn’t have any negative effects ๐Ÿ™‚ )


    public void add_floating_widget(Gtk.Widget widget) {
        this.vbox.pack_start(widget, true, true);
        this.vbox.reorder_child(widget, 0);
    }

Here is a simple function to add our ‘floating widget’. It simply packs the widget into the VBox and makes sure it is at the top.


    private void on_hadjustment_changed() {
        // If the scrollbar is needed, show it, otherwise hide it
        if (this.hadjustment.page_size == this.hadjustment.upper) {
            this.hscrollbar.hide();
        } else {
            this.hscrollbar.show();
        }
    }
    
    private void on_vadjustment_changed() {
        // If the scrollbar is needed, show it, otherwise hide it
        if (this.vadjustment.page_size == this.vadjustment.upper) {
            this.vscrollbar.hide();
        } else {
            this.vscrollbar.show();
        }
    }

These callbacks are connect to the ‘changed’ signal of both Gtk.Adjustments. Basically these callbacks control whether the scrollbars should be shown, based on whether they are needed (i.e. is the scrollable widget too big to fit in the available space and therefore needs to be scrolled.)


    private bool on_widget_scroll_event(Gdk.EventScroll event) {
        if ((event.direction == Gdk.ScrollDirection.UP) || (event.direction == Gdk.ScrollDirection.DOWN)) {
            this.vscrollbar.scroll_event(event);
        } else if ((event.direction == Gdk.ScrollDirection.LEFT) || (event.direction == Gdk.ScrollDirection.RIGHT)) {
            this.hscrollbar.scroll_event(event);
        }
        return true;
    }

This is the final callback and takes care of when a user scrolls the mouse-wheel on the scrollable widget. It checks whether they scrolled horizontally or vertically and passes the event onto the appropriate scrollbar.

The finished product

And that is it! Your floating widget and Gtk.Scrollbars combo should now work a treat! You can download the full code from here: https://code.launchpad.net/~and471/+junk/programming-howtos