public class Entity : Gtk.Grid {
    /*
        Třída entity je mřížkový kontejner se 4mi tlačítky. Klik na tlačítko
        vyvolá jeden ze čtyř příslušných signálů, které může uživatel objektu
        pouužít.
    */
    public signal void left (Gtk.Widget w);     // definice signálů
    public signal void right (Gtk.Widget w);
    public signal void up (Gtk.Widget w);
    public signal void down (Gtk.Widget w);

    public Entity () {
        var left = new Gtk.Button.with_label ("<");
        left.clicked.connect (on_left);
        attach (left, 0, 1, 1, 1);

        var right = new Gtk.Button.with_label (">");
        right.clicked.connect (on_right);
        attach (right, 2, 1, 1, 1);

        var up = new Gtk.Button.with_label ("^");
        up.clicked.connect (on_up);
        attach (up, 1, 0, 1, 1);

        var down = new Gtk.Button.with_label ("v");
        down.clicked.connect (on_down);
        attach (down, 1, 2, 1, 1);
    }

    public void on_left (Gtk.Widget w) {
        left (this);
    }

    public void on_right (Gtk.Widget w) {
        right (this);
    }

    public void on_up (Gtk.Widget w) {
        up (this);
    }

    public void on_down (Gtk.Widget w) {
        down (this);
    }
}

public class Application: Gtk.Window {
    private Gtk.Fixed fixed;
    private int x;
    private int y;

    public Application () {
        set_size_request (400, 400);            // nastavim velikost prvku (okna)
        set_resizable (false);                  // oknu se nedá měnit velikost
        destroy.connect (Gtk.main_quit);

        x = y = 150;
        fixed = new Gtk.Fixed ();               // kontejner fixed
        add (fixed);

        var konec = new Gtk.Button.with_label ("Konec");
        konec.clicked.connect (Gtk.main_quit);
        fixed.put (konec, 160, 180);            // do fixed se vkládá absolutně
                                                // hodnoty x a y jsou v pixelech

        var entity = new Entity ();
        entity.up.connect ((w) => {             // signál up
                    y = (y > 0) ? y-10 : 300;   // změní souřadnice y
                    fixed.move (w, x, y);       // a posune entitu na novou pozici
                });
        entity.down.connect ((w) => {
                    y = (y < 300) ? y+10 : 0;
                    fixed.move (w, x, y);
                });
        entity.left.connect ((w) => {
                    x = (x > 0) ? x-10 : 300;
                    fixed.move (w, x, y);
                });
        entity.right.connect ((w) => {
                    x = (x < 300) ? x+10 : 0;
                    fixed.move (w, x, y);
                });

        fixed.put (entity, x, y);       // prvky se v kontejneru překrývají dle pořadí
                                        // vložení, entity je poslední, tedy nejvýš
    }

    public static int main (string args[]) {
        Gtk.init (ref args);
        var app = new Application();
        app.show_all ();
        Gtk.main ();
        return 0;
    }
}

