Merge lp:~3v1n0/unity/shortcuts-hidpi into lp:unity

Proposed by Marco Trevisan (Treviño)
Status: Superseded
Proposed branch: lp:~3v1n0/unity/shortcuts-hidpi
Merge into: lp:unity
Prerequisite: lp:~3v1n0/unity/shutdown-hidpi-fixes
Diff against target: 595 lines (+210/-84)
7 files modified
shortcuts/ShortcutController.cpp (+1/-1)
shortcuts/ShortcutView.cpp (+113/-48)
shortcuts/ShortcutView.h (+9/-3)
tests/test_unity_window_view.cpp (+9/-9)
unity-shared/UnityWindowStyle.cpp (+65/-15)
unity-shared/UnityWindowStyle.h (+6/-3)
unity-shared/UnityWindowView.cpp (+7/-5)
To merge this branch: bzr merge lp:~3v1n0/unity/shortcuts-hidpi
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Needs Fixing
Andrea Azzarone (community) Needs Fixing
Review via email: mp+218738@code.launchpad.net

This proposal has been superseded by a proposal from 2014-05-16.

Commit message

ShortcutView: use RawPixel's for the size values and convert them to match current scaling

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Andrea Azzarone (azzar1) wrote :
review: Needs Fixing
Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

> Here the overlay appears different before and after the fix.
>
> https://www.dropbox.com/s/0is33cmdjf6uj19/before.png
> https://www.dropbox.com/s/9dph4shu4p3ym5r/after.png

This is because both in English and many localized versions the keys
or descriptions are cut, while there's no reason to limit the
horizontal size, since most of netbooks will still be able to see it.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'shortcuts/ShortcutController.cpp'
2--- shortcuts/ShortcutController.cpp 2014-05-16 00:33:37 +0000
3+++ shortcuts/ShortcutController.cpp 2014-05-16 00:33:37 +0000
4@@ -70,11 +70,11 @@
5 if (!view_)
6 return;
7
8+ model->Fill();
9 view_->SetModel(model);
10
11 if (Visible())
12 {
13- model->Fill();
14 auto const& offset = GetOffsetPerMonitor(view_->monitor());
15
16 if (offset.x < 0 || offset.y < 0)
17
18=== modified file 'shortcuts/ShortcutView.cpp'
19--- shortcuts/ShortcutView.cpp 2013-11-16 11:44:23 +0000
20+++ shortcuts/ShortcutView.cpp 2014-05-16 00:33:37 +0000
21@@ -38,10 +38,16 @@
22 const unsigned MAIN_TITLE_FONT_SIZE = 15;
23 const unsigned SECTION_NAME_FONT_SIZE = 12;
24 const unsigned SHORTKEY_ENTRY_FONT_SIZE = 9;
25- const unsigned INTER_SPACE_SHORTKEY_DESCRIPTION = 10;
26- const unsigned SHORTKEY_COLUMN_WIDTH = 150;
27- const unsigned DESCRIPTION_COLUMN_WIDTH = 265;
28- const unsigned LINE_SPACING = 5;
29+ const RawPixel INTER_SPACE_SHORTKEY_DESCRIPTION = 10_em;
30+ const RawPixel SHORTKEY_COLUMN_DEFAULT_WIDTH = 150_em;
31+ const RawPixel SHORTKEY_COLUMN_MAX_WIDTH = 350_em;
32+ const RawPixel DESCRIPTION_COLUMN_DEFAULT_WIDTH = 265_em;
33+ const RawPixel DESCRIPTION_COLUMN_MAX_WIDTH = 500_em;
34+ const RawPixel LINE_SPACING = 3_em;
35+ const RawPixel MAIN_HORIZONTAL_PADDING = 30_em;
36+ const RawPixel MAIN_VERTICAL_PADDING = 18_em;
37+ const RawPixel MAIN_CHILDREN_SPACE = 20_em;
38+ const RawPixel COLUMNS_CHILDREN_SPACE = 30_em;
39
40 // We need this class because SetVisible doesn't work for layouts.
41 class SectionView : public nux::View
42@@ -72,8 +78,8 @@
43 : ui::UnityWindowView()
44 {
45 auto main_layout = new nux::VLayout();
46- main_layout->SetPadding(30, 18);
47- main_layout->SetSpaceBetweenChildren(20);
48+ main_layout->SetPadding(MAIN_HORIZONTAL_PADDING.CP(scale), MAIN_VERTICAL_PADDING.CP(scale));
49+ main_layout->SetSpaceBetweenChildren(MAIN_CHILDREN_SPACE.CP(scale));
50 SetLayout(main_layout);
51
52 std::string header = "<b>"+std::string(_("Keyboard Shortcuts"))+"</b>";
53@@ -81,13 +87,22 @@
54 auto* header_view = new StaticCairoText(header, NUX_TRACKER_LOCATION);
55 header_view->SetFont(FONT_NAME+" "+std::to_string(MAIN_TITLE_FONT_SIZE));
56 header_view->SetLines(-1);
57+ header_view->SetScale(scale);
58 main_layout->AddView(header_view, 1 , nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);
59
60 main_layout->AddView(new HSeparator(), 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);
61
62 columns_layout_ = new nux::HLayout();
63- columns_layout_->SetSpaceBetweenChildren(30);
64+ columns_layout_->SetSpaceBetweenChildren(COLUMNS_CHILDREN_SPACE.CP(scale));
65 main_layout->AddLayout(columns_layout_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);
66+
67+ scale.changed.connect([this, main_layout, header_view] (double scale) {
68+ main_layout->SetPadding(MAIN_HORIZONTAL_PADDING.CP(scale), MAIN_VERTICAL_PADDING.CP(scale));
69+ main_layout->SetSpaceBetweenChildren(MAIN_CHILDREN_SPACE.CP(scale));
70+ columns_layout_->SetSpaceBetweenChildren(COLUMNS_CHILDREN_SPACE.CP(scale));
71+ header_view->SetScale(scale);
72+ RenderColumns();
73+ });
74 }
75
76 void View::SetModel(Model::Ptr model)
77@@ -114,14 +129,17 @@
78 auto* section_name_view = new StaticCairoText(name, NUX_TRACKER_LOCATION);
79 section_name_view->SetFont(FONT_NAME+" "+std::to_string(SECTION_NAME_FONT_SIZE));
80 section_name_view->SetLines(-1);
81- layout->AddView(new nux::SpaceLayout(10, 10, 10, 10), 0, nux::MINOR_POSITION_START, nux::MINOR_SIZE_MATCHCONTENT);
82+ section_name_view->SetScale(scale);
83+ const int top_space = (10_em).CP(scale);
84+ const int bottom_space = (15_em).CP(scale);
85+ layout->AddView(new nux::SpaceLayout(top_space, top_space, top_space, top_space), 0, nux::MINOR_POSITION_START, nux::MINOR_SIZE_MATCHCONTENT);
86 layout->AddView(section_name_view, 0, nux::MINOR_POSITION_START, nux::MINOR_SIZE_MATCHCONTENT);
87- layout->AddView(new nux::SpaceLayout(15, 15, 15, 15), 0, nux::MINOR_POSITION_START, nux::MINOR_SIZE_MATCHCONTENT);
88+ layout->AddView(new nux::SpaceLayout(bottom_space, bottom_space, bottom_space, bottom_space), 0, nux::MINOR_POSITION_START, nux::MINOR_SIZE_MATCHCONTENT);
89
90 return layout;
91 }
92
93-nux::View* View::CreateShortKeyEntryView(AbstractHint::Ptr const& hint)
94+nux::View* View::CreateShortKeyEntryView(AbstractHint::Ptr const& hint, StaticCairoText* shortkey_view, StaticCairoText* description_view)
95 {
96 auto* view = new SectionView(NUX_TRACKER_LOCATION);
97
98@@ -131,56 +149,56 @@
99 nux::HLayout* shortkey_layout = new nux::HLayout(NUX_TRACKER_LOCATION);
100 nux::HLayout* description_layout = new nux::HLayout(NUX_TRACKER_LOCATION);
101
102- glib::String shortkey(g_markup_escape_text(hint->shortkey().c_str(), -1));
103-
104- std::string skey = "<b>"+shortkey.Str()+"</b>";
105- auto* shortkey_view = new StaticCairoText(skey, NUX_TRACKER_LOCATION);
106- shortkey_view->SetTextAlignment(StaticCairoText::AlignState::NUX_ALIGN_LEFT);
107- shortkey_view->SetFont(FONT_NAME+" "+std::to_string(SHORTKEY_ENTRY_FONT_SIZE));
108- shortkey_view->SetLines(-1);
109- shortkey_view->SetMinimumWidth(SHORTKEY_COLUMN_WIDTH);
110- shortkey_view->SetMaximumWidth(SHORTKEY_COLUMN_WIDTH);
111-
112- glib::String es_desc(g_markup_escape_text(hint->description().c_str(), -1));
113-
114- auto* description_view = new StaticCairoText(es_desc.Str(), NUX_TRACKER_LOCATION);
115- description_view->SetTextAlignment(StaticCairoText::AlignState::NUX_ALIGN_LEFT);
116- description_view->SetFont(FONT_NAME+" "+std::to_string(SHORTKEY_ENTRY_FONT_SIZE));
117- description_view->SetLines(-1);
118- description_view->SetMinimumWidth(DESCRIPTION_COLUMN_WIDTH);
119- description_view->SetMaximumWidth(DESCRIPTION_COLUMN_WIDTH);
120-
121 shortkey_layout->AddView(shortkey_view, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT);
122 shortkey_layout->SetContentDistribution(nux::MAJOR_POSITION_START);
123- shortkey_layout->SetMinimumWidth(SHORTKEY_COLUMN_WIDTH);
124- shortkey_layout->SetMaximumWidth(SHORTKEY_COLUMN_WIDTH);
125
126 description_layout->AddView(description_view, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT);
127 description_layout->SetContentDistribution(nux::MAJOR_POSITION_START);
128- description_layout->SetMinimumWidth(DESCRIPTION_COLUMN_WIDTH);
129- description_layout->SetMaximumWidth(DESCRIPTION_COLUMN_WIDTH);
130
131 layout->AddLayout(shortkey_layout, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT);
132 layout->AddLayout(description_layout, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT);
133- layout->SetSpaceBetweenChildren(INTER_SPACE_SHORTKEY_DESCRIPTION);
134+ layout->SetSpaceBetweenChildren(INTER_SPACE_SHORTKEY_DESCRIPTION.CP(scale));
135 description_layout->SetContentDistribution(nux::MAJOR_POSITION_START);
136
137- view->key_changed_conn_ = hint->shortkey.changed.connect([this, view, shortkey_view] (std::string const& new_key) {
138- bool enabled = !new_key.empty();
139- shortkey_view->SetText(enabled ? "<b>"+new_key+"</b>" : "");
140- view->SetVisible(enabled);
141+ view->key_changed_conn_ = hint->shortkey.changed.connect([this, view, shortkey_view] (std::string const& key) {
142+ std::string escaped = glib::String(g_markup_escape_text(key.c_str(), -1)).Str();
143+
144+ if (!escaped.empty())
145+ escaped = "<b>"+escaped+"</b>";
146+
147+ shortkey_view->SetText(escaped);
148+ shortkey_view->SetVisible(!escaped.empty());
149+ view->SetVisible(shortkey_view->IsVisible());
150 QueueRelayout();
151+ QueueDraw();
152 });
153
154- view->SetVisible(!shortkey.Str().empty());
155+ view->SetVisible(shortkey_view->IsVisible());
156
157 return view;
158 }
159
160+StaticCairoText* View::CreateShortcutTextView(std::string const& text, bool bold)
161+{
162+ std::string escaped = glib::String(g_markup_escape_text(text.c_str(), -1)).Str();
163+
164+ if (bold && !text.empty())
165+ escaped = "<b>"+escaped+"</b>";
166+
167+ auto* text_view = new StaticCairoText(escaped, NUX_TRACKER_LOCATION);
168+ text_view->SetTextAlignment(StaticCairoText::AlignState::NUX_ALIGN_LEFT);
169+ text_view->SetFont(FONT_NAME+" "+std::to_string(SHORTKEY_ENTRY_FONT_SIZE));
170+ text_view->SetLines(-1);
171+ text_view->SetScale(scale);
172+ text_view->SetVisible(!escaped.empty());
173+
174+ return text_view;
175+}
176+
177 nux::LinearLayout* View::CreateIntermediateLayout()
178 {
179 nux::VLayout* layout = new nux::VLayout(NUX_TRACKER_LOCATION);
180- layout->SetSpaceBetweenChildren(LINE_SPACING);
181+ layout->SetSpaceBetweenChildren(LINE_SPACING.CP(scale));
182
183 return layout;
184 }
185@@ -195,9 +213,38 @@
186 view_layout_->ProcessDraw(GfxContext, force_draw);
187 }
188
189+void View::PreLayoutManagement()
190+{
191+ UnityWindowView::PreLayoutManagement();
192+
193+ for (auto const& column : shortkeys_)
194+ {
195+ int min_width = SHORTKEY_COLUMN_DEFAULT_WIDTH.CP(scale);
196+
197+ for (auto* shortkey : column)
198+ min_width = std::min(std::max(min_width, shortkey->GetTextExtents().width), shortkey->GetMaximumWidth());
199+
200+ for (auto* shortkey : column)
201+ shortkey->SetMinimumWidth(min_width);
202+ }
203+
204+ for (auto const& column : descriptions_)
205+ {
206+ int min_width = DESCRIPTION_COLUMN_DEFAULT_WIDTH.CP(scale);
207+
208+ for (auto* description : column)
209+ min_width = std::min(std::max(min_width, description->GetTextExtents().width), description->GetMaximumWidth());
210+
211+ for (auto* description : column)
212+ description->SetMinimumWidth(min_width);
213+ }
214+}
215+
216 void View::RenderColumns()
217 {
218 columns_layout_->Clear();
219+ shortkeys_.clear();
220+ descriptions_.clear();
221
222 if (!model_)
223 {
224@@ -209,11 +256,21 @@
225 int i = 0;
226 int column_idx = 0;
227 auto const& columns = columns_layout_->GetChildren();
228-
229- for (auto const& category : model_->categories())
230+ auto const& categories = model_->categories();
231+ const int categories_per_column = model_->categories_per_column();
232+ const int columns_number = categories.size() / categories_per_column + 1;
233+ const int top_space = (23_em).CP(scale);
234+ const int bottom_space = (20_em).CP(scale);
235+ const int max_shortkeys_width = SHORTKEY_COLUMN_MAX_WIDTH.CP(scale);
236+ const int max_descriptions_width = DESCRIPTION_COLUMN_MAX_WIDTH.CP(scale);
237+
238+ shortkeys_.resize(columns_number);
239+ descriptions_.resize(columns_number);
240+
241+ for (auto const& category : categories)
242 {
243 // Computing column index based on current index
244- column_idx = i/model_->categories_per_column();
245+ column_idx = i/categories_per_column;
246
247 nux::LinearLayout* section_layout = CreateSectionLayout(category);
248 nux::LinearLayout* intermediate_layout = CreateIntermediateLayout();
249@@ -221,19 +278,27 @@
250
251 for (auto const& hint : model_->hints().at(category))
252 {
253- nux::View* view = CreateShortKeyEntryView(hint);
254+ StaticCairoText* shortkey = CreateShortcutTextView(hint->shortkey(), true);
255+ shortkey->SetMaximumWidth(max_shortkeys_width);
256+ shortkeys_[column_idx].push_back(shortkey);
257+
258+ StaticCairoText* description = CreateShortcutTextView(hint->description(), false);
259+ description->SetMaximumWidth(max_descriptions_width);
260+ descriptions_[column_idx].push_back(description);
261+
262+ nux::View* view = CreateShortKeyEntryView(hint, shortkey, description);
263 intermediate_layout->AddView(view, 0, nux::MINOR_POSITION_START, nux::MINOR_SIZE_FULL);
264 }
265
266 section_layout->AddLayout(intermediate_layout, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);
267
268- if ((i + 1) % model_->categories_per_column() != 0 && category != model_->categories().back())
269+ if ((i + 1) % categories_per_column != 0 && category != categories.back())
270 {
271 // Add a line with some padding after and before each category that is not
272 // the last of the column.
273- section_layout->AddView(new nux::SpaceLayout(23, 23, 23, 23), 0, nux::MINOR_POSITION_START, nux::MINOR_SIZE_MATCHCONTENT);
274+ section_layout->AddView(new nux::SpaceLayout(top_space, top_space, top_space, top_space), 0, nux::MINOR_POSITION_START, nux::MINOR_SIZE_MATCHCONTENT);
275 section_layout->AddView(new HSeparator(), 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);
276- section_layout->AddView(new nux::SpaceLayout(20, 20, 20, 20), 0, nux::MINOR_POSITION_START, nux::MINOR_SIZE_MATCHCONTENT);
277+ section_layout->AddView(new nux::SpaceLayout(bottom_space, bottom_space, bottom_space, bottom_space), 0, nux::MINOR_POSITION_START, nux::MINOR_SIZE_MATCHCONTENT);
278 }
279
280 nux::VLayout* column = nullptr;
281@@ -251,7 +316,7 @@
282
283 column->AddView(section_layout, 1, nux::MINOR_POSITION_START, nux::MINOR_SIZE_FULL);
284
285- i++;
286+ ++i;
287 }
288
289 ComputeContentSize();
290
291=== modified file 'shortcuts/ShortcutView.h'
292--- shortcuts/ShortcutView.h 2013-11-16 11:44:23 +0000
293+++ shortcuts/ShortcutView.h 2014-05-16 00:33:37 +0000
294@@ -29,6 +29,8 @@
295
296 namespace unity
297 {
298+class StaticCairoText;
299+
300 namespace shortcut
301 {
302
303@@ -47,8 +49,9 @@
304
305 protected:
306 // Protected methods
307- void DrawOverlay(nux::GraphicsEngine& GfxContext, bool force_draw, nux::Geometry const& clip);
308- nux::Geometry GetBackgroundGeometry();
309+ void DrawOverlay(nux::GraphicsEngine& GfxContext, bool force_draw, nux::Geometry const& clip) override;
310+ nux::Geometry GetBackgroundGeometry() override;
311+ void PreLayoutManagement() override;
312
313 // Introspectable methods
314 std::string GetName() const;
315@@ -56,7 +59,8 @@
316 private:
317 // Private methods
318 nux::LinearLayout* CreateSectionLayout(std::string const& section_name);
319- nux::View* CreateShortKeyEntryView(AbstractHint::Ptr const& hint);
320+ nux::View* CreateShortKeyEntryView(AbstractHint::Ptr const&, StaticCairoText* shortkey, StaticCairoText* description);
321+ StaticCairoText* CreateShortcutTextView(std::string const& text, bool bold);
322 nux::LinearLayout* CreateIntermediateLayout();
323
324 void RenderColumns();
325@@ -64,6 +68,8 @@
326 // Private members
327 Model::Ptr model_;
328 nux::HLayout* columns_layout_;
329+ std::vector<std::vector<StaticCairoText*>> shortkeys_;
330+ std::vector<std::vector<StaticCairoText*>> descriptions_;
331
332 friend class TestShortcutView;
333 };
334
335=== modified file 'tests/test_unity_window_view.cpp'
336--- tests/test_unity_window_view.cpp 2014-03-21 04:40:12 +0000
337+++ tests/test_unity_window_view.cpp 2014-05-16 00:33:37 +0000
338@@ -82,10 +82,10 @@
339 view.closable = true;
340 ASSERT_NE(view.close_button_, nullptr);
341
342- EXPECT_EQ(view.close_button_->texture(), view.style()->GetCloseIcon());
343+ EXPECT_EQ(view.close_button_->texture(), view.style()->GetTexture(view.scale, WindowTextureType::CLOSE_ICON));
344 EXPECT_EQ(view.close_button_->GetParentObject(), &view);
345
346- int padding = view.style()->GetCloseButtonPadding();
347+ int padding = view.style()->GetCloseButtonPadding(view.scale);
348 EXPECT_EQ(view.close_button_->GetBaseX(), padding);
349 EXPECT_EQ(view.close_button_->GetBaseY(), padding);
350 }
351@@ -96,16 +96,16 @@
352 ASSERT_NE(view.close_button_, nullptr);
353
354 view.close_button_->mouse_enter.emit(0, 0, 0, 0);
355- EXPECT_EQ(view.close_button_->texture(), view.style()->GetCloseIconHighligted());
356+ EXPECT_EQ(view.close_button_->texture(), view.style()->GetTexture(view.scale, WindowTextureType::CLOSE_ICON_HIGHLIGHTED));
357
358 view.close_button_->mouse_leave.emit(0, 0, 0, 0);
359- EXPECT_EQ(view.close_button_->texture(), view.style()->GetCloseIcon());
360+ EXPECT_EQ(view.close_button_->texture(), view.style()->GetTexture(view.scale, WindowTextureType::CLOSE_ICON));
361
362 view.close_button_->mouse_down.emit(0, 0, 0, 0);
363- EXPECT_EQ(view.close_button_->texture(), view.style()->GetCloseIconPressed());
364+ EXPECT_EQ(view.close_button_->texture(), view.style()->GetTexture(view.scale, WindowTextureType::CLOSE_ICON_PRESSED));
365
366 view.close_button_->mouse_up.emit(0, 0, 0, 0);
367- EXPECT_EQ(view.close_button_->texture(), view.style()->GetCloseIcon());
368+ EXPECT_EQ(view.close_button_->texture(), view.style()->GetTexture(view.scale, WindowTextureType::CLOSE_ICON));
369 }
370
371 TEST_F(TestUnityWindowView, CloseButtonClicksRequestsClose)
372@@ -185,7 +185,7 @@
373 view.SetLayout(layout);
374 view.ComputeContentSize();
375
376- int offset = view.style()->GetInternalOffset();
377+ int offset = view.style()->GetInternalOffset(view.scale);
378 EXPECT_EQ(layout->GetBaseX(), offset);
379 EXPECT_EQ(layout->GetBaseY(), offset);
380 }
381@@ -199,7 +199,7 @@
382
383 TEST_F(TestUnityWindowView, GetInternalBackground)
384 {
385- int offset = view.style()->GetInternalOffset();
386+ int offset = view.style()->GetInternalOffset(view.scale);
387 view.background_geo_.Set(g_random_int(), g_random_int(), g_random_int(), g_random_int());
388 EXPECT_EQ(view.GetInternalBackground(), view.background_geo_.GetExpand(-offset, -offset));
389 }
390@@ -240,4 +240,4 @@
391 }
392
393 } // ui
394-} // unity
395\ No newline at end of file
396+} // unity
397
398=== modified file 'unity-shared/UnityWindowStyle.cpp'
399--- unity-shared/UnityWindowStyle.cpp 2014-05-16 00:33:37 +0000
400+++ unity-shared/UnityWindowStyle.cpp 2014-05-16 00:33:37 +0000
401@@ -21,9 +21,13 @@
402
403 #include <NuxCore/Logger.h>
404
405+#include "UnitySettings.h"
406 #include "UnityWindowStyle.h"
407+#include "UScreen.h"
408 #include "config.h"
409
410+#include <unordered_set>
411+
412 namespace unity
413 {
414 namespace ui
415@@ -38,14 +42,31 @@
416 const char* const DIALOG_HIGHLIGHT = PKGDATADIR"/dialog_close_highlight.png";
417 const char* const DIALOG_PRESS = PKGDATADIR"/dialog_close_press.png";
418
419- double const DEFAULT_SCALE = 1.0;
420+
421+ RawPixel const INTERNAL_OFFSET = 20_em;
422+ RawPixel const BORDER_SIZE = 30_em;
423+ RawPixel const CLOSE_PADDING = 3_em;
424 }
425
426 DECLARE_LOGGER(logger, "unity.ui.unity.window.style");
427
428+
429 UnityWindowStyle::UnityWindowStyle()
430 {
431- LoadAllTextureInScale(DEFAULT_SCALE);
432+ unsigned monitors = UScreen::GetDefault()->GetPluggedMonitorsNumber();
433+ auto& settings = Settings::Instance();
434+
435+ // Pre-load scale values per monitor
436+ for (unsigned i = 0; i < monitors; ++i)
437+ {
438+ double scale = settings.Instance().em(i)->DPIScale();
439+
440+ if (unity_window_textures_.find(scale) == unity_window_textures_.end())
441+ LoadAllTextureInScale(scale);
442+ }
443+
444+ settings.Instance().dpi_changed.connect(sigc::mem_fun(this, &UnityWindowStyle::CleanUpUnusedTextures));
445+ UScreen::GetDefault()->changed.connect(sigc::mem_fun(this, &UnityWindowStyle::OnMonitorChanged));
446 }
447
448 void UnityWindowStyle::LoadAllTextureInScale(double scale)
449@@ -76,6 +97,35 @@
450 return max_size;
451 }
452
453+void UnityWindowStyle::OnMonitorChanged(int primary, std::vector<nux::Geometry> const& monitors)
454+{
455+ CleanUpUnusedTextures();
456+}
457+
458+// Get current in use scale values, if a scaled value is allocated, but
459+// not in use clean up the scaled textures in unity_window_textures
460+void UnityWindowStyle::CleanUpUnusedTextures()
461+{
462+ unsigned monitors = UScreen::GetDefault()->GetPluggedMonitorsNumber();
463+ auto& settings = Settings::Instance();
464+ std::unordered_set<double> used_scales;
465+
466+ for (unsigned i = 0; i < monitors; ++i)
467+ used_scales.insert(settings.em(i)->DPIScale());
468+
469+ for (auto it = unity_window_textures_.begin(); it != unity_window_textures_.end();)
470+ {
471+ if (used_scales.find(it->first) == used_scales.end())
472+ {
473+ it = unity_window_textures_.erase(it);
474+ }
475+ else
476+ {
477+ ++it;
478+ }
479+ }
480+}
481+
482 UnityWindowStyle::Ptr const& UnityWindowStyle::Get()
483 {
484 // This is set only the first time;
485@@ -83,19 +133,19 @@
486 return instance;
487 }
488
489-int UnityWindowStyle::GetBorderSize() const
490-{
491- return 30; // as measured from textures
492-}
493-
494-int UnityWindowStyle::GetInternalOffset() const
495-{
496- return 20;
497-}
498-
499-int UnityWindowStyle::GetCloseButtonPadding() const
500-{
501- return 3;
502+int UnityWindowStyle::GetBorderSize(double scale) const
503+{
504+ return BORDER_SIZE.CP(scale); // as measured from textures
505+}
506+
507+int UnityWindowStyle::GetInternalOffset(double scale) const
508+{
509+ return INTERNAL_OFFSET.CP(scale);
510+}
511+
512+int UnityWindowStyle::GetCloseButtonPadding(double scale) const
513+{
514+ return CLOSE_PADDING.CP(scale);
515 }
516
517 UnityWindowStyle::BaseTexturePtr UnityWindowStyle::GetTexture(double scale, WindowTextureType const& type)
518
519=== modified file 'unity-shared/UnityWindowStyle.h'
520--- unity-shared/UnityWindowStyle.h 2014-05-16 00:33:37 +0000
521+++ unity-shared/UnityWindowStyle.h 2014-05-16 00:33:37 +0000
522@@ -52,9 +52,9 @@
523 static UnityWindowStyle::Ptr const& Get();
524
525 BaseTexturePtr GetTexture(double scale, WindowTextureType const& type);
526- int GetCloseButtonPadding() const;
527- int GetBorderSize() const;
528- int GetInternalOffset() const;
529+ int GetCloseButtonPadding(double scale) const;
530+ int GetBorderSize(double scale) const;
531+ int GetInternalOffset(double scale) const;
532
533 private:
534 UnityWindowStyle();
535@@ -63,6 +63,9 @@
536 void LoadAllTextureInScale(double scale);
537 nux::BaseTexture* LoadTexture(double scale, const char* const texture_name) const;
538 RawPixel GetDefaultMaxTextureSize(const char* const texture_name) const;
539+
540+ void OnMonitorChanged(int primary, std::vector<nux::Geometry> const& monitors);
541+ void CleanUpUnusedTextures();
542
543 typedef std::array<BaseTexturePtr, size_t(WindowTextureType::Size)> UnityWindowTextures;
544 std::unordered_map<double, UnityWindowTextures> unity_window_textures_;
545
546=== modified file 'unity-shared/UnityWindowView.cpp'
547--- unity-shared/UnityWindowView.cpp 2014-05-16 00:33:37 +0000
548+++ unity-shared/UnityWindowView.cpp 2014-05-16 00:33:37 +0000
549@@ -70,7 +70,7 @@
550
551 if (internal_layout_)
552 {
553- int offset = RawPixel(style()->GetInternalOffset()).CP(scale);
554+ int offset = style()->GetInternalOffset(scale);
555 view_layout_->SetPadding(offset, offset);
556 }
557 }
558@@ -138,7 +138,7 @@
559 }
560
561 auto const& texture = style()->GetTexture(scale, WindowTextureType::CLOSE_ICON);
562- int padding = RawPixel(style()->GetCloseButtonPadding()).CP(scale);
563+ int padding = style()->GetCloseButtonPadding(scale);
564
565 close_button_ = new IconTexture(texture);
566 close_button_->SetBaseXY(padding, padding);
567@@ -179,7 +179,7 @@
568 {
569 if (layout && layout->IsLayout())
570 {
571- int offset = RawPixel(style()->GetInternalOffset()).CP(scale);
572+ int offset = style()->GetInternalOffset(scale);
573
574 // We wrap the internal layout adding some padding, so that inherited classes
575 // can ignore the offsets we define here.
576@@ -204,7 +204,8 @@
577
578 nux::Geometry UnityWindowView::GetInternalBackground()
579 {
580- int offset = RawPixel(style()->GetInternalOffset()).CP(scale);
581+ int offset = style()->GetInternalOffset(scale);
582+
583 return GetBackgroundGeometry().GetExpand(-offset, -offset);
584 }
585
586@@ -354,7 +355,8 @@
587
588 void UnityWindowView::DrawBackground(nux::GraphicsEngine& GfxContext, nux::Geometry const& geo)
589 {
590- int border = RawPixel(style()->GetBorderSize()).CP(scale);
591+ int border = style()->GetBorderSize(scale);
592+
593 auto background_corner_textrue = style()->GetTexture(scale, WindowTextureType::BACKGROUND_CORNER)->GetDeviceTexture();
594
595 GfxContext.GetRenderStates().SetBlend(true, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);