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

Proposed by Marco Trevisan (Treviño) on 2014-05-16
Status: Merged
Approved by: Andrea Azzarone on 2014-05-16
Approved revision: 3809
Merged at revision: 3816
Proposed branch: lp:~3v1n0/unity/shortcuts-hidpi
Merge into: lp:unity
Prerequisite: lp:~brandontschaefer/unity/shutdown-dialog-hi-dpi
Diff against target: 333 lines (+123/-52)
3 files modified
shortcuts/ShortcutController.cpp (+1/-1)
shortcuts/ShortcutView.cpp (+113/-48)
shortcuts/ShortcutView.h (+9/-3)
To merge this branch: bzr merge lp:~3v1n0/unity/shortcuts-hidpi
Reviewer Review Type Date Requested Status
Andrea Azzarone (community) 2014-05-16 Approve on 2014-05-16
PS Jenkins bot continuous-integration 2014-05-16 Pending
Review via email: mp+219771@code.launchpad.net

This proposal supersedes a proposal from 2014-05-08.

Commit message

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

Plus dinamically allocate horizontal space, not to cut the text.

To post a comment you must log in.
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Andrea Azzarone (azzar1) wrote : Posted in a previous version of this proposal
review: Needs Fixing
Marco Trevisan (Treviño) (3v1n0) wrote : Posted in a previous version of this proposal

> 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.

PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Andrea Azzarone (azzar1) wrote :

LGTM.

review: Approve

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:35:23 +0000
3+++ shortcuts/ShortcutController.cpp 2014-05-16 00:35:23 +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:35:23 +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:35:23 +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 };