Search code examples
linuxgtk3valaelementary-os

Simple dialog box with icon, text and two buttons in VALA on Linux (elementary OS)


For the last two days I'm trying to figure out how to achieve a standard dialogbox layout with icon on the left, a text on the right and two buttons below in Vala on linux (elementaryOS JUNO). Couldn't also find any template for this. Here is my code, feel free to modify it.

/*
 * The Button widget is commonly found in programs and used to launch processes
 * and operations.
*/

using Gtk;

public class XScreensaverControl : Window
{
    private Button button;

    public XScreensaverControl()
    {
        this.title = "Control XScreensaver";
        this.destroy.connect(Gtk.main_quit);

        //Box with icon and text in horizontal layout
        var hbox = new Box(Gtk.Orientation.HORIZONTAL, 20);
        hbox.set_spacing(5);
        this.add(hbox);
        var image = new Gtk.Image.from_icon_name ("dialog-question", Gtk.IconSize.DIALOG);
        image.halign = Gtk.Align.START;
        hbox.add(image);
        var label1 = new Label(null);
        hbox.add(label1);
        label1.set_markup("What do you want to do with <b>XScreensaver</b>?");
        hbox.margin = 12;

        //Box with buttons in horizontal layout
        var hbox2 = new Box(Gtk.Orientation.HORIZONTAL, 20);
        button = new Button();
        button.set_label("Turn Off");
        button.get_style_context ().add_class (Gtk.STYLE_CLASS_DESTRUCTIVE_ACTION);
        button.clicked.connect(off_button_clicked);
        hbox2.add(button);
        button = new Button();
        button.set_label("Turn On");
        button.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION);
        button.clicked.connect(on_button_clicked);
        hbox2.add(button);
        hbox2.halign = Gtk.Align.END;
        resizable = false;

        //Vertical box container for two horizontal boxes
        var vbox = new Box(Gtk.Orientation.VERTICAL, 1);
        vbox.set_spacing(1);
        vbox.add(hbox2);
        hbox.add(vbox);

    }

    private void off_button_clicked(Button button)
    {
        var label = button.get_label();
        stdout.printf("%s clicked\n", label);
                // Non blocking - does not wait for process to finish
        Process.spawn_command_line_async ("xscreensaver-command -exit");
    }

    private void on_button_clicked(Button button)
    {
        var label = button.get_label();
        stdout.printf("%s clicked\n", label);
                // Non blocking - does not wait for process to finish
        Process.spawn_command_line_async ("xscreensaver -nosplash");
    }


    public static int main(string[] args)
    {
        Gtk.init(ref args);

        var window = new XScreensaverControl();
        window.show_all();

        Gtk.main();

        return 0;
    }

}

For now it produces this result: enter image description here

But I would like to end up with something like this (mockup created in photopea.com): enter image description here

After two afternoons of thinking im out of ideas as an hobbyist how to achieve this layout.


Solution

  • using Gtk;
    
    public class XScreensaverControl : Window
    {
        private Button button1 = new Button.with_label("Turn Off");
        private Button button2 = new Button.with_label("Turn On");
    
        public XScreensaverControl()
        {
            this.title = "Control XScreensaver";
            this.destroy.connect(Gtk.main_quit);
    
            //Box with icon and text in horizontal layout
            var hbox = new Box(Gtk.Orientation.HORIZONTAL, 20);
            hbox.set_spacing(5);
            var image = new Gtk.Image.from_icon_name ("dialog-question", Gtk.IconSize.DIALOG);
            image.halign = Gtk.Align.START;
            hbox.add(image);
            var label1 = new Label(null);
            hbox.add(label1);
            label1.set_markup("What do you want to do with <b>XScreensaver</b>?");
            hbox.margin = 12;
    
            //Box with buttons in horizontal layout
            var hbox2 = new Box(Gtk.Orientation.HORIZONTAL, 20);
    
            button1.get_style_context ().add_class (Gtk.STYLE_CLASS_DESTRUCTIVE_ACTION);
            button1.clicked.connect(off_button_clicked);
            hbox2.add(button1);
            button2.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION);
            button2.clicked.connect(on_button_clicked);
            hbox2.add(button2);
            hbox2.halign = Gtk.Align.END;
            resizable = false;
    
            //Vertical box container for two horizontal boxes
            var vbox = new Box(Gtk.Orientation.VERTICAL, 1);
            vbox.set_spacing(1);
            vbox.add(hbox);
            vbox.add(hbox2);
            this.add(vbox);
        }
    
        private void off_button_clicked(Button button)
        {
            var label = button.get_label();
            stdout.printf("%s clicked\n", label);
                    // Non blocking - does not wait for process to finish
            Process.spawn_command_line_async ("xscreensaver-command -exit");
        }
    
        private void on_button_clicked(Button button)
        {
            var label = button.get_label();
            stdout.printf("%s clicked\n", label);
                    // Non blocking - does not wait for process to finish
            Process.spawn_command_line_async ("xscreensaver -nosplash");
        }
    
    
        public static int main(string[] args)
        {
            Gtk.init(ref args);
            var window = new XScreensaverControl();
            window.show_all();
            Gtk.main();
            return 0;
        }
    
    }
    

    Now you need to deal with the margins.

    enter image description here