Merge lp:~agateau/unity-2d/use-gtk-rendering into lp:unity-2d/3.0
- use-gtk-rendering
- Merge into natty
Status: | Superseded |
---|---|
Proposed branch: | lp:~agateau/unity-2d/use-gtk-rendering |
Merge into: | lp:unity-2d/3.0 |
Prerequisite: | lp:~agateau/unity-2d/unity-core |
Diff against target: |
1345 lines (+523/-434) 16 files modified
CMakeLists.txt (+1/-0) libunity-2d-private/src/CMakeLists.txt (+4/-0) libunity-2d-private/src/unity2dapplication.cpp (+49/-1) libunity-2d-private/src/unity2dapplication.h (+3/-0) panel/applets/CMakeLists.txt (+4/-0) panel/applets/appname/appnameapplet.cpp (+2/-47) panel/applets/appname/croppedlabel.cpp (+140/-0) panel/applets/appname/croppedlabel.h (+45/-0) panel/applets/common/cairoutils.cpp (+42/-0) panel/applets/common/cairoutils.h (+47/-0) panel/applets/common/fakecairo.h (+0/-125) panel/applets/common/indicatorentrywidget.cpp (+135/-157) panel/applets/common/indicatorentrywidget.h (+10/-1) panel/applets/common/panelstyle.cpp (+30/-91) panel/applets/common/panelstyle.h (+7/-10) panel/applets/homebutton/homebutton.cpp (+4/-2) |
To merge this branch: | bzr merge lp:~agateau/unity-2d/use-gtk-rendering |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Florian Boucault | Pending | ||
Review via email: mp+69113@code.launchpad.net |
This proposal has been superseded by a proposal from 2011-07-27.
Commit message
[panel] Use GTK3 primitives to draw labels and panel menubar item background
Description of the change
This branch uses GTK3 primitives to draw labels and active menubar item background instead of the Cairo code which was copied from unity-3d.
- 695. By Aurélien Gâteau
-
Sync with unity-core
- 696. By Aurélien Gâteau
-
Sync with unity-core
- 697. By Aurélien Gâteau
-
[platform] Move all font handling from PanelStyle to Unity2dApplication
- 698. By Aurélien Gâteau
-
[panel] Fix home button active background
Do not use bfb_bg_active.png: it only works with Ambiance theme
- 699. By Aurélien Gâteau
-
Sync with unity-core
Unmerged revisions
- 699. By Aurélien Gâteau
-
Sync with unity-core
- 698. By Aurélien Gâteau
-
[panel] Fix home button active background
Do not use bfb_bg_active.png: it only works with Ambiance theme
- 697. By Aurélien Gâteau
-
[platform] Move all font handling from PanelStyle to Unity2dApplication
- 696. By Aurélien Gâteau
-
Sync with unity-core
- 695. By Aurélien Gâteau
-
Sync with unity-core
- 694. By Aurélien Gâteau
-
Synced with unity-core branch
- 693. By Aurélien Gâteau
-
#define => static const char*
- 692. By Aurélien Gâteau
-
[panel] Cleanup, simplify, comment text drawing code
- 691. By Aurélien Gâteau
-
[panel] Crude port of Unity label drawing code
- 690. By Aurélien Gâteau
-
[panel] Move qtgconf test up so that it can be used in panel
Preview Diff
1 | === modified file 'CMakeLists.txt' | |||
2 | --- CMakeLists.txt 2011-07-27 15:41:41 +0000 | |||
3 | +++ CMakeLists.txt 2011-07-27 15:41:41 +0000 | |||
4 | @@ -29,6 +29,7 @@ | |||
5 | 29 | pkg_check_modules(GTK REQUIRED gtk+-3.0) | 29 | pkg_check_modules(GTK REQUIRED gtk+-3.0) |
6 | 30 | pkg_check_modules(GIO REQUIRED gio-2.0) | 30 | pkg_check_modules(GIO REQUIRED gio-2.0) |
7 | 31 | pkg_check_modules(WNCK REQUIRED libwnck-3.0) | 31 | pkg_check_modules(WNCK REQUIRED libwnck-3.0) |
8 | 32 | pkg_check_modules(QTGCONF REQUIRED libqtgconf) | ||
9 | 32 | 33 | ||
10 | 33 | 34 | ||
11 | 34 | # GSettings schemas | 35 | # GSettings schemas |
12 | 35 | 36 | ||
13 | === modified file 'libunity-2d-private/src/CMakeLists.txt' | |||
14 | --- libunity-2d-private/src/CMakeLists.txt 2011-07-27 15:41:41 +0000 | |||
15 | +++ libunity-2d-private/src/CMakeLists.txt 2011-07-27 15:41:41 +0000 | |||
16 | @@ -31,6 +31,8 @@ | |||
17 | 31 | ${CMAKE_CURRENT_BINARY_DIR} | 31 | ${CMAKE_CURRENT_BINARY_DIR} |
18 | 32 | ${CMAKE_CURRENT_SOURCE_DIR} | 32 | ${CMAKE_CURRENT_SOURCE_DIR} |
19 | 33 | ${GLIB_INCLUDE_DIRS} | 33 | ${GLIB_INCLUDE_DIRS} |
20 | 34 | ${GTK_INCLUDE_DIRS} | ||
21 | 35 | ${PANGO_INCLUDE_DIRS} | ||
22 | 34 | ${WNCK_INCLUDE_DIRS} | 36 | ${WNCK_INCLUDE_DIRS} |
23 | 35 | ) | 37 | ) |
24 | 36 | 38 | ||
25 | @@ -48,6 +50,8 @@ | |||
26 | 48 | ${QT_QTOPENGL_LIBRARIES} | 50 | ${QT_QTOPENGL_LIBRARIES} |
27 | 49 | ${X11_LIBRARIES} | 51 | ${X11_LIBRARIES} |
28 | 50 | ${GLIB_LDFLAGS} | 52 | ${GLIB_LDFLAGS} |
29 | 53 | ${GTK_LDFLAGS} | ||
30 | 54 | ${PANGO_LDFLAGS} | ||
31 | 51 | ${WNCK_LDFLAGS} | 55 | ${WNCK_LDFLAGS} |
32 | 52 | ) | 56 | ) |
33 | 53 | 57 | ||
34 | 54 | 58 | ||
35 | === modified file 'libunity-2d-private/src/unity2dapplication.cpp' | |||
36 | --- libunity-2d-private/src/unity2dapplication.cpp 2011-07-27 15:41:41 +0000 | |||
37 | +++ libunity-2d-private/src/unity2dapplication.cpp 2011-07-27 15:41:41 +0000 | |||
38 | @@ -25,14 +25,59 @@ | |||
39 | 25 | 25 | ||
40 | 26 | // libunity-2d | 26 | // libunity-2d |
41 | 27 | #include <debug_p.h> | 27 | #include <debug_p.h> |
42 | 28 | #include <gconnector.h> | ||
43 | 29 | #include <gscopedpointer.h> | ||
44 | 28 | #include <unity2ddebug.h> | 30 | #include <unity2ddebug.h> |
45 | 29 | 31 | ||
46 | 30 | // Qt | 32 | // Qt |
47 | 33 | #include <QFont> | ||
48 | 31 | #include <QWindowsStyle> | 34 | #include <QWindowsStyle> |
49 | 32 | 35 | ||
50 | 33 | // GTK | 36 | // GTK |
51 | 34 | #include <gtk/gtk.h> | 37 | #include <gtk/gtk.h> |
53 | 35 | 38 | #include <pango/pango.h> | |
54 | 39 | |||
55 | 40 | /////////////////////////////// | ||
56 | 41 | class PlatformFontTracker | ||
57 | 42 | { | ||
58 | 43 | public: | ||
59 | 44 | PlatformFontTracker() | ||
60 | 45 | { | ||
61 | 46 | m_gConnector.connect(gtk_settings_get_default(), "notify::gtk-font-name", | ||
62 | 47 | G_CALLBACK(PlatformFontTracker::onFontChanged), this); | ||
63 | 48 | |||
64 | 49 | updateFont(); | ||
65 | 50 | } | ||
66 | 51 | |||
67 | 52 | private: | ||
68 | 53 | void updateFont() | ||
69 | 54 | { | ||
70 | 55 | gchar* fontName = 0; | ||
71 | 56 | g_object_get(gtk_settings_get_default(), "gtk-font-name", &fontName, NULL); | ||
72 | 57 | GScopedPointer<PangoFontDescription, pango_font_description_free> fontDescription( | ||
73 | 58 | pango_font_description_from_string(fontName) | ||
74 | 59 | ); | ||
75 | 60 | g_free(fontName); | ||
76 | 61 | |||
77 | 62 | int size = pango_font_description_get_size(fontDescription.data()); | ||
78 | 63 | |||
79 | 64 | QFont font = QFont( | ||
80 | 65 | pango_font_description_get_family(fontDescription.data()), | ||
81 | 66 | size / PANGO_SCALE | ||
82 | 67 | ); | ||
83 | 68 | |||
84 | 69 | QApplication::setFont(font); | ||
85 | 70 | } | ||
86 | 71 | |||
87 | 72 | static void onFontChanged(GObject*, GParamSpec*, PlatformFontTracker* obj) | ||
88 | 73 | { | ||
89 | 74 | obj->updateFont(); | ||
90 | 75 | } | ||
91 | 76 | |||
92 | 77 | GConnector m_gConnector; | ||
93 | 78 | }; | ||
94 | 79 | |||
95 | 80 | /////////////////////////////// | ||
96 | 36 | AbstractX11EventFilter::~AbstractX11EventFilter() | 81 | AbstractX11EventFilter::~AbstractX11EventFilter() |
97 | 37 | { | 82 | { |
98 | 38 | Unity2dApplication* application = Unity2dApplication::instance(); | 83 | Unity2dApplication* application = Unity2dApplication::instance(); |
99 | @@ -41,6 +86,7 @@ | |||
100 | 41 | } | 86 | } |
101 | 42 | } | 87 | } |
102 | 43 | 88 | ||
103 | 89 | /////////////////////////////// | ||
104 | 44 | static bool arrayContains(char** begin, char** end, const char* string) | 90 | static bool arrayContains(char** begin, char** end, const char* string) |
105 | 45 | { | 91 | { |
106 | 46 | for (char** ptr = begin; ptr != end; ++ptr) { | 92 | for (char** ptr = begin; ptr != end; ++ptr) { |
107 | @@ -83,6 +129,7 @@ | |||
108 | 83 | 129 | ||
109 | 84 | Unity2dApplication::Unity2dApplication(int& argc, char** argv) | 130 | Unity2dApplication::Unity2dApplication(int& argc, char** argv) |
110 | 85 | : QApplication(argc, argv) | 131 | : QApplication(argc, argv) |
111 | 132 | , m_platformFontTracker(new PlatformFontTracker) | ||
112 | 86 | { | 133 | { |
113 | 87 | /* Allow developers to run Unity 2D uninstalled by telling dconf-qt | 134 | /* Allow developers to run Unity 2D uninstalled by telling dconf-qt |
114 | 88 | where to look for Unity 2D's schemas. | 135 | where to look for Unity 2D's schemas. |
115 | @@ -96,6 +143,7 @@ | |||
116 | 96 | Unity2dApplication::~Unity2dApplication() | 143 | Unity2dApplication::~Unity2dApplication() |
117 | 97 | { | 144 | { |
118 | 98 | qDeleteAll(m_x11EventFilters); | 145 | qDeleteAll(m_x11EventFilters); |
119 | 146 | delete m_platformFontTracker; | ||
120 | 99 | } | 147 | } |
121 | 100 | 148 | ||
122 | 101 | Unity2dApplication* Unity2dApplication::instance() | 149 | Unity2dApplication* Unity2dApplication::instance() |
123 | 102 | 150 | ||
124 | === modified file 'libunity-2d-private/src/unity2dapplication.h' | |||
125 | --- libunity-2d-private/src/unity2dapplication.h 2011-07-18 13:47:29 +0000 | |||
126 | +++ libunity-2d-private/src/unity2dapplication.h 2011-07-27 15:41:41 +0000 | |||
127 | @@ -27,6 +27,8 @@ | |||
128 | 27 | 27 | ||
129 | 28 | class Unity2dApplication; | 28 | class Unity2dApplication; |
130 | 29 | 29 | ||
131 | 30 | class PlatformFontTracker; | ||
132 | 31 | |||
133 | 30 | class AbstractX11EventFilter | 32 | class AbstractX11EventFilter |
134 | 31 | { | 33 | { |
135 | 32 | public: | 34 | public: |
136 | @@ -65,6 +67,7 @@ | |||
137 | 65 | 67 | ||
138 | 66 | private: | 68 | private: |
139 | 67 | QList<AbstractX11EventFilter*> m_x11EventFilters; | 69 | QList<AbstractX11EventFilter*> m_x11EventFilters; |
140 | 70 | PlatformFontTracker* m_platformFontTracker; | ||
141 | 68 | }; | 71 | }; |
142 | 69 | 72 | ||
143 | 70 | #endif // UNITY2DAPPLICATION_H | 73 | #endif // UNITY2DAPPLICATION_H |
144 | 71 | 74 | ||
145 | === modified file 'panel/applets/CMakeLists.txt' | |||
146 | --- panel/applets/CMakeLists.txt 2011-07-27 15:41:41 +0000 | |||
147 | +++ panel/applets/CMakeLists.txt 2011-07-27 15:41:41 +0000 | |||
148 | @@ -12,12 +12,14 @@ | |||
149 | 12 | appindicator/appindicatorapplet.cpp | 12 | appindicator/appindicatorapplet.cpp |
150 | 13 | appindicator/sniitem.cpp | 13 | appindicator/sniitem.cpp |
151 | 14 | appname/appnameapplet.cpp | 14 | appname/appnameapplet.cpp |
152 | 15 | appname/croppedlabel.cpp | ||
153 | 15 | appname/menubarwidget.cpp | 16 | appname/menubarwidget.cpp |
154 | 16 | appname/windowhelper.cpp | 17 | appname/windowhelper.cpp |
155 | 17 | common/applet.cpp | 18 | common/applet.cpp |
156 | 18 | common/indicatorentrywidget.cpp | 19 | common/indicatorentrywidget.cpp |
157 | 19 | common/indicatorsmanager.cpp | 20 | common/indicatorsmanager.cpp |
158 | 20 | common/indicatorwidget.cpp | 21 | common/indicatorwidget.cpp |
159 | 22 | common/cairoutils.cpp | ||
160 | 21 | common/panelstyle.cpp | 23 | common/panelstyle.cpp |
161 | 22 | homebutton/homebuttonapplet.cpp | 24 | homebutton/homebuttonapplet.cpp |
162 | 23 | homebutton/homebutton.cpp | 25 | homebutton/homebutton.cpp |
163 | @@ -41,6 +43,7 @@ | |||
164 | 41 | ${CMAKE_CURRENT_SOURCE_DIR}/indicator | 43 | ${CMAKE_CURRENT_SOURCE_DIR}/indicator |
165 | 42 | ${CMAKE_CURRENT_SOURCE_DIR}/unitycore | 44 | ${CMAKE_CURRENT_SOURCE_DIR}/unitycore |
166 | 43 | ${QTBAMF_INCLUDE_DIRS} | 45 | ${QTBAMF_INCLUDE_DIRS} |
167 | 46 | ${QTGCONF_INCLUDE_DIRS} | ||
168 | 44 | ${DBUSMENUQT_INCLUDE_DIRS} | 47 | ${DBUSMENUQT_INCLUDE_DIRS} |
169 | 45 | ${GTK_INCLUDE_DIRS} | 48 | ${GTK_INCLUDE_DIRS} |
170 | 46 | ${WNCK_INCLUDE_DIRS} | 49 | ${WNCK_INCLUDE_DIRS} |
171 | @@ -58,6 +61,7 @@ | |||
172 | 58 | ${QT_QTCORE_LIBRARIES} | 61 | ${QT_QTCORE_LIBRARIES} |
173 | 59 | ${DBUSMENUQT_LDFLAGS} | 62 | ${DBUSMENUQT_LDFLAGS} |
174 | 60 | ${QTBAMF_LDFLAGS} | 63 | ${QTBAMF_LDFLAGS} |
175 | 64 | ${QTGCONF_LDFLAGS} | ||
176 | 61 | ${GTK_LDFLAGS} | 65 | ${GTK_LDFLAGS} |
177 | 62 | ${WNCK_LDFLAGS} | 66 | ${WNCK_LDFLAGS} |
178 | 63 | ${X11_LIBRARIES} | 67 | ${X11_LIBRARIES} |
179 | 64 | 68 | ||
180 | === modified file 'panel/applets/appname/appnameapplet.cpp' | |||
181 | --- panel/applets/appname/appnameapplet.cpp 2011-07-27 15:41:41 +0000 | |||
182 | +++ panel/applets/appname/appnameapplet.cpp 2011-07-27 15:41:41 +0000 | |||
183 | @@ -23,6 +23,7 @@ | |||
184 | 23 | #include "appnameapplet.h" | 23 | #include "appnameapplet.h" |
185 | 24 | 24 | ||
186 | 25 | // Local | 25 | // Local |
187 | 26 | #include "croppedlabel.h" | ||
188 | 26 | #include "menubarwidget.h" | 27 | #include "menubarwidget.h" |
189 | 27 | #include "windowhelper.h" | 28 | #include "windowhelper.h" |
190 | 28 | 29 | ||
191 | @@ -49,9 +50,7 @@ | |||
192 | 49 | 50 | ||
193 | 50 | static const int WINDOW_BUTTONS_RIGHT_MARGIN = 4; | 51 | static const int WINDOW_BUTTONS_RIGHT_MARGIN = 4; |
194 | 51 | 52 | ||
198 | 52 | static const int APPNAME_LABEL_LEFT_MARGIN = 12; | 53 | static const int APPNAME_LABEL_LEFT_MARGIN = 6; |
196 | 53 | |||
197 | 54 | static const int FADEOUT_WIDTH = 16; | ||
199 | 55 | 54 | ||
200 | 56 | namespace Unity2d | 55 | namespace Unity2d |
201 | 57 | { | 56 | { |
202 | @@ -106,50 +105,6 @@ | |||
203 | 106 | } | 105 | } |
204 | 107 | }; | 106 | }; |
205 | 108 | 107 | ||
206 | 109 | /** | ||
207 | 110 | * This label makes sure minimumSizeHint() is not set. This ensures the applet | ||
208 | 111 | * does not get wider if a window title is very long | ||
209 | 112 | */ | ||
210 | 113 | class CroppedLabel : public QLabel | ||
211 | 114 | { | ||
212 | 115 | public: | ||
213 | 116 | CroppedLabel(QWidget* parent = 0) | ||
214 | 117 | : QLabel(parent) | ||
215 | 118 | {} | ||
216 | 119 | |||
217 | 120 | QSize minimumSizeHint() const | ||
218 | 121 | { | ||
219 | 122 | return QWidget::minimumSizeHint(); | ||
220 | 123 | } | ||
221 | 124 | |||
222 | 125 | protected: | ||
223 | 126 | void paintEvent(QPaintEvent* event) | ||
224 | 127 | { | ||
225 | 128 | QImage image(width(), height(), QImage::Format_ARGB32_Premultiplied); | ||
226 | 129 | { | ||
227 | 130 | QPainter painter(&image); | ||
228 | 131 | painter.initFrom(this); | ||
229 | 132 | painter.setCompositionMode(QPainter::CompositionMode_Source); | ||
230 | 133 | painter.fillRect(rect(), Qt::transparent); | ||
231 | 134 | |||
232 | 135 | painter.setCompositionMode(QPainter::CompositionMode_SourceOver); | ||
233 | 136 | painter.drawText(contentsRect(), Qt::AlignLeft | Qt::AlignVCenter, text()); | ||
234 | 137 | |||
235 | 138 | if (QLabel::minimumSizeHint().width() > contentsRect().width()) { | ||
236 | 139 | // Text does not fit, fade the end | ||
237 | 140 | painter.setCompositionMode(QPainter::CompositionMode_DestinationIn); | ||
238 | 141 | QRect gradientRect(width() - FADEOUT_WIDTH, 0, FADEOUT_WIDTH, height()); | ||
239 | 142 | QLinearGradient gradient(gradientRect.topLeft(), gradientRect.topRight()); | ||
240 | 143 | gradient.setColorAt(0, Qt::white); | ||
241 | 144 | gradient.setColorAt(1, Qt::transparent); | ||
242 | 145 | painter.fillRect(gradientRect, gradient); | ||
243 | 146 | } | ||
244 | 147 | } | ||
245 | 148 | QPainter painter(this); | ||
246 | 149 | painter.drawImage(0, 0, image); | ||
247 | 150 | } | ||
248 | 151 | }; | ||
249 | 152 | |||
250 | 153 | struct AppNameAppletPrivate | 108 | struct AppNameAppletPrivate |
251 | 154 | { | 109 | { |
252 | 155 | AppNameApplet* q; | 110 | AppNameApplet* q; |
253 | 156 | 111 | ||
254 | === added file 'panel/applets/appname/croppedlabel.cpp' | |||
255 | --- panel/applets/appname/croppedlabel.cpp 1970-01-01 00:00:00 +0000 | |||
256 | +++ panel/applets/appname/croppedlabel.cpp 2011-07-27 15:41:41 +0000 | |||
257 | @@ -0,0 +1,140 @@ | |||
258 | 1 | /* | ||
259 | 2 | * This file is part of unity-2d | ||
260 | 3 | * | ||
261 | 4 | * Copyright 2011 Canonical Ltd. | ||
262 | 5 | * | ||
263 | 6 | * Authors: | ||
264 | 7 | * - Aurélien Gâteau <aurelien.gateau@canonical.com> | ||
265 | 8 | * | ||
266 | 9 | * This program is free software; you can redistribute it and/or modify | ||
267 | 10 | * it under the terms of the GNU General Public License as published by | ||
268 | 11 | * the Free Software Foundation; version 3. | ||
269 | 12 | * | ||
270 | 13 | * This program is distributed in the hope that it will be useful, | ||
271 | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
272 | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
273 | 16 | * GNU General Public License for more details. | ||
274 | 17 | * | ||
275 | 18 | * You should have received a copy of the GNU General Public License | ||
276 | 19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
277 | 20 | */ | ||
278 | 21 | // Self | ||
279 | 22 | #include "croppedlabel.h" | ||
280 | 23 | |||
281 | 24 | // Local | ||
282 | 25 | #include <cairoutils.h> | ||
283 | 26 | #include <panelstyle.h> | ||
284 | 27 | |||
285 | 28 | // unity-2d | ||
286 | 29 | #include <debug_p.h> | ||
287 | 30 | |||
288 | 31 | // libqtgconf | ||
289 | 32 | #include <gconfitem-qml-wrapper.h> | ||
290 | 33 | |||
291 | 34 | // Qt | ||
292 | 35 | #include <QImage> | ||
293 | 36 | #include <QPainter> | ||
294 | 37 | |||
295 | 38 | // GTK | ||
296 | 39 | #include <gtk/gtk.h> | ||
297 | 40 | |||
298 | 41 | static const int FADEOUT_WIDTH = 30; | ||
299 | 42 | |||
300 | 43 | static const char* WINDOW_TITLE_FONT_KEY = "/apps/metacity/general/titlebar_font"; | ||
301 | 44 | |||
302 | 45 | CroppedLabel::CroppedLabel(QWidget* parent) | ||
303 | 46 | : QLabel(parent) | ||
304 | 47 | { | ||
305 | 48 | } | ||
306 | 49 | |||
307 | 50 | QSize CroppedLabel::minimumSizeHint() const | ||
308 | 51 | { | ||
309 | 52 | return QWidget::minimumSizeHint(); | ||
310 | 53 | } | ||
311 | 54 | |||
312 | 55 | static void paintFadeoutGradient(QImage* image) | ||
313 | 56 | { | ||
314 | 57 | QPainter painter(image); | ||
315 | 58 | painter.setCompositionMode(QPainter::CompositionMode_DestinationIn); | ||
316 | 59 | QRect gradientRect(image->width() - FADEOUT_WIDTH, 0, FADEOUT_WIDTH, image->height()); | ||
317 | 60 | QLinearGradient gradient(gradientRect.topLeft(), gradientRect.topRight()); | ||
318 | 61 | gradient.setColorAt(0, Qt::white); | ||
319 | 62 | gradient.setColorAt(1, Qt::transparent); | ||
320 | 63 | painter.fillRect(gradientRect, gradient); | ||
321 | 64 | } | ||
322 | 65 | |||
323 | 66 | static QString getWindowTitleFontName() | ||
324 | 67 | { | ||
325 | 68 | GConfItemQmlWrapper client; | ||
326 | 69 | client.setKey(WINDOW_TITLE_FONT_KEY); | ||
327 | 70 | return client.getValue().toString(); | ||
328 | 71 | } | ||
329 | 72 | |||
330 | 73 | void CroppedLabel::paintEvent(QPaintEvent* event) | ||
331 | 74 | { | ||
332 | 75 | // Create an image filled with background brush (to avoid subpixel hinting | ||
333 | 76 | // artefacts around text) | ||
334 | 77 | QImage image(width(), height(), QImage::Format_ARGB32_Premultiplied); | ||
335 | 78 | { | ||
336 | 79 | QPainter painter(&image); | ||
337 | 80 | painter.initFrom(this); | ||
338 | 81 | painter.eraseRect(rect()); | ||
339 | 82 | } | ||
340 | 83 | |||
341 | 84 | // Create a pango layout | ||
342 | 85 | GObjectScopedPointer<PangoContext> pangoContext(gdk_pango_context_get()); | ||
343 | 86 | GObjectScopedPointer<PangoLayout> layout(pango_layout_new(pangoContext.data())); | ||
344 | 87 | |||
345 | 88 | // Set font | ||
346 | 89 | QByteArray fontName = getWindowTitleFontName().toUtf8(); | ||
347 | 90 | PangoFontDescription* desc = pango_font_description_from_string(fontName.data()); | ||
348 | 91 | pango_layout_set_font_description(layout.data(), desc); | ||
349 | 92 | pango_font_description_free(desc); | ||
350 | 93 | |||
351 | 94 | // Set text | ||
352 | 95 | QByteArray utf8Text = text().toUtf8(); | ||
353 | 96 | pango_layout_set_text (layout.data(), utf8Text.data(), -1); | ||
354 | 97 | |||
355 | 98 | // Get text size | ||
356 | 99 | int textWidth = 0; | ||
357 | 100 | int textHeight = 0; | ||
358 | 101 | pango_layout_get_pixel_size(layout.data(), &textWidth, &textHeight); | ||
359 | 102 | |||
360 | 103 | // Draw text | ||
361 | 104 | CairoUtils::SurfacePointer surface(CairoUtils::createSurfaceForQImage(&image)); | ||
362 | 105 | CairoUtils::Pointer cr(cairo_create(surface.data())); | ||
363 | 106 | |||
364 | 107 | PanelStyle* style = PanelStyle::instance(); | ||
365 | 108 | GtkStyleContext* style_context = style->styleContext(); | ||
366 | 109 | |||
367 | 110 | gtk_style_context_save(style_context); | ||
368 | 111 | |||
369 | 112 | GtkWidgetPath* widget_path = gtk_widget_path_new(); | ||
370 | 113 | gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_BAR); | ||
371 | 114 | gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_ITEM); | ||
372 | 115 | gtk_widget_path_iter_set_name(widget_path, -1 , "UnityPanelWidget"); | ||
373 | 116 | |||
374 | 117 | gtk_style_context_set_path(style_context, widget_path); | ||
375 | 118 | gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUBAR); | ||
376 | 119 | gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUITEM); | ||
377 | 120 | |||
378 | 121 | gtk_render_layout(style_context, cr.data(), | ||
379 | 122 | contentsRect().left(), | ||
380 | 123 | contentsRect().top() + (height() - textHeight) / 2, | ||
381 | 124 | layout.data()); | ||
382 | 125 | |||
383 | 126 | gtk_widget_path_free(widget_path); | ||
384 | 127 | |||
385 | 128 | gtk_style_context_restore(style_context); | ||
386 | 129 | |||
387 | 130 | // Fade if necessary | ||
388 | 131 | if (textWidth > contentsRect().width()) { | ||
389 | 132 | paintFadeoutGradient(&image); | ||
390 | 133 | } | ||
391 | 134 | |||
392 | 135 | // Paint on our widget | ||
393 | 136 | QPainter painter(this); | ||
394 | 137 | painter.drawImage(0, 0, image); | ||
395 | 138 | } | ||
396 | 139 | |||
397 | 140 | #include "croppedlabel.moc" | ||
398 | 0 | 141 | ||
399 | === added file 'panel/applets/appname/croppedlabel.h' | |||
400 | --- panel/applets/appname/croppedlabel.h 1970-01-01 00:00:00 +0000 | |||
401 | +++ panel/applets/appname/croppedlabel.h 2011-07-27 15:41:41 +0000 | |||
402 | @@ -0,0 +1,45 @@ | |||
403 | 1 | /* | ||
404 | 2 | * This file is part of unity-2d | ||
405 | 3 | * | ||
406 | 4 | * Copyright 2011 Canonical Ltd. | ||
407 | 5 | * | ||
408 | 6 | * Authors: | ||
409 | 7 | * - Aurélien Gâteau <aurelien.gateau@canonical.com> | ||
410 | 8 | * | ||
411 | 9 | * This program is free software; you can redistribute it and/or modify | ||
412 | 10 | * it under the terms of the GNU General Public License as published by | ||
413 | 11 | * the Free Software Foundation; version 3. | ||
414 | 12 | * | ||
415 | 13 | * This program is distributed in the hope that it will be useful, | ||
416 | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
417 | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
418 | 16 | * GNU General Public License for more details. | ||
419 | 17 | * | ||
420 | 18 | * You should have received a copy of the GNU General Public License | ||
421 | 19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
422 | 20 | */ | ||
423 | 21 | #ifndef CROPPEDLABEL_H | ||
424 | 22 | #define CROPPEDLABEL_H | ||
425 | 23 | |||
426 | 24 | // Local | ||
427 | 25 | |||
428 | 26 | // Qt | ||
429 | 27 | #include <QLabel> | ||
430 | 28 | |||
431 | 29 | /** | ||
432 | 30 | * This label makes sure minimumSizeHint() is not set. This ensures the applet | ||
433 | 31 | * does not get wider if a window title is very long | ||
434 | 32 | */ | ||
435 | 33 | class CroppedLabel : public QLabel | ||
436 | 34 | { | ||
437 | 35 | Q_OBJECT | ||
438 | 36 | public: | ||
439 | 37 | CroppedLabel(QWidget* parent = 0); | ||
440 | 38 | |||
441 | 39 | QSize minimumSizeHint() const; | ||
442 | 40 | |||
443 | 41 | protected: | ||
444 | 42 | void paintEvent(QPaintEvent*); | ||
445 | 43 | }; | ||
446 | 44 | |||
447 | 45 | #endif /* CROPPEDLABEL_H */ | ||
448 | 0 | 46 | ||
449 | === added file 'panel/applets/common/cairoutils.cpp' | |||
450 | --- panel/applets/common/cairoutils.cpp 1970-01-01 00:00:00 +0000 | |||
451 | +++ panel/applets/common/cairoutils.cpp 2011-07-27 15:41:41 +0000 | |||
452 | @@ -0,0 +1,42 @@ | |||
453 | 1 | /* | ||
454 | 2 | * This file is part of unity-2d | ||
455 | 3 | * | ||
456 | 4 | * Copyright 2011 Canonical Ltd. | ||
457 | 5 | * | ||
458 | 6 | * Authors: | ||
459 | 7 | * - Aurélien Gâteau <aurelien.gateau@canonical.com> | ||
460 | 8 | * | ||
461 | 9 | * This program is free software; you can redistribute it and/or modify | ||
462 | 10 | * it under the terms of the GNU General Public License as published by | ||
463 | 11 | * the Free Software Foundation; version 3. | ||
464 | 12 | * | ||
465 | 13 | * This program is distributed in the hope that it will be useful, | ||
466 | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
467 | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
468 | 16 | * GNU General Public License for more details. | ||
469 | 17 | * | ||
470 | 18 | * You should have received a copy of the GNU General Public License | ||
471 | 19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
472 | 20 | */ | ||
473 | 21 | // Self | ||
474 | 22 | #include "cairoutils.h" | ||
475 | 23 | |||
476 | 24 | // Local | ||
477 | 25 | |||
478 | 26 | // Qt | ||
479 | 27 | #include <QImage> | ||
480 | 28 | |||
481 | 29 | namespace CairoUtils { | ||
482 | 30 | |||
483 | 31 | cairo_surface_t* createSurfaceForQImage(QImage* image) | ||
484 | 32 | { | ||
485 | 33 | return cairo_image_surface_create_for_data( | ||
486 | 34 | image->bits(), | ||
487 | 35 | CAIRO_FORMAT_ARGB32, | ||
488 | 36 | image->width(), | ||
489 | 37 | image->height(), | ||
490 | 38 | image->bytesPerLine() | ||
491 | 39 | ); | ||
492 | 40 | } | ||
493 | 41 | |||
494 | 42 | } // namespace | ||
495 | 0 | 43 | ||
496 | === added file 'panel/applets/common/cairoutils.h' | |||
497 | --- panel/applets/common/cairoutils.h 1970-01-01 00:00:00 +0000 | |||
498 | +++ panel/applets/common/cairoutils.h 2011-07-27 15:41:41 +0000 | |||
499 | @@ -0,0 +1,47 @@ | |||
500 | 1 | /* | ||
501 | 2 | * This file is part of unity-2d | ||
502 | 3 | * | ||
503 | 4 | * Copyright 2011 Canonical Ltd. | ||
504 | 5 | * | ||
505 | 6 | * Authors: | ||
506 | 7 | * - Aurélien Gâteau <aurelien.gateau@canonical.com> | ||
507 | 8 | * | ||
508 | 9 | * This program is free software; you can redistribute it and/or modify | ||
509 | 10 | * it under the terms of the GNU General Public License as published by | ||
510 | 11 | * the Free Software Foundation; version 3. | ||
511 | 12 | * | ||
512 | 13 | * This program is distributed in the hope that it will be useful, | ||
513 | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
514 | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
515 | 16 | * GNU General Public License for more details. | ||
516 | 17 | * | ||
517 | 18 | * You should have received a copy of the GNU General Public License | ||
518 | 19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
519 | 20 | */ | ||
520 | 21 | #ifndef CAIROUTILS_H | ||
521 | 22 | #define CAIROUTILS_H | ||
522 | 23 | |||
523 | 24 | // Local | ||
524 | 25 | #include <gscopedpointer.h> | ||
525 | 26 | |||
526 | 27 | // Qt | ||
527 | 28 | |||
528 | 29 | // Cairo | ||
529 | 30 | #include <cairo.h> | ||
530 | 31 | |||
531 | 32 | class QImage; | ||
532 | 33 | |||
533 | 34 | namespace CairoUtils { | ||
534 | 35 | |||
535 | 36 | typedef GScopedPointer<cairo_surface_t, cairo_surface_destroy> SurfacePointer; | ||
536 | 37 | typedef GScopedPointer<cairo_t, cairo_destroy> Pointer; | ||
537 | 38 | |||
538 | 39 | /** | ||
539 | 40 | * Creates a Cairo surface for a QImage. | ||
540 | 41 | * QImage format must be Format_ARGB32_Premultiplied. | ||
541 | 42 | */ | ||
542 | 43 | cairo_surface_t* createSurfaceForQImage(QImage*); | ||
543 | 44 | |||
544 | 45 | } // namespace | ||
545 | 46 | |||
546 | 47 | #endif /* CAIROUTILS_H */ | ||
547 | 0 | 48 | ||
548 | === removed file 'panel/applets/common/fakecairo.h' | |||
549 | --- panel/applets/common/fakecairo.h 2011-07-27 15:41:41 +0000 | |||
550 | +++ panel/applets/common/fakecairo.h 1970-01-01 00:00:00 +0000 | |||
551 | @@ -1,125 +0,0 @@ | |||
552 | 1 | /* | ||
553 | 2 | * This file is part of unity-2d | ||
554 | 3 | * | ||
555 | 4 | * Copyright 2011 Canonical Ltd. | ||
556 | 5 | * | ||
557 | 6 | * Authors: | ||
558 | 7 | * - Aurélien Gâteau <aurelien.gateau@canonical.com> | ||
559 | 8 | * | ||
560 | 9 | * This program is free software; you can redistribute it and/or modify | ||
561 | 10 | * it under the terms of the GNU General Public License as published by | ||
562 | 11 | * the Free Software Foundation; version 3. | ||
563 | 12 | * | ||
564 | 13 | * This program is distributed in the hope that it will be useful, | ||
565 | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
566 | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
567 | 16 | * GNU General Public License for more details. | ||
568 | 17 | * | ||
569 | 18 | * You should have received a copy of the GNU General Public License | ||
570 | 19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
571 | 20 | */ | ||
572 | 21 | #ifndef FAKECAIRO_H | ||
573 | 22 | #define FAKECAIRO_H | ||
574 | 23 | |||
575 | 24 | // NuxCore | ||
576 | 25 | #include <NuxCore/Color.h> | ||
577 | 26 | |||
578 | 27 | // Qt | ||
579 | 28 | #include <QPainter> | ||
580 | 29 | #include <QPainterPath> | ||
581 | 30 | |||
582 | 31 | /* | ||
583 | 32 | * This module attempts to fake Cairo calls using QPainter, making it easier to | ||
584 | 33 | * port Cairo paint operations to Qt | ||
585 | 34 | */ | ||
586 | 35 | struct fcairo_t | ||
587 | 36 | { | ||
588 | 37 | fcairo_t(QPainter* _painter) | ||
589 | 38 | : painter(_painter) | ||
590 | 39 | { | ||
591 | 40 | painter->save(); | ||
592 | 41 | } | ||
593 | 42 | |||
594 | 43 | ~fcairo_t() | ||
595 | 44 | { | ||
596 | 45 | painter->restore(); | ||
597 | 46 | } | ||
598 | 47 | |||
599 | 48 | QPainter* painter; | ||
600 | 49 | QPainterPath path; | ||
601 | 50 | }; | ||
602 | 51 | |||
603 | 52 | inline void fcairo_arc(fcairo_t& cr, qreal xc, qreal yc, qreal radius, qreal angle1, qreal angle2) | ||
604 | 53 | { | ||
605 | 54 | QRectF rect(xc - radius, yc - radius, radius * 2, radius * 2); | ||
606 | 55 | |||
607 | 56 | while (angle2 < angle1) { | ||
608 | 57 | angle2 += 2 * M_PI; | ||
609 | 58 | } | ||
610 | 59 | |||
611 | 60 | qreal start = (2. - angle1 / M_PI) * 180; | ||
612 | 61 | qreal stop = (2. - angle2 / M_PI) * 180; | ||
613 | 62 | cr.path.arcTo(rect, start, stop - start); | ||
614 | 63 | } | ||
615 | 64 | |||
616 | 65 | inline void fcairo_move_to(fcairo_t& cr, qreal x, qreal y) | ||
617 | 66 | { | ||
618 | 67 | cr.path.moveTo(x, y); | ||
619 | 68 | } | ||
620 | 69 | |||
621 | 70 | inline void fcairo_line_to(fcairo_t& cr, qreal x, qreal y) | ||
622 | 71 | { | ||
623 | 72 | cr.path.lineTo(x, y); | ||
624 | 73 | } | ||
625 | 74 | |||
626 | 75 | inline void fcairo_fill_preserve(fcairo_t& cr) | ||
627 | 76 | { | ||
628 | 77 | cr.painter->fillPath(cr.path, cr.painter->brush()); | ||
629 | 78 | } | ||
630 | 79 | |||
631 | 80 | inline void fcairo_stroke(fcairo_t& cr) | ||
632 | 81 | { | ||
633 | 82 | QPen pen(cr.painter->brush().color(), 1); | ||
634 | 83 | cr.painter->strokePath(cr.path, pen); | ||
635 | 84 | cr.path = QPainterPath(); | ||
636 | 85 | } | ||
637 | 86 | |||
638 | 87 | typedef QGradient fcairo_pattern_t; | ||
639 | 88 | |||
640 | 89 | inline fcairo_pattern_t* fcairo_pattern_create_linear (qreal x1, qreal y1, qreal x2, qreal y2) | ||
641 | 90 | { | ||
642 | 91 | return new QLinearGradient(x1, y1, x2, y2); | ||
643 | 92 | } | ||
644 | 93 | |||
645 | 94 | inline void fcairo_pattern_destroy(fcairo_pattern_t* pattern) | ||
646 | 95 | { | ||
647 | 96 | delete pattern; | ||
648 | 97 | } | ||
649 | 98 | |||
650 | 99 | inline void fcairo_pattern_add_color_stop_rgba(fcairo_pattern_t* pattern, qreal offset, qreal r, qreal g, qreal b, qreal a) | ||
651 | 100 | { | ||
652 | 101 | pattern->setColorAt(offset, QColor::fromRgbF(r, g, b, a)); | ||
653 | 102 | } | ||
654 | 103 | |||
655 | 104 | inline void fcairo_set_source(fcairo_t& cr, fcairo_pattern_t* pattern) | ||
656 | 105 | { | ||
657 | 106 | cr.painter->setPen(Qt::NoPen); | ||
658 | 107 | cr.painter->setBrush(*pattern); | ||
659 | 108 | } | ||
660 | 109 | |||
661 | 110 | inline void fcairo_set_source_rgb(fcairo_t& cr, qreal r, qreal g, qreal b) | ||
662 | 111 | { | ||
663 | 112 | cr.painter->setBrush(QColor::fromRgbF(r, g, b)); | ||
664 | 113 | } | ||
665 | 114 | |||
666 | 115 | inline nux::color::Color nuxColorFromQColor(const QColor& qColor) | ||
667 | 116 | { | ||
668 | 117 | nux::color::Color color; | ||
669 | 118 | color.red = qColor.redF(); | ||
670 | 119 | color.green = qColor.greenF(); | ||
671 | 120 | color.blue = qColor.blueF(); | ||
672 | 121 | color.alpha = qColor.alphaF(); | ||
673 | 122 | return color; | ||
674 | 123 | } | ||
675 | 124 | |||
676 | 125 | #endif /* FAKECAIRO_H */ | ||
677 | 126 | 0 | ||
678 | === modified file 'panel/applets/common/indicatorentrywidget.cpp' | |||
679 | --- panel/applets/common/indicatorentrywidget.cpp 2011-07-27 15:41:41 +0000 | |||
680 | +++ panel/applets/common/indicatorentrywidget.cpp 2011-07-27 15:41:41 +0000 | |||
681 | @@ -22,8 +22,9 @@ | |||
682 | 22 | #include "indicatorentrywidget.h" | 22 | #include "indicatorentrywidget.h" |
683 | 23 | 23 | ||
684 | 24 | // Local | 24 | // Local |
685 | 25 | #include <cairoutils.h> | ||
686 | 25 | #include <debug_p.h> | 26 | #include <debug_p.h> |
688 | 26 | #include <fakecairo.h> | 27 | #include <gscopedpointer.h> |
689 | 27 | #include <panelstyle.h> | 28 | #include <panelstyle.h> |
690 | 28 | 29 | ||
691 | 29 | // Qt | 30 | // Qt |
692 | @@ -42,56 +43,25 @@ | |||
693 | 42 | 43 | ||
694 | 43 | using namespace unity::indicator; | 44 | using namespace unity::indicator; |
695 | 44 | 45 | ||
696 | 45 | // Copied from libdbusmenu-qt | ||
697 | 46 | static QString swapMnemonicChar(const QString &in, const char src, const char dst) | ||
698 | 47 | { | ||
699 | 48 | QString out; | ||
700 | 49 | bool mnemonicFound = false; | ||
701 | 50 | |||
702 | 51 | for (int pos = 0; pos < in.length(); ) { | ||
703 | 52 | QChar ch = in[pos]; | ||
704 | 53 | if (ch == src) { | ||
705 | 54 | if (pos == in.length() - 1) { | ||
706 | 55 | // 'src' at the end of string, skip it | ||
707 | 56 | ++pos; | ||
708 | 57 | } else { | ||
709 | 58 | if (in[pos + 1] == src) { | ||
710 | 59 | // A real 'src' | ||
711 | 60 | out += src; | ||
712 | 61 | pos += 2; | ||
713 | 62 | } else if (!mnemonicFound) { | ||
714 | 63 | // We found the mnemonic | ||
715 | 64 | mnemonicFound = true; | ||
716 | 65 | out += dst; | ||
717 | 66 | ++pos; | ||
718 | 67 | } else { | ||
719 | 68 | // We already have a mnemonic, just skip the char | ||
720 | 69 | ++pos; | ||
721 | 70 | } | ||
722 | 71 | } | ||
723 | 72 | } else if (ch == dst) { | ||
724 | 73 | // Escape 'dst' | ||
725 | 74 | out += dst; | ||
726 | 75 | out += dst; | ||
727 | 76 | ++pos; | ||
728 | 77 | } else { | ||
729 | 78 | out += ch; | ||
730 | 79 | ++pos; | ||
731 | 80 | } | ||
732 | 81 | } | ||
733 | 82 | |||
734 | 83 | return out; | ||
735 | 84 | } | ||
736 | 85 | |||
737 | 86 | IndicatorEntryWidget::IndicatorEntryWidget(const Entry::Ptr& entry) | 46 | IndicatorEntryWidget::IndicatorEntryWidget(const Entry::Ptr& entry) |
738 | 87 | : m_entry(entry) | 47 | : m_entry(entry) |
739 | 88 | , m_padding(PADDING) | 48 | , m_padding(PADDING) |
740 | 89 | , m_hasIcon(false) | 49 | , m_hasIcon(false) |
741 | 90 | , m_hasLabel(false) | 50 | , m_hasLabel(false) |
742 | 51 | , m_gtkWidgetPath(gtk_widget_path_new()) | ||
743 | 91 | { | 52 | { |
744 | 53 | gtk_widget_path_append_type(m_gtkWidgetPath, GTK_TYPE_WINDOW); | ||
745 | 54 | gtk_widget_path_iter_set_name(m_gtkWidgetPath, -1 , "UnityPanelWidget"); | ||
746 | 55 | gtk_widget_path_append_type(m_gtkWidgetPath, GTK_TYPE_MENU_BAR); | ||
747 | 56 | gtk_widget_path_append_type(m_gtkWidgetPath, GTK_TYPE_MENU_ITEM); | ||
748 | 57 | |||
749 | 92 | setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum); | 58 | setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum); |
750 | 93 | m_entry->updated.connect(sigc::mem_fun(this, &IndicatorEntryWidget::updatePix)); | 59 | m_entry->updated.connect(sigc::mem_fun(this, &IndicatorEntryWidget::updatePix)); |
752 | 94 | updatePix(); | 60 | } |
753 | 61 | |||
754 | 62 | IndicatorEntryWidget::~IndicatorEntryWidget() | ||
755 | 63 | { | ||
756 | 64 | gtk_widget_path_free(m_gtkWidgetPath); | ||
757 | 95 | } | 65 | } |
758 | 96 | 66 | ||
759 | 97 | QSize IndicatorEntryWidget::minimumSizeHint() const | 67 | QSize IndicatorEntryWidget::minimumSizeHint() const |
760 | @@ -104,105 +74,47 @@ | |||
761 | 104 | return m_pix.size(); | 74 | return m_pix.size(); |
762 | 105 | } | 75 | } |
763 | 106 | 76 | ||
764 | 77 | void IndicatorEntryWidget::resizeEvent(QResizeEvent* event) | ||
765 | 78 | { | ||
766 | 79 | QWidget::resizeEvent(event); | ||
767 | 80 | updatePix(); | ||
768 | 81 | } | ||
769 | 82 | |||
770 | 107 | void IndicatorEntryWidget::paintEvent(QPaintEvent*) | 83 | void IndicatorEntryWidget::paintEvent(QPaintEvent*) |
771 | 108 | { | 84 | { |
772 | 109 | if (!m_pix.isNull()) { | 85 | if (!m_pix.isNull()) { |
773 | 110 | QPainter painter(this); | 86 | QPainter painter(this); |
774 | 111 | if (m_entry->active()) { | ||
775 | 112 | paintActiveBackground(&painter); | ||
776 | 113 | } | ||
777 | 114 | painter.drawPixmap(0, 0, m_pix); | 87 | painter.drawPixmap(0, 0, m_pix); |
778 | 115 | } | 88 | } |
779 | 116 | } | 89 | } |
780 | 117 | 90 | ||
781 | 118 | 91 | ||
783 | 119 | void IndicatorEntryWidget::paintActiveBackground(QPainter* painter) | 92 | void IndicatorEntryWidget::paintActiveBackground(QImage* image) |
784 | 120 | { | 93 | { |
786 | 121 | // This code should be kept in sync with the draw_menu_bg() function from | 94 | // This code should be kept in sync with corresponding unityshell code from |
787 | 122 | // plugins/unityshell/src/PanelIndicatorObjectEntryView.cpp | 95 | // plugins/unityshell/src/PanelIndicatorObjectEntryView.cpp |
871 | 123 | int radius = 4; | 96 | |
872 | 124 | double x = 0; | 97 | // Get a surface and a context |
873 | 125 | double y = 0; | 98 | CairoUtils::SurfacePointer surface(CairoUtils::createSurfaceForQImage(image)); |
874 | 126 | double xos = 0.5; | 99 | CairoUtils::Pointer cr(cairo_create(surface.data())); |
875 | 127 | double yos = 0.5; | 100 | |
876 | 128 | /* FIXME */ | 101 | // Init style |
877 | 129 | double mpi = 3.14159265358979323846; | 102 | GtkStyleContext* styleContext = PanelStyle::instance()->styleContext(); |
878 | 130 | 103 | ||
879 | 131 | PanelStyle* style = PanelStyle::instance(); | 104 | gtk_style_context_save(styleContext); |
880 | 132 | nux::color::Color bgtop = nuxColorFromQColor(style->backgroundTopColor()); | 105 | |
881 | 133 | nux::color::Color bgbot = nuxColorFromQColor(style->backgroundBottomColor()); | 106 | gtk_style_context_set_path(styleContext, m_gtkWidgetPath); |
882 | 134 | nux::color::Color line = nuxColorFromQColor(style->lineColor()); | 107 | gtk_style_context_add_class(styleContext, GTK_STYLE_CLASS_MENUBAR); |
883 | 135 | 108 | gtk_style_context_add_class(styleContext, GTK_STYLE_CLASS_MENUITEM); | |
884 | 136 | painter->setRenderHint(QPainter::Antialiasing); | 109 | gtk_style_context_set_state(styleContext, GTK_STATE_FLAG_PRELIGHT); |
885 | 137 | 110 | ||
886 | 138 | fcairo_t cr(painter); | 111 | // Draw |
887 | 139 | 112 | // FIXME(Cimi) probably some padding is needed here. | |
888 | 140 | fcairo_move_to (cr, x+xos+radius, y+yos); | 113 | gtk_render_background(styleContext, cr.data(), 0, 0, width(), height()); |
889 | 141 | fcairo_arc (cr, x+xos+width()-xos*2-radius, y+yos+radius, radius, mpi*1.5, mpi*2); | 114 | gtk_render_frame(styleContext, cr.data(), 0, 0, width(), height()); |
890 | 142 | fcairo_line_to (cr, x+xos+width()-xos*2, y+yos+height()-yos*2+2); | 115 | |
891 | 143 | fcairo_line_to (cr, x+xos, y+yos+height()-yos*2+2); | 116 | // Clean up |
892 | 144 | fcairo_arc (cr, x+xos+radius, y+yos+radius, radius, mpi, mpi*1.5); | 117 | gtk_style_context_restore(styleContext); |
810 | 145 | |||
811 | 146 | fcairo_pattern_t * pat = fcairo_pattern_create_linear (x+xos, y, x+xos, y+height()-yos*2+2); | ||
812 | 147 | fcairo_pattern_add_color_stop_rgba (pat, 0.0, | ||
813 | 148 | bgtop.red, | ||
814 | 149 | bgtop.green, | ||
815 | 150 | bgtop.blue, | ||
816 | 151 | 1.0f - bgbot.red); | ||
817 | 152 | fcairo_pattern_add_color_stop_rgba (pat, 1.0, | ||
818 | 153 | bgbot.red, | ||
819 | 154 | bgbot.green, | ||
820 | 155 | bgbot.blue, | ||
821 | 156 | 1.0f - bgtop.red); | ||
822 | 157 | fcairo_set_source (cr, pat); | ||
823 | 158 | fcairo_fill_preserve (cr); | ||
824 | 159 | fcairo_pattern_destroy (pat); | ||
825 | 160 | |||
826 | 161 | /* | ||
827 | 162 | pat = fcairo_pattern_create_linear (x+xos, y, x+xos, y+height()-yos*2+2); | ||
828 | 163 | fcairo_pattern_add_color_stop_rgba (pat, 0.0, | ||
829 | 164 | line.red, | ||
830 | 165 | line.green, | ||
831 | 166 | line.blue, | ||
832 | 167 | 1.0f); | ||
833 | 168 | fcairo_pattern_add_color_stop_rgba (pat, 1.0, | ||
834 | 169 | line.red, | ||
835 | 170 | line.green, | ||
836 | 171 | line.blue, | ||
837 | 172 | 1.0f); | ||
838 | 173 | fcairo_set_source (cr, pat); | ||
839 | 174 | */ | ||
840 | 175 | fcairo_set_source_rgb (cr, line.red, line.green, line.blue); | ||
841 | 176 | fcairo_stroke (cr); | ||
842 | 177 | //fcairo_pattern_destroy (pat); | ||
843 | 178 | |||
844 | 179 | xos++; | ||
845 | 180 | yos++; | ||
846 | 181 | |||
847 | 182 | /* enlarging the area to not draw the lightborder at bottom, ugly trick :P */ | ||
848 | 183 | fcairo_move_to (cr, x+radius+xos, y+yos); | ||
849 | 184 | fcairo_arc (cr, x+xos+width()-xos*2-radius, y+yos+radius, radius, mpi*1.5, mpi*2); | ||
850 | 185 | fcairo_line_to (cr, x+xos+width()-xos*2, y+yos+height()-yos*2+3); | ||
851 | 186 | fcairo_line_to (cr, x+xos, y+yos+height()-yos*2+3); | ||
852 | 187 | fcairo_arc (cr, x+xos+radius, y+yos+radius, radius, mpi, mpi*1.5); | ||
853 | 188 | |||
854 | 189 | /* | ||
855 | 190 | pat = fcairo_pattern_create_linear (x+xos, y, x+xos, y+height()-yos*2+3); | ||
856 | 191 | fcairo_pattern_add_color_stop_rgba (pat, 0.0, | ||
857 | 192 | bgbot.red, | ||
858 | 193 | bgbot.green, | ||
859 | 194 | bgbot.blue, | ||
860 | 195 | 1.0f); | ||
861 | 196 | fcairo_pattern_add_color_stop_rgba (pat, 1.0, | ||
862 | 197 | bgbot.red, | ||
863 | 198 | bgbot.green, | ||
864 | 199 | bgbot.blue, | ||
865 | 200 | 1.0f); | ||
866 | 201 | fcairo_set_source (cr, pat); | ||
867 | 202 | */ | ||
868 | 203 | fcairo_set_source_rgb (cr, bgbot.red, bgbot.green, bgbot.blue); | ||
869 | 204 | fcairo_stroke (cr); | ||
870 | 205 | //fcairo_pattern_destroy (pat); | ||
893 | 206 | } | 118 | } |
894 | 207 | 119 | ||
895 | 208 | void IndicatorEntryWidget::updatePix() | 120 | void IndicatorEntryWidget::updatePix() |
896 | @@ -213,6 +125,8 @@ | |||
897 | 213 | int iconX = m_padding; | 125 | int iconX = m_padding; |
898 | 214 | int labelX = 0; | 126 | int labelX = 0; |
899 | 215 | 127 | ||
900 | 128 | GObjectScopedPointer<PangoLayout> pangoLayout; | ||
901 | 129 | |||
902 | 216 | // Compute width, labelX and update m_has{Icon,Label} | 130 | // Compute width, labelX and update m_has{Icon,Label} |
903 | 217 | QPixmap iconPix; | 131 | QPixmap iconPix; |
904 | 218 | if (m_entry->image_visible()) { | 132 | if (m_entry->image_visible()) { |
905 | @@ -225,17 +139,18 @@ | |||
906 | 225 | width += iconPix.width(); | 139 | width += iconPix.width(); |
907 | 226 | } | 140 | } |
908 | 227 | 141 | ||
912 | 228 | QString label = QString::fromUtf8(m_entry->label().c_str()); | 142 | m_hasLabel = !m_entry->label().empty() && m_entry->label_visible(); |
910 | 229 | label = swapMnemonicChar(label, '_', '&'); | ||
911 | 230 | m_hasLabel = !label.isEmpty() && m_entry->label_visible(); | ||
913 | 231 | if (m_hasLabel) { | 143 | if (m_hasLabel) { |
914 | 232 | if (m_hasIcon) { | 144 | if (m_hasIcon) { |
915 | 233 | width += SPACING; | 145 | width += SPACING; |
916 | 234 | } | 146 | } |
917 | 235 | labelX = width; | 147 | labelX = width; |
921 | 236 | QString visibleLabel = label; | 148 | pangoLayout.reset(createPangoLayout()); |
922 | 237 | visibleLabel.remove('&'); | 149 | int labelWidth; |
923 | 238 | width += fontMetrics().width(visibleLabel); | 150 | int labelHeight; |
924 | 151 | pango_layout_get_pixel_size(pangoLayout.data(), &labelWidth, &labelHeight); | ||
925 | 152 | |||
926 | 153 | width += labelWidth; | ||
927 | 239 | } | 154 | } |
928 | 240 | 155 | ||
929 | 241 | width += m_padding; | 156 | width += m_padding; |
930 | @@ -245,38 +160,27 @@ | |||
931 | 245 | if (!m_hasIcon && !m_hasLabel) { | 160 | if (!m_hasIcon && !m_hasLabel) { |
932 | 246 | m_pix = QPixmap(); | 161 | m_pix = QPixmap(); |
933 | 247 | } else { | 162 | } else { |
937 | 248 | m_pix = QPixmap(width, 24); | 163 | QImage img(width, height(), QImage::Format_ARGB32_Premultiplied); |
938 | 249 | m_pix.fill(Qt::transparent); | 164 | QPainter painter(&img); |
936 | 250 | QPainter painter(&m_pix); | ||
939 | 251 | painter.initFrom(this); | 165 | painter.initFrom(this); |
940 | 166 | painter.eraseRect(img.rect()); | ||
941 | 167 | if (m_entry->active()) { | ||
942 | 168 | paintActiveBackground(&img); | ||
943 | 169 | } | ||
944 | 252 | if (m_hasIcon) { | 170 | if (m_hasIcon) { |
945 | 253 | bool disabled = !m_entry->image_sensitive(); | 171 | bool disabled = !m_entry->image_sensitive(); |
946 | 254 | if (disabled) { | 172 | if (disabled) { |
947 | 255 | painter.setOpacity(0.5); | 173 | painter.setOpacity(0.5); |
948 | 256 | } | 174 | } |
950 | 257 | painter.drawPixmap(iconX, 0, iconPix); | 175 | painter.drawPixmap(iconX, (height() - iconPix.height()) / 2, iconPix); |
951 | 258 | if (disabled) { | 176 | if (disabled) { |
952 | 259 | painter.setOpacity(1); | 177 | painter.setOpacity(1); |
953 | 260 | } | 178 | } |
954 | 261 | } | 179 | } |
955 | 262 | if (m_hasLabel) { | 180 | if (m_hasLabel) { |
972 | 263 | PanelStyle* style = PanelStyle::instance(); | 181 | paintLabel(&img, pangoLayout.data(), labelX); |
957 | 264 | |||
958 | 265 | int flags = Qt::AlignLeft | Qt::AlignVCenter; | ||
959 | 266 | flags |= m_entry->show_now() ? Qt::TextShowMnemonic : Qt::TextHideMnemonic; | ||
960 | 267 | |||
961 | 268 | // Shadow | ||
962 | 269 | QColor color = style->textShadowColor(); | ||
963 | 270 | color.setAlphaF(1. - color.redF()); | ||
964 | 271 | painter.setPen(color); | ||
965 | 272 | painter.drawText(labelX, 1, width - labelX, m_pix.height(), flags, label); | ||
966 | 273 | |||
967 | 274 | // Text | ||
968 | 275 | color = style->textColor(); | ||
969 | 276 | color.setAlphaF(m_entry->label_sensitive() ? 1. : .5); | ||
970 | 277 | painter.setPen(color); | ||
971 | 278 | painter.drawText(labelX, 0, width - labelX, m_pix.height(), flags, label); | ||
973 | 279 | } | 182 | } |
974 | 183 | m_pix = QPixmap::fromImage(img); | ||
975 | 280 | } | 184 | } |
976 | 281 | 185 | ||
977 | 282 | // Notify others we changed, but only trigger a layout update if necessary | 186 | // Notify others we changed, but only trigger a layout update if necessary |
978 | @@ -294,6 +198,80 @@ | |||
979 | 294 | } | 198 | } |
980 | 295 | } | 199 | } |
981 | 296 | 200 | ||
982 | 201 | PangoLayout* IndicatorEntryWidget::createPangoLayout() | ||
983 | 202 | { | ||
984 | 203 | // Parse | ||
985 | 204 | PangoAttrList* attrs = NULL; | ||
986 | 205 | if (m_entry->show_now()) { | ||
987 | 206 | if (!pango_parse_markup(m_entry->label().c_str(), | ||
988 | 207 | -1, | ||
989 | 208 | '_', | ||
990 | 209 | &attrs, | ||
991 | 210 | NULL, | ||
992 | 211 | NULL, | ||
993 | 212 | NULL)) | ||
994 | 213 | { | ||
995 | 214 | UQ_WARNING << "pango_parse_markup failed"; | ||
996 | 215 | } | ||
997 | 216 | } | ||
998 | 217 | |||
999 | 218 | // Create layout | ||
1000 | 219 | GObjectScopedPointer<PangoContext> pangoContext(gdk_pango_context_get()); | ||
1001 | 220 | PangoLayout* layout = pango_layout_new(pangoContext.data()); | ||
1002 | 221 | |||
1003 | 222 | if (attrs) { | ||
1004 | 223 | pango_layout_set_attributes(layout, attrs); | ||
1005 | 224 | pango_attr_list_unref(attrs); | ||
1006 | 225 | } | ||
1007 | 226 | |||
1008 | 227 | // Set font | ||
1009 | 228 | char* font_description = NULL; | ||
1010 | 229 | GtkSettings *settings = gtk_settings_get_default(); | ||
1011 | 230 | g_object_get(settings, | ||
1012 | 231 | "gtk-font-name", &font_description, | ||
1013 | 232 | NULL); | ||
1014 | 233 | PangoFontDescription* desc = pango_font_description_from_string(font_description); | ||
1015 | 234 | pango_font_description_set_weight(desc, PANGO_WEIGHT_NORMAL); | ||
1016 | 235 | pango_layout_set_font_description(layout, desc); | ||
1017 | 236 | pango_font_description_free(desc); | ||
1018 | 237 | g_free(font_description); | ||
1019 | 238 | |||
1020 | 239 | // Set text | ||
1021 | 240 | QString label = QString::fromUtf8(m_entry->label().c_str()); | ||
1022 | 241 | label.replace('_', QString()); | ||
1023 | 242 | QByteArray utf8Label = label.toUtf8(); | ||
1024 | 243 | pango_layout_set_text(layout, utf8Label.data(), -1); | ||
1025 | 244 | |||
1026 | 245 | return layout; | ||
1027 | 246 | } | ||
1028 | 247 | |||
1029 | 248 | void IndicatorEntryWidget::paintLabel(QImage* image, PangoLayout* layout, int labelX) | ||
1030 | 249 | { | ||
1031 | 250 | // This code should be kept in sync with corresponding unityshell code from | ||
1032 | 251 | // plugins/unityshell/src/PanelIndicatorObjectEntryView.cpp | ||
1033 | 252 | int labelWidth, labelHeight; | ||
1034 | 253 | pango_layout_get_pixel_size(layout, &labelWidth, &labelHeight); | ||
1035 | 254 | CairoUtils::SurfacePointer surface(CairoUtils::createSurfaceForQImage(image)); | ||
1036 | 255 | CairoUtils::Pointer cr(cairo_create(surface.data())); | ||
1037 | 256 | pango_cairo_update_layout(cr.data(), layout); | ||
1038 | 257 | |||
1039 | 258 | PanelStyle* style = PanelStyle::instance(); | ||
1040 | 259 | GtkStyleContext* styleContext = style->styleContext(); | ||
1041 | 260 | |||
1042 | 261 | gtk_style_context_save(styleContext); | ||
1043 | 262 | |||
1044 | 263 | gtk_style_context_set_path(styleContext, m_gtkWidgetPath); | ||
1045 | 264 | gtk_style_context_add_class(styleContext, GTK_STYLE_CLASS_MENUBAR); | ||
1046 | 265 | gtk_style_context_add_class(styleContext, GTK_STYLE_CLASS_MENUITEM); | ||
1047 | 266 | |||
1048 | 267 | if (m_entry->active()) { | ||
1049 | 268 | gtk_style_context_set_state(styleContext, GTK_STATE_FLAG_PRELIGHT); | ||
1050 | 269 | } | ||
1051 | 270 | |||
1052 | 271 | gtk_render_layout(styleContext, cr.data(), labelX, (image->height() - labelHeight) / 2, layout); | ||
1053 | 272 | gtk_style_context_restore(styleContext); | ||
1054 | 273 | } | ||
1055 | 274 | |||
1056 | 297 | QPixmap IndicatorEntryWidget::decodeIcon() | 275 | QPixmap IndicatorEntryWidget::decodeIcon() |
1057 | 298 | { | 276 | { |
1058 | 299 | QPixmap pix; | 277 | QPixmap pix; |
1059 | 300 | 278 | ||
1060 | === modified file 'panel/applets/common/indicatorentrywidget.h' | |||
1061 | --- panel/applets/common/indicatorentrywidget.h 2011-07-27 15:41:41 +0000 | |||
1062 | +++ panel/applets/common/indicatorentrywidget.h 2011-07-27 15:41:41 +0000 | |||
1063 | @@ -29,6 +29,9 @@ | |||
1064 | 29 | // Qt | 29 | // Qt |
1065 | 30 | #include <QWidget> | 30 | #include <QWidget> |
1066 | 31 | 31 | ||
1067 | 32 | struct _GtkWidgetPath; | ||
1068 | 33 | struct _PangoLayout; | ||
1069 | 34 | |||
1070 | 32 | class QPainter; | 35 | class QPainter; |
1071 | 33 | 36 | ||
1072 | 34 | class IndicatorEntryWidget : public QWidget, public sigc::trackable | 37 | class IndicatorEntryWidget : public QWidget, public sigc::trackable |
1073 | @@ -36,6 +39,7 @@ | |||
1074 | 36 | Q_OBJECT | 39 | Q_OBJECT |
1075 | 37 | public: | 40 | public: |
1076 | 38 | IndicatorEntryWidget(const unity::indicator::Entry::Ptr& entry); | 41 | IndicatorEntryWidget(const unity::indicator::Entry::Ptr& entry); |
1077 | 42 | ~IndicatorEntryWidget(); | ||
1078 | 39 | 43 | ||
1079 | 40 | QSize minimumSizeHint() const; | 44 | QSize minimumSizeHint() const; |
1080 | 41 | QSize sizeHint() const; | 45 | QSize sizeHint() const; |
1081 | @@ -61,6 +65,7 @@ | |||
1082 | 61 | void isEmptyChanged(); | 65 | void isEmptyChanged(); |
1083 | 62 | 66 | ||
1084 | 63 | protected: | 67 | protected: |
1085 | 68 | void resizeEvent(QResizeEvent*); | ||
1086 | 64 | void paintEvent(QPaintEvent*); | 69 | void paintEvent(QPaintEvent*); |
1087 | 65 | void mousePressEvent(QMouseEvent*); | 70 | void mousePressEvent(QMouseEvent*); |
1088 | 66 | void mouseReleaseEvent(QMouseEvent*); | 71 | void mouseReleaseEvent(QMouseEvent*); |
1089 | @@ -73,9 +78,13 @@ | |||
1090 | 73 | int m_padding; | 78 | int m_padding; |
1091 | 74 | bool m_hasIcon; | 79 | bool m_hasIcon; |
1092 | 75 | bool m_hasLabel; | 80 | bool m_hasLabel; |
1093 | 81 | struct _GtkWidgetPath* m_gtkWidgetPath; | ||
1094 | 76 | void updatePix(); | 82 | void updatePix(); |
1095 | 77 | QPixmap decodeIcon(); | 83 | QPixmap decodeIcon(); |
1097 | 78 | void paintActiveBackground(QPainter*); | 84 | void paintActiveBackground(QImage*); |
1098 | 85 | |||
1099 | 86 | struct _PangoLayout* createPangoLayout(); | ||
1100 | 87 | void paintLabel(QImage*, struct _PangoLayout*, int labelX); | ||
1101 | 79 | }; | 88 | }; |
1102 | 80 | 89 | ||
1103 | 81 | #endif /* INDICATORENTRYWIDGET_H */ | 90 | #endif /* INDICATORENTRYWIDGET_H */ |
1104 | 82 | 91 | ||
1105 | === modified file 'panel/applets/common/panelstyle.cpp' | |||
1106 | --- panel/applets/common/panelstyle.cpp 2011-07-27 15:41:41 +0000 | |||
1107 | +++ panel/applets/common/panelstyle.cpp 2011-07-27 15:41:41 +0000 | |||
1108 | @@ -22,92 +22,54 @@ | |||
1109 | 22 | #include "panelstyle.h" | 22 | #include "panelstyle.h" |
1110 | 23 | 23 | ||
1111 | 24 | // libunity-2d | 24 | // libunity-2d |
1112 | 25 | #include <cairoutils.h> | ||
1113 | 25 | #include <debug_p.h> | 26 | #include <debug_p.h> |
1114 | 26 | #include <gconnector.h> | 27 | #include <gconnector.h> |
1115 | 27 | #include <gscopedpointer.h> | 28 | #include <gscopedpointer.h> |
1116 | 28 | 29 | ||
1117 | 29 | // Qt | 30 | // Qt |
1118 | 30 | #include <QApplication> | 31 | #include <QApplication> |
1119 | 31 | #include <QColor> | ||
1120 | 32 | #include <QFont> | ||
1121 | 33 | #include <QPalette> | 32 | #include <QPalette> |
1122 | 34 | 33 | ||
1123 | 35 | // GTK | 34 | // GTK |
1124 | 36 | #include <gtk/gtk.h> | 35 | #include <gtk/gtk.h> |
1125 | 37 | #include <pango/pango.h> | ||
1126 | 38 | |||
1127 | 39 | typedef void (*ColorGetter)(GtkStyleContext*, GtkStateFlags, GdkRGBA*); | ||
1128 | 40 | |||
1129 | 41 | inline QColor colorFromContext(ColorGetter getter, GtkStyleContext* context, GtkStateFlags state) | ||
1130 | 42 | { | ||
1131 | 43 | GdkRGBA color; | ||
1132 | 44 | getter(context, state, &color); | ||
1133 | 45 | return QColor::fromRgbF(color.red, color.green, color.blue, color.alpha); | ||
1134 | 46 | } | ||
1135 | 47 | 36 | ||
1136 | 48 | class PanelStylePrivate | 37 | class PanelStylePrivate |
1137 | 49 | { | 38 | { |
1138 | 50 | public: | 39 | public: |
1139 | 51 | PanelStyle* q; | 40 | PanelStyle* q; |
1141 | 52 | GtkWidget* m_offScreenWindow; | 41 | GObjectScopedPointer<GtkStyleContext> m_styleContext; |
1142 | 53 | GConnector m_gConnector; | 42 | GConnector m_gConnector; |
1143 | 54 | 43 | ||
1144 | 55 | QColor m_textColor; | ||
1145 | 56 | QColor m_backgroundTopColor; | ||
1146 | 57 | QColor m_backgroundBottomColor; | ||
1147 | 58 | QColor m_textShadowColor; | ||
1148 | 59 | QColor m_lineColor; | ||
1149 | 60 | QFont m_font; | ||
1150 | 61 | |||
1151 | 62 | static void onThemeChanged(GObject*, GParamSpec*, gpointer data) | 44 | static void onThemeChanged(GObject*, GParamSpec*, gpointer data) |
1152 | 63 | { | 45 | { |
1153 | 64 | PanelStylePrivate* priv = reinterpret_cast<PanelStylePrivate*>(data); | 46 | PanelStylePrivate* priv = reinterpret_cast<PanelStylePrivate*>(data); |
1154 | 65 | priv->updatePalette(); | 47 | priv->updatePalette(); |
1155 | 66 | } | 48 | } |
1156 | 67 | 49 | ||
1157 | 68 | static void onFontChanged(GObject*, GParamSpec*, gpointer data) | ||
1158 | 69 | { | ||
1159 | 70 | PanelStylePrivate* priv = reinterpret_cast<PanelStylePrivate*>(data); | ||
1160 | 71 | priv->updateFont(); | ||
1161 | 72 | } | ||
1162 | 73 | |||
1163 | 74 | void updatePalette() | 50 | void updatePalette() |
1164 | 75 | { | 51 | { |
1167 | 76 | GtkStyleContext* context = gtk_widget_get_style_context(m_offScreenWindow); | 52 | GtkStyleContext* context = m_styleContext.data(); |
1168 | 77 | UQ_RETURN_IF_FAIL(context); | 53 | gtk_style_context_invalidate(context); |
1169 | 78 | 54 | ||
1175 | 79 | m_textColor = colorFromContext(gtk_style_context_get_color, context, GTK_STATE_FLAG_NORMAL); | 55 | // Without this line, it seems the GtkStyleContext is not correctly |
1176 | 80 | m_textShadowColor = colorFromContext(gtk_style_context_get_color, context, GTK_STATE_FLAG_SELECTED); | 56 | // initialized and we get some uninitialized pixels in the background |
1177 | 81 | m_lineColor = colorFromContext(gtk_style_context_get_background_color, context, GTK_STATE_FLAG_NORMAL).darker(130); | 57 | // brush. |
1178 | 82 | m_backgroundTopColor = colorFromContext(gtk_style_context_get_background_color, context, GTK_STATE_FLAG_ACTIVE); | 58 | gtk_style_context_get(context, GTK_STATE_FLAG_NORMAL, NULL); |
1174 | 83 | m_backgroundBottomColor = colorFromContext(gtk_style_context_get_background_color, context, GTK_STATE_FLAG_NORMAL); | ||
1179 | 84 | 59 | ||
1180 | 85 | QPalette pal; | 60 | QPalette pal; |
1186 | 86 | pal.setColor(QPalette::Window, m_backgroundTopColor); | 61 | pal.setBrush(QPalette::Window, generateBackgroundBrush()); |
1182 | 87 | pal.setColor(QPalette::Button, m_backgroundTopColor); | ||
1183 | 88 | pal.setColor(QPalette::Text, m_textColor); | ||
1184 | 89 | pal.setColor(QPalette::WindowText, m_textColor); | ||
1185 | 90 | pal.setColor(QPalette::ButtonText, m_textColor); | ||
1187 | 91 | QApplication::setPalette(pal); | 62 | QApplication::setPalette(pal); |
1188 | 92 | } | 63 | } |
1189 | 93 | 64 | ||
1191 | 94 | void updateFont() | 65 | QBrush generateBackgroundBrush() |
1192 | 95 | { | 66 | { |
1208 | 96 | gchar* fontName = 0; | 67 | QImage image(100, 24, QImage::Format_ARGB32_Premultiplied); // FIXME: Hardcoded |
1209 | 97 | g_object_get(gtk_settings_get_default(), "gtk-font-name", &fontName, NULL); | 68 | image.fill(Qt::transparent); |
1210 | 98 | GScopedPointer<PangoFontDescription, pango_font_description_free> fontDescription( | 69 | CairoUtils::SurfacePointer surface(CairoUtils::createSurfaceForQImage(&image)); |
1211 | 99 | pango_font_description_from_string(fontName) | 70 | CairoUtils::Pointer cr(cairo_create(surface.data())); |
1212 | 100 | ); | 71 | gtk_render_background(m_styleContext.data(), cr.data(), 0, 0, image.width(), image.height()); |
1213 | 101 | g_free(fontName); | 72 | return QBrush(image); |
1199 | 102 | |||
1200 | 103 | int size = pango_font_description_get_size(fontDescription.data()); | ||
1201 | 104 | |||
1202 | 105 | m_font = QFont( | ||
1203 | 106 | pango_font_description_get_family(fontDescription.data()), | ||
1204 | 107 | size / PANGO_SCALE | ||
1205 | 108 | ); | ||
1206 | 109 | |||
1207 | 110 | QApplication::setFont(m_font); | ||
1214 | 111 | } | 73 | } |
1215 | 112 | }; | 74 | }; |
1216 | 113 | 75 | ||
1217 | @@ -115,24 +77,26 @@ | |||
1218 | 115 | : d(new PanelStylePrivate) | 77 | : d(new PanelStylePrivate) |
1219 | 116 | { | 78 | { |
1220 | 117 | d->q = this; | 79 | d->q = this; |
1226 | 118 | d->m_offScreenWindow = gtk_offscreen_window_new(); | 80 | d->m_styleContext.reset(gtk_style_context_new()); |
1227 | 119 | gtk_widget_set_name(d->m_offScreenWindow, "UnityPanelWidget"); | 81 | |
1228 | 120 | gtk_widget_set_size_request(d->m_offScreenWindow, 100, 24); | 82 | GtkWidgetPath* widgetPath = gtk_widget_path_new (); |
1229 | 121 | gtk_style_context_add_class(gtk_widget_get_style_context(d->m_offScreenWindow), "menubar"); | 83 | gtk_widget_path_append_type(widgetPath, GTK_TYPE_WINDOW); |
1230 | 122 | gtk_widget_show_all(d->m_offScreenWindow); | 84 | gtk_widget_path_iter_set_name(widgetPath, -1 , "UnityPanelWidget"); |
1231 | 85 | |||
1232 | 86 | gtk_style_context_set_path(d->m_styleContext.data(), widgetPath); | ||
1233 | 87 | gtk_style_context_add_class(d->m_styleContext.data(), "gnome-panel-menu-bar"); | ||
1234 | 88 | gtk_style_context_add_class(d->m_styleContext.data(), "unity-panel"); | ||
1235 | 89 | |||
1236 | 90 | gtk_widget_path_free (widgetPath); | ||
1237 | 123 | 91 | ||
1238 | 124 | d->m_gConnector.connect(gtk_settings_get_default(), "notify::gtk-theme-name", | 92 | d->m_gConnector.connect(gtk_settings_get_default(), "notify::gtk-theme-name", |
1239 | 125 | G_CALLBACK(PanelStylePrivate::onThemeChanged), d); | 93 | G_CALLBACK(PanelStylePrivate::onThemeChanged), d); |
1240 | 126 | d->m_gConnector.connect(gtk_settings_get_default(), "notify::gtk-font-name", | ||
1241 | 127 | G_CALLBACK(PanelStylePrivate::onFontChanged), d); | ||
1242 | 128 | 94 | ||
1243 | 129 | d->updatePalette(); | 95 | d->updatePalette(); |
1244 | 130 | d->updateFont(); | ||
1245 | 131 | } | 96 | } |
1246 | 132 | 97 | ||
1247 | 133 | PanelStyle::~PanelStyle() | 98 | PanelStyle::~PanelStyle() |
1248 | 134 | { | 99 | { |
1249 | 135 | gtk_widget_destroy(d->m_offScreenWindow); | ||
1250 | 136 | delete d; | 100 | delete d; |
1251 | 137 | } | 101 | } |
1252 | 138 | 102 | ||
1253 | @@ -142,34 +106,9 @@ | |||
1254 | 142 | return &style; | 106 | return &style; |
1255 | 143 | } | 107 | } |
1256 | 144 | 108 | ||
1285 | 145 | QColor PanelStyle::textColor() const | 109 | GtkStyleContext* PanelStyle::styleContext() const |
1286 | 146 | { | 110 | { |
1287 | 147 | return d->m_textColor; | 111 | return d->m_styleContext.data(); |
1260 | 148 | } | ||
1261 | 149 | |||
1262 | 150 | QColor PanelStyle::backgroundTopColor() const | ||
1263 | 151 | { | ||
1264 | 152 | return d->m_backgroundTopColor; | ||
1265 | 153 | } | ||
1266 | 154 | |||
1267 | 155 | QColor PanelStyle::backgroundBottomColor() const | ||
1268 | 156 | { | ||
1269 | 157 | return d->m_backgroundBottomColor; | ||
1270 | 158 | } | ||
1271 | 159 | |||
1272 | 160 | QColor PanelStyle::textShadowColor() const | ||
1273 | 161 | { | ||
1274 | 162 | return d->m_textShadowColor; | ||
1275 | 163 | } | ||
1276 | 164 | |||
1277 | 165 | QColor PanelStyle::lineColor() const | ||
1278 | 166 | { | ||
1279 | 167 | return d->m_lineColor; | ||
1280 | 168 | } | ||
1281 | 169 | |||
1282 | 170 | QFont PanelStyle::font() const | ||
1283 | 171 | { | ||
1284 | 172 | return d->m_font; | ||
1288 | 173 | } | 112 | } |
1289 | 174 | 113 | ||
1290 | 175 | #include "panelstyle.moc" | 114 | #include "panelstyle.moc" |
1291 | 176 | 115 | ||
1292 | === modified file 'panel/applets/common/panelstyle.h' | |||
1293 | --- panel/applets/common/panelstyle.h 2011-07-27 15:41:41 +0000 | |||
1294 | +++ panel/applets/common/panelstyle.h 2011-07-27 15:41:41 +0000 | |||
1295 | @@ -26,12 +26,15 @@ | |||
1296 | 26 | // Qt | 26 | // Qt |
1297 | 27 | #include <QObject> | 27 | #include <QObject> |
1298 | 28 | 28 | ||
1301 | 29 | class QColor; | 29 | struct _GtkStyleContext; |
1300 | 30 | class QFont; | ||
1302 | 31 | 30 | ||
1303 | 32 | class PanelStylePrivate; | 31 | class PanelStylePrivate; |
1304 | 33 | /** | 32 | /** |
1306 | 34 | * Provides easy access to panel colors | 33 | * Provides easy access to panel style context and track platform theme to |
1307 | 34 | * ensure we have the correct background brush. | ||
1308 | 35 | * | ||
1309 | 36 | * FIXME: This class does not have a very clear focus and has side-effects | ||
1310 | 37 | * (background brush handling). It should be refactored. | ||
1311 | 35 | */ | 38 | */ |
1312 | 36 | class PanelStyle : public QObject | 39 | class PanelStyle : public QObject |
1313 | 37 | { | 40 | { |
1314 | @@ -42,13 +45,7 @@ | |||
1315 | 42 | 45 | ||
1316 | 43 | static PanelStyle* instance(); | 46 | static PanelStyle* instance(); |
1317 | 44 | 47 | ||
1325 | 45 | QColor textColor() const; | 48 | struct _GtkStyleContext* styleContext() const; |
1319 | 46 | QColor backgroundTopColor() const; | ||
1320 | 47 | QColor backgroundBottomColor() const; | ||
1321 | 48 | QColor textShadowColor() const; | ||
1322 | 49 | QColor lineColor() const; | ||
1323 | 50 | |||
1324 | 51 | QFont font() const; | ||
1326 | 52 | 49 | ||
1327 | 53 | private: | 50 | private: |
1328 | 54 | friend class PanelStylePrivate; | 51 | friend class PanelStylePrivate; |
1329 | 55 | 52 | ||
1330 | === modified file 'panel/applets/homebutton/homebutton.cpp' | |||
1331 | --- panel/applets/homebutton/homebutton.cpp 2011-05-26 16:41:04 +0000 | |||
1332 | +++ panel/applets/homebutton/homebutton.cpp 2011-07-27 15:41:41 +0000 | |||
1333 | @@ -40,8 +40,10 @@ | |||
1334 | 40 | setStyleSheet( | 40 | setStyleSheet( |
1335 | 41 | "QToolButton { border: none; margin: 0; padding: 0; width: 61 }" | 41 | "QToolButton { border: none; margin: 0; padding: 0; width: 61 }" |
1336 | 42 | "QToolButton:checked, QToolButton:pressed {" | 42 | "QToolButton:checked, QToolButton:pressed {" |
1339 | 43 | // Use border-image here, not background-image, because bfb_bg_active.png is 56px wide | 43 | " padding-top: 1px;" |
1340 | 44 | " border-image: url(theme:/bfb_bg_active.png);" | 44 | " padding-left: 1px;" |
1341 | 45 | " padding-right: -1px;" | ||
1342 | 46 | " padding-bottom: -1px;" | ||
1343 | 45 | "}" | 47 | "}" |
1344 | 46 | ); | 48 | ); |
1345 | 47 | } | 49 | } |