diff --git a/src/draw.cc b/src/draw.cc index b03719f5..885012da 100644 --- a/src/draw.cc +++ b/src/draw.cc @@ -33,8 +33,8 @@ Draw::Draw(MiddlewareInterface& middleware) { this->disableEdit(); set_top_margin(12); - set_left_margin(20); // fallback - set_right_margin(20); // fallback + set_left_margin(10); // fallback + set_right_margin(10); // fallback set_bottom_margin(0); set_indent(0); // fallback set_monospace(false); @@ -343,6 +343,10 @@ void Draw::newDocument() this->redoPool.clear(); this->clear(); + // Set margins to defaults in editor mode + set_left_margin(10); + set_right_margin(10); + enableEdit(); grab_focus(); // Claim focus on text view } diff --git a/src/mainwindow.cc b/src/mainwindow.cc index ac1bc970..6826ea13 100644 --- a/src/mainwindow.cc +++ b/src/mainwindow.cc @@ -31,6 +31,7 @@ MainWindow::MainWindow(const std::string& timeout) : m_accelGroup(Gtk::AccelGroup::create()), m_settings(), m_brightnessAdjustment(Gtk::Adjustment::create(1.0, 0.0, 1.0, 0.05, 0.1)), + m_maxContentWidthAdjustment(Gtk::Adjustment::create(700, 0, 99999, 10, 20)), m_spacingAdjustment(Gtk::Adjustment::create(0, -10, 10, 1, 2)), m_marginsAdjustment(Gtk::Adjustment::create(20, 0, 1000, 10, 20)), m_indentAdjustment(Gtk::Adjustment::create(0, 0, 1000, 5, 10)), @@ -89,11 +90,13 @@ MainWindow::MainWindow(const std::string& timeout) m_networkOutcomingLabel("Outcoming"), m_networkKiloBytesLabel("Kilobytes/s"), m_fontLabel("Font"), + m_maxContentWidthLabel("Content width"), m_spacingLabel("Spacing"), m_marginsLabel("Margins"), m_indentLabel("Indent"), m_textWrappingLabel("Wrapping"), m_themeLabel("Dark Theme"), + m_readerViewLabel("Reader View"), m_iconThemeLabel("Active Theme"), // Private members middleware_(*this, timeout), @@ -104,9 +107,12 @@ MainWindow::MainWindow(const std::string& timeout) fontFamily_("Sans"), defaultFontSize_(10), currentFontSize_(10), + contentMargin_(20), + contentMaxWidth_(700), fontSpacing_(0), brightnessScale_(1.0), useDarkTheme_(false), + isReaderViewEnabled_(true), currentHistoryIndex_(0) { set_title(appName_); @@ -367,14 +373,14 @@ void MainWindow::loadStoredSettings() currentFontSize_ = defaultFontSize_ = m_settings->get_int("font-size"); m_fontButton.set_font_name(fontFamily_ + " " + std::to_string(currentFontSize_)); + contentMaxWidth_ = m_settings->get_int("max-content-width"); fontSpacing_ = m_settings->get_int("spacing"); - int margins = m_settings->get_int("margins"); + contentMargin_ = m_settings->get_int("margins"); int indent = m_settings->get_int("indent"); + m_maxContentWidthAdjustment->set_value(contentMaxWidth_); m_spacingAdjustment->set_value(fontSpacing_); - m_marginsAdjustment->set_value(margins); + m_marginsAdjustment->set_value(contentMargin_); m_indentAdjustment->set_value(indent); - m_draw_primary.set_left_margin(margins); - m_draw_primary.set_right_margin(margins); m_draw_primary.set_indent(indent); int tocDividerPosition = m_settings->get_int("position-divider-toc"); m_panedRoot.set_position(tocDividerPosition); @@ -382,15 +388,16 @@ void MainWindow::loadStoredSettings() useCurrentGTKIconTheme_ = m_settings->get_boolean("icon-gtk-theme"); brightnessScale_ = m_settings->get_double("brightness"); useDarkTheme_ = m_settings->get_boolean("dark-theme"); + isReaderViewEnabled_ = m_settings->get_boolean("reader-view"); } else { std::cerr << "ERROR: Gsettings schema file could not be found!" << std::endl; // Fallback adjustment controls - int margins = m_draw_primary.get_margin_left(); int indent = m_draw_primary.get_indent(); - m_spacingAdjustment->set_value(0); - m_marginsAdjustment->set_value(margins); + m_maxContentWidthAdjustment->set_value(contentMaxWidth_); + m_spacingAdjustment->set_value(fontSpacing_); + m_marginsAdjustment->set_value(contentMaxWidth_); m_indentAdjustment->set_value(indent); // Fallback ToC paned divider m_panedRoot.set_position(300); @@ -793,11 +800,10 @@ void MainWindow::initSettingsPopover() m_scaleSettingsBrightness.signal_value_changed().connect(sigc::mem_fun(this, &MainWindow::on_brightness_changed)); m_hboxSetingsBrightness.pack_start(m_brightnessImage, false, false); m_hboxSetingsBrightness.pack_end(m_scaleSettingsBrightness); - // Dark theme switch - m_themeSwitch.set_active(useDarkTheme_); // Override with current dark theme preference - // Settings buttons + // Settings labels / buttons m_wrapWordChar.set_active(true); // Default wrapping mode m_fontLabel.set_tooltip_text("Font familiy"); + m_maxContentWidthLabel.set_tooltip_text("Max content width"); m_spacingLabel.set_tooltip_text("Text spacing"); m_marginsLabel.set_tooltip_text("Text margins"); m_indentLabel.set_tooltip_text("Text indentation"); @@ -806,21 +812,31 @@ void MainWindow::initSettingsPopover() m_wrapChar.set_tooltip_text("Character wrapping"); m_wrapWord.set_tooltip_text("Word wrapping"); m_wrapWordChar.set_tooltip_text("Word wrapping (+ character)"); + m_maxContentWidthSpinButton.set_adjustment(m_maxContentWidthAdjustment); m_spacingSpinButton.set_adjustment(m_spacingAdjustment); m_marginsSpinButton.set_adjustment(m_marginsAdjustment); m_indentSpinButton.set_adjustment(m_indentAdjustment); m_fontLabel.set_xalign(1); + m_maxContentWidthLabel.set_xalign(1); m_spacingLabel.set_xalign(1); m_marginsLabel.set_xalign(1); m_indentLabel.set_xalign(1); m_textWrappingLabel.set_xalign(1); m_themeLabel.set_xalign(1); + m_readerViewLabel.set_xalign(1); m_fontLabel.get_style_context()->add_class("dim-label"); + m_maxContentWidthLabel.get_style_context()->add_class("dim-label"); m_spacingLabel.get_style_context()->add_class("dim-label"); m_marginsLabel.get_style_context()->add_class("dim-label"); m_indentLabel.get_style_context()->add_class("dim-label"); m_textWrappingLabel.get_style_context()->add_class("dim-label"); m_themeLabel.get_style_context()->add_class("dim-label"); + m_readerViewLabel.get_style_context()->add_class("dim-label"); + // Dark theme switch + m_themeSwitch.set_active(useDarkTheme_); // Override with current dark theme preference + // Reader view switch + m_readerViewSwitch.set_active(isReaderViewEnabled_); + // Settings grid m_settingsGrid.set_margin_start(6); m_settingsGrid.set_margin_top(6); m_settingsGrid.set_margin_bottom(6); @@ -828,19 +844,23 @@ void MainWindow::initSettingsPopover() m_settingsGrid.set_column_spacing(10); m_settingsGrid.attach(m_fontLabel, 0, 0, 1); m_settingsGrid.attach(m_fontButton, 1, 0, 2); - m_settingsGrid.attach(m_spacingLabel, 0, 1, 1); - m_settingsGrid.attach(m_spacingSpinButton, 1, 1, 2); - m_settingsGrid.attach(m_marginsLabel, 0, 2, 1); - m_settingsGrid.attach(m_marginsSpinButton, 1, 2, 2); - m_settingsGrid.attach(m_indentLabel, 0, 3, 1); - m_settingsGrid.attach(m_indentSpinButton, 1, 3, 2); - m_settingsGrid.attach(m_textWrappingLabel, 0, 4, 1); - m_settingsGrid.attach(m_wrapNone, 1, 4, 1); - m_settingsGrid.attach(m_wrapChar, 2, 4, 1); - m_settingsGrid.attach(m_wrapWord, 1, 5, 1); - m_settingsGrid.attach(m_wrapWordChar, 2, 5, 1); - m_settingsGrid.attach(m_themeLabel, 0, 6, 1); - m_settingsGrid.attach(m_themeSwitch, 1, 6, 2); + m_settingsGrid.attach(m_maxContentWidthLabel, 0, 1, 1); + m_settingsGrid.attach(m_maxContentWidthSpinButton, 1, 1, 2); + m_settingsGrid.attach(m_spacingLabel, 0, 2, 1); + m_settingsGrid.attach(m_spacingSpinButton, 1, 2, 2); + m_settingsGrid.attach(m_marginsLabel, 0, 3, 1); + m_settingsGrid.attach(m_marginsSpinButton, 1, 3, 2); + m_settingsGrid.attach(m_indentLabel, 0, 4, 1); + m_settingsGrid.attach(m_indentSpinButton, 1, 4, 2); + m_settingsGrid.attach(m_textWrappingLabel, 0, 5, 1); + m_settingsGrid.attach(m_wrapNone, 1, 5, 1); + m_settingsGrid.attach(m_wrapChar, 2, 5, 1); + m_settingsGrid.attach(m_wrapWord, 1, 6, 1); + m_settingsGrid.attach(m_wrapWordChar, 2, 6, 1); + m_settingsGrid.attach(m_themeLabel, 0, 7, 1); + m_settingsGrid.attach(m_themeSwitch, 1, 7, 2); + m_settingsGrid.attach(m_readerViewLabel, 0, 8, 1); + m_settingsGrid.attach(m_readerViewSwitch, 1, 8, 2); // Icon theme (+ submenu) m_iconThemeButton.set_label("Icon Theme"); m_iconThemeButton.property_menu_name() = "icon-theme"; @@ -908,6 +928,10 @@ void MainWindow::initSignals() { // Window signals signal_delete_event().connect(sigc::mem_fun(this, &MainWindow::delete_window)); + // TODO: Trigger all GDK resize events on m_draw_primary, otherwise it doesn't trigger always + m_draw_primary.signal_configure_event().connect(sigc::mem_fun(this, &MainWindow::on_configure_event)); + + // m_panedDraw.signal_configure_event().. // Table of contents m_closeTocWindowButton.signal_clicked().connect(sigc::mem_fun(m_vboxToc, &Gtk::Widget::hide)); tocTreeView.signal_row_activated().connect(sigc::mem_fun(this, &MainWindow::on_toc_row_activated)); @@ -978,6 +1002,7 @@ void MainWindow::initSignals() m_zoomRestoreButton.signal_clicked().connect(sigc::mem_fun(this, &MainWindow::on_zoom_restore)); m_zoomInButton.signal_clicked().connect(sigc::mem_fun(this, &MainWindow::on_zoom_in)); m_fontButton.signal_font_set().connect(sigc::mem_fun(this, &MainWindow::on_font_set)); + m_maxContentWidthSpinButton.signal_value_changed().connect(sigc::mem_fun(this, &MainWindow::on_max_content_width_changed)); m_spacingSpinButton.signal_value_changed().connect(sigc::mem_fun(this, &MainWindow::on_spacing_changed)); m_marginsSpinButton.signal_value_changed().connect(sigc::mem_fun(this, &MainWindow::on_margins_changed)); m_indentSpinButton.signal_value_changed().connect(sigc::mem_fun(this, &MainWindow::on_indent_changed)); @@ -986,6 +1011,7 @@ void MainWindow::initSignals() m_wrapWord.signal_toggled().connect(sigc::bind(sigc::mem_fun(this, &MainWindow::on_wrap_toggled), Gtk::WrapMode::WRAP_WORD)); m_wrapWordChar.signal_toggled().connect(sigc::bind(sigc::mem_fun(this, &MainWindow::on_wrap_toggled), Gtk::WrapMode::WRAP_WORD_CHAR)); m_themeSwitch.property_active().signal_changed().connect(sigc::mem_fun(this, &MainWindow::on_theme_changed)); + m_readerViewSwitch.property_active().signal_changed().connect(sigc::mem_fun(this, &MainWindow::on_reader_view_changed)); m_iconThemeListBox.signal_row_activated().connect(sigc::mem_fun(this, &MainWindow::on_icon_theme_activated)); m_aboutButton.signal_clicked().connect(sigc::mem_fun(m_about, &About::show_about)); } @@ -1031,6 +1057,8 @@ bool MainWindow::delete_window(GdkEventAny* any_event __attribute__((unused))) // m_settings->set_boolean("fullscreen", is_fullscreen()); m_settings->set_string("font-family", fontFamily_); m_settings->set_int("font-size", currentFontSize_); + m_settings->set_boolean("reader-view", isReaderViewEnabled_); + m_settings->set_int("max-content-width", m_maxContentWidthSpinButton.get_value_as_int()); m_settings->set_int("spacing", m_spacingSpinButton.get_value_as_int()); m_settings->set_int("margins", m_marginsSpinButton.get_value_as_int()); m_settings->set_int("indent", m_indentSpinButton.get_value_as_int()); @@ -1192,6 +1220,16 @@ void MainWindow::selectAll() } } +/** + * \brief Triggered on windows resize + */ +bool MainWindow::on_configure_event(__attribute__((unused)) GdkEventConfigure* configure_event) +{ + if (!isEditorEnabled()) + updateMargins(); + return false; +} + /** * \brief Triggered when user clicked on the column in ToC */ @@ -2019,6 +2057,36 @@ std::string MainWindow::getIconImageFromTheme(const std::string& iconName, const } } +/** + * \brief Calculate & update drawing margins + */ +void MainWindow::updateMargins() +{ + if (isReaderViewEnabled_) + { + + int width = m_draw_primary.get_width(); + std::cout << "Width: " << width << std::endl; + if (width > (contentMaxWidth_ + (2 * contentMargin_))) + { + // Calculate margins on the fly + int margin = (width - contentMaxWidth_) / 2; + m_draw_primary.set_left_margin(margin); + m_draw_primary.set_right_margin(margin); + } + else + { + m_draw_primary.set_left_margin(contentMargin_); + m_draw_primary.set_right_margin(contentMargin_); + } + } + else + { + m_draw_primary.set_left_margin(contentMargin_); + m_draw_primary.set_right_margin(contentMargin_); + } +} + /** * \brief Update the CSS provider data */ @@ -2164,16 +2232,24 @@ void MainWindow::on_font_set() updateCSS(); } +void MainWindow::on_max_content_width_changed() +{ + contentMaxWidth_ = m_maxContentWidthSpinButton.get_value_as_int(); + if (!isEditorEnabled()) + updateMargins(); +} + void MainWindow::on_spacing_changed() { - fontSpacing_ = m_spacingSpinButton.get_value_as_int(); // Letter spacing + fontSpacing_ = m_spacingSpinButton.get_value_as_int(); // Letter-spacing updateCSS(); } void MainWindow::on_margins_changed() { - m_draw_primary.set_left_margin(m_marginsSpinButton.get_value_as_int()); - m_draw_primary.set_right_margin(m_marginsSpinButton.get_value_as_int()); + contentMargin_ = m_marginsSpinButton.get_value_as_int(); + if (!isEditorEnabled()) + updateMargins(); } void MainWindow::on_indent_changed() @@ -2199,6 +2275,13 @@ void MainWindow::on_theme_changed() setTheme(); } +void MainWindow::on_reader_view_changed() +{ + isReaderViewEnabled_ = m_readerViewSwitch.get_active(); + if (!isEditorEnabled()) + updateMargins(); +} + void MainWindow::on_icon_theme_activated(Gtk::ListBoxRow* row) { std::string themeName = static_cast(row->get_data("value")); diff --git a/src/mainwindow.h b/src/mainwindow.h index b198729b..2bf0969b 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -75,6 +75,7 @@ class MainWindow : public Gtk::Window void paste(); void del(); void selectAll(); + bool on_configure_event(GdkEventConfigure* configure_event); void on_toc_row_activated(const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* column); void new_doc(); void open(); @@ -107,21 +108,24 @@ class MainWindow : public Gtk::Window void on_zoom_restore(); void on_zoom_in(); void on_font_set(); + void on_max_content_width_changed(); void on_spacing_changed(); void on_margins_changed(); void on_indent_changed(); void on_wrap_toggled(Gtk::WrapMode mode); void on_brightness_changed(); void on_theme_changed(); + void on_reader_view_changed(); void on_icon_theme_activated(Gtk::ListBoxRow* row); - Glib::RefPtr m_accelGroup; /*!< Accelerator group, used for keyboard shortcut bindings */ - Glib::RefPtr m_settings; /*!< Settings to store our preferences, even during restarts */ - Glib::RefPtr m_brightnessAdjustment; /*!< Bridghtness adjustment settings */ - Glib::RefPtr m_spacingAdjustment; /*!< Spacing adjustment settings */ - Glib::RefPtr m_marginsAdjustment; /*!< Margins adjustment settings */ - Glib::RefPtr m_indentAdjustment; /*!< Indent adjustment settings */ - Glib::RefPtr m_drawCSSProvider; /*!< CSS Provider for draw textviews */ + Glib::RefPtr m_accelGroup; /*!< Accelerator group, used for keyboard shortcut bindings */ + Glib::RefPtr m_settings; /*!< Settings to store our preferences, even during restarts */ + Glib::RefPtr m_brightnessAdjustment; /*!< Bridghtness adjustment settings */ + Glib::RefPtr m_maxContentWidthAdjustment; /*!< max content width adjustment settings */ + Glib::RefPtr m_spacingAdjustment; /*!< Spacing adjustment settings */ + Glib::RefPtr m_marginsAdjustment; /*!< Margins adjustment settings */ + Glib::RefPtr m_indentAdjustment; /*!< Indent adjustment settings */ + Glib::RefPtr m_drawCSSProvider; /*!< CSS Provider for draw textviews */ // Child widgets Menu m_menu; @@ -159,6 +163,7 @@ class MainWindow : public Gtk::Window Gtk::Button m_zoomRestoreButton; Gtk::Button m_zoomInButton; Gtk::FontButton m_fontButton; + Gtk::SpinButton m_maxContentWidthSpinButton; Gtk::SpinButton m_spacingSpinButton; Gtk::SpinButton m_marginsSpinButton; Gtk::SpinButton m_indentSpinButton; @@ -243,6 +248,7 @@ class MainWindow : public Gtk::Window Gtk::PopoverMenu m_settingsPopover; Gtk::ModelButton m_copyIDButton; Gtk::ModelButton m_copyPublicKeyButton; + Gtk::Switch m_readerViewSwitch; Gtk::Switch m_themeSwitch; Gtk::Label m_tableOfContentsLabel; Gtk::Label m_networkHeadingLabel; @@ -263,11 +269,13 @@ class MainWindow : public Gtk::Window Gtk::Label m_networkOutcomingStatusLabel; Gtk::Label m_networkKiloBytesLabel; Gtk::Label m_fontLabel; + Gtk::Label m_maxContentWidthLabel; Gtk::Label m_spacingLabel; Gtk::Label m_marginsLabel; Gtk::Label m_indentLabel; Gtk::Label m_textWrappingLabel; Gtk::Label m_themeLabel; + Gtk::Label m_readerViewLabel; Gtk::Label m_iconThemeLabel; std::unique_ptr m_contentPublishedDialog; Gtk::ScrolledWindow m_scrolledToc; @@ -297,9 +305,12 @@ class MainWindow : public Gtk::Window std::string fontFamily_; int defaultFontSize_; int currentFontSize_; + int contentMargin_; + int contentMaxWidth_; int fontSpacing_; double brightnessScale_; bool useDarkTheme_; + bool isReaderViewEnabled_; std::string currentFileSavedPath_; std::size_t currentHistoryIndex_; std::vector history_; @@ -322,6 +333,7 @@ class MainWindow : public Gtk::Window void disableEdit(); bool isEditorEnabled(); std::string getIconImageFromTheme(const std::string& iconName, const std::string& typeofIcon); + void updateMargins(); void updateCSS(); void showNotification(const Glib::ustring& title, const Glib::ustring& message = ""); }; diff --git a/src/schema/org.libreweb.browser.gschema.xml b/src/schema/org.libreweb.browser.gschema.xml index 8ca3b1b0..a015a3ac 100644 --- a/src/schema/org.libreweb.browser.gschema.xml +++ b/src/schema/org.libreweb.browser.gschema.xml @@ -33,6 +33,10 @@ 10 Font size + + 700 + Max document content width + 0 Font spacing @@ -61,5 +65,9 @@ false Prefer dark theme + + true + Is reader view enabled +