From 5082995c982a48771ba5c6e4e358262f749841d5 Mon Sep 17 00:00:00 2001 From: Colin Kiama Date: Sun, 10 Nov 2024 16:15:48 +0000 Subject: [PATCH] Add GTK 4 Samples Fixes #21 --- .../gui-programming/gtk4-samples.rst | 43 ++++++ .../gtk4-samples/basic-app.rst | 50 +++++++ .../gtk4-samples/clipboard.rst | 78 ++++++++++ .../gtk4-samples/column-view.rst | 134 ++++++++++++++++++ .../entry-completion-two-cells.rst | 88 ++++++++++++ .../gtk4-samples/list-view-check-buttons.rst | 96 +++++++++++++ .../gtk4-samples/list-view.rst | 121 ++++++++++++++++ .../gtk4-samples/minimal-app.rst | 54 +++++++ .../gtk4-samples/synchronising-widgets.rst | 67 +++++++++ .../gtk4-samples/text-file-viewer.rst | 101 +++++++++++++ 10 files changed, 832 insertions(+) create mode 100644 source/tutorials/gui-programming/gtk4-samples.rst create mode 100644 source/tutorials/gui-programming/gtk4-samples/basic-app.rst create mode 100644 source/tutorials/gui-programming/gtk4-samples/clipboard.rst create mode 100644 source/tutorials/gui-programming/gtk4-samples/column-view.rst create mode 100644 source/tutorials/gui-programming/gtk4-samples/entry-completion-two-cells.rst create mode 100644 source/tutorials/gui-programming/gtk4-samples/list-view-check-buttons.rst create mode 100644 source/tutorials/gui-programming/gtk4-samples/list-view.rst create mode 100644 source/tutorials/gui-programming/gtk4-samples/minimal-app.rst create mode 100644 source/tutorials/gui-programming/gtk4-samples/synchronising-widgets.rst create mode 100644 source/tutorials/gui-programming/gtk4-samples/text-file-viewer.rst diff --git a/source/tutorials/gui-programming/gtk4-samples.rst b/source/tutorials/gui-programming/gtk4-samples.rst new file mode 100644 index 0000000..8a5ee16 --- /dev/null +++ b/source/tutorials/gui-programming/gtk4-samples.rst @@ -0,0 +1,43 @@ +GTK4 Samples +============ + +.. important:: + + GTK 4 is required is required to compile and run the Vala code samples. + Depending on your environment, you may need to install a gtk4 development package. + + You can learn more about GTK and how to install GTK 4 at https://gtk.org + + +Introduction +------------ + +This tutorial is a subset of GTK4 Samples written in Vala. + +This serves as an introduction to developing GTK4 Appliations in Vala. + +Source Code +----------- + +You can view the full set of Vala GTK4 Samples in in the +`Vala GTK4 Samples source code repository `_ + +The repository includes the sample code featured in this website. + +Samples +------- + +.. toctree:: + :maxdepth: 1 + :glob: + + gtk4-samples/minimal-app + gtk4-samples/basic-app + gtk4-samples/synchronising-widgets + gtk4-samples/text-file-viewer + gtk4-samples/list-view + gtk4-samples/list-view-check-buttons + gtk4-samples/column-view + gtk4-samples/clipboard + gtk4-samples/entry-completion-two-cells + \ No newline at end of file diff --git a/source/tutorials/gui-programming/gtk4-samples/basic-app.rst b/source/tutorials/gui-programming/gtk4-samples/basic-app.rst new file mode 100644 index 0000000..05c45b8 --- /dev/null +++ b/source/tutorials/gui-programming/gtk4-samples/basic-app.rst @@ -0,0 +1,50 @@ +Basic App +========= + +Source Code +----------- + +.. code-block:: vala + + // BasicApp.vala + + public class BasicAppSample : Gtk.Application { + public BasicAppSample () { + Object (application_id: "com.example.BasicAppSample"); + } + + public override void activate () { + var window = new Gtk.ApplicationWindow (this) { + title = "Basic GTK4 App" + }; + + var button = new Gtk.Button.with_label ("Click me!"); + button.clicked.connect (() => { + button.label = "Thank you"; + }); + + window.child = button; + window.present (); + } + + public static int main (string[] args) { + var app = new BasicAppSample (); + return app.run (args); + } + } + +Compile and Run +--------------- + +Compile: + +.. code-block:: console + + $ valac --pkg gtk4 BasicAppSample.vala + +Run: + +.. code-block:: console + + $ ./BasicAppSample.vala + diff --git a/source/tutorials/gui-programming/gtk4-samples/clipboard.rst b/source/tutorials/gui-programming/gtk4-samples/clipboard.rst new file mode 100644 index 0000000..1698359 --- /dev/null +++ b/source/tutorials/gui-programming/gtk4-samples/clipboard.rst @@ -0,0 +1,78 @@ +Clipboard +========= + +Source Code +----------- + +.. code-block:: vala + + // Clipboard.vala + + public class ClipboardSample : Gtk.Application { + private Gtk.Entry entry; + private Gdk.Clipboard clipboard; + private Gtk.ApplicationWindow window; + + + public ClipboardSample () { + Object (application_id: "com.example.ClipboardSample"); + } + + public override void activate () { + this.window = new Gtk.ApplicationWindow (this) { + title = "Clipboard", + default_width = 300, + default_height = 60, + }; + + this.entry = new Gtk.Entry (); + entry.placeholder_text = "Type here to set the clipboard's content!"; + + this.clipboard = entry.get_clipboard (); + this.clipboard.changed.connect (this.on_clipboard_changed); + + // If the user types something ... + entry.changed.connect (() => { + // Set text to clipboard + clipboard.set_text (entry.text); + }); + + this.window.child = entry; + this.window.present (); + } + + private void on_clipboard_changed () { + clipboard.read_text_async.begin (null, (obj, res) => { + try { + var content = clipboard.read_text_async.end (res); + // Only load text from clipboard when the app starts + this.clipboard.changed.disconnect(this.on_clipboard_changed); + this.entry.text = content; + } catch (GLib.Error err) { + stderr.printf ("Error: %s", err.message); + } + }); + } + + public static int main (string[] args) { + var app = new ClipboardSample (); + return app.run (args); + } + } + + +Compile and Run +--------------- + +Compile: + +.. code-block:: console + + $ valac --pkg gtk4 Clipboard.vala + +Run: + +.. code-block:: console + + $ ./Clipboard.vala + diff --git a/source/tutorials/gui-programming/gtk4-samples/column-view.rst b/source/tutorials/gui-programming/gtk4-samples/column-view.rst new file mode 100644 index 0000000..67d752b --- /dev/null +++ b/source/tutorials/gui-programming/gtk4-samples/column-view.rst @@ -0,0 +1,134 @@ +ColumnView +========== + +Source Code +----------- + +.. code-block:: vala + + // ColumnView.vala + + public class Account : GLib.Object { + public string name { get; set; } + public string account_type { get; set; } + public string balance { get; set; } + + public Account (string name, string account_type, string balance) { + Object ( + name: name, + account_type: account_type, + balance: balance + ); + } + } + + public class ColumnViewSample : Gtk.Application { + public ColumnViewSample () { + Object (application_id: "com.example.ColumnViewSample"); + } + + public override void activate () { + var window = new Gtk.ApplicationWindow (this) { + title = "ColumnView Sample", + default_width = 375, + default_height = 150 + }; + + var accounts = new GLib.ListStore(typeof (Account)); + var selection_model = new Gtk.SingleSelection (accounts) { + autoselect = true + }; + + accounts.append (new Account ("Visa", "Card", "102.10")); + accounts.append (new Account ("Mastercard", "Card", "10.20")); + + var name_column_factory = new Gtk.SignalListItemFactory (); + name_column_factory.setup.connect (on_name_column_setup); + name_column_factory.bind.connect (on_name_column_bind); + + var account_type_column_factory = new Gtk.SignalListItemFactory (); + account_type_column_factory.setup.connect (on_account_type_column_setup); + account_type_column_factory.bind.connect (on_account_type_column_bind); + + var balance_column_factory = new Gtk.SignalListItemFactory (); + balance_column_factory.setup.connect (on_balance_column_setup); + balance_column_factory.bind.connect (on_balance_column_bind); + + var name_column = new Gtk.ColumnViewColumn ("Account Name", name_column_factory); + name_column.expand = true; + + var account_type_column = new Gtk.ColumnViewColumn ("Type", account_type_column_factory); + + var balance_column = new Gtk.ColumnViewColumn ("Balance", balance_column_factory); + balance_column.expand = true; + + var column_view = new Gtk.ColumnView (selection_model); + column_view.append_column(name_column); + column_view.append_column(account_type_column); + column_view.append_column(balance_column); + + window.child = column_view; + window.present (); + } + + private void on_name_column_setup (Gtk.SignalListItemFactory factory, GLib.Object list_item_obj) { + var label = new Gtk.Label (""); + label.halign = Gtk.Align.START; + ((Gtk.ListItem) list_item_obj).child = label; + } + + private void on_name_column_bind (Gtk.SignalListItemFactory factory, GLib.Object list_item_obj) { + var list_item = (Gtk.ListItem) list_item_obj; + var item_data = (Account) list_item.item ; + var label = (Gtk.Label) list_item.child; + label.label = item_data.name; + } + + private void on_account_type_column_setup (Gtk.SignalListItemFactory factory, GLib.Object list_item_obj) { + var label = new Gtk.Label (""); + label.halign = Gtk.Align.START; + ((Gtk.ListItem) list_item_obj).child = label; + } + + private void on_account_type_column_bind (Gtk.SignalListItemFactory factory, GLib.Object list_item_obj) { + var list_item = (Gtk.ListItem) list_item_obj; + var item_data = (Account) list_item.item; + var label = (Gtk.Label) list_item.child; + label.label = item_data.account_type; + } + + private void on_balance_column_setup (Gtk.SignalListItemFactory factory, GLib.Object list_item_obj) { + var label = new Gtk.Label (""); + label.halign = Gtk.Align.START; + ((Gtk.ListItem) list_item_obj).child = label; + } + + private void on_balance_column_bind (Gtk.SignalListItemFactory factory, GLib.Object list_item_obj) { + var list_item = (Gtk.ListItem) list_item_obj; + var item_data = (Account) list_item.item; + var label = (Gtk.Label) list_item.child; + label.label = item_data.balance; + } + + public static int main (string[] args) { + var app = new ColumnViewSample (); + return app.run (args); + } + } + + +Compile and Run +--------------- + +Compile: + +.. code-block:: console + + $ valac --pkg gtk4 ColumnView.vala + +Run: + +.. code-block:: console + + $ ./ColumnView.vala + diff --git a/source/tutorials/gui-programming/gtk4-samples/entry-completion-two-cells.rst b/source/tutorials/gui-programming/gtk4-samples/entry-completion-two-cells.rst new file mode 100644 index 0000000..b15ee12 --- /dev/null +++ b/source/tutorials/gui-programming/gtk4-samples/entry-completion-two-cells.rst @@ -0,0 +1,88 @@ +Entry Completion with Two Cells +=============================== + +Source Code +----------- + +.. code-block:: vala + + // EntryCompletionTwoCells.vala + + public class EntryCompletionTwoCellsSample : Gtk.Application { + public EntryCompletionTwoCellsSample () { + Object (application_id: "com.example.EntryCompletionTwoCellsSample"); + } + + public override void activate () { + // Prepare Gtk.Window + var window = new Gtk.ApplicationWindow (this) { + title = "Entry Completion - Two Cells", + default_width = 350, + default_height = 70, + }; + + // The Entry + var entry = new Gtk.Entry () { + placeholder_text = "Enter a Location", + }; + + // The EntryCompletion + Gtk.EntryCompletion completion = new Gtk.EntryCompletion (); + entry.set_completion (completion); + + // Create, fill & register a Gtk.ListStore + Gtk.ListStore list_store = new Gtk.ListStore (2, typeof (string), typeof (string)); + completion.set_model (list_store); + completion.set_text_column (0); + + var cell = new Gtk.CellRendererText (); + completion.pack_start(cell, false); + completion.add_attribute(cell, "text", 1); + + Gtk.TreeIter iter; + + list_store.append (out iter); + list_store.set (iter, 0, "Burgenland", 1, "Austria"); + list_store.append (out iter); + list_store.set (iter, 0, "Berlin", 1, "Germany"); + list_store.append (out iter); + list_store.set (iter, 0, "Lower Austria", 1, "Austria"); + list_store.append (out iter); + list_store.set (iter, 0, "Upper Austria", 1, "Austria"); + list_store.append (out iter); + list_store.set (iter, 0, "Salzburg", 1, "Austria"); + list_store.append (out iter); + list_store.set (iter, 0, "Styria", 1, "Austria"); + list_store.append (out iter); + list_store.set (iter, 0, "Tehran", 1, "Iran"); + list_store.append (out iter); + list_store.set (iter, 0, "Vorarlberg", 1, "Austria"); + list_store.append (out iter); + list_store.set (iter, 0, "Vienna", 1, "Austria"); + + window.child = entry; + window.present (); + } + + public static int main (string[] args) { + var app = new EntryCompletionTwoCellsSample (); + return app.run (args); + } + } + + +Compile and Run +--------------- + +Compile: + +.. code-block:: console + + $ valac --pkg gtk4 EntryCompletionTwoCells.vala + +Run: + +.. code-block:: console + + $ ./EntryCompletionTwoCells.vala + diff --git a/source/tutorials/gui-programming/gtk4-samples/list-view-check-buttons.rst b/source/tutorials/gui-programming/gtk4-samples/list-view-check-buttons.rst new file mode 100644 index 0000000..c228a3d --- /dev/null +++ b/source/tutorials/gui-programming/gtk4-samples/list-view-check-buttons.rst @@ -0,0 +1,96 @@ +ListView with CheckButtons +========================== + +Source Code +----------- + +.. code-block:: vala + + // ListViewCheckButtons.vala + + public class Item : GLib.Object { + public string name { get; set; } + public bool checked { get; set; } + + public Item (string name, bool checked) { + Object ( + name: name, + checked: checked + ); + } + } + + public class ListViewCheckButtonsSample : Gtk.Application { + public ListViewCheckButtonsSample () { + Object (application_id: "com.example.ListViewCheckButtonsSample"); + } + + public override void activate () { + var window = new Gtk.ApplicationWindow (this) { + title = "ListView CheckButtons Sample", + default_width = 280, + default_height = 200 + }; + + var items = new GLib.ListStore(typeof (Item)); + var selection_model = new Gtk.SingleSelection (items) { + autoselect = true + }; + + items.append (new Item ("Item 1", true)); + items.append (new Item ("Item 2", false)); + + var list_view_factory = new Gtk.SignalListItemFactory (); + list_view_factory.setup.connect (on_list_view_setup); + list_view_factory.bind.connect (on_list_view_bind); + + var list_view = new Gtk.ListView (selection_model, list_view_factory); + + window.child = list_view; + window.present (); + } + + private void on_list_view_setup (Gtk.SignalListItemFactory factory, GLib.Object list_item_obj) { + var vbox = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0); + var checkbox = new Gtk.CheckButton (); + var name_label = new Gtk.Label (""); + name_label.halign = Gtk.Align.START; + + vbox.append (checkbox); + vbox.append (name_label); + ((Gtk.ListItem) list_item_obj).child = vbox; + } + + private void on_list_view_bind (Gtk.SignalListItemFactory factory, GLib.Object list_item_obj) { + var list_item = (Gtk.ListItem) list_item_obj; + var item_data = (Item) list_item.item; + var vbox = (Gtk.Box) list_item.child; + var checkbox = (Gtk.CheckButton) vbox.get_first_child (); + var name_label = (Gtk.Label) checkbox.get_next_sibling (); + + checkbox.active = item_data.checked; + name_label.label = item_data.name; + } + + public static int main (string[] args) { + var app = new ListViewCheckButtonsSample (); + return app.run (args); + } + } + + +Compile and Run +--------------- + +Compile: + +.. code-block:: console + + $ valac --pkg gtk4 ListViewCheckButtons.vala + +Run: + +.. code-block:: console + + $ ./ListViewCheckButtons.vala + diff --git a/source/tutorials/gui-programming/gtk4-samples/list-view.rst b/source/tutorials/gui-programming/gtk4-samples/list-view.rst new file mode 100644 index 0000000..0498a0b --- /dev/null +++ b/source/tutorials/gui-programming/gtk4-samples/list-view.rst @@ -0,0 +1,121 @@ +ListView +======== + +Source Code +----------- + +.. code-block:: vala + + // ListView.vala + + public class Customer : GLib.Object { + public string first_name { get; set; } + public string last_name { get; set; } + public string id { get; set; } + + public Customer (string first_name, string last_name, string id) { + Object ( + first_name: first_name, + last_name: last_name, + id: id + ); + } + } + + public class ListViewSample : Gtk.Application { + public ListViewSample () { + Object (application_id: "com.example.ListViewSample"); + } + + public override void activate () { + var window = new Gtk.ApplicationWindow (this) { + title = "ListView Sample", + default_width = 240, + default_height = 400 + }; + + var customers = new GLib.ListStore(typeof (Customer)); + var selection_model = new Gtk.SingleSelection (customers) { + autoselect = true + }; + + customers.append (new Customer ("Linus", "Legend", "1991")); + customers.append (new Customer ("John", "Smith", "1992")); + customers.append (new Customer ("Alice", "Key", "1993")); + customers.append (new Customer ("Bob", "Key", "1994")); + customers.append (new Customer ("Jane", "Doe", "1995")); + customers.append (new Customer ("Gabe", "Goode", "1996")); + + var list_view_factory = new Gtk.SignalListItemFactory (); + list_view_factory.setup.connect (on_list_view_setup); + list_view_factory.bind.connect (on_list_view_bind); + + var list_view_header_factory = new Gtk.SignalListItemFactory (); + list_view_header_factory.setup.connect (on_list_view_header_setup); + list_view_header_factory.bind.connect (on_list_view_header_bind); + + var list_view = new Gtk.ListView (selection_model, list_view_factory); + list_view.header_factory = list_view_header_factory; + + window.child = list_view; + window.present (); + } + + private void on_list_view_setup (Gtk.SignalListItemFactory factory, GLib.Object list_item_obj) { + var vbox = new Gtk.Box (Gtk.Orientation.VERTICAL, 4); + var name_label = new Gtk.Label (""); + name_label.halign = Gtk.Align.START; + + var id_label = new Gtk.Label (""); + id_label.halign = Gtk.Align.START; + + vbox.append (name_label); + vbox.append (id_label); + ((Gtk.ListItem) list_item_obj).child = vbox; + } + + private void on_list_view_bind (Gtk.SignalListItemFactory factory, GLib.Object list_item_obj) { + var list_item = (Gtk.ListItem) list_item_obj; + var item_data = (Customer) list_item.item; + var vbox = (Gtk.Box) list_item.child; + var name_label = (Gtk.Label) vbox.get_first_child (); + var id_label = (Gtk.Label) name_label.get_next_sibling (); + + name_label.label = @"$(item_data.first_name) $(item_data.last_name)"; + id_label.label = @"ID: $(item_data.id)"; + } + + private void on_list_view_header_setup (Gtk.SignalListItemFactory factory, GLib.Object list_header_obj) { + var header_label = new Gtk.Label (""); + header_label.halign = Gtk.Align.START; + ((Gtk.ListHeader) list_header_obj).child = header_label; + } + + private void on_list_view_header_bind (Gtk.SignalListItemFactory factory, GLib.Object list_header_obj) { + var list_header = (Gtk.ListHeader) list_header_obj; + var header_label = (Gtk.Label) list_header.child; + header_label.label = "Customers"; + } + + public static int main (string[] args) { + var app = new ListViewSample (); + return app.run (args); + } + } + + +Compile and Run +--------------- + +Compile: + +.. code-block:: console + + $ valac --pkg gtk4 ListView.vala + +Run: + +.. code-block:: console + + $ ./ListView.vala + diff --git a/source/tutorials/gui-programming/gtk4-samples/minimal-app.rst b/source/tutorials/gui-programming/gtk4-samples/minimal-app.rst new file mode 100644 index 0000000..591fe22 --- /dev/null +++ b/source/tutorials/gui-programming/gtk4-samples/minimal-app.rst @@ -0,0 +1,54 @@ +Minimal App +=========== + +Source Code +----------- + +.. attention:: + + Don't use this code for creating applications. + + Unless you know what you are sure about what you're doing, + follow the :doc:`Basic App Sample ` instead. + +.. code-block:: vala + + // MinimalApp.vala + + int main (string[] args) { + Gtk.init (); + + var window = new Gtk.Window () { + title = "Minimal GTK4 App" + }; + + var button = new Gtk.Button.with_label ("Click me!"); + button.clicked.connect (() => { + button.label = "Thank you"; + }); + + window.child = button; + window.present (); + + while (Gtk.Window.get_toplevels ().get_n_items () > 0) { + GLib.MainContext.@default ().iteration (true); + } + + return 0; + } + +Compile and Run +--------------- + +Compile: + +.. code-block:: console + + $ valac --pkg gtk4 MinimalAppSample.vala + +Run: + +.. code-block:: console + + $ ./MinimalAppSample.vala + diff --git a/source/tutorials/gui-programming/gtk4-samples/synchronising-widgets.rst b/source/tutorials/gui-programming/gtk4-samples/synchronising-widgets.rst new file mode 100644 index 0000000..b570654 --- /dev/null +++ b/source/tutorials/gui-programming/gtk4-samples/synchronising-widgets.rst @@ -0,0 +1,67 @@ +Synchronising Widgets +===================== + +Source Code +----------- + +.. code-block:: vala + + // SyncingWidgets.vala + + public class SyncSample : Gtk.Application { + private Gtk.SpinButton spin_box; + private Gtk.Scale slider; + + public SyncSample () { + Object (application_id: "com.example.SyncSample"); + } + + public override void activate () { + var window = new Gtk.ApplicationWindow (this) { + title = "Enter your age", + default_width = 300, + default_height = 20, + }; + + this.spin_box = new Gtk.SpinButton.with_range (0, 130, 1); + this.slider = new Gtk.Scale.with_range (Gtk.Orientation.HORIZONTAL, 0, 130, 1); + + this.spin_box.adjustment.value_changed.connect (() => { + slider.adjustment.value = spin_box.adjustment.value; + }); + + this.slider.adjustment.value_changed.connect (() => { + spin_box.adjustment.value = slider.adjustment.value; + }); + + var hbox = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 5); + hbox.homogeneous = true; + hbox.append (spin_box); + hbox.append (slider); + + window.child = hbox; + window.present (); + } + + public static int main (string[] args) { + var app = new SyncSample (); + return app.run (args); + } + } + + +Compile and Run +--------------- + +Compile: + +.. code-block:: console + + $ valac --pkg gtk4 SyncingWidgets.vala + +Run: + +.. code-block:: console + + $ ./SyncingWidgets.vala + diff --git a/source/tutorials/gui-programming/gtk4-samples/text-file-viewer.rst b/source/tutorials/gui-programming/gtk4-samples/text-file-viewer.rst new file mode 100644 index 0000000..0dcdb28 --- /dev/null +++ b/source/tutorials/gui-programming/gtk4-samples/text-file-viewer.rst @@ -0,0 +1,101 @@ +Text File Viewer +================ + +Source Code +----------- + +.. code-block:: vala + + // TextFileViewer.vala + + public class TextFileViewerSample : Gtk.Application { + private Gtk.TextView text_view; + private Gtk.ApplicationWindow window; + + public TextFileViewerSample () { + Object (application_id: "com.example.TextFileViewerSample"); + } + + public override void activate () { + this.window = new Gtk.ApplicationWindow (this) { + title = "Text File Viewer", + default_width = 400, + default_height = 300 + }; + + var toolbar = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0); + toolbar.add_css_class ("toolbar"); + + var open_image = new Gtk.Image.from_icon_name ("document-open"); + var open_label = new Gtk.Label ("Open"); + + var open_button_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0); + open_button_box.append (open_image); + open_button_box.append (open_label); + + var open_button = new Gtk.Button (); + open_button.child = open_button_box; + open_button.clicked.connect(on_open_button_clicked); + + toolbar.append (open_button); + + this.text_view = new Gtk.TextView () { + editable = false, + cursor_visible = false, + }; + + var scroll_view = new Gtk.ScrolledWindow () { + hscrollbar_policy = Gtk.PolicyType.AUTOMATIC, + vscrollbar_policy = Gtk.PolicyType.AUTOMATIC, + vexpand = true, + valign = Gtk.Align.FILL, + child = this.text_view, + }; + + var vbox = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); + vbox.append (toolbar); + vbox.append (scroll_view); + + this.window.child = vbox; + this.window.present (); + } + + private void on_open_button_clicked () { + var file_dialog = new Gtk.FileDialog () { + title = "Open File" + }; + + file_dialog.open.begin (this.window, null, (obj, res) => { + try { + var file = file_dialog.open.end (res); + uint8[] contents; + file.load_contents (null, out contents, null); + this.text_view.buffer.text = (string) contents; + } catch (Error e) { + stderr.printf ("Error: %s\n", e.message); + } + }); + } + + public static int main (string[] args) { + var app = new TextFileViewerSample (); + return app.run (args); + } + } + + +Compile and Run +--------------- + +Compile: + +.. code-block:: console + + $ valac --pkg gtk4 TextFileViewer.vala + +Run: + +.. code-block:: console + + $ ./TextFileViewer.vala +