Merge lp:~mandel/unity/add-action-link into lp:unity

Proposed by Manuel de la Peña
Status: Merged
Approved by: Nick Dedekind
Approved revision: no longer in the source branch.
Merged at revision: 2949
Proposed branch: lp:~mandel/unity/add-action-link
Merge into: lp:unity
Prerequisite: lp:~mandel/unity/add-text-entry
Diff against target: 739 lines (+610/-2)
7 files modified
dash/previews/ActionLink.cpp (+248/-0)
dash/previews/ActionLink.h (+100/-0)
dash/previews/CMakeLists.txt (+1/-0)
tests/CMakeLists.txt (+1/-0)
tests/test_action_link.cpp (+188/-0)
unity-shared/StaticCairoText.cpp (+62/-2)
unity-shared/StaticCairoText.h (+10/-0)
To merge this branch: bzr merge lp:~mandel/unity/add-action-link
Reviewer Review Type Date Requested Status
Nick Dedekind (community) Approve
Marco Trevisan (Treviño) Approve
PS Jenkins bot continuous-integration Pending
Review via email: mp+130107@code.launchpad.net

Commit message

- Provide a re-usable UI element that looks and behaves like a url link (LP: #1067705).

Description of the change

- Provide a re-usable UI element that looks and behaves like a url link (LP: #1067705).

To post a comment you must log in.
Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

Firstly, you need to watch out when copying classes. You should do a full code check to make sure there is nothing left over that isn't used in the new class, and anything (defs/comment) that references the old class.

I don't think this belongs to the AbstractButton scope; it's more in the StaticCairoText area, seeing as that's all a link really is as far as I'm aware (a label which you can click). You can then put the mouse/keyboard activation into the overriding class.

Other than that, here are a few code comments.

34 +namespace
35 +{
36 +
37 +
38 +nux::logging::Logger logger("unity.dash.actionlink");
39 +}

remove extra white-space

99 +void ActionLink::BuildLayout(std::string const& label, std::string const& extra_hint)

no extra_hint in an action link.

94 + cr_normal_.reset(new nux::CairoWrapper(geo,
95 + [](nux::Geometry const& geom, cairo_t* cr) {}));

You're not using the texture, so remove it from the class/drawing. (left over from ActionButton)

Underline: Can you not use font/markup to do the underlining instead of a fairly hacky hseparator?

review: Needs Fixing
Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

apon furthur inspection, looks OK to leave it as a button.
Thought there was a bit more to a abstract button than there is.

Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

Please, add tests too.

Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

56 +ActionLink::~ActionLink()
57 +{
58 +}

Get rid of it

Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

Please get rid of the magic numbers in GetLinkAlpha replacing them with const values into an anonymous namespace, however that's globally nice, thanks! ;)

review: Approve
Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

50 + SetAcceptKeyNavFocusOnMouseDown(false);
51 + SetAcceptKeyNavFocusOnMouseEnter(true);

Since you have an Init function, you should put these in there.

73 + SetMinimumHeight(40);

MAGIC. Is there a reason you need a minimum height and are not just using the layout's height calculated from the contents? If you do need it, use a const in anon namespace.

105 + static_text_->SetTextAlignment(nux::StaticCairoText::NUX_ALIGN_CENTRE);
106 + static_text_->SetUnderline(nux::StaticCairoText::NUX_UNDERLINE_SINGLE)

Since this is a general control these should be options on the action link, which are defaulted to these values. (SetTextAlignment/SetTextUnderline)

139 + if (cached_geometry_ != geo && geo.width > 0 && geo.height > 0)
140 + {
141 + cached_geometry_ = geo;
142 + }

There doesn't seem to be a purpose for the geometry caching that I can see, in which case you should be able to remove the ComputeContentSize override.

179 + nux::Geometry clip_geo = geo;

No need to make a copy of the geometry ref unless you're modifying it.

review: Needs Fixing
Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

LGTM.
All tests run successfully.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file 'dash/previews/ActionLink.cpp'
--- dash/previews/ActionLink.cpp 1970-01-01 00:00:00 +0000
+++ dash/previews/ActionLink.cpp 2012-11-28 10:01:36 +0000
@@ -0,0 +1,248 @@
1/*
2 * Copyright 2012 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License version 3, as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranties of
10 * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
11 * PURPOSE. See the applicable version of the GNU Lesser General Public
12 * License for more details.
13 *
14 * You should have received a copy of both the GNU Lesser General Public
15 * License version 3 along with this program. If not, see
16 * <http://www.gnu.org/licenses/>
17 *
18 * Authored by: Manuel de la Pena <manuel.delapena@canonical.com>
19 *
20 */
21
22#include "ActionLink.h"
23#include <NuxCore/Logger.h>
24#include <Nux/VLayout.h>
25#include <UnityCore/Variant.h>
26#include "unity-shared/DashStyle.h"
27#include "unity-shared/IconTexture.h"
28#include "unity-shared/StaticCairoText.h"
29
30namespace
31{
32nux::logging::Logger logger("unity.dash.actionlink");
33const double LINK_NORMAL_ALPHA_VALUE = 4;
34const double LINK_HIGHLIGHTED_ALPHA_VALUE = 1;
35}
36
37namespace unity
38{
39namespace dash
40{
41
42ActionLink::ActionLink(std::string const& action_hint, std::string const& label, NUX_FILE_LINE_DECL)
43 : nux::AbstractButton(NUX_FILE_LINE_PARAM)
44 , action_hint_(action_hint)
45 , aligment_(nux::StaticCairoText::NUX_ALIGN_CENTRE)
46 , underline_(nux::StaticCairoText::NUX_UNDERLINE_SINGLE)
47{
48 Init();
49 BuildLayout(label);
50}
51
52std::string ActionLink::GetName() const
53{
54 return "ActionLink";
55}
56
57void ActionLink::AddProperties(GVariantBuilder* builder)
58{
59 variant::BuilderWrapper(builder)
60 .add(GetAbsoluteGeometry())
61 .add("action", action_hint_)
62 .add("label", label_)
63 .add("font-hint", font_hint)
64 .add("active", active_)
65 .add("text-aligment", text_aligment)
66 .add("underline-state", underline_state);
67}
68
69void ActionLink::Init()
70{
71 SetAcceptKeyNavFocusOnMouseDown(false);
72 SetAcceptKeyNavFocusOnMouseEnter(true);
73
74 // set properties to ensure that we do redraw when one of them changes
75 text_aligment.SetSetterFunction(sigc::mem_fun(this, &ActionLink::set_aligment));
76 text_aligment.SetGetterFunction(sigc::mem_fun(this, &ActionLink::get_aligment));
77
78 underline_state.SetSetterFunction(sigc::mem_fun(this, &ActionLink::set_underline));
79 underline_state.SetGetterFunction(sigc::mem_fun(this, &ActionLink::get_underline));
80
81 font_hint.SetSetterFunction(sigc::mem_fun(this, &ActionLink::set_font_hint));
82 font_hint.SetGetterFunction(sigc::mem_fun(this, &ActionLink::get_font_hint));
83
84 key_nav_focus_change.connect([&] (nux::Area*, bool, nux::KeyNavDirection)
85 {
86 QueueDraw();
87 });
88
89 key_nav_focus_activate.connect([&](nux::Area*)
90 {
91 if (GetInputEventSensitivity())
92 activate.emit(this, action_hint_);
93 });
94}
95
96void ActionLink::BuildLayout(std::string const& label)
97{
98
99 if (label != label_)
100 {
101 label_ = label;
102 if (static_text_)
103 {
104 static_text_.Release();
105 static_text_ = NULL;
106 }
107
108 if (!label_.empty())
109 {
110 static_text_ = new nux::StaticCairoText(label_, true, NUX_TRACKER_LOCATION);
111 if (!font_hint_.empty())
112 static_text_->SetFont(font_hint_);
113 static_text_->SetInputEventSensitivity(false);
114 static_text_->SetTextAlignment(aligment_);
115 static_text_->SetUnderline(underline_);
116 }
117 }
118
119 RemoveLayout();
120
121 nux::VLayout* layout = new nux::VLayout();
122 if (static_text_)
123 {
124 layout->AddView(static_text_.GetPointer(),
125 1, nux::MINOR_POSITION_START, nux::MINOR_SIZE_FULL,
126 100.0f, nux::NUX_LAYOUT_END);
127 }
128 SetLayout(layout);
129
130 ComputeContentSize();
131 QueueDraw();
132}
133
134int ActionLink::GetLinkAlpha(nux::ButtonVisualState state)
135{
136 if (state == nux::ButtonVisualState::VISUAL_STATE_PRELIGHT)
137 return LINK_HIGHLIGHTED_ALPHA_VALUE;
138 else
139 return LINK_NORMAL_ALPHA_VALUE;
140}
141
142void ActionLink::Draw(nux::GraphicsEngine& GfxContext, bool force_draw)
143{
144 nux::Geometry const& geo = GetGeometry();
145
146 gPainter.PaintBackground(GfxContext, geo);
147 // set up our texture mode
148 nux::TexCoordXForm texxform;
149 texxform.SetWrap(nux::TEXWRAP_REPEAT, nux::TEXWRAP_REPEAT);
150 texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);
151
152 // clear what is behind us
153 unsigned int alpha = 0, src = 0, dest = 0;
154
155 // set the alpha of the text according to its state
156 static_text_->SetTextAlpha(GetLinkAlpha(GetVisualState()));
157
158 GfxContext.GetRenderStates().GetBlend(alpha, src, dest);
159 GfxContext.GetRenderStates().SetBlend(true, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
160
161 nux::Color col = nux::color::Black;
162 col.alpha = 0;
163 GfxContext.QRP_Color(geo.x,
164 geo.y,
165 geo.width,
166 geo.height,
167 col);
168
169 GfxContext.GetRenderStates().SetBlend(alpha, src, dest);
170
171 if (GetCompositionLayout())
172 {
173 gPainter.PushPaintLayerStack();
174 {
175
176 GfxContext.PushClippingRectangle(geo);
177 gPainter.PushPaintLayerStack();
178 GetCompositionLayout()->ProcessDraw(GfxContext, force_draw);
179 gPainter.PopPaintLayerStack();
180 GfxContext.PopClippingRectangle();
181 }
182 gPainter.PopPaintLayerStack();
183 }
184}
185
186void ActionLink::RecvClick(int x, int y, unsigned long button_flags, unsigned long key_flags)
187{
188 activate.emit(this, action_hint_);
189}
190
191bool ActionLink::set_aligment(nux::StaticCairoText::AlignState aligment)
192{
193 if(static_text_ && aligment_ != aligment)
194 {
195 static_text_->SetTextAlignment(aligment_);
196 aligment_ = aligment;
197 ComputeContentSize();
198 QueueDraw();
199 }
200 return true;
201}
202
203nux::StaticCairoText::AlignState ActionLink::get_aligment()
204{
205 return aligment_;
206}
207
208bool ActionLink::set_underline(nux::StaticCairoText::UnderlineState underline)
209{
210 if(static_text_ && underline_ != underline)
211 {
212 static_text_->SetUnderline(underline_);
213 underline_ = underline;
214 ComputeContentSize();
215 QueueDraw();
216 }
217 return true;
218}
219
220nux::StaticCairoText::UnderlineState ActionLink::get_underline()
221{
222 return underline_;
223}
224
225bool ActionLink::set_font_hint(std::string font_hint)
226{
227 if(static_text_ && font_hint_ != font_hint)
228 {
229 static_text_->SetFont(font_hint_);
230 font_hint_ = font_hint;
231 ComputeContentSize();
232 QueueDraw();
233 }
234 return true;
235}
236
237std::string ActionLink::get_font_hint()
238{
239 return font_hint_;
240}
241
242std::string ActionLink::GetLabel() const
243{
244 return label_;
245}
246
247} // namespace dash
248} // namespace unity
0249
=== added file 'dash/previews/ActionLink.h'
--- dash/previews/ActionLink.h 1970-01-01 00:00:00 +0000
+++ dash/previews/ActionLink.h 2012-11-28 10:01:36 +0000
@@ -0,0 +1,100 @@
1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2/*
3 * Copyright 2012 Canonical Ltd.
4 *
5 * This program is free software: you can redistribute it and/or modify it
6 * under the terms of the GNU Lesser General Public License version 3, as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranties of
11 * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
12 * PURPOSE. See the applicable version of the GNU Lesser General Public
13 * License for more details.
14 *
15 * You should have received a copy of both the GNU Lesser General Public
16 * License version 3 along with this program. If not, see
17 * <http://www.gnu.org/licenses/>
18 *
19 * Authored by: Manuel de la Pena <manuel.delapena@canonical.com>
20 *
21 */
22
23#ifndef ACTIONLINK_H
24#define ACTIONLINK_H
25
26#include <Nux/Nux.h>
27#include <Nux/CairoWrapper.h>
28#include <Nux/AbstractButton.h>
29#include "unity-shared/Introspectable.h"
30#include "unity-shared/StaticCairoText.h"
31
32
33namespace unity
34{
35class IconTexture;
36
37namespace dash
38{
39
40class ActionLink : public nux::AbstractButton, public debug::Introspectable
41{
42public:
43 ActionLink(std::string const& action_hint, std::string const& label, NUX_FILE_LINE_PROTO);
44
45 sigc::signal<void, ActionLink*, std::string const&> activate;
46
47 nux::RWProperty<nux::StaticCairoText::AlignState> text_aligment;
48 nux::RWProperty<nux::StaticCairoText::UnderlineState> underline_state;
49 nux::RWProperty<std::string> font_hint;
50
51 void Activate() {}
52 void Deactivate() {}
53
54 virtual bool AcceptKeyNavFocus() const { return true; }
55
56 std::string GetLabel() const;
57 std::string GetExtraText() const;
58
59protected:
60 nux::ObjectPtr<nux::StaticCairoText> static_text_;
61
62 int GetLinkAlpha(nux::ButtonVisualState state);
63
64 void Draw(nux::GraphicsEngine& GfxContext, bool force_draw);
65 void DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw) {}
66 void RecvClick(int x, int y, unsigned long button_flags, unsigned long key_flags);
67
68 void Init();
69
70 void BuildLayout(std::string const& label);
71
72 // From debug::Introspectable
73 std::string GetName() const;
74 void AddProperties(GVariantBuilder* builder);
75
76 // this methods/vars could be private but are protected to make testing
77 // easier
78 bool set_aligment(nux::StaticCairoText::AlignState aligment);
79 nux::StaticCairoText::AlignState get_aligment();
80
81 bool set_underline(nux::StaticCairoText::UnderlineState underline);
82 nux::StaticCairoText::UnderlineState get_underline();
83
84 bool set_font_hint(std::string font_hint);
85 std::string get_font_hint();
86
87 std::string action_hint_;
88 std::string font_hint_;
89 nux::StaticCairoText::AlignState aligment_;
90 nux::StaticCairoText::UnderlineState underline_;
91private:
92 typedef std::unique_ptr<nux::CairoWrapper> NuxCairoPtr;
93
94
95};
96
97} // namespace dash
98} // namespace unity
99
100#endif // ACTIONLINK_H
0101
=== modified file 'dash/previews/CMakeLists.txt'
--- dash/previews/CMakeLists.txt 2012-11-26 16:09:53 +0000
+++ dash/previews/CMakeLists.txt 2012-11-28 10:01:36 +0000
@@ -26,6 +26,7 @@
26#26#
27set (PREVIEWS_SOURCES27set (PREVIEWS_SOURCES
28 ActionButton.cpp28 ActionButton.cpp
29 ActionLink.cpp
29 ApplicationPreview.cpp30 ApplicationPreview.cpp
30 GenericPreview.cpp31 GenericPreview.cpp
31 MusicPreview.cpp32 MusicPreview.cpp
3233
=== modified file 'tests/CMakeLists.txt'
--- tests/CMakeLists.txt 2012-11-24 15:34:32 +0000
+++ tests/CMakeLists.txt 2012-11-28 10:01:36 +0000
@@ -206,6 +206,7 @@
206# Tests that require X206# Tests that require X
207 add_executable(test-gtest207 add_executable(test-gtest
208 test_main.cpp208 test_main.cpp
209 test_action_link.cpp
209 test_application_launcher_icon.cpp210 test_application_launcher_icon.cpp
210 test_bfb_launcher_icon.cpp211 test_bfb_launcher_icon.cpp
211 test_dashview_impl.cpp212 test_dashview_impl.cpp
212213
=== added file 'tests/test_action_link.cpp'
--- tests/test_action_link.cpp 1970-01-01 00:00:00 +0000
+++ tests/test_action_link.cpp 2012-11-28 10:01:36 +0000
@@ -0,0 +1,188 @@
1/*
2 * Copyright 2012 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License version 3, as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranties of
10 * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
11 * PURPOSE. See the applicable version of the GNU Lesser General Public
12 * License for more details.
13 *
14 * You should have received a copy of both the GNU Lesser General Public
15 * License version 3 along with this program. If not, see
16 * <http://www.gnu.org/licenses/>
17 *
18 * Authored by: Manuel de la Pena <manuel.delapena@canonical.com>
19 *
20 */
21
22#include <gmock/gmock.h>
23#include <gtest/gtest.h>
24
25#include <unity-shared/StaticCairoText.h>
26
27#include "dash/previews/ActionLink.cpp"
28#include "test_utils.h"
29
30using namespace nux;
31using namespace unity;
32using namespace unity::dash;
33
34namespace unity
35{
36
37namespace dash
38{
39
40class ActionLinkMock : public ActionLink
41{
42 public:
43 MOCK_METHOD0(QueueDraw, void());
44 MOCK_METHOD0(ComputeContentSize, long());
45 MOCK_METHOD2(CalculateBar, void(nux::GraphicsEngine&, bool));
46
47 ActionLinkMock(std::string const& action_hint, std::string const& label, NUX_FILE_LINE_PROTO)
48 : ActionLink(action_hint, label){}
49 ~ActionLinkMock(){}
50
51 nux::ObjectPtr<nux::StaticCairoText> GetText() { return static_text_; }
52
53 using ActionLink::GetLinkAlpha;
54 using ActionLink::Draw;
55 using ActionLink::DrawContent;
56 using ActionLink::RecvClick;
57 using ActionLink::GetName;
58 using ActionLink::AddProperties;
59 using ActionLink::set_aligment;
60 using ActionLink::get_aligment;
61 using ActionLink::set_underline;
62 using ActionLink::get_underline;
63 using ActionLink::set_font_hint;
64 using ActionLink::get_font_hint;
65 using ActionLink::action_hint_;
66 using ActionLink::font_hint_;
67 using ActionLink::aligment_;
68 using ActionLink::underline_;
69};
70
71class TestActionLink : public ::testing::Test
72{
73 protected:
74 TestActionLink() : Test()
75 {
76 action_link = new ActionLinkMock("action_id", "display_name");
77 }
78 nux::ObjectPtr<ActionLinkMock> action_link;
79};
80
81TEST_F(TestActionLink, AligmentCorrectlySetDifferent)
82{
83 ActionLinkMock link("test", "test");
84
85 EXPECT_CALL(link, ComputeContentSize()).Times(1);
86 EXPECT_CALL(link, QueueDraw()).Times(1);
87
88 link.text_aligment.Set(nux::StaticCairoText::NUX_ALIGN_RIGHT);
89}
90
91TEST_F(TestActionLink, AligmentCorrectlySetSame)
92{
93 ActionLinkMock link("test", "test");
94
95 EXPECT_CALL(link, ComputeContentSize()).Times(0);
96 EXPECT_CALL(link, QueueDraw()).Times(0);
97
98 link.text_aligment.Set(link.text_aligment.Get());
99}
100
101TEST_F(TestActionLink, AligmentCorrectlyRetrieved)
102{
103 nux::StaticCairoText::AlignState aligment =
104 nux::StaticCairoText::NUX_ALIGN_RIGHT;
105 action_link->aligment_ = aligment;
106 EXPECT_EQ(aligment, action_link->text_aligment.Get());
107}
108
109TEST_F(TestActionLink, UnderlineCorrectlySetDifferent)
110{
111 ActionLinkMock link("test", "test");
112
113 EXPECT_CALL(link, ComputeContentSize()).Times(1);
114 EXPECT_CALL(link, QueueDraw()).Times(1);
115 link.underline_state.Set(nux::StaticCairoText::NUX_UNDERLINE_NONE);
116}
117
118TEST_F(TestActionLink, UnderlineCorrectlySetSame)
119{
120 ActionLinkMock link("test", "test");
121
122 EXPECT_CALL(link, ComputeContentSize()).Times(0);
123 EXPECT_CALL(link, QueueDraw()).Times(0);
124 link.underline_state.Set(link.underline_state.Get());
125}
126
127TEST_F(TestActionLink, UnderlineCorrectlyRetrieved)
128{
129 nux::StaticCairoText::UnderlineState underline =
130 nux::StaticCairoText::NUX_UNDERLINE_DOUBLE;
131 action_link->underline_ = underline;
132 EXPECT_EQ(underline, action_link->underline_state.Get());
133}
134
135TEST_F(TestActionLink, FontCorrectlySetDifferent)
136{
137 ActionLinkMock link("test", "test");
138 link.font_hint_ = "Ubuntu 10";
139
140 EXPECT_CALL(link, ComputeContentSize()).Times(1);
141 EXPECT_CALL(link, QueueDraw()).Times(1);
142 link.font_hint.Set("Ubuntu 11");
143}
144
145TEST_F(TestActionLink, FontCorrectlySetSame)
146{
147 ActionLinkMock link("test", "test");
148 link.font_hint_ = "Ubuntu 10";
149
150 EXPECT_CALL(link, ComputeContentSize()).Times(0);
151 EXPECT_CALL(link, QueueDraw()).Times(0);
152 link.font_hint.Set(link.font_hint.Get());
153}
154
155TEST_F(TestActionLink, FontCorrectlyRetrieved)
156{
157 std::string font_hint = "Ubuntu 11";
158 action_link->font_hint_ = font_hint;
159 EXPECT_EQ(font_hint, action_link->font_hint.Get());
160}
161
162TEST_F(TestActionLink, LinkAlphaOnPressed)
163{
164 ButtonVisualState state = ButtonVisualState::VISUAL_STATE_PRESSED;
165 EXPECT_EQ(4, action_link->GetLinkAlpha(state));
166}
167
168TEST_F(TestActionLink, LinkAlphaOnNormal)
169{
170 ButtonVisualState state = ButtonVisualState::VISUAL_STATE_NORMAL;
171 EXPECT_EQ(4, action_link->GetLinkAlpha(state));
172}
173
174TEST_F(TestActionLink, LinkAlphaOnPrelight)
175{
176 ButtonVisualState state = ButtonVisualState::VISUAL_STATE_PRELIGHT;
177 EXPECT_EQ(1, action_link->GetLinkAlpha(state));
178}
179
180TEST_F(TestActionLink, LinkAlphaOnDisabled)
181{
182 ButtonVisualState state = ButtonVisualState::VISUAL_STATE_DISABLED;
183 EXPECT_EQ(4, action_link->GetLinkAlpha(state));
184}
185
186}
187
188}
0189
=== modified file 'unity-shared/StaticCairoText.cpp'
--- unity-shared/StaticCairoText.cpp 2012-11-22 10:46:13 +0000
+++ unity-shared/StaticCairoText.cpp 2012-11-28 10:01:36 +0000
@@ -54,6 +54,7 @@
54 std::string GetEffectiveFont() const;54 std::string GetEffectiveFont() const;
55 Size GetTextExtents() const;55 Size GetTextExtents() const;
5656
57 void SetAttributes(PangoLayout* layout);
57 void DrawText(cairo_t* cr, int width, int height, int line_spacing, Color const& color);58 void DrawText(cairo_t* cr, int width, int height, int line_spacing, Color const& color);
5859
59 void UpdateTexture();60 void UpdateTexture();
@@ -75,6 +76,7 @@
75 EllipsizeState ellipsize_;76 EllipsizeState ellipsize_;
76 AlignState align_;77 AlignState align_;
77 AlignState valign_;78 AlignState valign_;
79 UnderlineState underline_;
7880
79 std::string font_;81 std::string font_;
8082
@@ -97,6 +99,7 @@
97 , ellipsize_(NUX_ELLIPSIZE_END)99 , ellipsize_(NUX_ELLIPSIZE_END)
98 , align_(NUX_ALIGN_LEFT)100 , align_(NUX_ALIGN_LEFT)
99 , valign_(NUX_ALIGN_TOP)101 , valign_(NUX_ALIGN_TOP)
102 , underline_(NUX_UNDERLINE_NONE)
100 , lines_(-2) // should find out why -2...103 , lines_(-2) // should find out why -2...
101 // the desired height of the layout in Pango units if positive, or desired104 // the desired height of the layout in Pango units if positive, or desired
102 // number of lines if negative.105 // number of lines if negative.
@@ -312,6 +315,16 @@
312 }315 }
313}316}
314317
318void StaticCairoText::SetTextAlpha(unsigned int alpha)
319{
320 if (pimpl->text_color_.alpha != alpha)
321 {
322 pimpl->text_color_.alpha = alpha;
323 pimpl->UpdateTexture();
324 QueueDraw();
325 }
326}
327
315void StaticCairoText::SetMaximumSize(int w, int h)328void StaticCairoText::SetMaximumSize(int w, int h)
316{329{
317 if (w != GetMaximumWidth())330 if (w != GetMaximumWidth())
@@ -320,7 +333,7 @@
320 View::SetMaximumSize(w, h);333 View::SetMaximumSize(w, h);
321 pimpl->UpdateTexture();334 pimpl->UpdateTexture();
322 return;335 return;
323 } 336 }
324337
325 View::SetMaximumSize(w, h);338 View::SetMaximumSize(w, h);
326}339}
@@ -380,6 +393,18 @@
380 return pimpl->font_;393 return pimpl->font_;
381}394}
382395
396void StaticCairoText::SetUnderline(UnderlineState underline)
397{
398 if (pimpl->underline_ != underline)
399 {
400 pimpl->underline_ = underline;
401 pimpl->need_new_extent_cache_ = true;
402 Size s = GetTextExtents();
403 SetMinimumHeight(s.height);
404 NeedRedraw();
405 }
406}
407
383int StaticCairoText::GetLineCount() const408int StaticCairoText::GetLineCount() const
384{409{
385 return pimpl->actual_lines_;410 return pimpl->actual_lines_;
@@ -489,6 +514,37 @@
489 return result;514 return result;
490}515}
491516
517void StaticCairoText::Impl::SetAttributes(PangoLayout *layout)
518{
519 PangoAttrList* attr_list = NULL;
520 PangoAttribute* underline_attr = NULL;
521
522 attr_list = pango_layout_get_attributes(layout);
523 if(!attr_list)
524 {
525 attr_list = pango_attr_list_new();
526 }
527
528 PangoUnderline underline_type;
529
530 switch(underline_){
531 case(NUX_UNDERLINE_SINGLE):
532 underline_type = PANGO_UNDERLINE_SINGLE;
533 break;
534 case(NUX_UNDERLINE_DOUBLE):
535 underline_type = PANGO_UNDERLINE_DOUBLE;
536 break;
537 case(NUX_UNDERLINE_LOW):
538 underline_type = PANGO_UNDERLINE_LOW;
539 break;
540 default:
541 underline_type = PANGO_UNDERLINE_NONE;
542 }
543 underline_attr = pango_attr_underline_new(underline_type);
544 pango_attr_list_insert(attr_list, underline_attr);
545 pango_layout_set_attributes(layout, attr_list);
546}
547
492void StaticCairoText::Impl::DrawText(cairo_t* cr,548void StaticCairoText::Impl::DrawText(cairo_t* cr,
493 int width,549 int width,
494 int height,550 int height,
@@ -506,8 +562,9 @@
506562
507 cairo_set_font_options(cr, gdk_screen_get_font_options(screen));563 cairo_set_font_options(cr, gdk_screen_get_font_options(screen));
508 layout = pango_cairo_create_layout(cr);564 layout = pango_cairo_create_layout(cr);
565
566
509 desc = pango_font_description_from_string(font.c_str());567 desc = pango_font_description_from_string(font.c_str());
510
511 pango_layout_set_font_description(layout, desc);568 pango_layout_set_font_description(layout, desc);
512 pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);569 pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
513 pango_layout_set_ellipsize(layout, GetPangoEllipsizeMode());570 pango_layout_set_ellipsize(layout, GetPangoEllipsizeMode());
@@ -518,6 +575,9 @@
518 pango_layout_set_spacing(layout, line_spacing * PANGO_SCALE);575 pango_layout_set_spacing(layout, line_spacing * PANGO_SCALE);
519576
520 pango_layout_set_height(layout, lines_);577 pango_layout_set_height(layout, lines_);
578
579 SetAttributes(layout);
580
521 pangoCtx = pango_layout_get_context(layout); // is not ref'ed581 pangoCtx = pango_layout_get_context(layout); // is not ref'ed
522 pango_cairo_context_set_font_options(pangoCtx,582 pango_cairo_context_set_font_options(pangoCtx,
523 gdk_screen_get_font_options(screen));583 gdk_screen_get_font_options(screen));
524584
=== modified file 'unity-shared/StaticCairoText.h'
--- unity-shared/StaticCairoText.h 2012-11-22 10:46:13 +0000
+++ unity-shared/StaticCairoText.h 2012-11-28 10:01:36 +0000
@@ -51,6 +51,14 @@
51 NUX_ALIGN_BOTTOM = NUX_ALIGN_RIGHT51 NUX_ALIGN_BOTTOM = NUX_ALIGN_RIGHT
52 };52 };
5353
54 enum UnderlineState
55 {
56 NUX_UNDERLINE_NONE,
57 NUX_UNDERLINE_SINGLE,
58 NUX_UNDERLINE_DOUBLE,
59 NUX_UNDERLINE_LOW
60 };
61
54 StaticCairoText(std::string const& text, NUX_FILE_LINE_PROTO);62 StaticCairoText(std::string const& text, NUX_FILE_LINE_PROTO);
55 StaticCairoText(std::string const& text, bool escape_text, NUX_FILE_LINE_PROTO);63 StaticCairoText(std::string const& text, bool escape_text, NUX_FILE_LINE_PROTO);
56 ~StaticCairoText();64 ~StaticCairoText();
@@ -67,12 +75,14 @@
6775
68 // public API76 // public API
69 void SetText(std::string const& text, bool escape_text = false);77 void SetText(std::string const& text, bool escape_text = false);
78 void SetTextAlpha(unsigned int alpha);
70 void SetTextColor(Color const& textColor);79 void SetTextColor(Color const& textColor);
71 void SetTextEllipsize(EllipsizeState state);80 void SetTextEllipsize(EllipsizeState state);
72 void SetTextAlignment(AlignState state);81 void SetTextAlignment(AlignState state);
73 void SetTextVerticalAlignment(AlignState state);82 void SetTextVerticalAlignment(AlignState state);
74 void SetFont(std::string const& font);83 void SetFont(std::string const& font);
75 std::string GetFont();84 std::string GetFont();
85 void SetUnderline(UnderlineState underline);
76 void SetLines(int maximum_lines);86 void SetLines(int maximum_lines);
77 void SetLineSpacing(float line_spacing);87 void SetLineSpacing(float line_spacing);
7888