diff --git a/meson.build b/meson.build index 923faf19..31b9f8ca 100644 --- a/meson.build +++ b/meson.build @@ -21,6 +21,7 @@ config_file = configure_file( core_deps = [ dependency('glib-2.0'), dependency('gobject-2.0'), + dependency('libadwaita-1'), meson.get_compiler('vala').find_library('posix'), meson.get_compiler('c').find_library('m', required : false) ] diff --git a/po/POTFILES b/po/POTFILES index 6a5f3049..fa1c1103 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -1,7 +1,7 @@ src/Application.vala src/Button.vala src/MainWindow.vala -src/HistoryDialog.vala +src/HistorySidebar.vala src/Core/Token.vala src/Core/Scanner.vala src/Core/Evaluation.vala diff --git a/src/HistoryDialog.vala b/src/HistoryDialog.vala deleted file mode 100644 index aa823117..00000000 --- a/src/HistoryDialog.vala +++ /dev/null @@ -1,154 +0,0 @@ -/*- - * Copyright 2018-2021 elementary, Inc. (https://elementary.io) - * 2014 Marvin Beckers - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * Authored by: Marvin Beckers - */ - -namespace PantheonCalculator { - public class HistoryDialog : Granite.Dialog { - public unowned List history { get; construct; } - public signal void clear_history (); - - private Gtk.TreeView view; - private Gtk.ListStore list_store; - - private Gtk.CheckButton expression_check_button; - private Gtk.CheckButton result_check_button; - - public signal void added (string text); - - public HistoryDialog (List _history) { - Object (history: _history); - } - - construct { - deletable = false; - title = _("History"); - default_width = 250; - - var description_label = new Gtk.Label (_("Insert a previous expression or result into the current calculation.")) { - xalign = 0, - halign = Gtk.Align.START, - hexpand = true, - justify = Gtk.Justification.LEFT, - wrap = true - }; - - list_store = new Gtk.ListStore (2, typeof (string), typeof (string)); - Gtk.TreeIter iter; - - foreach (MainWindow.History h in history) { - list_store.insert (out iter, 0); - list_store.set (iter, 0, h.exp, 1, h.output); - } - - var cell = new Gtk.CellRendererText (); - - view = new Gtk.TreeView.with_model (list_store) { - hexpand = true, - vexpand = true, - headers_visible = false - }; - view.add_css_class (Granite.STYLE_CLASS_H3_LABEL); - view.insert_column_with_attributes (-1, null, cell, "text", 0); - view.insert_column_with_attributes (-1, null, cell, "text", 1); - view.get_column (1).min_width = 75; - view.get_column (0).min_width = 200; - - var scrolled = new Gtk.ScrolledWindow () { - min_content_height = 125, - child = view - }; - - var frame = new Gtk.Frame (null) { - child = scrolled - }; - - var add_label = new Gtk.Label (_("Value to insert:")) { - halign = Gtk.Align.END, - hexpand = true - }; - - result_check_button = new Gtk.CheckButton.with_label (_("Result")) { - active = true - }; - - expression_check_button = new Gtk.CheckButton.with_label (_("Expression")) { - group = result_check_button - }; - - var main_grid = new Gtk.Grid () { - column_spacing = 12, - hexpand = true, - vexpand = true, - margin_start = 12, - margin_end = 12, - margin_bottom = 12, - margin_top = 0, - row_spacing = 12 - }; - main_grid.attach (description_label, 0, 0, 3, 1); - main_grid.attach (frame, 0, 1, 3, 1); - main_grid.attach (add_label, 0, 2); - main_grid.attach (result_check_button, 2, 2); - main_grid.attach (expression_check_button, 1, 2); - - get_content_area ().append (main_grid); - - // Use a custom response code for "Clear History" action - var button_clear = add_button (_("Clear History"), 0); - button_clear.add_css_class (Granite.STYLE_CLASS_DESTRUCTIVE_ACTION); - - add_button (_("Close"), Gtk.ResponseType.CLOSE); - - var button_add = add_button (_("Insert"), Gtk.ResponseType.APPLY); - button_add.add_css_class (Granite.STYLE_CLASS_SUGGESTED_ACTION); - - response.connect (on_response); - } - - public void append (MainWindow.History entry) { - Gtk.TreeIter iter; - list_store.insert (out iter, 0); - list_store.set (iter, 0, entry.exp, 1, entry.output); - } - - private void on_response (Gtk.Dialog source, int response_id) { - if (response_id == 0) { - list_store.clear (); - clear_history (); - } else if (response_id == Gtk.ResponseType.APPLY) { - var selection = view.get_selection (); - Gtk.TreeIter iter; - if (selection.get_selected (null, out iter)) { - Value val = Value (typeof (string)); - - if (result_check_button.get_active ()) { - list_store.get_value (iter, 1, out val); - } else if (expression_check_button.get_active ()) { - list_store.get_value (iter, 0, out val); - } - - added (val.get_string ()); - } - } - - hide (); - destroy (); - } - } -} diff --git a/src/HistorySidebar.vala b/src/HistorySidebar.vala new file mode 100644 index 00000000..8b835411 --- /dev/null +++ b/src/HistorySidebar.vala @@ -0,0 +1,122 @@ +/*- + * Copyright 2018-2021 elementary, Inc. (https://elementary.io) + * 2014 Marvin Beckers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Authored by: Marvin Beckers + */ + +namespace PantheonCalculator { + public class HistorySidebar : Gtk.Grid { + public signal void clear_history (); + + private GLib.ListStore history_list; + + public signal void added (string text); + + construct { + var clear_button = new Gtk.Button () { + icon_name = "user-trash-full-symbolic", + tooltip_text = _("Clear History") + }; + + clear_button.clicked.connect (() => { + clear_history (); + history_list.remove_all (); + }); + + var headerbar = new Adw.HeaderBar () { + show_title = false + }; + headerbar.pack_end (clear_button); + headerbar.add_css_class (Granite.STYLE_CLASS_FLAT); + headerbar.add_css_class (Granite.STYLE_CLASS_DEFAULT_DECORATION); + + history_list = new GLib.ListStore (typeof (MainWindow.History)); + + var listbox = new Gtk.ListBox () { + hexpand = true + }; + listbox.bind_model (history_list, create_widget_func); + listbox.add_css_class (Granite.STYLE_CLASS_BACKGROUND); + listbox.row_activated.connect ((row) => { + MainWindow.History history = row.get_data ("history"); + added (history.output); + }); + + var listbox_scrolled = new Gtk.ScrolledWindow () { + hscrollbar_policy = NEVER, + max_content_height = 200, + propagate_natural_height = true, + child = listbox, + hexpand = true, + vexpand = true + }; + + var main_box = new Gtk.Box (VERTICAL, 0) { + hexpand = true, + vexpand = true + }; + main_box.append (listbox_scrolled); + + var toolbar_view = new Adw.ToolbarView (); + toolbar_view.add_top_bar (headerbar); + toolbar_view.content = main_box; + + attach (toolbar_view, 0, 0); + } + + public void append (MainWindow.History entry) { + history_list.insert (0, entry); + } + + private Gtk.Widget create_widget_func (Object object) { + var history = (MainWindow.History) object; + + var exp_label = new Gtk.Label (history.exp) { + halign = START, + ellipsize = END, + tooltip_text = history.exp + }; + exp_label.add_css_class (Granite.STYLE_CLASS_DIM_LABEL); + exp_label.add_css_class (Granite.STYLE_CLASS_SMALL_LABEL); + + var output_label = new Gtk.Label ("%s".printf (history.output)) { + halign = START, + use_markup = true, + ellipsize = END, + tooltip_text = history.output + }; + + var row_grid = new Gtk.Grid () { + margin_top = 6, + margin_bottom = 6, + margin_start = 12, + margin_end = 12, + row_spacing = 3 + }; + row_grid.attach (exp_label, 0, 0, 1, 1); + row_grid.attach (output_label, 0, 1, 1, 1); + + var row = new Gtk.ListBoxRow () { + child = row_grid + }; + + row.set_data ("history", history); + + return row; + } + } +} diff --git a/src/MainWindow.vala b/src/MainWindow.vala index b3d3bb5f..9fc1fed6 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -31,7 +31,8 @@ public class PantheonCalculator.MainWindow : Gtk.ApplicationWindow { private Gtk.Button button_mc; private Gtk.Button button_gt; private Gtk.ToggleButton button_extended; - private HistoryDialog history_dialog; + private HistorySidebar history_sidebar; + private Adw.OverlaySplitView overlay_split_view; private Gtk.InfoBar infobar; private Gtk.Label infobar_label; @@ -44,7 +45,6 @@ public class PantheonCalculator.MainWindow : Gtk.ApplicationWindow { /* Define the decimal places */ private int decimal_places; - public struct History { string exp; string output; } private double memory_value = 0; private const string ACTION_PREFIX = "win."; @@ -107,8 +107,8 @@ public class PantheonCalculator.MainWindow : Gtk.ApplicationWindow { show_title_buttons = true, title_widget = new Gtk.Label (null) }; + headerbar.pack_start (button_history); headerbar.pack_end (button_extended); - headerbar.pack_end (button_history); headerbar.add_css_class (Granite.STYLE_CLASS_DEFAULT_DECORATION); headerbar.add_css_class (Granite.STYLE_CLASS_FLAT); @@ -464,8 +464,33 @@ public class PantheonCalculator.MainWindow : Gtk.ApplicationWindow { global_box.append (infobar); global_box.append (main_grid); - child = global_box; - set_titlebar (headerbar); + var toolbar_view = new Adw.ToolbarView (); + toolbar_view.add_top_bar (headerbar); + toolbar_view.content = global_box; + + history_sidebar = new HistorySidebar (); + history_sidebar.added.connect (history_added); + history_sidebar.clear_history.connect (() => { + history.foreach ((entry) => { + history.delete_link (history.find (entry)); + }); + button_ans.sensitive = false; + }); + + overlay_split_view = new Adw.OverlaySplitView () { + collapsed = true, + max_sidebar_width = 175, + min_sidebar_width = 175, + }; + overlay_split_view.content = toolbar_view; + overlay_split_view.sidebar = history_sidebar; + + child = overlay_split_view; + + var null_title = new Gtk.Grid () { + visible = false + }; + set_titlebar (null_title); entry.grab_focus (); @@ -593,7 +618,9 @@ public class PantheonCalculator.MainWindow : Gtk.ApplicationWindow { try { var output = eval.evaluate (entry.get_text (), decimal_places); if (entry.get_text () != output) { - History history_entry = History () { exp = entry.get_text (), output = output }; + History history_entry = new History (); + history_entry.exp = entry.get_text (); + history_entry.output = output; history.append (history_entry); update_history_dialog (history_entry); entry.set_text (output); @@ -787,30 +814,13 @@ public class PantheonCalculator.MainWindow : Gtk.ApplicationWindow { entry.set_position (position); } - private void show_history (Gtk.Button button) { + private void show_history () { + overlay_split_view.show_sidebar = true; position = entry.get_position (); - - history_dialog = new HistoryDialog (history) { - transient_for = this - }; - history_dialog.present (); - - history_dialog.added.connect (history_added); - history_dialog.clear_history.connect (() => { - history.foreach ((entry) => { - history.delete_link (history.find (entry)); - }); - button_ans.sensitive = false; - }); - history_dialog.hide.connect (() => { - button_history.sensitive = history != null; - }); } private void update_history_dialog (History entry) { - if (history_dialog != null) { - history_dialog.append (entry); - } + history_sidebar.append (entry); } private void history_added (string input) { @@ -819,6 +829,8 @@ public class PantheonCalculator.MainWindow : Gtk.ApplicationWindow { position += input.length; entry.grab_focus (); entry.set_position (position); + + overlay_split_view.show_sidebar = false; } private void remove_error () { @@ -846,4 +858,9 @@ public class PantheonCalculator.MainWindow : Gtk.ApplicationWindow { Signal.stop_emission_by_name ((void*) entry.get_delegate (), "insert-text"); } } + + public class History : GLib.Object { + public string exp { get; set; } + public string output { get; set; } + } } diff --git a/src/meson.build b/src/meson.build index 0207fbaa..12f3989a 100644 --- a/src/meson.build +++ b/src/meson.build @@ -4,7 +4,7 @@ executable( 'Application.vala', 'Button.vala', 'MainWindow.vala', - 'HistoryDialog.vala', + 'HistorySidebar.vala', 'Core/Token.vala', 'Core/Scanner.vala', 'Core/Evaluation.vala',