1 | // Aseprite |
2 | // Copyright (C) 2020-2022 Igara Studio S.A. |
3 | // Copyright (C) 2001-2017 David Capello |
4 | // |
5 | // This program is distributed under the terms of |
6 | // the End-User License Agreement for Aseprite. |
7 | |
8 | #ifndef APP_UI_SKIN_SKIN_THEME_H_INCLUDED |
9 | #define APP_UI_SKIN_SKIN_THEME_H_INCLUDED |
10 | #pragma once |
11 | |
12 | #include "app/ui/skin/skin_part.h" |
13 | #include "gfx/color.h" |
14 | #include "gfx/fwd.h" |
15 | #include "ui/cursor.h" |
16 | #include "ui/cursor_type.h" |
17 | #include "ui/manager.h" |
18 | #include "ui/scale.h" |
19 | #include "ui/theme.h" |
20 | |
21 | #include "theme.xml.h" |
22 | |
23 | #include <array> |
24 | #include <map> |
25 | #include <string> |
26 | |
27 | namespace ui { |
28 | class Entry; |
29 | class Graphics; |
30 | } |
31 | |
32 | namespace app { |
33 | namespace skin { |
34 | |
35 | class FontData; |
36 | |
37 | // This is the GUI theme used by Aseprite (which use images from |
38 | // data/skins directory). |
39 | class SkinTheme : public ui::Theme |
40 | , public app::gen::ThemeFile<SkinTheme> { |
41 | public: |
42 | static const char* kThemesFolderName; |
43 | |
44 | static SkinTheme* instance(); |
45 | static SkinTheme* get(const ui::Widget* widget); |
46 | |
47 | SkinTheme(); |
48 | ~SkinTheme(); |
49 | |
50 | const std::string& path() { return m_path; } |
51 | int preferredScreenScaling() { return m_preferredScreenScaling; } |
52 | int preferredUIScaling() { return m_preferredUIScaling; } |
53 | |
54 | os::Font* getDefaultFont() const override { return m_defaultFont.get(); } |
55 | os::Font* getWidgetFont(const ui::Widget* widget) const override; |
56 | os::Font* getMiniFont() const { return m_miniFont.get(); } |
57 | |
58 | ui::Cursor* getStandardCursor(ui::CursorType type) override; |
59 | void initWidget(ui::Widget* widget) override; |
60 | void getWindowMask(ui::Widget* widget, gfx::Region& region) override; |
61 | int getScrollbarSize() override; |
62 | gfx::Size getEntryCaretSize(ui::Widget* widget) override; |
63 | |
64 | void paintEntry(ui::PaintEvent& ev) override; |
65 | void paintListBox(ui::PaintEvent& ev) override; |
66 | void (ui::PaintEvent& ev) override; |
67 | void (ui::PaintEvent& ev) override; |
68 | void paintSlider(ui::PaintEvent& ev) override; |
69 | void paintComboBoxEntry(ui::PaintEvent& ev) override; |
70 | void paintTextBox(ui::PaintEvent& ev) override; |
71 | void paintViewViewport(ui::PaintEvent& ev) override; |
72 | |
73 | SkinPartPtr getToolPart(const char* toolId) const; |
74 | os::Surface* getToolIcon(const char* toolId) const; |
75 | |
76 | // Helper functions to draw bounds/hlines with sheet parts |
77 | void drawRect(ui::Graphics* g, const gfx::Rect& rc, |
78 | os::Surface* nw, os::Surface* n, os::Surface* ne, |
79 | os::Surface* e, os::Surface* se, os::Surface* s, |
80 | os::Surface* sw, os::Surface* w); |
81 | void drawRect(ui::Graphics* g, const gfx::Rect& rc, SkinPart* skinPart, const bool drawCenter = true); |
82 | void drawRect2(ui::Graphics* g, const gfx::Rect& rc, int x_mid, SkinPart* nw1, SkinPart* nw2); |
83 | void drawHline(ui::Graphics* g, const gfx::Rect& rc, SkinPart* skinPart); |
84 | void drawVline(ui::Graphics* g, const gfx::Rect& rc, SkinPart* skinPart); |
85 | void paintProgressBar(ui::Graphics* g, const gfx::Rect& rc, double progress); |
86 | |
87 | ui::Style* getStyleById(const std::string& id) const { |
88 | auto it = m_styles.find(id); |
89 | if (it != m_styles.end()) |
90 | return it->second; |
91 | else |
92 | return nullptr; |
93 | } |
94 | |
95 | SkinPartPtr getPartById(const std::string& id) const { |
96 | auto it = m_parts_by_id.find(id); |
97 | if (it != m_parts_by_id.end()) |
98 | return it->second; |
99 | else |
100 | return SkinPartPtr(nullptr); |
101 | } |
102 | |
103 | ui::Cursor* getCursorById(const std::string& id) const { |
104 | auto it = m_cursors.find(id); |
105 | if (it != m_cursors.end()) |
106 | return it->second; |
107 | else |
108 | return nullptr; |
109 | } |
110 | |
111 | int getDimensionById(const std::string& id) const { |
112 | auto it = m_dimensions_by_id.find(id); |
113 | if (it != m_dimensions_by_id.end()) |
114 | return it->second * ui::guiscale(); |
115 | else |
116 | return 0; |
117 | } |
118 | |
119 | gfx::Color getColorById(const std::string& id) const { |
120 | auto it = m_colors_by_id.find(id); |
121 | if (it != m_colors_by_id.end()) |
122 | return it->second; |
123 | else |
124 | return gfx::ColorNone; |
125 | } |
126 | |
127 | void drawEntryCaret(ui::Graphics* g, ui::Entry* widget, int x, int y); |
128 | |
129 | protected: |
130 | void onRegenerateTheme() override; |
131 | |
132 | private: |
133 | struct BackwardCompatibility; |
134 | |
135 | void loadFontData(); |
136 | void loadAll(const std::string& themeId, |
137 | BackwardCompatibility* backward = nullptr); |
138 | void loadSheet(); |
139 | void loadXml(BackwardCompatibility* backward); |
140 | |
141 | os::SurfaceRef sliceSheet(os::SurfaceRef sur, const gfx::Rect& bounds); |
142 | gfx::Color getWidgetBgColor(ui::Widget* widget); |
143 | void drawText(ui::Graphics* g, |
144 | const char* t, |
145 | const gfx::Color fgColor, |
146 | const gfx::Color bgColor, |
147 | const ui::Widget* widget, |
148 | const gfx::Rect& rc, |
149 | const int textAlign, |
150 | const int mnemonic); |
151 | void drawEntryText(ui::Graphics* g, ui::Entry* widget); |
152 | |
153 | std::string findThemePath(const std::string& themeId) const; |
154 | |
155 | std::string m_path; |
156 | os::SurfaceRef m_sheet; |
157 | std::map<std::string, SkinPartPtr> m_parts_by_id; |
158 | std::map<std::string, gfx::Color> m_colors_by_id; |
159 | std::map<std::string, int> m_dimensions_by_id; |
160 | std::map<std::string, ui::Cursor*> m_cursors; |
161 | std::array<ui::Cursor*, ui::kCursorTypes> m_standardCursors; |
162 | std::map<std::string, ui::Style*> m_styles; |
163 | std::map<std::string, FontData*> m_fonts; |
164 | std::map<std::string, os::FontRef> m_themeFonts; |
165 | os::FontRef m_defaultFont; |
166 | os::FontRef m_miniFont; |
167 | int m_preferredScreenScaling; |
168 | int m_preferredUIScaling; |
169 | }; |
170 | |
171 | } // namespace skin |
172 | } // namespace app |
173 | |
174 | #endif |
175 | |