diff options
40 files changed, 622 insertions, 415 deletions
diff --git a/UnityCore/DesktopUtilities.cpp b/UnityCore/DesktopUtilities.cpp index 5b841cd0d..180ee7340 100644 --- a/UnityCore/DesktopUtilities.cpp +++ b/UnityCore/DesktopUtilities.cpp @@ -35,6 +35,11 @@ namespace DECLARE_LOGGER(logger, "unity.desktop.utilities"); } +std::string DesktopUtilities::GetUserHomeDirectory() +{ + return glib::gchar_to_string(g_get_home_dir()); +} + std::string DesktopUtilities::GetUserDataDirectory() { const char* user_dir = g_get_user_data_dir(); @@ -43,12 +48,12 @@ std::string DesktopUtilities::GetUserDataDirectory() return user_dir; // This shouldn't ever happen, but let's manually fallback to the default - const char* home = g_get_home_dir(); + auto home = GetUserHomeDirectory(); - if (home) + if (!home.empty()) { const char* subdir = G_DIR_SEPARATOR_S ".local" G_DIR_SEPARATOR_S "share"; - return std::string(home).append(subdir); + return home.append(subdir); } return ""; diff --git a/UnityCore/DesktopUtilities.h b/UnityCore/DesktopUtilities.h index 5c0488eaf..dbc79ed79 100644 --- a/UnityCore/DesktopUtilities.h +++ b/UnityCore/DesktopUtilities.h @@ -29,6 +29,7 @@ namespace unity class DesktopUtilities { public: + static std::string GetUserHomeDirectory(); static std::string GetUserDataDirectory(); static std::string GetUserCacheDirectory(); static std::string GetUserRuntimeDirectory(); diff --git a/dash/FilterBasicButton.cpp b/dash/FilterBasicButton.cpp index 727be89dc..a1466a6ac 100644 --- a/dash/FilterBasicButton.cpp +++ b/dash/FilterBasicButton.cpp @@ -72,6 +72,7 @@ FilterBasicButton::FilterBasicButton(std::string const& label, nux::TextureArea* scale.changed.connect(sigc::mem_fun(this, &FilterBasicButton::UpdateScale)); Settings::Instance().font_scaling.changed.connect(sigc::hide(sigc::mem_fun(this, &FilterBasicButton::InitTheme))); + Style::Instance().changed.connect(sigc::mem_fun(this, &FilterBasicButton::InitTheme)); } void FilterBasicButton::InitTheme() diff --git a/dash/ResultRendererTile.cpp b/dash/ResultRendererTile.cpp index 83abd127e..602c85057 100644 --- a/dash/ResultRendererTile.cpp +++ b/dash/ResultRendererTile.cpp @@ -32,6 +32,7 @@ #include "unity-shared/DashStyle.h" #include "unity-shared/TextureCache.h" #include "unity-shared/UnitySettings.h" +#include "unity-shared/ThemeSettings.h" namespace unity { @@ -465,13 +466,10 @@ void ResultRendererTile::LoadText(Result const& row) PangoFontDescription* desc = NULL; PangoContext* pango_context = NULL; GdkScreen* screen = gdk_screen_get_default(); // not ref'ed - glib::String font; - - g_object_get(gtk_settings_get_default(), "gtk-font-name", &font, NULL); cairo_set_font_options(cr, gdk_screen_get_font_options(screen)); layout = pango_cairo_create_layout(cr); - desc = pango_font_description_from_string(font.Value()); + desc = pango_font_description_from_string(theme::Settings::Get()->font().c_str()); pango_font_description_set_size (desc, FONT_SIZE * FONT_MULTIPLIER); pango_layout_set_font_description(layout, desc); diff --git a/decorations/DecorationsForceQuitDialog.cpp b/decorations/DecorationsForceQuitDialog.cpp index 98b6349d7..990072d58 100644 --- a/decorations/DecorationsForceQuitDialog.cpp +++ b/decorations/DecorationsForceQuitDialog.cpp @@ -385,7 +385,7 @@ GtkWidget* close_button_new() gtk_widget_set_can_focus(self, FALSE); gtk_widget_set_halign(self, GTK_ALIGN_START); - auto const& file = decoration::Style::Get()->ThemedFilePath(CLOSE_BUTTON_INACTIVE_FILE, {PKGDATADIR"/"}); + auto const& file = decoration::Style::Get()->ThemedFilePath(CLOSE_BUTTON_INACTIVE_FILE, {PKGDATADIR}); auto* img = gtk_image_new_from_file(file.c_str()); gtk_container_add(GTK_CONTAINER(self), img); CLOSE_BUTTON(self)->priv->img = GTK_IMAGE(img); @@ -419,13 +419,13 @@ static void close_button_class_init(CloseButtonClass* klass) auto new_flags = gtk_widget_get_state_flags(self); auto const& deco_style = decoration::Style::Get(); - auto file = deco_style->ThemedFilePath(CLOSE_BUTTON_INACTIVE_FILE, {PKGDATADIR"/"}); + auto file = deco_style->ThemedFilePath(CLOSE_BUTTON_INACTIVE_FILE, {PKGDATADIR}); if (((new_flags & GTK_STATE_FLAG_PRELIGHT) && !gtk_widget_get_can_focus(self)) || (new_flags & GTK_STATE_FLAG_FOCUSED)) { auto const& basename = (new_flags & GTK_STATE_FLAG_ACTIVE) ? CLOSE_BUTTON_ACTIVE_FILE : CLOSE_BUTTON_FOCUSED_FILE; - file = deco_style->ThemedFilePath(basename, {PKGDATADIR"/"}); + file = deco_style->ThemedFilePath(basename, {PKGDATADIR}); } gtk_image_set_from_file(img, file.c_str()); diff --git a/decorations/DecorationsMenuDropdown.cpp b/decorations/DecorationsMenuDropdown.cpp index 1beb3d51b..084c470ec 100644 --- a/decorations/DecorationsMenuDropdown.cpp +++ b/decorations/DecorationsMenuDropdown.cpp @@ -19,6 +19,7 @@ #include "DecorationsMenuDropdown.h" #include "DecorationStyle.h" +#include "unity-shared/ThemeSettings.h" namespace unity { @@ -39,6 +40,7 @@ MenuDropdown::MenuDropdown(Indicators::Ptr const& indicators, CompWindow* win) natural_.width = ICON_SIZE; natural_.height = ICON_SIZE; entry_->set_image(1, ICON_NAME, true, true); + theme::Settings::Get()->icons_changed.connect(sigc::mem_fun(this, &MenuDropdown::RenderTexture)); } void MenuDropdown::ShowMenu(unsigned button) diff --git a/decorations/DecorationsMenuEntry.cpp b/decorations/DecorationsMenuEntry.cpp index 53fdca562..ec884dafc 100644 --- a/decorations/DecorationsMenuEntry.cpp +++ b/decorations/DecorationsMenuEntry.cpp @@ -40,11 +40,15 @@ MenuEntry::MenuEntry(Entry::Ptr const& entry, CompWindow* win) , show_menu_enabled_(true) { entry_->updated.connect(sigc::mem_fun(this, &MenuEntry::EntryUpdated)); - horizontal_padding.changed.connect(sigc::hide(sigc::mem_fun(this, &MenuEntry::RenderTexture))); - vertical_padding.changed.connect(sigc::hide(sigc::mem_fun(this, &MenuEntry::RenderTexture))); - scale.changed.connect(sigc::hide(sigc::mem_fun(this, &MenuEntry::RenderTexture))); - focused.changed.connect(sigc::hide(sigc::mem_fun(this, &MenuEntry::RenderTexture))); in_dropdown.changed.connect([this] (bool in) { visible = entry_->visible() && !in; }); + + auto render_texture_cb = sigc::hide(sigc::mem_fun(this, &MenuEntry::RenderTexture)); + horizontal_padding.changed.connect(render_texture_cb); + vertical_padding.changed.connect(render_texture_cb); + scale.changed.connect(render_texture_cb); + focused.changed.connect(render_texture_cb); + Style::Get()->font.changed.connect(render_texture_cb); + EntryUpdated(); } diff --git a/launcher/BFBLauncherIcon.cpp b/launcher/BFBLauncherIcon.cpp index 12c8a80bc..f285ecf9f 100644 --- a/launcher/BFBLauncherIcon.cpp +++ b/launcher/BFBLauncherIcon.cpp @@ -21,6 +21,7 @@ #include "config.h" #include <glib/gi18n-lib.h> #include "unity-shared/UBusMessages.h" +#include "unity-shared/ThemeSettings.h" #include "unity-shared/UnitySettings.h" #include "BFBLauncherIcon.h" @@ -35,15 +36,15 @@ BFBLauncherIcon::BFBLauncherIcon(LauncherHideMode hide_mode) , reader_(dash::GSettingsScopesReader::GetDefault()) , launcher_hide_mode_(hide_mode) { - icon_name = PKGDATADIR"/launcher_bfb.png"; position = Position::BEGIN; SetQuirk(Quirk::VISIBLE, true); SkipQuirkAnimation(Quirk::VISIBLE); - background_color_ = nux::color::White; + UpdateIcon(); UpdateDefaultSearchText(); + theme::Settings::Get()->theme.changed.connect(sigc::hide(sigc::mem_fun(this, &BFBLauncherIcon::UpdateIcon))); Settings::Instance().remote_content.changed.connect(sigc::hide(sigc::mem_fun(this, &BFBLauncherIcon::UpdateDefaultSearchText))); mouse_enter.connect([this](int m) { ubus_manager_.SendMessage(UBUS_DASH_ABOUT_TO_SHOW, NULL); }); @@ -51,6 +52,11 @@ BFBLauncherIcon::BFBLauncherIcon(LauncherHideMode hide_mode) ubus_manager_.RegisterInterest(UBUS_OVERLAY_HIDDEN, sigc::bind(sigc::mem_fun(this, &BFBLauncherIcon::OnOverlayShown), false)); } +void BFBLauncherIcon::UpdateIcon() +{ + icon_name = theme::Settings::Get()->ThemedFilePath("launcher_bfb", {PKGDATADIR}); +} + void BFBLauncherIcon::SetHideMode(LauncherHideMode hide_mode) { launcher_hide_mode_ = hide_mode; diff --git a/launcher/BFBLauncherIcon.h b/launcher/BFBLauncherIcon.h index 0c03ddb81..60ca3a2de 100644 --- a/launcher/BFBLauncherIcon.h +++ b/launcher/BFBLauncherIcon.h @@ -53,6 +53,7 @@ private: void OnOverlayShown(GVariant *data, bool visible); void OnMenuitemActivated(DbusmenuMenuitem* item, int time, std::string const& scope_id); void UpdateDefaultSearchText(); + void UpdateIcon(); nux::Color background_color_; dash::GSettingsScopesReader::Ptr reader_; diff --git a/launcher/ExpoLauncherIcon.h b/launcher/ExpoLauncherIcon.h index cdc993326..f8c7a76ab 100644 --- a/launcher/ExpoLauncherIcon.h +++ b/launcher/ExpoLauncherIcon.h @@ -20,6 +20,8 @@ #ifndef EXPO_LAUNCHER_ICON_H #define EXPO_LAUNCHER_ICON_H +#include <UnityCore/GLibSignal.h> + #include "SimpleLauncherIcon.h" namespace unity diff --git a/launcher/LauncherIcon.cpp b/launcher/LauncherIcon.cpp index f67dd0020..4f9575251 100644 --- a/launcher/LauncherIcon.cpp +++ b/launcher/LauncherIcon.cpp @@ -26,6 +26,7 @@ #include "LauncherIcon.h" #include "unity-shared/AnimationUtils.h" #include "unity-shared/CairoTexture.h" +#include "unity-shared/ThemeSettings.h" #include "unity-shared/UnitySettings.h" #include "unity-shared/UScreen.h" @@ -52,8 +53,6 @@ namespace const int IGNORE_REPEAT_SHORTCUT_DURATION = 250; const std::string DEFAULT_ICON = "application-default-icon"; -const std::string MONO_TEST_ICON = "gnome-home"; -const std::string UNITY_THEME_NAME = "unity-icon-theme"; const std::string CENTER_STABILIZE_TIMEOUT = "center-stabilize-timeout"; const std::string PRESENT_TIMEOUT = "present-timeout"; @@ -65,9 +64,6 @@ const int COUNT_PADDING = 2; NUX_IMPLEMENT_OBJECT_TYPE(LauncherIcon); -int LauncherIcon::_current_theme_is_mono = -1; -glib::Object<GtkIconTheme> LauncherIcon::_unity_theme; - LauncherIcon::LauncherIcon(IconType type) : _icon_type(type) , _sticky(false) @@ -325,46 +321,6 @@ void LauncherIcon::ColorForIcon(GdkPixbuf* pixbuf, nux::Color& background, nux:: glow = nux::Color(nux::color::RedGreenBlue(hsv)); } -/* - * FIXME, all this code (and below), should be put in a facility for IconLoader - * to share between launcher and places the same Icon loading logic and not look - * having etoomanyimplementationofsamethings. - */ -/* static */ -bool LauncherIcon::IsMonoDefaultTheme() -{ - if (_current_theme_is_mono != -1) - return (bool)_current_theme_is_mono; - - GtkIconTheme* default_theme; - glib::Object<GtkIconInfo> info; - default_theme = gtk_icon_theme_get_default(); - - _current_theme_is_mono = (int)false; - info = gtk_icon_theme_lookup_icon(default_theme, MONO_TEST_ICON.c_str(), icon_size(), GTK_ICON_LOOKUP_FORCE_SIZE); - - if (!info) - return (bool)_current_theme_is_mono; - - // yeah, it's evil, but it's blessed upstream - if (g_strrstr(gtk_icon_info_get_filename(info), "ubuntu-mono") != NULL) - _current_theme_is_mono = (int)true; - - return (bool)_current_theme_is_mono; -} - -GtkIconTheme* LauncherIcon::GetUnityTheme() -{ - // The theme object is invalid as soon as you add a new icon to change the theme. - // invalidate the cache then and rebuild the theme the first time after a icon theme update. - if (!_unity_theme.IsType(GTK_TYPE_ICON_THEME)) - { - _unity_theme = gtk_icon_theme_new(); - gtk_icon_theme_set_custom_theme(_unity_theme, UNITY_THEME_NAME.c_str()); - } - return _unity_theme; -} - BaseTexturePtr LauncherIcon::TextureFromPixbuf(GdkPixbuf* pixbuf, int size, bool update_glow_colors) { g_return_val_if_fail(GDK_IS_PIXBUF(pixbuf), BaseTexturePtr()); @@ -391,7 +347,7 @@ BaseTexturePtr LauncherIcon::TextureFromGtkTheme(std::string icon_name, int size result = TextureFromSpecificGtkTheme(default_theme, icon_name, size, update_glow_colors); if (!result) - result = TextureFromSpecificGtkTheme(GetUnityTheme(), icon_name, size, update_glow_colors); + result = TextureFromSpecificGtkTheme(theme::Settings::Get()->UnityIconTheme(), icon_name, size, update_glow_colors); if (!result) result = TextureFromSpecificGtkTheme(default_theme, icon_name, size, update_glow_colors, true); @@ -1068,9 +1024,8 @@ BaseTexturePtr LauncherIcon::DrawCountTexture(unsigned count, double scale) glib::Object<PangoContext> pango_ctx(gdk_pango_context_get()); glib::Object<PangoLayout> layout(pango_layout_new(pango_ctx)); - glib::String font_name; - g_object_get(gtk_settings_get_default(), "gtk-font-name", &font_name, nullptr); - std::shared_ptr<PangoFontDescription> desc(pango_font_description_from_string(font_name), pango_font_description_free); + auto const& font = theme::Settings::Get()->font(); + std::shared_ptr<PangoFontDescription> desc(pango_font_description_from_string(font.c_str()), pango_font_description_free); int font_size = pango_units_from_double(Settings::Instance().font_scaling() * COUNT_FONT_SIZE); pango_font_description_set_absolute_size(desc.get(), font_size); pango_layout_set_font_description(layout, desc.get()); diff --git a/launcher/LauncherIcon.h b/launcher/LauncherIcon.h index 142f3d003..1391b7d7a 100644 --- a/launcher/LauncherIcon.h +++ b/launcher/LauncherIcon.h @@ -277,10 +277,6 @@ protected: BaseTexturePtr TextureFromPath(std::string const& name, int size, bool update_glow_colors = true); - static bool IsMonoDefaultTheme(); - - GtkIconTheme* GetUnityTheme(); - void OnRemoteEmblemChanged(LauncherEntryRemote* remote); void OnRemoteCountChanged(LauncherEntryRemote* remote); @@ -309,9 +305,6 @@ protected: return *_quirk_animations[monitor][unsigned(quirk)]; } - // This looks like a case for boost::logical::tribool - static int _current_theme_is_mono; - private: IconType _icon_type; @@ -357,8 +350,6 @@ private: connection::Manager _remote_connections; glib::Object<DbusmenuClient> _remote_menus; - static glib::Object<GtkIconTheme> _unity_theme; - protected: glib::SourceManager _source_manager; }; diff --git a/launcher/QuicklistMenuItem.cpp b/launcher/QuicklistMenuItem.cpp index 9c8aa7613..905c67b91 100644 --- a/launcher/QuicklistMenuItem.cpp +++ b/launcher/QuicklistMenuItem.cpp @@ -20,6 +20,7 @@ */ #include <gtk/gtk.h> +#include "unity-shared/ThemeSettings.h" #include "unity-shared/UBusWrapper.h" #include "unity-shared/UBusMessages.h" #include "unity-shared/UnitySettings.h" @@ -291,10 +292,7 @@ void QuicklistMenuItem::DrawText(nux::CairoGraphics& cairo, double width, double return; GdkScreen* screen = gdk_screen_get_default(); // not ref'ed - GtkSettings* settings = gtk_settings_get_default(); // not ref'ed - - glib::String font_name; - g_object_get(settings, "gtk-font-name", &font_name, nullptr); + auto const& font = theme::Settings::Get()->font(); cairo_t* cr = cairo.GetInternalContext(); cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); @@ -302,7 +300,7 @@ void QuicklistMenuItem::DrawText(nux::CairoGraphics& cairo, double width, double cairo_set_font_options(cr, gdk_screen_get_font_options(screen)); glib::Object<PangoLayout> layout(pango_cairo_create_layout(cr)); - std::shared_ptr<PangoFontDescription> desc(pango_font_description_from_string(font_name), pango_font_description_free); + std::shared_ptr<PangoFontDescription> desc(pango_font_description_from_string(font.c_str()), pango_font_description_free); pango_layout_set_font_description(layout, desc.get()); pango_layout_set_height(layout, -1); pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR); diff --git a/launcher/SimpleLauncherIcon.cpp b/launcher/SimpleLauncherIcon.cpp index 85a803be1..49898b344 100644 --- a/launcher/SimpleLauncherIcon.cpp +++ b/launcher/SimpleLauncherIcon.cpp @@ -22,6 +22,7 @@ #include "SimpleLauncherIcon.h" +#include "unity-shared/ThemeSettings.h" #include "unity-shared/UBusWrapper.h" #include "unity-shared/UBusMessages.h" @@ -36,11 +37,7 @@ SimpleLauncherIcon::SimpleLauncherIcon(IconType type) , icon_name("", sigc::mem_fun(this, &SimpleLauncherIcon::SetIconName)) , icon_pixbuf(glib::Object<GdkPixbuf>(), sigc::mem_fun(this, &SimpleLauncherIcon::SetIconPixbuf)) { - auto* theme = gtk_icon_theme_get_default(); - theme_changed_signal_.Connect(theme, "changed", [this] (GtkIconTheme *) { - _current_theme_is_mono = -1; - ReloadIcon(); - }); + theme::Settings::Get()->icons_changed.connect(sigc::mem_fun(this, &SimpleLauncherIcon::ReloadIcon)); } void SimpleLauncherIcon::ActivateLauncherIcon(ActionArg arg) diff --git a/launcher/SimpleLauncherIcon.h b/launcher/SimpleLauncherIcon.h index 902651d42..9f46dc4ae 100644 --- a/launcher/SimpleLauncherIcon.h +++ b/launcher/SimpleLauncherIcon.h @@ -20,7 +20,6 @@ #ifndef UNITYSHELL_SIMPLELAUNCHERICON_H #define UNITYSHELL_SIMPLELAUNCHERICON_H -#include <UnityCore/GLibSignal.h> #include "LauncherIcon.h" namespace unity @@ -54,11 +53,9 @@ private: private: std::unordered_map<int, BaseTexturePtr> texture_map_; - glib::Signal<void, GtkIconTheme*> theme_changed_signal_; }; } } #endif // SIMPLELAUNCHERICON_H - diff --git a/panel/PanelIndicatorEntryView.cpp b/panel/PanelIndicatorEntryView.cpp index 16a682a9f..67a80956b 100644 --- a/panel/PanelIndicatorEntryView.cpp +++ b/panel/PanelIndicatorEntryView.cpp @@ -32,6 +32,7 @@ #include "unity-shared/PanelStyle.h" #include "unity-shared/RawPixel.h" #include "unity-shared/WindowManager.h" +#include "unity-shared/ThemeSettings.h" #include "unity-shared/UnitySettings.h" namespace unity @@ -72,16 +73,12 @@ PanelIndicatorEntryView::PanelIndicatorEntryView(Entry::Ptr const& proxy, int pa InputArea::mouse_wheel.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::OnMouseWheel)); } - if (type_ != MENU) - { - icon_theme_changed_.Connect(gtk_icon_theme_get_default(), "changed", [this] (GtkIconTheme*) { - if (proxy_->image_type() && proxy_->image_visible()) - Refresh(); - }); - } + auto refresh_cb = sigc::mem_fun(this, &PanelIndicatorEntryView::Refresh); + panel::Style::Instance().changed.connect(refresh_cb); + unity::Settings::Instance().dpi_changed.connect(refresh_cb); - panel::Style::Instance().changed.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::Refresh)); - unity::Settings::Instance().dpi_changed.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::Refresh)); + if (type_ != MENU) + theme::Settings::Get()->icons_changed.connect(refresh_cb); Refresh(); } diff --git a/panel/PanelIndicatorEntryView.h b/panel/PanelIndicatorEntryView.h index 845f99a72..4ccd14147 100644 --- a/panel/PanelIndicatorEntryView.h +++ b/panel/PanelIndicatorEntryView.h @@ -28,7 +28,6 @@ #include <UnityCore/IndicatorEntry.h> #include <UnityCore/GLibWrapper.h> -#include <UnityCore/GLibSignal.h> #include <gtk/gtk.h> @@ -119,7 +118,6 @@ private: IndicatorEntryType type_; nux::ObjectPtr<nux::BaseTexture> entry_texture_; nux::Geometry cached_geo_; - glib::Signal<void, GtkIconTheme*> icon_theme_changed_; int monitor_; double opacity_; bool draw_active_; diff --git a/resources/dash-widgets.json b/resources/dash-widgets.json index 11da04b10..ac93e2839 100644 --- a/resources/dash-widgets.json +++ b/resources/dash-widgets.json @@ -9,53 +9,62 @@ "bag" : ["/usr/share/icons/unity/bag.svg", "32px", "32px"], "next" : ["/usr/share/icons/unity/next.svg", "32px", "32px"], "prev" : ["/usr/share/icons/unity/prev.svg", "32px", "32px"], - "play" : ["/usr/share/icons/unity/play.svg", "32px", "32px"]}, + "play" : ["/usr/share/icons/unity/play.svg", "32px", "32px"] + }, "regular-text" : { "text-color" : "#ffffff", - "text-opacity" : 1.0, + "text-opacity" : 1.0, "text-size" : 13.0, "text-mode" : "normal", - "text-weight" : "regular"}, + "text-weight" : "regular" + }, "comments": { - "states" : ["ACTIVE", "NORMAL","PRELIGHT","SELECTED","INSENSITIVE"]}, + "states" : ["ACTIVE", "NORMAL","PRELIGHT","SELECTED","INSENSITIVE"] + }, "button-icon": { "color" : ["#ffffff", "#FFFFFF", "#FFFFFF", "#FFFFFF", "#FFFFFF"], "opacity" : [ 1.0, 1.0, 1.0, 0.8, 0.8], "overlay-opacity": [ 0.30, 0.48, 0.48, 0.45, 0.45], "overlay-mode" : [ "normal","multiply", "multiply", "normal", "normal"], - "blur-size" : [ 5, 0, 0, 0, 0]}, + "blur-size" : [ 5, 0, 0, 0, 0] + }, "icon-only" : { "color" : "#123456", "opacity" : 1.0, "overlay-opacity": 0.2, "overlay-mode" : "normal", - "blur-size" : 6}, + "blur-size" : 6 + }, "lens-nav-bar" : { "icon-height" : 20, - "icon-gap" : 40}, + "icon-gap" : 40 + }, "button-label": { "border-opacity" : [ 0.8, 0.13, 0.13, 0.13, 0.13], "border-color" : ["#ffffff", "#FFFFFF", "#FFFFFF", "#FFFFFF", "#FFFFFF"], "border-size" : [ 2.0, 1.0, 1.0, 0.5, 0.5], + "border-radius" : 4.0, "text-size" : 1.0, "text-color" : ["#ffffff", "#ffffff", "#ffffff", "#ffffff", "#ffffff"], - "text-opacity" : [ 1.0, 1.0, 1.0, 1.0, 1.0], + "text-opacity" : [ 1.0, 1.0, 1.0, 1.0, 1.0], "fill-color" : ["#FFFFFF", "#000000", "#000000", "#000000", "#000000"], "fill-opacity" : [ 0.13, 0.0, 0.0, 0.0, 0.0], "overlay-opacity": [ 0.1, 0.1, 0.1, 0.0, 0.0], "overlay-mode" : [ "normal", "normal", "normal", "normal", "normal"], - "blur-size" : [ 1, 1, 1, 0, 0]}, + "blur-size" : [ 1, 1, 1, 0, 0] + }, "track-view" : { "line-gap" : 26.0, "heading-list-gap" : 30, - "left-padding" : 20}, + "left-padding" : 20 + }, "row-caption" : { "main-text-color" : "#ffffff", @@ -68,7 +77,8 @@ "sub-text-weight" : "regular", "icon-main-gap" : 10, "main-sub-gap" : 15, - "sub-arrow-gap" : 10}, + "sub-arrow-gap" : 10 + }, "preview-heading-small" : { "main-title-size" : 23.0, @@ -82,7 +92,8 @@ "sub-title-mode" : "normal", "sub-title-weight" : "regular", "main-sub-gap" : 15, - "padding" : 10}, + "padding" : 10 + }, "preview-heading" : { "main-title-size" : 30.0, @@ -96,16 +107,28 @@ "sub-title-mode" : "normal", "sub-title-weight" : "regular", "main-sub-gap" : 15, - "padding" : 10}, + "padding" : 10 + }, - "scrollbar" : { - "color" : "#ffffff", + "scrollbar" : { + "color" : "#fff", + "opacity" : 1.0, + "size" : 8, + "buttons-size" : 0, + "corner-radius" : 3 + }, + + "scrollbar-overlay": { + "color" : "#fff", "opacity" : 1.0, - "overlay-opacity": 0.30, - "overlay-mode" : "normal", - "blur-size" : 5, "size" : 3, - "corner-radius" : 1.5}, + "corner-radius" : 1.5 + }, + + "scrollbar-track": { + "color" : "#fff", + "opacity" : 0.4 + }, "filter-pane" : { "width" : 330, @@ -116,15 +139,17 @@ "title-style" : "bold", "title-arrow-gap" : 10, "button-height" : 30, - "border-size" : 1}, + "border-size" : 1 + }, "separator" : { "size" : 1.0, "color" : "#ffffff", - "opacity" : 0.15, + "opacity" : 0.15, "overlay-opacity": 0.47, "overlay-mode" : "normal", - "blur-size" : 6}, + "blur-size" : 6 + }, "filter-caption" : { "text-size" : 17, @@ -132,6 +157,6 @@ "text-opacity" : 1.0, "text-mode" : "normal", "text-weight" : "bold", - "text-arrow-gap" : 10} - + "text-arrow-gap" : 10 + } } diff --git a/unity-shared/CMakeLists.txt b/unity-shared/CMakeLists.txt index 2a8f3db39..7ad243f57 100644 --- a/unity-shared/CMakeLists.txt +++ b/unity-shared/CMakeLists.txt @@ -62,6 +62,7 @@ set (UNITY_SHARED_SOURCES TextureCache.cpp TextInput.cpp TextureThumbnailProvider.cpp + ThemeSettings.cpp ThumbnailGenerator.cpp Timer.cpp UBusServer.cpp diff --git a/unity-shared/DashStyle.cpp b/unity-shared/DashStyle.cpp index 987fefcdb..49df47c37 100755 --- a/unity-shared/DashStyle.cpp +++ b/unity-shared/DashStyle.cpp @@ -34,15 +34,13 @@ #include <NuxCore/Logger.h> #include <NuxGraphics/ImageSurface.h> #include <NuxGraphics/CairoGraphics.h> - #include <Nux/PaintLayer.h> - -#include <UnityCore/GLibSignal.h> #include <UnityCore/GLibWrapper.h> #include "CairoTexture.h" #include "JSONParser.h" #include "TextureCache.h" +#include "ThemeSettings.h" #include "UnitySettings.h" #include "config.h" @@ -59,9 +57,6 @@ Style* style_instance = nullptr; const int STATES = 5; -const double BUTTON_CORNER_RADIUS = 7.0; - - // These cairo overrides may also be reused somewhere... void cairo_set_source_rgba(cairo_t* cr, nux::Color const& color) { @@ -123,6 +118,7 @@ struct Style::Impl : sigc::trackable void Blur(cairo_t* cr, int size); + void LoadStyleFile(); void SetDefaultValues(); void GetTextExtents(int& width, @@ -173,7 +169,6 @@ struct Style::Impl : sigc::trackable void Refresh(); void UpdateFormFactor(FormFactor); - void OnFontChanged(GtkSettings* object, GParamSpec* pspec); BaseTexturePtr LoadScaledTexture(std::string const& name, double scale) { @@ -189,6 +184,7 @@ struct Style::Impl : sigc::trackable std::vector<nux::Color> button_label_border_color_; std::vector<double> button_label_border_size_; + double button_label_border_radius_; double button_label_text_size_; std::vector<nux::Color> button_label_text_color_; @@ -209,14 +205,14 @@ struct Style::Impl : sigc::trackable BlendMode separator_overlay_mode_; int separator_blur_size_; - nux::Color scrollbar_color_; - double scrollbar_overlay_opacity_; - BlendMode scrollbar_overlay_mode_; - int scrollbar_blur_size_; int scrollbar_size_; + int scrollbar_overlay_size_; + int scrollbar_buttons_size_; + nux::Color scrollbar_color_; + nux::Color scrollbar_overlay_color_; + nux::Color scrollbar_track_color_; double scrollbar_corner_radius_; - - glib::SignalManager signal_manager_; + double scrollbar_overlay_corner_radius_; nux::Color text_color_; @@ -265,13 +261,14 @@ Style::Impl::Impl(Style* owner) , star_selected_texture_("/star_selected.png") , star_highlight_texture_("/star_highlight.png") { - signal_manager_.Add(new glib::Signal<void, GtkSettings*, GParamSpec*> - (gtk_settings_get_default(), - "notify::gtk-font-name", - sigc::mem_fun(this, &Impl::OnFontChanged))); + auto refresh_cb = sigc::hide(sigc::mem_fun(this, &Impl::Refresh)); + + auto theme_settings = theme::Settings::Get(); + theme_settings->font.changed.connect(refresh_cb); + theme_settings->theme.changed.connect(sigc::hide(sigc::mem_fun(this, &Impl::LoadStyleFile))); auto& settings = Settings::Instance(); - settings.font_scaling.changed.connect(sigc::hide(sigc::mem_fun(this, &Impl::Refresh))); + settings.font_scaling.changed.connect(refresh_cb); settings.form_factor.changed.connect(sigc::mem_fun(this, &Impl::UpdateFormFactor)); Refresh(); @@ -291,17 +288,28 @@ Style::Impl::Impl(Style* owner) CAIRO_HINT_METRICS_ON); } + LoadStyleFile(); +} + +void Style::Impl::LoadStyleFile() +{ json::Parser parser; + // Since the parser skips values if they are not found, make sure everything // is initialised. SetDefaultValues(); - if (!parser.Open(DASH_WIDGETS_FILE)) + + if (!parser.Open(theme::Settings::Get()->ThemedFilePath("dash-widgets", {UNITYDATADIR"/themes"}, {"json"}))) + { + LOG_ERROR(logger) << "Impossible to find a dash-widgets.json in theme paths"; return; + } // button-label parser.ReadColors("button-label", "border-color", "border-opacity", button_label_border_color_); parser.ReadDoubles("button-label", "border-size", button_label_border_size_); + parser.ReadDouble("button-label", "border-radius", button_label_border_radius_); parser.ReadDouble("button-label", "text-size", button_label_text_size_); parser.ReadColors("button-label", "text-color", "text-opacity", button_label_text_color_); @@ -342,13 +350,16 @@ Style::Impl::Impl(Style* owner) parser.ReadInt("separator", "blur-size", separator_blur_size_); // scrollbar - parser.ReadColor("scrollbar", "color", "opacity", scrollbar_color_); - parser.ReadDouble("scrollbar", "overlay-opacity", scrollbar_overlay_opacity_); - parser.ReadMappedString("scrollbar", "overlay-mode", blend_mode_map, - scrollbar_overlay_mode_); - parser.ReadInt("scrollbar", "blur-size", scrollbar_blur_size_); parser.ReadInt("scrollbar", "size", scrollbar_size_); + parser.ReadInt("scrollbar-overlay", "size", scrollbar_overlay_size_); + parser.ReadInt("scrollbar", "buttons-size", scrollbar_buttons_size_); + parser.ReadColor("scrollbar", "color", "opacity", scrollbar_color_); + parser.ReadColor("scrollbar-overlay", "color", "opacity", scrollbar_overlay_color_); + parser.ReadColor("scrollbar-track", "color", "opacity", scrollbar_track_color_); parser.ReadDouble("scrollbar", "corner-radius", scrollbar_corner_radius_); + parser.ReadDouble("scrollbar-overlay", "corner-radius", scrollbar_overlay_corner_radius_); + + owner_->changed.emit(); } Style::Impl::~Impl() @@ -360,14 +371,12 @@ Style::Impl::~Impl() void Style::Impl::Refresh() { const char* const SAMPLE_MAX_TEXT = "Chromium Web Browser"; - GtkSettings* settings = ::gtk_settings_get_default(); nux::CairoGraphics util_cg(CAIRO_FORMAT_ARGB32, 1, 1); cairo_t* cr = util_cg.GetInternalContext(); - glib::String font_description; - ::g_object_get(settings, "gtk-font-name", &font_description, nullptr); - PangoFontDescription* desc = ::pango_font_description_from_string(font_description); + auto const& font = theme::Settings::Get()->font(); + PangoFontDescription* desc = ::pango_font_description_from_string(font.c_str()); ::pango_font_description_set_weight(desc, PANGO_WEIGHT_NORMAL); ::pango_font_description_set_size(desc, 9 * PANGO_SCALE); @@ -392,11 +401,6 @@ void Style::Impl::Refresh() pango_font_description_free(desc); } -void Style::Impl::OnFontChanged(GtkSettings* object, GParamSpec* pspec) -{ - Refresh(); -} - void Style::Impl::UpdateFormFactor(FormFactor form_factor) { owner_->always_maximised = (form_factor == FormFactor::NETBOOK || form_factor == FormFactor::TV); @@ -700,6 +704,7 @@ void Style::Impl::SetDefaultValues() //button_label_border_size_[nux::NUX_STATE_SELECTED] = 0.5; //button_label_border_size_[nux::NUX_STATE_INSENSITIVE] = 0.5; + button_label_border_radius_ = 4.0; button_label_text_size_ = 1.0; button_label_text_color_[nux::VISUAL_STATE_NORMAL] = nux::color::White; @@ -746,12 +751,14 @@ void Style::Impl::SetDefaultValues() separator_blur_size_ = 6; // scrollbar - scrollbar_color_ = nux::color::White; - scrollbar_overlay_opacity_ = 0.3; - scrollbar_overlay_mode_ = BlendMode::NORMAL; - scrollbar_blur_size_ = 5; - scrollbar_size_ = 3; - scrollbar_corner_radius_ = 1.5; + scrollbar_size_ = 8; + scrollbar_overlay_size_ = 3; + scrollbar_buttons_size_ = 0; + scrollbar_color_ = nux::color::White; + scrollbar_overlay_color_ = nux::color::White; + scrollbar_track_color_ = nux::color::White * 0.4; + scrollbar_corner_radius_ = 3; + scrollbar_overlay_corner_radius_ = 1.5; } void Style::Impl::ArrowPath(cairo_t* cr, Arrow arrow) @@ -1356,9 +1363,7 @@ void Style::Impl::GetTextExtents(int& width, PangoFontDescription* desc = NULL; PangoContext* pangoCtx = NULL; PangoRectangle inkRect = {0, 0, 0, 0}; - char* fontName = NULL; GdkScreen* screen = gdk_screen_get_default(); // is not ref'ed - GtkSettings* settings = gtk_settings_get_default();// is not ref'ed surface = cairo_image_surface_create(CAIRO_FORMAT_A1, 1, 1); cr = cairo_create(surface); @@ -1366,16 +1371,9 @@ void Style::Impl::GetTextExtents(int& width, cairo_set_font_options(cr, default_font_options_); else cairo_set_font_options(cr, gdk_screen_get_font_options(screen)); - layout = pango_cairo_create_layout(cr); - g_object_get(settings, "gtk-font-name", &fontName, NULL); - if (!fontName) - desc = pango_font_description_from_string("Sans 10"); - else - { - desc = pango_font_description_from_string(fontName); - g_free(fontName); - } + layout = pango_cairo_create_layout(cr); + desc = pango_font_description_from_string(theme::Settings::Get()->font().c_str()); pango_layout_set_font_description(layout, desc); pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR); @@ -1423,9 +1421,7 @@ void Style::Impl::Text(cairo_t* cr, PangoFontDescription* desc = NULL; PangoContext* pangoCtx = NULL; GdkScreen* screen = gdk_screen_get_default(); // not ref'ed - GtkSettings* settings = gtk_settings_get_default(); // not ref'ed gchar* fontName = NULL; - //double horizMargin = 10.0; get_actual_cairo_size(cr, &w, &h); w -= 2 * horizMargin; @@ -1434,13 +1430,9 @@ void Style::Impl::Text(cairo_t* cr, cairo_set_font_options(cr, default_font_options_); else cairo_set_font_options(cr, gdk_screen_get_font_options(screen)); - layout = pango_cairo_create_layout(cr); - g_object_get(settings, "gtk-font-name", &fontName, NULL); - if (!fontName) - desc = pango_font_description_from_string("Ubuntu 10"); - else - desc = pango_font_description_from_string(fontName); + layout = pango_cairo_create_layout(cr); + desc = pango_font_description_from_string(theme::Settings::Get()->font().c_str()); if (text_size > 0) { @@ -1638,7 +1630,7 @@ bool Style::Button(cairo_t* cr, nux::ButtonVisualState state, 1.0, (double) (garnish) + 1.0, (double) (garnish) + 1.0, - BUTTON_CORNER_RADIUS, + pimpl->button_label_border_radius_, w - (double) (2 * garnish) - 2.0, h - (double) (2 * garnish) - 2.0); else @@ -1646,7 +1638,7 @@ bool Style::Button(cairo_t* cr, nux::ButtonVisualState state, 1.0, (double) (garnish) + 0.5, (double) (garnish) + 0.5, - BUTTON_CORNER_RADIUS, + pimpl->button_label_border_radius_, w - (double) (2 * garnish) - 1.0, h - (double) (2 * garnish) - 1.0); @@ -1739,7 +1731,7 @@ bool Style::SquareButton(cairo_t* cr, nux::ButtonVisualState state, cairo_move_to(cr, _align(x + width, odd), y); if (curve_bottom) { - double radius = BUTTON_CORNER_RADIUS; + double radius = pimpl->button_label_border_radius_; LOG_DEBUG(logger) << "curve: " << _align(x + width, odd) << " - " << _align(y + height - radius, odd); // line to bottom-right corner cairo_line_to(cr, _align(x + width, odd), _align(y + height - radius, odd)); @@ -1844,7 +1836,7 @@ bool Style::ButtonFocusOverlay(cairo_t* cr, float alpha) 1.0, (double) 0.5, (double) 0.5, - BUTTON_CORNER_RADIUS, + pimpl->button_label_border_radius_, w - 1.0, h - 1.0); @@ -1893,7 +1885,7 @@ bool Style::MultiRangeSegment(cairo_t* cr, 1.0, x, y, - BUTTON_CORNER_RADIUS, + pimpl->button_label_border_radius_, w, h, segment); @@ -1916,7 +1908,7 @@ bool Style::MultiRangeSegment(cairo_t* cr, 1.0, x, y + line_width/2, - BUTTON_CORNER_RADIUS, + pimpl->button_label_border_radius_, w, h - line_width, segment, @@ -2189,11 +2181,6 @@ RawPixel Style::GetSeparatorGarnishSize() const return pimpl->separator_blur_size_; } -RawPixel Style::GetScrollbarGarnishSize() const -{ - return pimpl->scrollbar_blur_size_; -} - nux::Color const& Style::GetTextColor() const { return pimpl->text_color_; @@ -2406,9 +2393,44 @@ RawPixel Style::GetFilterViewRightPadding() const return 10; } -RawPixel Style::GetScrollbarWidth() const +RawPixel Style::GetOverlayScrollbarSize() const +{ + return pimpl->scrollbar_overlay_size_; +} + +RawPixel Style::GetScrollbarSize() const +{ + return pimpl->scrollbar_size_; +} + +RawPixel Style::GetScrollbarButtonsSize() const +{ + return pimpl->scrollbar_buttons_size_; +} + +RawPixel Style::GetOverlayScrollbarCornerRadius() const +{ + return pimpl->scrollbar_overlay_corner_radius_; +} + +RawPixel Style::GetScrollbarCornerRadius() const +{ + return pimpl->scrollbar_corner_radius_; +} + +nux::Color Style::GetOverlayScrollbarColor() const +{ + return pimpl->scrollbar_overlay_color_; +} + +nux::Color Style::GetScrollbarColor() const +{ + return pimpl->scrollbar_color_; +} + +nux::Color Style::GetScrollbarTrackColor() const { - return 3; + return pimpl->scrollbar_track_color_; } RawPixel Style::GetCategoryIconSize() const diff --git a/unity-shared/DashStyle.h b/unity-shared/DashStyle.h index dd73a3048..818c27f7c 100755 --- a/unity-shared/DashStyle.h +++ b/unity-shared/DashStyle.h @@ -140,8 +140,6 @@ public: RawPixel GetSeparatorGarnishSize() const; - RawPixel GetScrollbarGarnishSize() const; - void Blur(cairo_t* cr, int size); void RoundedRect(cairo_t* cr, @@ -237,7 +235,16 @@ public: RawPixel GetSpaceBetweenScopeAndFilters() const; // Scrollbars - RawPixel GetScrollbarWidth() const; + RawPixel GetOverlayScrollbarSize() const; + RawPixel GetScrollbarSize() const; + RawPixel GetScrollbarButtonsSize() const; + + RawPixel GetOverlayScrollbarCornerRadius() const; + RawPixel GetScrollbarCornerRadius() const; + + nux::Color GetOverlayScrollbarColor() const; + nux::Color GetScrollbarColor() const; + nux::Color GetScrollbarTrackColor() const; // Places Group RawPixel GetCategoryIconSize() const; diff --git a/unity-shared/DecorationStyle.cpp b/unity-shared/DecorationStyle.cpp index e6c529e42..8d06cd912 100644 --- a/unity-shared/DecorationStyle.cpp +++ b/unity-shared/DecorationStyle.cpp @@ -19,12 +19,16 @@ #include "config.h" #include "DecorationStyle.h" -#include <gtk/gtk.h> + +#include <math.h> #include <NuxCore/Colors.h> #include <NuxCore/Logger.h> +#include <UnityCore/ConnectionManager.h> #include <UnityCore/GLibWrapper.h> #include <UnityCore/GLibSignal.h> -#include <math.h> + +#include "GtkUtils.h" +#include "ThemeSettings.h" namespace unity { @@ -53,7 +57,6 @@ const int DEFAULT_TITLE_FADING_PIXELS = 35; const int DEFAULT_GLOW_SIZE = 10; const nux::Color DEFAULT_GLOW_COLOR(221, 72, 20); -const std::array<std::string, 2> THEMED_FILE_EXTENSIONS = { "svg", "png" }; const std::array<std::string, size_t(WindowButtonType::Size)> WBUTTON_NAMES = { "close", "minimize", "unmaximize", "maximize" }; const std::array<std::string, size_t(WidgetState::Size)> WBUTTON_STATES = {"", "_focused_prelight", "_focused_pressed", "_unfocused", "_unfocused", "_unfocused_prelight", "_unfocused_pressed" }; @@ -157,8 +160,9 @@ struct Style::Impl gtk_widget_path_append_type(widget_path.get(), unity_decoration_get_type()); gtk_style_context_set_path(ctx_, widget_path.get()); - parent_->theme = glib::String(GetSettingValue<gchar*>("gtk-theme-name")).Str(); - parent_->font = glib::String(GetSettingValue<gchar*>("gtk-font-name")).Str(); + auto theme_settings = theme::Settings::Get(); + parent_->theme.SetGetterFunction([theme_settings] { return theme_settings->theme(); }); + parent_->font.SetGetterFunction([theme_settings] { return theme_settings->font(); }); parent_->font_scale = 1.0; SetTitleFont(); @@ -166,29 +170,26 @@ struct Style::Impl UpdateMenuItemPangoContext(parent_->font); UpdateThemedValues(); - GtkSettings* settings = gtk_settings_get_default(); - signals_.Add<void, GtkSettings*, GParamSpec*>(settings, "notify::gtk-theme-name", [this] (GtkSettings*, GParamSpec*) { + connections_.Add(theme_settings->theme.changed.connect([this] (std::string const& theme) { #if !GTK_CHECK_VERSION(3, 11, 0) gtk_style_context_invalidate(ctx_); #endif UpdateThemedValues(); - parent_->theme = glib::String(GetSettingValue<gchar*>("gtk-theme-name")).Str(); - LOG_INFO(logger) << "gtk-theme-name changed to " << parent_->theme(); - }); + parent_->theme.EmitChanged(theme); + LOG_INFO(logger) << "unity theme changed to " << parent_->theme(); + })); - signals_.Add<void, GtkSettings*, GParamSpec*>(settings, "notify::gtk-font-name", [this] (GtkSettings*, GParamSpec*) { - auto const& font = glib::String(GetSettingValue<gchar*>("gtk-font-name")).Str(); + connections_.Add(theme_settings->font.changed.connect([this] (std::string const& font) { UpdateMenuItemPangoContext(font); - parent_->font = font; + parent_->font.EmitChanged(font); if (g_settings_get_boolean(settings_, USE_SYSTEM_FONT_KEY.c_str())) { UpdateTitlePangoContext(parent_->font()); parent_->title_font = parent_->font(); } - - LOG_INFO(logger) << "gtk-font-name changed to " << parent_->font(); - }); + LOG_INFO(logger) << "unity font changed to " << parent_->font(); + })); parent_->font_scale.changed.connect([this] (bool scale) { UpdateTitlePangoContext(parent_->title_font); @@ -297,14 +298,6 @@ struct Style::Impl return value; } - template <typename TYPE> - inline TYPE GetSettingValue(std::string const& name) - { - TYPE value; - g_object_get(gtk_settings_get_default(), name.c_str(), &value, nullptr); - return value; - } - WMAction WMActionFromString(std::string const& action) const { if (action == "toggle-shade") @@ -391,54 +384,10 @@ struct Style::Impl gtk_style_context_restore(ctx_); } - std::string ThemedFilePath(std::string const& base_filename, std::vector<std::string> const& extra_folders = {}) const - { - auto const& theme = parent_->theme(); - const char* home_dir = g_get_home_dir(); - const char* gtk_prefix = g_getenv("GTK_DATA_PREFIX"); - if (!gtk_prefix) - gtk_prefix = GTK_PREFIX; - - for (auto const& extension : THEMED_FILE_EXTENSIONS) - { - auto filename = base_filename + '.' + extension; - glib::String subpath(g_build_filename(theme.c_str(), "unity", filename.c_str(), nullptr)); - - // Look in home directory - if (home_dir) - { - glib::String local_file(g_build_filename(home_dir, ".local", "share", "themes", subpath.Value(), nullptr)); - - if (g_file_test(local_file, G_FILE_TEST_EXISTS)) - return local_file.Str(); - - glib::String home_file(g_build_filename(home_dir, ".themes", subpath.Value(), nullptr)); - - if (g_file_test(home_file, G_FILE_TEST_EXISTS)) - return home_file.Str(); - } - - glib::String path(g_build_filename(gtk_prefix, "share", "themes", subpath.Value(), nullptr)); - - if (g_file_test(path, G_FILE_TEST_EXISTS)) - return path.Str(); - - for (auto const& folder : extra_folders) - { - glib::String path(g_build_filename(folder.c_str(), filename.c_str(), nullptr)); - - if (g_file_test(path, G_FILE_TEST_EXISTS)) - return path.Str(); - } - } - - return std::string(); - } - std::string WindowButtonFile(WindowButtonType type, WidgetState state) const { auto base_filename = WBUTTON_NAMES[unsigned(type)] + WBUTTON_STATES[unsigned(state)]; - auto const& file_path = ThemedFilePath(base_filename); + auto const& file_path = parent_->ThemedFilePath(base_filename); if (!file_path.empty()) return file_path; @@ -677,6 +626,7 @@ struct Style::Impl glib::Object<GSettings> usettings_; glib::Object<PangoContext> title_pango_ctx_; glib::Object<PangoContext> menu_item_pango_ctx_; + connection::Manager connections_; decoration::Border border_; decoration::Border input_edges_; decoration::Border radius_; @@ -751,7 +701,7 @@ void Style::DrawMenuItemIcon(std::string const& i, WidgetState ws, cairo_t* cr, std::string Style::ThemedFilePath(std::string const& basename, std::vector<std::string> const& extra_folders) const { - return impl_->ThemedFilePath(basename, extra_folders); + return theme::Settings::Get()->ThemedFilePath(basename, extra_folders); } std::string Style::WindowButtonFile(WindowButtonType type, WidgetState state) const @@ -832,12 +782,12 @@ WMAction Style::WindowManagerAction(WMEvent event) const int Style::DoubleClickMaxDistance() const { - return impl_->GetSettingValue<int>("gtk-double-click-distance"); + return gtk::GetSettingValue<int>("gtk-double-click-distance"); } int Style::DoubleClickMaxTimeDelta() const { - return impl_->GetSettingValue<int>("gtk-double-click-time"); + return gtk::GetSettingValue<int>("gtk-double-click-time"); } nux::Size Style::TitleNaturalSize(std::string const& text) diff --git a/unity-shared/DecorationStyle.h b/unity-shared/DecorationStyle.h index 18ff1d316..9c4891813 100644 --- a/unity-shared/DecorationStyle.h +++ b/unity-shared/DecorationStyle.h @@ -115,10 +115,10 @@ public: typedef std::shared_ptr<Style> Ptr; static Style::Ptr const& Get(); - virtual ~Style(); + ~Style(); - nux::Property<std::string> theme; - nux::Property<std::string> font; + nux::ROProperty<std::string> theme; + nux::ROProperty<std::string> font; nux::Property<std::string> title_font; nux::Property<unsigned> grab_wait; nux::Property<double> font_scale; diff --git a/unity-shared/FontSettings.cpp b/unity-shared/FontSettings.cpp index 4da0e9679..ace5347bd 100644 --- a/unity-shared/FontSettings.cpp +++ b/unity-shared/FontSettings.cpp @@ -17,71 +17,59 @@ */ #include "FontSettings.h" - #include <cairo/cairo.h> -#include <UnityCore/GLibWrapper.h> -#include <sigc++/sigc++.h> - namespace unity { FontSettings::FontSettings() + : hintstyle_("gtk-xft-hintstyle") + , rgba_("gtk-xft-rgba") + , antialias_("gtk-xft-antialias") { - GtkSettings* settings = gtk_settings_get_default(); - - sig_man_.Add<void, GtkSettings*, GParamSpec*>(settings, "notify::gtk-xft-hintstyle", sigc::mem_fun(this, &FontSettings::Refresh)); - sig_man_.Add<void, GtkSettings*, GParamSpec*>(settings, "notify::gtk-xft-rgba", sigc::mem_fun(this, &FontSettings::Refresh)); - sig_man_.Add<void, GtkSettings*, GParamSpec*>(settings, "notify::gtk-xft-antialias", sigc::mem_fun(this, &FontSettings::Refresh)); + auto refresh_cb = sigc::hide(sigc::mem_fun(this, &FontSettings::Refresh)); + hintstyle_.changed.connect(refresh_cb); + rgba_.changed.connect(refresh_cb); + antialias_.changed.connect(refresh_cb); Refresh(); } -void FontSettings::Refresh(GtkSettings* unused0, GParamSpec* unused1) +void FontSettings::Refresh() { - GtkSettings* settings = gtk_settings_get_default(); cairo_font_options_t* font_options = cairo_font_options_create(); - { - cairo_subpixel_order_t order = CAIRO_SUBPIXEL_ORDER_DEFAULT; - glib::String value; - g_object_get(settings, "gtk-xft-rgba", &value, NULL); - gint antialias; - g_object_get(settings, "gtk-xft-antialias", &antialias, NULL); - - if (value.Str() == "rgb") - order = CAIRO_SUBPIXEL_ORDER_RGB; - else if (value.Str() == "bgr") - order = CAIRO_SUBPIXEL_ORDER_BGR; - else if (value.Str() == "vrgb") - order = CAIRO_SUBPIXEL_ORDER_VRGB; - else if (value.Str() == "vbgr") - order = CAIRO_SUBPIXEL_ORDER_VBGR; + auto const& rgba = rgba_(); + cairo_subpixel_order_t order = CAIRO_SUBPIXEL_ORDER_DEFAULT; + + if (rgba == "rgb") + order = CAIRO_SUBPIXEL_ORDER_RGB; + else if (rgba == "bgr") + order = CAIRO_SUBPIXEL_ORDER_BGR; + else if (rgba == "vrgb") + order = CAIRO_SUBPIXEL_ORDER_VRGB; + else if (rgba == "vbgr") + order = CAIRO_SUBPIXEL_ORDER_VBGR; + + cairo_font_options_set_subpixel_order(font_options, order); + cairo_font_options_set_antialias(font_options, + rgba == "none" ? (antialias_() ? CAIRO_ANTIALIAS_GRAY : CAIRO_ANTIALIAS_NONE) + : CAIRO_ANTIALIAS_SUBPIXEL); - cairo_font_options_set_subpixel_order(font_options, order); - cairo_font_options_set_antialias(font_options, - value.Str() == "none" ? (antialias ? CAIRO_ANTIALIAS_GRAY : CAIRO_ANTIALIAS_NONE) - : CAIRO_ANTIALIAS_SUBPIXEL); + auto const& hintstyle = hintstyle_(); + cairo_hint_style_t style = CAIRO_HINT_STYLE_DEFAULT; - } + if (hintstyle == "hintnone") + style = CAIRO_HINT_STYLE_NONE; + else if (hintstyle == "hintslight") + style = CAIRO_HINT_STYLE_SLIGHT; + else if (hintstyle == "hintmedium") + style = CAIRO_HINT_STYLE_MEDIUM; + else if (hintstyle == "hintfull") + style = CAIRO_HINT_STYLE_FULL; - { - cairo_hint_style_t style = CAIRO_HINT_STYLE_DEFAULT; - glib::String value; - g_object_get(settings, "gtk-xft-hintstyle", &value, NULL); - - if (value.Str() == "hintnone") - style = CAIRO_HINT_STYLE_NONE; - else if (value.Str() == "hintslight") - style = CAIRO_HINT_STYLE_SLIGHT; - else if (value.Str() == "hintmedium") - style = CAIRO_HINT_STYLE_MEDIUM; - else if (value.Str() == "hintfull") - style = CAIRO_HINT_STYLE_FULL; + cairo_font_options_set_hint_style(font_options, style); - cairo_font_options_set_hint_style(font_options, style); - } - // FIXME: Where do we read this value from? cairo_font_options_set_hint_metrics(font_options, CAIRO_HINT_METRICS_ON); diff --git a/unity-shared/FontSettings.h b/unity-shared/FontSettings.h index 362d3e7f8..02fbd5247 100644 --- a/unity-shared/FontSettings.h +++ b/unity-shared/FontSettings.h @@ -19,23 +19,23 @@ #ifndef UNITY_FONT_SETTINGS_H_ #define UNITY_FONT_SETTINGS_H_ -#include <gtk/gtk.h> - -#include <UnityCore/GLibSignal.h> +#include "GtkUtils.h" namespace unity { -class FontSettings +class FontSettings : public sigc::trackable { public: FontSettings(); private: - void Refresh(GtkSettings* unused0=nullptr, GParamSpec* unused1=nullptr); + void Refresh(); private: - glib::SignalManager sig_man_; + gtk::Setting<std::string> hintstyle_; + gtk::Setting<std::string> rgba_; + gtk::Setting<int> antialias_; }; } diff --git a/unity-shared/GtkUtils.h b/unity-shared/GtkUtils.h new file mode 100644 index 000000000..4b9d2a0b3 --- /dev/null +++ b/unity-shared/GtkUtils.h @@ -0,0 +1,73 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright (C) 2016 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * 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 <http://www.gnu.org/licenses/>. + * + * Authored by: Marco Trevisan <marco.trevisan@canonical.com> + */ + +#ifndef UNITY_GTK_UTILS +#define UNITY_GTK_UTILS + +#include <gtk/gtk.h> +#include <sigc++/sigc++.h> + +#include <UnityCore/GLibWrapper.h> +#include <UnityCore/GLibSignal.h> + +namespace unity +{ +namespace gtk +{ + +template <typename TYPE> +inline TYPE GetSettingValue(std::string const& name) +{ + TYPE value; + g_object_get(gtk_settings_get_default(), name.c_str(), &value, nullptr); + return value; +} + +template <> +inline std::string GetSettingValue(std::string const& name) +{ + return glib::String(gtk::GetSettingValue<gchar*>(name)).Str(); +} + +template <typename TYPE> +class Setting +{ +public: + Setting(std::string const& name) + : name_(name) + { + connection_.Connect(gtk_settings_get_default(), "notify::"+name_, [this] (GtkSettings*, GParamSpec*) { + changed.emit(GetSettingValue<TYPE>(name_)); + }); + } + + TYPE Value() const { return GetSettingValue<TYPE>(name_); } + TYPE operator()() const { return Value(); } + + sigc::signal<void, TYPE const&> changed; + +private: + std::string name_; + glib::Signal<void, GtkSettings*, GParamSpec*> connection_; +}; + +} // theme namespace +} // gtk namespace + +#endif // UNITY_GTK_UTILS diff --git a/unity-shared/IconLoader.cpp b/unity-shared/IconLoader.cpp index 059e6aa4c..1adfc9ba0 100644 --- a/unity-shared/IconLoader.cpp +++ b/unity-shared/IconLoader.cpp @@ -30,11 +30,12 @@ #include <Nux/Nux.h> #include <NuxCore/Logger.h> #include <NuxGraphics/CairoGraphics.h> +#include <UnityCore/ConnectionManager.h> #include <UnityCore/GLibSource.h> -#include <UnityCore/GLibSignal.h> #include <UnityCore/GLibWrapper.h> #include "unity-shared/Timer.h" +#include "unity-shared/ThemeSettings.h" #include "unity-shared/UnitySettings.h" namespace unity @@ -313,12 +314,11 @@ private: glib::Object<PangoLayout> layout; PangoContext* pango_context = NULL; GdkScreen* screen = gdk_screen_get_default(); // not ref'ed - glib::String font; + auto const& font = theme::Settings::Get()->font(); - g_object_get(gtk_settings_get_default(), "gtk-font-name", &font, NULL); cairo_set_font_options(cr, gdk_screen_get_font_options(screen)); layout = pango_cairo_create_layout(cr); - std::shared_ptr<PangoFontDescription> desc(pango_font_description_from_string(font), pango_font_description_free); + std::shared_ptr<PangoFontDescription> desc(pango_font_description_from_string(font.c_str()), pango_font_description_free); pango_font_description_set_weight(desc.get(), PANGO_WEIGHT_BOLD); int font_size = FONT_SIZE; pango_font_description_set_size (desc.get(), font_size * PANGO_SCALE); @@ -817,7 +817,7 @@ private: Handle handle_counter_; glib::Source::UniquePtr idle_; glib::Source::UniquePtr coalesce_timeout_; - glib::Signal<void, GtkIconTheme*> theme_changed_signal_; + connection::Wrapper theme_changed_; }; @@ -827,7 +827,7 @@ IconLoader::Impl::Impl() , theme_(::gtk_icon_theme_get_default()) , handle_counter_(0) { - theme_changed_signal_.Connect(theme_, "changed", [this] (GtkIconTheme*) { + theme_changed_ = theme::Settings::Get()->icons_changed.connect([this] { /* Since the theme has been changed we can clear the cache, however we * could include two improvements here: * 1) clear only the themed icons in cache @@ -914,14 +914,12 @@ void IconLoader::Impl::CalculateTextHeight(int* width, int* height) { // FIXME: what about CJK? const char* const SAMPLE_MAX_TEXT = "Chromium Web Browser"; - GtkSettings* settings = gtk_settings_get_default(); nux::CairoGraphics util_cg(CAIRO_FORMAT_ARGB32, 1, 1); cairo_t* cr = util_cg.GetInternalContext(); - glib::String font; - g_object_get(settings, "gtk-font-name", &font, nullptr); - std::shared_ptr<PangoFontDescription> desc(pango_font_description_from_string(font), pango_font_description_free); + auto const& font = theme::Settings::Get()->font(); + std::shared_ptr<PangoFontDescription> desc(pango_font_description_from_string(font.c_str()), pango_font_description_free); pango_font_description_set_weight(desc.get(), PANGO_WEIGHT_BOLD); pango_font_description_set_size(desc.get(), FONT_SIZE * PANGO_SCALE); diff --git a/unity-shared/IconRenderer.cpp b/unity-shared/IconRenderer.cpp index 844ffe88a..1104d0ba4 100644 --- a/unity-shared/IconRenderer.cpp +++ b/unity-shared/IconRenderer.cpp @@ -29,7 +29,7 @@ #include <UnityCore/ConnectionManager.h> #include <NuxGraphics/CairoGraphics.h> #include "unity-shared/CairoTexture.h" -#include "unity-shared/DecorationStyle.h" +#include "unity-shared/ThemeSettings.h" #include "unity-shared/TextureCache.h" #include "unity-shared/UnitySettings.h" #include "unity-shared/WindowManager.h" @@ -250,7 +250,7 @@ struct IconRenderer::LocalTextures LocalTextures(IconRenderer* parent) : parent_(parent) { - connections_.Add(decoration::Style::Get()->theme.changed.connect([this] (std::string const&) { + connections_.Add(theme::Settings::Get()->theme.changed.connect([this] (std::string const&) { auto& cache = TextureCache::GetDefault(); for (auto const& tex_data : texture_files_) @@ -294,7 +294,7 @@ struct IconRenderer::LocalTextures auto texture_loader = [] (std::string const& basename, int w, int h) { int size = std::max(w, h); - auto const& file = decoration::Style::Get()->ThemedFilePath(basename, {PKGDATADIR"/"}); + auto const& file = theme::Settings::Get()->ThemedFilePath(basename, {PKGDATADIR}); return nux::CreateTexture2DFromFile(file.c_str(), (size <= 0 ? -1 : size), true); }; @@ -827,8 +827,8 @@ nux::BaseTexture* IconRenderer::LocalTextures::RenderLabelTexture(char label, in cairo_fill(cr); glib::Object<PangoLayout> layout(pango_cairo_create_layout(cr)); - g_object_get(gtk_settings_get_default(), "gtk-font-name", &font_name, NULL); - std::shared_ptr<PangoFontDescription> desc(pango_font_description_from_string(font_name), + auto const& font = theme::Settings::Get()->font(); + std::shared_ptr<PangoFontDescription> desc(pango_font_description_from_string(font.c_str()), pango_font_description_free); const double text_ratio = 0.75; int text_size = pango_units_from_double(label_size * text_ratio * Settings::Instance().font_scaling()); diff --git a/unity-shared/JSONParser.h b/unity-shared/JSONParser.h index 7bd8dbdc8..6d9cb4f16 100644 --- a/unity-shared/JSONParser.h +++ b/unity-shared/JSONParser.h @@ -103,7 +103,7 @@ void Parser::ReadMappedStrings(std::string const& node_name, values.size()); for (std::size_t i = 0; i < size; ++i) { - std::string key(json_array_get_string_element(array, i)); + auto key = glib::gchar_to_string(json_array_get_string_element(array, i)); boost::to_lower(key); auto it = mapping.find(key); if (it != mapping.end()) @@ -121,7 +121,7 @@ void Parser::ReadMappedString(std::string const& node_name, if (!object) return; - std::string key(json_object_get_string_member(object, member_name.c_str())); + auto key = glib::gchar_to_string(json_object_get_string_member(object, member_name.c_str())); boost::to_lower(key); auto it = mapping.find(key); if (it != mapping.end()) diff --git a/unity-shared/PanelStyle.cpp b/unity-shared/PanelStyle.cpp index 8c191c57b..c7d16cb84 100644 --- a/unity-shared/PanelStyle.cpp +++ b/unity-shared/PanelStyle.cpp @@ -272,7 +272,7 @@ BaseTexturePtr Style::GetDashWindowButton(WindowButtonType type, WindowState sta static const std::array<std::string, 4> states = { "", "_prelight", "_pressed", "_disabled" }; auto base_filename = names[unsigned(type)] + states[unsigned(state)]; - auto const& file = decoration::Style::Get()->ThemedFilePath(base_filename, {PKGDATADIR"/"}); + auto const& file = decoration::Style::Get()->ThemedFilePath(base_filename, {PKGDATADIR}); if (file.empty()) return BaseTexturePtr(); diff --git a/unity-shared/PlacesOverlayVScrollBar.cpp b/unity-shared/PlacesOverlayVScrollBar.cpp index 0726b1e93..f952e3ab9 100644 --- a/unity-shared/PlacesOverlayVScrollBar.cpp +++ b/unity-shared/PlacesOverlayVScrollBar.cpp @@ -21,8 +21,8 @@ #include <Nux/Nux.h> #include "AnimationUtils.h" +#include "DashStyle.h" #include "PlacesOverlayVScrollBar.h" -#include "RawPixel.h" namespace unity { @@ -33,10 +33,6 @@ namespace const RawPixel PROXIMITY = 7_em; const int PAGE_SCROLL_ANIMATION = 200; const int CLICK_SCROLL_ANIMATION = 80; - -const RawPixel BUTTONS_HEIGHT = 0_em; -const RawPixel DEFAULT_WIDTH = 3_em; -const RawPixel ACTIVE_WIDTH = 8_em; } struct PlacesOverlayVScrollBar::ProximityArea : public nux::InputAreaProximity, public sigc::trackable @@ -62,6 +58,7 @@ PlacesOverlayVScrollBar::PlacesOverlayVScrollBar(NUX_FILE_LINE_DECL) }); auto update_sb_cb = sigc::mem_fun(this, &PlacesOverlayVScrollBar::UpdateScrollbarSize); + Style::Instance().changed.connect(update_sb_cb); auto update_sb_proximity_cb = sigc::hide(update_sb_cb); area_prox_->mouse_near.connect(update_sb_proximity_cb); @@ -94,22 +91,26 @@ PlacesOverlayVScrollBar::PlacesOverlayVScrollBar(NUX_FILE_LINE_DECL) void PlacesOverlayVScrollBar::UpdateScrollbarSize() { bool is_hovering = false; - SetMinimumWidth(ACTIVE_WIDTH.CP(scale)); - SetMaximumWidth(ACTIVE_WIDTH.CP(scale)); + auto& style = Style::Instance(); + + int active_width = style.GetScrollbarSize().CP(scale); + SetMinimumWidth(active_width); + SetMaximumWidth(active_width); - _scroll_up_button->SetMaximumHeight(BUTTONS_HEIGHT.CP(scale)); - _scroll_up_button->SetMinimumHeight(BUTTONS_HEIGHT.CP(scale)); - _scroll_down_button->SetMaximumHeight(BUTTONS_HEIGHT.CP(scale)); - _scroll_down_button->SetMinimumHeight(BUTTONS_HEIGHT.CP(scale)); + int buttons_height = style.GetScrollbarButtonsSize().CP(scale); + _scroll_up_button->SetMaximumHeight(buttons_height); + _scroll_up_button->SetMinimumHeight(buttons_height); + _scroll_down_button->SetMaximumHeight(buttons_height); + _scroll_down_button->SetMinimumHeight(buttons_height); - int slider_width = DEFAULT_WIDTH.CP(scale); + int slider_width = style.GetOverlayScrollbarSize().CP(scale); if (_track->IsMouseInside() || _track->IsMouseOwner() || _slider->IsMouseInside() || _slider->IsMouseOwner() || area_prox_->IsMouseNear()) { is_hovering = true; - slider_width = ACTIVE_WIDTH.CP(scale); + slider_width = active_width; } hovering = is_hovering; @@ -152,4 +153,3 @@ void PlacesOverlayVScrollBar::StartScrollAnimation(ScrollDir dir, int stop, unsi } // namespace dash } // namespace unity - diff --git a/unity-shared/PlacesVScrollBar.cpp b/unity-shared/PlacesVScrollBar.cpp index 9885fe12b..d2b5c0871 100644 --- a/unity-shared/PlacesVScrollBar.cpp +++ b/unity-shared/PlacesVScrollBar.cpp @@ -23,39 +23,30 @@ #include "PlacesVScrollBar.h" #include "unity-shared/CairoTexture.h" -#include "unity-shared/RawPixel.h" +#include "unity-shared/DashStyle.h" #include "unity-shared/GraphicsUtils.h" namespace unity { namespace dash { -namespace -{ -const RawPixel BUTTONS_HEIGHT = 0_em; -const RawPixel WIDTH = 3_em; -} PlacesVScrollBar::PlacesVScrollBar(NUX_FILE_LINE_DECL) : nux::VScrollBar(NUX_FILE_LINE_PARAM) , scale(1.0) , hovering(false) { - UpdateSize(); + Style::Instance().changed.connect(sigc::mem_fun(this, &PlacesVScrollBar::OnStyleChanged)); scale.changed.connect([this] (double scale) { - UpdateSize(); QueueRelayout(); QueueDraw(); }); } -void PlacesVScrollBar::UpdateSize() +void PlacesVScrollBar::OnStyleChanged() { - _scroll_up_button->SetMaximumHeight(BUTTONS_HEIGHT.CP(scale)); - _scroll_up_button->SetMinimumHeight(BUTTONS_HEIGHT.CP(scale)); - - _scroll_down_button->SetMaximumHeight(BUTTONS_HEIGHT.CP(scale)); - _scroll_down_button->SetMinimumHeight(BUTTONS_HEIGHT.CP(scale)); + slider_texture_.Release(); + QueueDraw(); } void PlacesVScrollBar::Draw(nux::GraphicsEngine& graphics_engine, bool force_draw) @@ -95,7 +86,10 @@ void PlacesVScrollBar::DrawContent(nux::GraphicsEngine& graphics_engine, bool fo nux::GetPainter().PushDrawLayer(graphics_engine, base, &layer); if (hovering) - graphics_engine.QRP_Color(base.x, base.y, base.width, base.height, nux::color::White * 0.4); + { + auto const& track_color = Style::Instance().GetScrollbarTrackColor(); + graphics_engine.QRP_Color(base.x, base.y, base.width, base.height, track_color * track_color.alpha); + } UpdateTexture(slider_geo); graphics_engine.QRP_1Tex(base.x + base.width - slider_geo.width, @@ -122,6 +116,7 @@ void PlacesVScrollBar::UpdateTexture(nux::Geometry const& geo) if (slider_texture_ && slider_texture_->GetWidth() == width && slider_texture_->GetHeight() == height) return; + auto& style = Style::Instance(); double unscaled_width = static_cast<double>(width) / scale(); double unscaled_height = static_cast<double>(height) / scale(); @@ -132,9 +127,12 @@ void PlacesVScrollBar::UpdateTexture(nux::Geometry const& geo) cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); cairo_paint(cr); + auto const& color = hovering ? style.GetScrollbarColor() : style.GetOverlayScrollbarColor(); + double radius = hovering ? style.GetScrollbarCornerRadius() : style.GetOverlayScrollbarCornerRadius(); + cairo_set_operator(cr, CAIRO_OPERATOR_OVER); - cairo_set_source_rgba(cr, 1.0f, 1.0f, 1.0f, 1.0f); - cg.DrawRoundedRectangle(cr, 1.0f, 0, 0, unscaled_width / 2.0, unscaled_width, unscaled_height - 2.0); + cairo_set_source_rgba(cr, color.red, color.green, color.blue, color.alpha); + cg.DrawRoundedRectangle(cr, 1.0f, 0, 0, radius, unscaled_width, unscaled_height - 2.0); cairo_fill(cr); slider_texture_ = texture_ptr_from_cairo_graphics(cg); diff --git a/unity-shared/PlacesVScrollBar.h b/unity-shared/PlacesVScrollBar.h index ec6517cb4..707c470dc 100644 --- a/unity-shared/PlacesVScrollBar.h +++ b/unity-shared/PlacesVScrollBar.h @@ -40,8 +40,8 @@ protected: void DrawContent(nux::GraphicsEngine& gfxContext, bool forceDraw); private: - void UpdateSize(); void UpdateTexture(nux::Geometry const&); + void OnStyleChanged(); private: nux::ObjectPtr<nux::BaseTexture> slider_texture_; diff --git a/unity-shared/SearchBar.cpp b/unity-shared/SearchBar.cpp index 5ac9b5276..9c3741f86 100644 --- a/unity-shared/SearchBar.cpp +++ b/unity-shared/SearchBar.cpp @@ -38,6 +38,7 @@ #include "RawPixel.h" #include "SearchBarSpinner.h" #include "StaticCairoText.h" +#include "ThemeSettings.h" #include "UnitySettings.h" namespace unity @@ -226,8 +227,8 @@ SearchBar::SearchBar(bool show_filter_hint, NUX_FILE_LINE_DECL) expand_icon_->mouse_click.connect(mouse_expand); } - sig_manager_.Add<void, GtkSettings*>(gtk_settings_get_default(), "notify::gtk-font-name", sigc::hide(sigc::mem_fun(this, &SearchBar::OnFontChanged))); - OnFontChanged(); + UpdateFont(); + theme::Settings::Get()->font.changed.connect(sigc::hide(sigc::mem_fun(this, &SearchBar::UpdateFont))); search_hint.changed.connect([this](std::string const& s) { OnSearchHintChanged(); }); search_string.SetGetterFunction([this] { return pango_entry_->GetText(); }); @@ -320,30 +321,23 @@ void SearchBar::UpdateScale(double scale) UpdateSearchBarSize(); } -void SearchBar::OnFontChanged() +void SearchBar::UpdateFont() { - glib::String font_name; - PangoFontDescription* desc; - std::ostringstream font_desc; + auto* desc = pango_font_description_from_string(theme::Settings::Get()->font().c_str()); - g_object_get(gtk_settings_get_default(), "gtk-font-name", &font_name, NULL); - - desc = pango_font_description_from_string(font_name.Value()); if (desc) { pango_entry_->SetFontFamily(pango_font_description_get_family(desc)); pango_entry_->SetFontSize(PANGO_ENTRY_FONT_SIZE.CP(scale * Settings::Instance().font_scaling())); pango_entry_->SetFontOptions(gdk_screen_get_font_options(gdk_screen_get_default())); - font_desc << pango_font_description_get_family(desc) << " " << HINT_LABEL_FONT_STYLE << " " << HINT_LABEL_FONT_SIZE; - hint_->SetFont(font_desc.str().c_str()); + auto font_desc = glib::gchar_to_string(pango_font_description_get_family(desc)) + " " + HINT_LABEL_FONT_STYLE + " " + HINT_LABEL_FONT_SIZE; + hint_->SetFont(font_desc.c_str()); if (show_filter_hint_) { - font_desc.str(""); - font_desc.clear(); - font_desc << pango_font_description_get_family(desc) << " " << SHOW_FILTERS_LABEL_FONT_STYLE << " " << SHOW_FILTERS_LABEL_FONT_SIZE; - show_filters_->SetFont(font_desc.str().c_str()); + font_desc = glib::gchar_to_string(pango_font_description_get_family(desc)) + " " + SHOW_FILTERS_LABEL_FONT_STYLE + " " + SHOW_FILTERS_LABEL_FONT_SIZE; + show_filters_->SetFont(font_desc.c_str()); } pango_font_description_free(desc); diff --git a/unity-shared/SearchBar.h b/unity-shared/SearchBar.h index 1ea02082f..c9af1db11 100644 --- a/unity-shared/SearchBar.h +++ b/unity-shared/SearchBar.h @@ -73,7 +73,7 @@ public: sigc::signal<void, std::string const&> live_search_reached; private: - void OnFontChanged(); + void UpdateFont(); void OnSearchHintChanged(); void Draw(nux::GraphicsEngine& GfxContext, bool force_draw); diff --git a/unity-shared/StaticCairoText.cpp b/unity-shared/StaticCairoText.cpp index bc2cbbb49..cc01337dd 100644 --- a/unity-shared/StaticCairoText.cpp +++ b/unity-shared/StaticCairoText.cpp @@ -33,9 +33,10 @@ #include <pango/pangocairo.h> #include <UnityCore/GLibWrapper.h> -#include <UnityCore/GLibSignal.h> +#include <UnityCore/ConnectionManager.h> #include "CairoTexture.h" +#include "ThemeSettings.h" #include "UnitySettings.h" using namespace nux; @@ -106,7 +107,7 @@ struct StaticCairoText::Impl : sigc::trackable float line_spacing_; double scale_; - glib::Signal<void, GtkSettings*, GParamSpec*> font_changed_; + connection::Wrapper font_changed_conn_; }; StaticCairoText::Impl::Impl(StaticCairoText* parent, std::string const& text) @@ -127,8 +128,9 @@ StaticCairoText::Impl::Impl(StaticCairoText* parent, std::string const& text) , line_spacing_(0.5) , scale_(1.0f) { - font_changed_.Connect(gtk_settings_get_default(), "notify::gtk-font-name", sigc::hide(sigc::hide(sigc::mem_fun(this, &Impl::OnFontChanged)))); - Settings::Instance().font_scaling.changed.connect(sigc::hide(sigc::mem_fun(this, &Impl::OnFontChanged))); + auto font_changed_cb = sigc::hide(sigc::mem_fun(this, &Impl::OnFontChanged)); + font_changed_conn_ = theme::Settings::Get()->font.changed.connect(font_changed_cb); + Settings::Instance().font_scaling.changed.connect(font_changed_cb); } PangoEllipsizeMode StaticCairoText::Impl::GetPangoEllipsizeMode() const @@ -410,6 +412,7 @@ void StaticCairoText::SetFont(std::string const& font) { if (pimpl->font_ != font) { + font.empty() ? pimpl->font_changed_conn_->unblock() : pimpl->font_changed_conn_->block(); pimpl->font_ = font; pimpl->need_new_extent_cache_ = true; Size s = GetTextExtents(); @@ -552,12 +555,7 @@ void StaticCairoText::AddProperties(debug::IntrospectionData& introspection) std::string StaticCairoText::Impl::GetEffectiveFont() const { if (font_.empty()) - { - GtkSettings* settings = gtk_settings_get_default(); // not ref'ed - glib::String font_name; - g_object_get(settings, "gtk-font-name", &font_name, NULL); - return font_name.Str(); - } + return theme::Settings::Get()->font(); return font_; } @@ -577,7 +575,7 @@ Size StaticCairoText::Impl::GetTextExtents() const } Size result; - std::string font = GetEffectiveFont(); + std::string const& font = GetEffectiveFont(); nux::Size layout_size(-1, lines_ < 0 ? lines_ : std::numeric_limits<int>::min()); surface = cairo_image_surface_create(CAIRO_FORMAT_A1, 1, 1); diff --git a/unity-shared/TextInput.cpp b/unity-shared/TextInput.cpp index 2eed30cb5..7d76424b3 100644 --- a/unity-shared/TextInput.cpp +++ b/unity-shared/TextInput.cpp @@ -36,6 +36,7 @@ #include "PreviewStyle.h" #include "RawPixel.h" #include "TextureCache.h" +#include "ThemeSettings.h" #include "UnitySettings.h" namespace unity @@ -141,7 +142,7 @@ TextInput::TextInput(NUX_FILE_LINE_DECL) layered_layout_->SetActiveLayerN(1); layout_->AddView(layered_layout_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FIX); - UpdateSize(); + UpdateFont(); // Caps lock warning warning_ = new IconTexture(LoadWarningIcon(DEFAULT_ICON_SIZE.CP(scale))); @@ -181,8 +182,7 @@ TextInput::TextInput(NUX_FILE_LINE_DECL) spinner_->scale = scale(); layout_->AddView(spinner_, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); - OnFontChanged(); - sig_manager_.Add<void, GtkSettings*>(gtk_settings_get_default(), "notify::gtk-font-name", sigc::hide(sigc::mem_fun(this, &TextInput::OnFontChanged))); + theme::Settings::Get()->font.changed.connect(sigc::hide(sigc::mem_fun(this, &TextInput::UpdateFont))); sig_manager_.Add<void, GdkKeymap*>(gdk_keymap_get_default(), "state-changed", [this](GdkKeymap*) { CheckLocks(); }); input_string.SetGetterFunction(sigc::mem_fun(this, &TextInput::get_input_string)); @@ -320,9 +320,6 @@ nux::ObjectPtr<nux::BaseTexture> TextInput::LoadWarningIcon(int icon_size) void TextInput::LoadWarningTooltip() { - glib::String font_name; - g_object_get(gtk_settings_get_default(), "gtk-font-name", &font_name, NULL); - glib::Object<GtkStyleContext> style_context(gtk_style_context_new()); std::shared_ptr<GtkWidgetPath> widget_path(gtk_widget_path_new(), gtk_widget_path_free); gtk_widget_path_append_type(widget_path.get(), GTK_TYPE_TOOLTIP); @@ -333,7 +330,8 @@ void TextInput::LoadWarningTooltip() glib::Object<PangoContext> context(gdk_pango_context_get()); glib::Object<PangoLayout> layout(pango_layout_new(context)); - std::shared_ptr<PangoFontDescription> desc(pango_font_description_from_string(font_name), pango_font_description_free); + auto const& font = theme::Settings::Get()->font(); + std::shared_ptr<PangoFontDescription> desc(pango_font_description_from_string(font.c_str()), pango_font_description_free); pango_context_set_font_description(context, desc.get()); pango_context_set_language(context, gtk_get_default_language()); pango_cairo_context_set_resolution(context, 96.0 * Settings::Instance().font_scaling()); @@ -369,14 +367,10 @@ void TextInput::LoadWarningTooltip() warning_tooltip_ = texture_ptr_from_cairo_graphics(cg); } -void TextInput::OnFontChanged() +void TextInput::UpdateFont() { - glib::String font_name; - PangoFontDescription* desc; - - g_object_get(gtk_settings_get_default(), "gtk-font-name", &font_name, NULL); + auto* desc = pango_font_description_from_string(theme::Settings::Get()->font().c_str()); - desc = pango_font_description_from_string(font_name.Value()); if (desc) { pango_entry_->SetFontFamily(pango_font_description_get_family(desc)); diff --git a/unity-shared/TextInput.h b/unity-shared/TextInput.h index fc5b13cfa..342bbbb3c 100644 --- a/unity-shared/TextInput.h +++ b/unity-shared/TextInput.h @@ -75,7 +75,7 @@ public: nux::Property<double> scale; private: - void OnFontChanged(); + void UpdateFont(); void UpdateHintFont(); void UpdateHintColor(); void Draw(nux::GraphicsEngine& GfxContext, bool force_draw); diff --git a/unity-shared/ThemeSettings.cpp b/unity-shared/ThemeSettings.cpp new file mode 100644 index 000000000..6c3cc440f --- /dev/null +++ b/unity-shared/ThemeSettings.cpp @@ -0,0 +1,145 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright (C) 2016 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * 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 <http://www.gnu.org/licenses/>. + * + * Authored by: Marco Trevisan <marco.trevisan@canonical.com> + */ + +#include "config.h" +#include "ThemeSettings.h" + +#include <NuxCore/Logger.h> +#include <UnityCore/DesktopUtilities.h> +#include <UnityCore/ConnectionManager.h> +#include "FontSettings.h" + +namespace unity +{ +namespace theme +{ +namespace +{ +DECLARE_LOGGER(logger, "unity.theme.settings"); + +const std::array<std::string, 2> THEMED_FILE_EXTENSIONS = { "svg", "png" }; +const std::string UNITY_THEME_NAME = "unity-icon-theme"; +} + +struct Settings::Impl +{ + Impl(Settings* parent) + : parent_(parent) + , theme_setting_("gtk-theme-name") + , font_setting_("gtk-font-name") + { + parent_->theme = theme_setting_(); + parent_->font = font_setting_(); + + connections_.Add(theme_setting_.changed.connect([this] (std::string const& theme) { + parent_->theme = theme; + LOG_INFO(logger) << "gtk-theme-name changed to " << parent_->theme(); + })); + + connections_.Add(font_setting_.changed.connect([this] (std::string const& font) { + parent_->font = font; + LOG_INFO(logger) << "gtk-font-name changed to " << parent_->font(); + })); + + unity_icon_theme_ = gtk_icon_theme_new(); + gtk_icon_theme_set_custom_theme(unity_icon_theme_, UNITY_THEME_NAME.c_str()); + + icon_theme_changed_.Connect(gtk_icon_theme_get_default(), "changed", [this] (GtkIconTheme*) { + LOG_INFO(logger) << "gtk default icon theme changed"; + parent_->icons_changed.emit(); + }); + } + + std::string ThemedFilePath(std::string const& base_filename, std::vector<std::string> const& extra_folders, std::vector<std::string> extensions) const + { + auto const& theme = parent_->theme(); + auto const& home_dir = DesktopUtilities::GetUserHomeDirectory(); + auto const& data_dir = DesktopUtilities::GetUserDataDirectory(); + const char* gtk_prefix = g_getenv("GTK_DATA_PREFIX"); + + if (!gtk_prefix || gtk_prefix[0] == '\0') + gtk_prefix = GTK_PREFIX; + + extensions.insert(end(extensions), begin(THEMED_FILE_EXTENSIONS), end(THEMED_FILE_EXTENSIONS)); + + for (auto const& extension : extensions) + { + auto filename = base_filename + '.' + extension; + glib::String subpath(g_build_filename(theme.c_str(), "unity", filename.c_str(), nullptr)); + glib::String local_file(g_build_filename(data_dir.c_str(), "themes", subpath.Value(), nullptr)); + + if (g_file_test(local_file, G_FILE_TEST_EXISTS)) + return local_file.Str(); + + glib::String home_file(g_build_filename(home_dir.c_str(), ".themes", subpath.Value(), nullptr)); + + if (g_file_test(home_file, G_FILE_TEST_EXISTS)) + return home_file.Str(); + + glib::String theme_file(g_build_filename(gtk_prefix, "share", "themes", subpath.Value(), nullptr)); + + if (g_file_test(theme_file, G_FILE_TEST_EXISTS)) + return theme_file.Str(); + + for (auto const& folder : extra_folders) + { + glib::String path(g_build_filename(folder.c_str(), filename.c_str(), nullptr)); + + if (g_file_test(path, G_FILE_TEST_EXISTS)) + return path.Str(); + } + } + + return std::string(); + } + + Settings* parent_; + FontSettings font_settings_; + gtk::Setting<std::string> theme_setting_; + gtk::Setting<std::string> font_setting_; + glib::Signal<void, GtkIconTheme*> icon_theme_changed_; + glib::Object<GtkIconTheme> unity_icon_theme_; + connection::Manager connections_; +}; + +Settings::Ptr const& Settings::Get() +{ + static Settings::Ptr theme(new Settings()); + return theme; +} + +Settings::Settings() + : impl_(new Impl(this)) +{} + +Settings::~Settings() +{} + +std::string Settings::ThemedFilePath(std::string const& basename, std::vector<std::string> const& extra_folders, std::vector<std::string> const& extra_extensions) const +{ + return impl_->ThemedFilePath(basename, extra_folders, extra_extensions); +} + +GtkIconTheme* Settings::UnityIconTheme() const +{ + return impl_->unity_icon_theme_; +} + +} // theme namespace +} // unity namespace diff --git a/unity-shared/ThemeSettings.h b/unity-shared/ThemeSettings.h new file mode 100644 index 000000000..962a0b42d --- /dev/null +++ b/unity-shared/ThemeSettings.h @@ -0,0 +1,61 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright (C) 2016 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * 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 <http://www.gnu.org/licenses/>. + * + * Authored by: Marco Trevisan <marco.trevisan@canonical.com> + */ + +#ifndef UNITY_THEME_SETTINGS +#define UNITY_THEME_SETTINGS + +#include <memory> +#include <NuxCore/Property.h> + +struct _GtkIconTheme; + +namespace unity +{ +namespace theme +{ + +class Settings +{ +public: + typedef std::shared_ptr<Settings> Ptr; + + static Settings::Ptr const& Get(); + ~Settings(); + + nux::Property<std::string> theme; + nux::Property<std::string> font; + + std::string ThemedFilePath(std::string const& basename, std::vector<std::string> const& extra_folders = {}, std::vector<std::string> const& extra_extensions = {}) const; + _GtkIconTheme* UnityIconTheme() const; + + sigc::signal<void> icons_changed; + +private: + Settings(); + Settings(Settings const&) = delete; + Settings& operator=(Settings const&) = delete; + + struct Impl; + std::unique_ptr<Impl> impl_; +}; + +} // theme namespace +} // unity namespace + +#endif // UNITY_THEME_SETTINGS |
