mirror of https://github.com/aseprite/aseprite.git
				
				
				
			From Edit > Preferences > Themes we now can customize the theme Font and Mini Font.
This commit is contained in:
		
							parent
							
								
									bc3433fcf2
								
							
						
					
					
						commit
						d4406629e6
					
				|  | @ -1513,6 +1513,12 @@ alpha_range = Alpha Range: | ||||||
| opacity_range = Opacity Range: | opacity_range = Opacity Range: | ||||||
| 8bit_value = 0-255 | 8bit_value = 0-255 | ||||||
| percentage = 0%-100% | percentage = 0%-100% | ||||||
|  | customize_theme = Customize Theme | ||||||
|  | font = Font: | ||||||
|  | mini_font = Mini Font: | ||||||
|  | preview = Preview: | ||||||
|  | font_preview = Font Preview | ||||||
|  | mini_font_preview = Mini Font Preview | ||||||
| available_themes = Available Themes | available_themes = Available Themes | ||||||
| extension_themes = Extension Themes | extension_themes = Extension Themes | ||||||
| select_theme = &Select | select_theme = &Select | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| <!-- Aseprite --> | <!-- Aseprite --> | ||||||
| <!-- Copyright (C) 2018-2024  Igara Studio S.A. --> | <!-- Copyright (C) 2018-2025  Igara Studio S.A. --> | ||||||
| <!-- Copyright (C) 2001-2018  David Capello --> | <!-- Copyright (C) 2001-2018  David Capello --> | ||||||
| <gui> | <gui> | ||||||
|   <window id="options" text="@.title" help="preferences"> |   <window id="options" text="@.title" help="preferences"> | ||||||
|  | @ -537,6 +537,20 @@ | ||||||
| 
 | 
 | ||||||
|         <!-- Theme --> |         <!-- Theme --> | ||||||
|         <vbox id="section_theme"> |         <vbox id="section_theme"> | ||||||
|  |           <separator text="@.customize_theme" horizontal="true" /> | ||||||
|  |           <grid columns="2"> | ||||||
|  |             <label text="@.preview" /> | ||||||
|  |             <vbox cell_align="horizontal" > | ||||||
|  |               <label id="font_preview" text="@.font_preview" /> | ||||||
|  |               <label id="mini_font_preview" text="@.mini_font_preview" /> | ||||||
|  |             </vbox> | ||||||
|  | 
 | ||||||
|  |             <check id="custom_theme_font" text="@.font" /> | ||||||
|  |             <font id="theme_font" cell_align="horizontal" /> | ||||||
|  | 
 | ||||||
|  |             <check id="custom_mini_font" text="@.mini_font" /> | ||||||
|  |             <font id="theme_mini_font" cell_align="horizontal" /> | ||||||
|  |           </grid> | ||||||
|           <separator text="@.available_themes" horizontal="true" /> |           <separator text="@.available_themes" horizontal="true" /> | ||||||
|           <view expansive="true" maxsize="true"> |           <view expansive="true" maxsize="true"> | ||||||
|             <listbox id="theme_list" /> |             <listbox id="theme_list" /> | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| // Aseprite
 | // Aseprite
 | ||||||
| // Copyright (C) 2018-2024  Igara Studio S.A.
 | // Copyright (C) 2018-2025  Igara Studio S.A.
 | ||||||
| // Copyright (C) 2001-2018  David Capello
 | // Copyright (C) 2001-2018  David Capello
 | ||||||
| //
 | //
 | ||||||
| // This program is distributed under the terms of
 | // This program is distributed under the terms of
 | ||||||
|  | @ -35,6 +35,7 @@ | ||||||
| #include "app/ui/sampling_selector.h" | #include "app/ui/sampling_selector.h" | ||||||
| #include "app/ui/separator_in_view.h" | #include "app/ui/separator_in_view.h" | ||||||
| #include "app/ui/skin/skin_theme.h" | #include "app/ui/skin/skin_theme.h" | ||||||
|  | #include "app/util/render_text.h" | ||||||
| #include "base/convert_to.h" | #include "base/convert_to.h" | ||||||
| #include "base/fs.h" | #include "base/fs.h" | ||||||
| #include "base/string.h" | #include "base/string.h" | ||||||
|  | @ -267,8 +268,10 @@ public: | ||||||
|   { |   { | ||||||
|     sectionListbox()->Change.connect([this] { onChangeSection(); }); |     sectionListbox()->Change.connect([this] { onChangeSection(); }); | ||||||
| 
 | 
 | ||||||
|     // Theme variants
 |     // Theme variants/fonts.
 | ||||||
|     fillThemeVariants(); |     fillThemeVariants(); | ||||||
|  |     fillThemeFonts(); | ||||||
|  |     updateFontPreviews(); | ||||||
| 
 | 
 | ||||||
|     // Recent files
 |     // Recent files
 | ||||||
|     clearRecentFiles()->Click.connect([this] { onClearRecentFiles(); }); |     clearRecentFiles()->Click.connect([this] { onClearRecentFiles(); }); | ||||||
|  | @ -440,6 +443,22 @@ public: | ||||||
|     // Undo preferences
 |     // Undo preferences
 | ||||||
|     limitUndo()->Click.connect([this] { onLimitUndoCheck(); }); |     limitUndo()->Click.connect([this] { onLimitUndoCheck(); }); | ||||||
| 
 | 
 | ||||||
|  |     // Theme Custom Font
 | ||||||
|  |     customThemeFont()->Click.connect([this] { | ||||||
|  |       const bool state = customThemeFont()->isSelected(); | ||||||
|  |       themeFont()->setEnabled(state); | ||||||
|  |       if (!state) | ||||||
|  |         themeFont()->setInfo(FontInfo(), FontEntry::From::Init); | ||||||
|  |     }); | ||||||
|  |     customMiniFont()->Click.connect([this] { | ||||||
|  |       const bool state = customMiniFont()->isSelected(); | ||||||
|  |       themeMiniFont()->setEnabled(state); | ||||||
|  |       if (!state) | ||||||
|  |         themeMiniFont()->setInfo(FontInfo(), FontEntry::From::Init); | ||||||
|  |     }); | ||||||
|  |     themeFont()->FontChange.connect([this] { updateFontPreviews(); }); | ||||||
|  |     themeMiniFont()->FontChange.connect([this] { updateFontPreviews(); }); | ||||||
|  | 
 | ||||||
|     // Theme buttons
 |     // Theme buttons
 | ||||||
|     themeList()->Change.connect([this] { onThemeChange(); }); |     themeList()->Change.connect([this] { onThemeChange(); }); | ||||||
|     themeList()->DoubleClickItem.connect([this] { onSelectTheme(); }); |     themeList()->DoubleClickItem.connect([this] { onSelectTheme(); }); | ||||||
|  | @ -893,6 +912,23 @@ public: | ||||||
|     ui::set_use_native_cursors(m_pref.cursor.useNativeCursor()); |     ui::set_use_native_cursors(m_pref.cursor.useNativeCursor()); | ||||||
|     ui::set_mouse_cursor_scale(m_pref.cursor.cursorScale()); |     ui::set_mouse_cursor_scale(m_pref.cursor.cursorScale()); | ||||||
| 
 | 
 | ||||||
|  |     // Change theme font
 | ||||||
|  |     bool reset_theme = false; | ||||||
|  |     { | ||||||
|  |       const FontInfo fontInfo = themeFont()->info(); | ||||||
|  |       const FontInfo miniFontInfo = themeMiniFont()->info(); | ||||||
|  | 
 | ||||||
|  |       auto fontStr = base::convert_to<std::string>(fontInfo); | ||||||
|  |       auto miniFontStr = base::convert_to<std::string>(miniFontInfo); | ||||||
|  | 
 | ||||||
|  |       if (m_pref.theme.font() != fontStr || m_pref.theme.miniFont() != miniFontStr) { | ||||||
|  |         m_pref.theme.font(fontStr); | ||||||
|  |         m_pref.theme.miniFont(miniFontStr); | ||||||
|  | 
 | ||||||
|  |         reset_theme = true; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     bool reset_screen = false; |     bool reset_screen = false; | ||||||
|     const int newScreenScale = base::convert_to<int>(screenScale()->getValue()); |     const int newScreenScale = base::convert_to<int>(screenScale()->getValue()); | ||||||
|     if (newScreenScale != m_pref.general.screenScale()) { |     if (newScreenScale != m_pref.general.screenScale()) { | ||||||
|  | @ -903,10 +939,13 @@ public: | ||||||
|     const int newUIScale = base::convert_to<int>(uiScale()->getValue()); |     const int newUIScale = base::convert_to<int>(uiScale()->getValue()); | ||||||
|     if (newUIScale != m_pref.general.uiScale()) { |     if (newUIScale != m_pref.general.uiScale()) { | ||||||
|       m_pref.general.uiScale(newUIScale); |       m_pref.general.uiScale(newUIScale); | ||||||
|       ui::set_theme(ui::get_theme(), newUIScale); |       reset_theme = true; | ||||||
|       reset_screen = true; |       reset_screen = true; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     if (reset_theme) | ||||||
|  |       ui::set_theme(ui::get_theme(), newUIScale); | ||||||
|  | 
 | ||||||
| #ifdef ENABLE_DEVMODE | #ifdef ENABLE_DEVMODE | ||||||
|     const bool newGpuAccel = gpuAcceleration()->isSelected(); |     const bool newGpuAccel = gpuAcceleration()->isSelected(); | ||||||
|     if (newGpuAccel != m_pref.general.gpuAcceleration()) { |     if (newGpuAccel != m_pref.general.gpuAcceleration()) { | ||||||
|  | @ -989,6 +1028,14 @@ public: | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|  |   void onInitTheme(InitThemeEvent& ev) override | ||||||
|  |   { | ||||||
|  |     app::gen::Options::onInitTheme(ev); | ||||||
|  | 
 | ||||||
|  |     fontPreview()->setFont(m_font); | ||||||
|  |     miniFontPreview()->setFont(m_miniFont); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   void fillThemeVariants() |   void fillThemeVariants() | ||||||
|   { |   { | ||||||
|     ButtonSet* list = nullptr; |     ButtonSet* list = nullptr; | ||||||
|  | @ -1027,6 +1074,34 @@ private: | ||||||
|     themeVariants()->initTheme(); |     themeVariants()->initTheme(); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   void fillThemeFonts() | ||||||
|  |   { | ||||||
|  |     auto& pref = Preferences::instance(); | ||||||
|  |     const FontInfo fontInfo = base::convert_to<FontInfo>(pref.theme.font()); | ||||||
|  |     const FontInfo miniInfo = base::convert_to<FontInfo>(pref.theme.miniFont()); | ||||||
|  | 
 | ||||||
|  |     customThemeFont()->setSelected(fontInfo.isValid()); | ||||||
|  |     customMiniFont()->setSelected(miniInfo.isValid()); | ||||||
|  | 
 | ||||||
|  |     themeFont()->setEnabled(fontInfo.isValid()); | ||||||
|  |     themeMiniFont()->setEnabled(miniInfo.isValid()); | ||||||
|  | 
 | ||||||
|  |     themeFont()->setInfo(fontInfo, FontEntry::From::Init); | ||||||
|  |     themeMiniFont()->setInfo(miniInfo, FontEntry::From::Init); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   void updateFontPreviews() | ||||||
|  |   { | ||||||
|  |     m_font = get_font_from_info(themeFont()->info()); | ||||||
|  |     m_miniFont = get_font_from_info(themeMiniFont()->info()); | ||||||
|  |     if (!m_miniFont) | ||||||
|  |       m_miniFont = skin::SkinTheme::get(this)->getMiniFont(); | ||||||
|  | 
 | ||||||
|  |     fontPreview()->setFont(m_font); | ||||||
|  |     miniFontPreview()->setFont(m_miniFont); | ||||||
|  |     layout(); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   void fillExtensionsCombobox(ui::ComboBox* combobox, const std::string& defExt) |   void fillExtensionsCombobox(ui::ComboBox* combobox, const std::string& defExt) | ||||||
|   { |   { | ||||||
|     base::paths exts = get_writable_extensions(); |     base::paths exts = get_writable_extensions(); | ||||||
|  | @ -2034,6 +2109,8 @@ private: | ||||||
|   BestFitCriteriaSelector m_bestFitCriteriaSelector; |   BestFitCriteriaSelector m_bestFitCriteriaSelector; | ||||||
|   ButtonSet* m_themeVars = nullptr; |   ButtonSet* m_themeVars = nullptr; | ||||||
|   SamplingSelector* m_samplingSelector = nullptr; |   SamplingSelector* m_samplingSelector = nullptr; | ||||||
|  |   text::FontRef m_font; | ||||||
|  |   text::FontRef m_miniFont; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| class OptionsCommand : public Command { | class OptionsCommand : public Command { | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| // Aseprite
 | // Aseprite
 | ||||||
| // Copyright (c) 2024  Igara Studio S.A.
 | // Copyright (c) 2024-2025  Igara Studio S.A.
 | ||||||
| //
 | //
 | ||||||
| // This program is distributed under the terms of
 | // This program is distributed under the terms of
 | ||||||
| // the End-User License Agreement for Aseprite.
 | // the End-User License Agreement for Aseprite.
 | ||||||
|  | @ -159,7 +159,7 @@ app::FontInfo convert_to(const std::string& from) | ||||||
|       type = app::FontInfo::Type::System; |       type = app::FontInfo::Type::System; | ||||||
|       name = parts[0].substr(7); |       name = parts[0].substr(7); | ||||||
|     } |     } | ||||||
|     else { |     else if (!parts[0].empty()) { | ||||||
|       type = app::FontInfo::Type::Name; |       type = app::FontInfo::Type::Name; | ||||||
|       name = parts[0]; |       name = parts[0]; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| // Aseprite
 | // Aseprite
 | ||||||
| // Copyright (C) 2019-2024  Igara Studio S.A.
 | // Copyright (C) 2019-2025  Igara Studio S.A.
 | ||||||
| // Copyright (C) 2001-2018  David Capello
 | // Copyright (C) 2001-2018  David Capello
 | ||||||
| //
 | //
 | ||||||
| // This program is distributed under the terms of
 | // This program is distributed under the terms of
 | ||||||
|  | @ -14,6 +14,7 @@ | ||||||
| #include "app/app.h" | #include "app/app.h" | ||||||
| #include "app/console.h" | #include "app/console.h" | ||||||
| #include "app/extensions.h" | #include "app/extensions.h" | ||||||
|  | #include "app/font_info.h" | ||||||
| #include "app/font_path.h" | #include "app/font_path.h" | ||||||
| #include "app/modules/gui.h" | #include "app/modules/gui.h" | ||||||
| #include "app/pref/preferences.h" | #include "app/pref/preferences.h" | ||||||
|  | @ -23,6 +24,7 @@ | ||||||
| #include "app/ui/skin/font_data.h" | #include "app/ui/skin/font_data.h" | ||||||
| #include "app/ui/skin/skin_property.h" | #include "app/ui/skin/skin_property.h" | ||||||
| #include "app/ui/skin/skin_slider_property.h" | #include "app/ui/skin/skin_slider_property.h" | ||||||
|  | #include "app/util/render_text.h" | ||||||
| #include "app/xml_document.h" | #include "app/xml_document.h" | ||||||
| #include "app/xml_exception.h" | #include "app/xml_exception.h" | ||||||
| #include "base/fs.h" | #include "base/fs.h" | ||||||
|  | @ -482,6 +484,19 @@ void SkinTheme::loadXml(BackwardCompatibility* backward) | ||||||
|   if (!m_miniFont) |   if (!m_miniFont) | ||||||
|     m_miniFont = m_defaultFont; |     m_miniFont = m_defaultFont; | ||||||
| 
 | 
 | ||||||
|  |   // Overwrite theme fonts by user defined fonts.
 | ||||||
|  |   Preferences& pref = Preferences::instance(); | ||||||
|  |   if (!pref.theme.font().empty()) { | ||||||
|  |     auto fi = base::convert_to<FontInfo>(pref.theme.font()); | ||||||
|  |     if (auto f = get_font_from_info(fi, this)) | ||||||
|  |       m_defaultFont = f; | ||||||
|  |   } | ||||||
|  |   if (!pref.theme.miniFont().empty()) { | ||||||
|  |     auto fi = base::convert_to<FontInfo>(pref.theme.miniFont()); | ||||||
|  |     if (auto f = get_font_from_info(fi, this)) | ||||||
|  |       m_miniFont = f; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   // Load dimension
 |   // Load dimension
 | ||||||
|   { |   { | ||||||
|     XMLElement* xmlDim = handle.FirstChildElement("theme") |     XMLElement* xmlDim = handle.FirstChildElement("theme") | ||||||
|  | @ -781,10 +796,22 @@ void SkinTheme::loadXml(BackwardCompatibility* backward) | ||||||
|       { |       { | ||||||
|         const char* fontId = xmlStyle->Attribute("font"); |         const char* fontId = xmlStyle->Attribute("font"); | ||||||
|         if (fontId) { |         if (fontId) { | ||||||
|  |           // Use m_defaultFont/m_miniFont just in case the user
 | ||||||
|  |           // customized these fonts.
 | ||||||
|  |           if (std::strcmp(fontId, "default") == 0) { | ||||||
|  |             style->setFont(m_defaultFont); | ||||||
|  |             style->setMnemonics(true); | ||||||
|  |           } | ||||||
|  |           else if (std::strcmp(fontId, "mini") == 0) { | ||||||
|  |             style->setFont(m_miniFont); | ||||||
|  |             style->setMnemonics(false); | ||||||
|  |           } | ||||||
|  |           else { | ||||||
|             auto themeFont = m_themeFonts[fontId]; |             auto themeFont = m_themeFonts[fontId]; | ||||||
|             style->setFont(themeFont.font()); |             style->setFont(themeFont.font()); | ||||||
|             style->setMnemonics(themeFont.mnemonics()); |             style->setMnemonics(themeFont.mnemonics()); | ||||||
|           } |           } | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         // Override mnemonics value if it is defined for this style.
 |         // Override mnemonics value if it is defined for this style.
 | ||||||
|         const char* mnemonicsStr = xmlStyle->Attribute("mnemonics"); |         const char* mnemonicsStr = xmlStyle->Attribute("mnemonics"); | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| // Aseprite
 | // Aseprite
 | ||||||
| // Copyright (C) 2022-2024  Igara Studio S.A.
 | // Copyright (C) 2022-2025  Igara Studio S.A.
 | ||||||
| // Copyright (C) 2001-2018  David Capello
 | // Copyright (C) 2001-2018  David Capello
 | ||||||
| //
 | //
 | ||||||
| // This program is distributed under the terms of
 | // This program is distributed under the terms of
 | ||||||
|  | @ -63,12 +63,14 @@ private: | ||||||
| 
 | 
 | ||||||
| } // anonymous namespace
 | } // anonymous namespace
 | ||||||
| 
 | 
 | ||||||
| text::FontRef get_font_from_info(const FontInfo& fontInfo) | text::FontRef get_font_from_info(const FontInfo& fontInfo, skin::SkinTheme* theme) | ||||||
| { | { | ||||||
|   auto* theme = skin::SkinTheme::instance(); |   if (!theme) { | ||||||
|  |     theme = skin::SkinTheme::instance(); | ||||||
|     ASSERT(theme); |     ASSERT(theme); | ||||||
|     if (!theme) |     if (!theme) | ||||||
|       return nullptr; |       return nullptr; | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   const text::FontMgrRef fontMgr = theme->fontMgr(); |   const text::FontMgrRef fontMgr = theme->fontMgr(); | ||||||
|   if (!fontMgr) |   if (!fontMgr) | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| // Aseprite
 | // Aseprite
 | ||||||
| // Copyright (C) 2024  Igara Studio S.A.
 | // Copyright (C) 2024-2025  Igara Studio S.A.
 | ||||||
| // Copyright (C) 2001-2015  David Capello
 | // Copyright (C) 2001-2015  David Capello
 | ||||||
| //
 | //
 | ||||||
| // This program is distributed under the terms of
 | // This program is distributed under the terms of
 | ||||||
|  | @ -20,8 +20,11 @@ namespace app { | ||||||
| 
 | 
 | ||||||
| class Color; | class Color; | ||||||
| class FontInfo; | class FontInfo; | ||||||
|  | namespace skin { | ||||||
|  | class SkinTheme; | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| text::FontRef get_font_from_info(const FontInfo& fontInfo); | text::FontRef get_font_from_info(const FontInfo& fontInfo, skin::SkinTheme* theme = nullptr); | ||||||
| 
 | 
 | ||||||
| text::TextBlobRef create_text_blob(const FontInfo& fontInfo, const std::string& text); | text::TextBlobRef create_text_blob(const FontInfo& fontInfo, const std::string& text); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue