Merge lp:~agateau/unity-2d/use-gtk-rendering into lp:unity-2d

Proposed by Aurélien Gâteau
Status: Superseded
Proposed branch: lp:~agateau/unity-2d/use-gtk-rendering
Merge into: lp:unity-2d
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
Reviewer Review Type Date Requested Status
Florian Boucault Pending
Review via email: mp+69489@code.launchpad.net

This proposal supersedes a proposal from 2011-07-25.

This proposal has been superseded by a proposal from 2011-07-27.

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.

To post a comment you must log in.
Revision history for this message
Bob The Builder (bobthebuilder-deactivatedaccount) wrote :

No proposals found for merge of lp:~agateau/unity-2d/unity-core into lp:unity-2d/4.0.

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'CMakeLists.txt'
--- CMakeLists.txt 2011-07-27 11:59:05 +0000
+++ CMakeLists.txt 2011-07-27 15:51:26 +0000
@@ -29,6 +29,7 @@
29pkg_check_modules(GTK REQUIRED gtk+-3.0)29pkg_check_modules(GTK REQUIRED gtk+-3.0)
30pkg_check_modules(GIO REQUIRED gio-2.0)30pkg_check_modules(GIO REQUIRED gio-2.0)
31pkg_check_modules(WNCK REQUIRED libwnck-3.0)31pkg_check_modules(WNCK REQUIRED libwnck-3.0)
32pkg_check_modules(QTGCONF REQUIRED libqtgconf)
3233
3334
34# GSettings schemas35# GSettings schemas
3536
=== modified file 'libunity-2d-private/src/CMakeLists.txt'
--- libunity-2d-private/src/CMakeLists.txt 2011-07-27 11:59:05 +0000
+++ libunity-2d-private/src/CMakeLists.txt 2011-07-27 15:51:26 +0000
@@ -31,6 +31,8 @@
31 ${CMAKE_CURRENT_BINARY_DIR}31 ${CMAKE_CURRENT_BINARY_DIR}
32 ${CMAKE_CURRENT_SOURCE_DIR}32 ${CMAKE_CURRENT_SOURCE_DIR}
33 ${GLIB_INCLUDE_DIRS}33 ${GLIB_INCLUDE_DIRS}
34 ${GTK_INCLUDE_DIRS}
35 ${PANGO_INCLUDE_DIRS}
34 ${WNCK_INCLUDE_DIRS}36 ${WNCK_INCLUDE_DIRS}
35 )37 )
3638
@@ -48,6 +50,8 @@
48 ${QT_QTOPENGL_LIBRARIES}50 ${QT_QTOPENGL_LIBRARIES}
49 ${X11_LIBRARIES}51 ${X11_LIBRARIES}
50 ${GLIB_LDFLAGS}52 ${GLIB_LDFLAGS}
53 ${GTK_LDFLAGS}
54 ${PANGO_LDFLAGS}
51 ${WNCK_LDFLAGS}55 ${WNCK_LDFLAGS}
52 )56 )
5357
5458
=== modified file 'libunity-2d-private/src/unity2dapplication.cpp'
--- libunity-2d-private/src/unity2dapplication.cpp 2011-07-27 11:59:05 +0000
+++ libunity-2d-private/src/unity2dapplication.cpp 2011-07-27 15:51:26 +0000
@@ -25,14 +25,59 @@
2525
26// libunity-2d26// libunity-2d
27#include <debug_p.h>27#include <debug_p.h>
28#include <gconnector.h>
29#include <gscopedpointer.h>
28#include <unity2ddebug.h>30#include <unity2ddebug.h>
2931
30// Qt32// Qt
33#include <QFont>
31#include <QWindowsStyle>34#include <QWindowsStyle>
3235
33// GTK36// GTK
34#include <gtk/gtk.h>37#include <gtk/gtk.h>
3538#include <pango/pango.h>
39
40///////////////////////////////
41class PlatformFontTracker
42{
43public:
44 PlatformFontTracker()
45 {
46 m_gConnector.connect(gtk_settings_get_default(), "notify::gtk-font-name",
47 G_CALLBACK(PlatformFontTracker::onFontChanged), this);
48
49 updateFont();
50 }
51
52private:
53 void updateFont()
54 {
55 gchar* fontName = 0;
56 g_object_get(gtk_settings_get_default(), "gtk-font-name", &fontName, NULL);
57 GScopedPointer<PangoFontDescription, pango_font_description_free> fontDescription(
58 pango_font_description_from_string(fontName)
59 );
60 g_free(fontName);
61
62 int size = pango_font_description_get_size(fontDescription.data());
63
64 QFont font = QFont(
65 pango_font_description_get_family(fontDescription.data()),
66 size / PANGO_SCALE
67 );
68
69 QApplication::setFont(font);
70 }
71
72 static void onFontChanged(GObject*, GParamSpec*, PlatformFontTracker* obj)
73 {
74 obj->updateFont();
75 }
76
77 GConnector m_gConnector;
78};
79
80///////////////////////////////
36AbstractX11EventFilter::~AbstractX11EventFilter()81AbstractX11EventFilter::~AbstractX11EventFilter()
37{82{
38 Unity2dApplication* application = Unity2dApplication::instance();83 Unity2dApplication* application = Unity2dApplication::instance();
@@ -41,6 +86,7 @@
41 }86 }
42}87}
4388
89///////////////////////////////
44static bool arrayContains(char** begin, char** end, const char* string)90static bool arrayContains(char** begin, char** end, const char* string)
45{91{
46 for (char** ptr = begin; ptr != end; ++ptr) {92 for (char** ptr = begin; ptr != end; ++ptr) {
@@ -83,6 +129,7 @@
83129
84Unity2dApplication::Unity2dApplication(int& argc, char** argv)130Unity2dApplication::Unity2dApplication(int& argc, char** argv)
85: QApplication(argc, argv)131: QApplication(argc, argv)
132, m_platformFontTracker(new PlatformFontTracker)
86{133{
87 /* Allow developers to run Unity 2D uninstalled by telling dconf-qt134 /* Allow developers to run Unity 2D uninstalled by telling dconf-qt
88 where to look for Unity 2D's schemas.135 where to look for Unity 2D's schemas.
@@ -96,6 +143,7 @@
96Unity2dApplication::~Unity2dApplication()143Unity2dApplication::~Unity2dApplication()
97{144{
98 qDeleteAll(m_x11EventFilters);145 qDeleteAll(m_x11EventFilters);
146 delete m_platformFontTracker;
99}147}
100148
101Unity2dApplication* Unity2dApplication::instance()149Unity2dApplication* Unity2dApplication::instance()
102150
=== modified file 'libunity-2d-private/src/unity2dapplication.h'
--- libunity-2d-private/src/unity2dapplication.h 2011-07-18 14:36:34 +0000
+++ libunity-2d-private/src/unity2dapplication.h 2011-07-27 15:51:26 +0000
@@ -27,6 +27,8 @@
2727
28class Unity2dApplication;28class Unity2dApplication;
2929
30class PlatformFontTracker;
31
30class AbstractX11EventFilter32class AbstractX11EventFilter
31{33{
32public:34public:
@@ -65,6 +67,7 @@
6567
66private:68private:
67 QList<AbstractX11EventFilter*> m_x11EventFilters;69 QList<AbstractX11EventFilter*> m_x11EventFilters;
70 PlatformFontTracker* m_platformFontTracker;
68};71};
6972
70#endif // UNITY2DAPPLICATION_H73#endif // UNITY2DAPPLICATION_H
7174
=== modified file 'panel/applets/CMakeLists.txt'
--- panel/applets/CMakeLists.txt 2011-07-27 12:44:39 +0000
+++ panel/applets/CMakeLists.txt 2011-07-27 15:51:26 +0000
@@ -12,12 +12,14 @@
12 appindicator/appindicatorapplet.cpp12 appindicator/appindicatorapplet.cpp
13 appindicator/sniitem.cpp13 appindicator/sniitem.cpp
14 appname/appnameapplet.cpp14 appname/appnameapplet.cpp
15 appname/croppedlabel.cpp
15 appname/menubarwidget.cpp16 appname/menubarwidget.cpp
16 appname/windowhelper.cpp17 appname/windowhelper.cpp
17 common/applet.cpp18 common/applet.cpp
18 common/indicatorentrywidget.cpp19 common/indicatorentrywidget.cpp
19 common/indicatorsmanager.cpp20 common/indicatorsmanager.cpp
20 common/indicatorwidget.cpp21 common/indicatorwidget.cpp
22 common/cairoutils.cpp
21 common/panelstyle.cpp23 common/panelstyle.cpp
22 homebutton/homebuttonapplet.cpp24 homebutton/homebuttonapplet.cpp
23 homebutton/homebutton.cpp25 homebutton/homebutton.cpp
@@ -41,6 +43,7 @@
41 ${CMAKE_CURRENT_SOURCE_DIR}/indicator43 ${CMAKE_CURRENT_SOURCE_DIR}/indicator
42 ${CMAKE_CURRENT_SOURCE_DIR}/unitycore44 ${CMAKE_CURRENT_SOURCE_DIR}/unitycore
43 ${QTBAMF_INCLUDE_DIRS}45 ${QTBAMF_INCLUDE_DIRS}
46 ${QTGCONF_INCLUDE_DIRS}
44 ${DBUSMENUQT_INCLUDE_DIRS}47 ${DBUSMENUQT_INCLUDE_DIRS}
45 ${GTK_INCLUDE_DIRS}48 ${GTK_INCLUDE_DIRS}
46 ${WNCK_INCLUDE_DIRS}49 ${WNCK_INCLUDE_DIRS}
@@ -58,6 +61,7 @@
58 ${QT_QTCORE_LIBRARIES}61 ${QT_QTCORE_LIBRARIES}
59 ${DBUSMENUQT_LDFLAGS}62 ${DBUSMENUQT_LDFLAGS}
60 ${QTBAMF_LDFLAGS}63 ${QTBAMF_LDFLAGS}
64 ${QTGCONF_LDFLAGS}
61 ${GTK_LDFLAGS}65 ${GTK_LDFLAGS}
62 ${WNCK_LDFLAGS}66 ${WNCK_LDFLAGS}
63 ${X11_LIBRARIES}67 ${X11_LIBRARIES}
6468
=== modified file 'panel/applets/appname/appnameapplet.cpp'
--- panel/applets/appname/appnameapplet.cpp 2011-07-27 11:59:05 +0000
+++ panel/applets/appname/appnameapplet.cpp 2011-07-27 15:51:26 +0000
@@ -23,6 +23,7 @@
23#include "appnameapplet.h"23#include "appnameapplet.h"
2424
25// Local25// Local
26#include "croppedlabel.h"
26#include "menubarwidget.h"27#include "menubarwidget.h"
27#include "windowhelper.h"28#include "windowhelper.h"
2829
@@ -49,9 +50,7 @@
4950
50static const int WINDOW_BUTTONS_RIGHT_MARGIN = 4;51static const int WINDOW_BUTTONS_RIGHT_MARGIN = 4;
5152
52static const int APPNAME_LABEL_LEFT_MARGIN = 12;53static const int APPNAME_LABEL_LEFT_MARGIN = 6;
53
54static const int FADEOUT_WIDTH = 16;
5554
56namespace Unity2d55namespace Unity2d
57{56{
@@ -106,50 +105,6 @@
106 }105 }
107};106};
108107
109/**
110 * This label makes sure minimumSizeHint() is not set. This ensures the applet
111 * does not get wider if a window title is very long
112 */
113class CroppedLabel : public QLabel
114{
115public:
116 CroppedLabel(QWidget* parent = 0)
117 : QLabel(parent)
118 {}
119
120 QSize minimumSizeHint() const
121 {
122 return QWidget::minimumSizeHint();
123 }
124
125protected:
126 void paintEvent(QPaintEvent* event)
127 {
128 QImage image(width(), height(), QImage::Format_ARGB32_Premultiplied);
129 {
130 QPainter painter(&image);
131 painter.initFrom(this);
132 painter.setCompositionMode(QPainter::CompositionMode_Source);
133 painter.fillRect(rect(), Qt::transparent);
134
135 painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
136 painter.drawText(contentsRect(), Qt::AlignLeft | Qt::AlignVCenter, text());
137
138 if (QLabel::minimumSizeHint().width() > contentsRect().width()) {
139 // Text does not fit, fade the end
140 painter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
141 QRect gradientRect(width() - FADEOUT_WIDTH, 0, FADEOUT_WIDTH, height());
142 QLinearGradient gradient(gradientRect.topLeft(), gradientRect.topRight());
143 gradient.setColorAt(0, Qt::white);
144 gradient.setColorAt(1, Qt::transparent);
145 painter.fillRect(gradientRect, gradient);
146 }
147 }
148 QPainter painter(this);
149 painter.drawImage(0, 0, image);
150 }
151};
152
153struct AppNameAppletPrivate108struct AppNameAppletPrivate
154{109{
155 AppNameApplet* q;110 AppNameApplet* q;
156111
=== added file 'panel/applets/appname/croppedlabel.cpp'
--- panel/applets/appname/croppedlabel.cpp 1970-01-01 00:00:00 +0000
+++ panel/applets/appname/croppedlabel.cpp 2011-07-27 15:51:26 +0000
@@ -0,0 +1,140 @@
1/*
2 * This file is part of unity-2d
3 *
4 * Copyright 2011 Canonical Ltd.
5 *
6 * Authors:
7 * - Aurélien Gâteau <aurelien.gateau@canonical.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; version 3.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21// Self
22#include "croppedlabel.h"
23
24// Local
25#include <cairoutils.h>
26#include <panelstyle.h>
27
28// unity-2d
29#include <debug_p.h>
30
31// libqtgconf
32#include <gconfitem-qml-wrapper.h>
33
34// Qt
35#include <QImage>
36#include <QPainter>
37
38// GTK
39#include <gtk/gtk.h>
40
41static const int FADEOUT_WIDTH = 30;
42
43static const char* WINDOW_TITLE_FONT_KEY = "/apps/metacity/general/titlebar_font";
44
45CroppedLabel::CroppedLabel(QWidget* parent)
46: QLabel(parent)
47{
48}
49
50QSize CroppedLabel::minimumSizeHint() const
51{
52 return QWidget::minimumSizeHint();
53}
54
55static void paintFadeoutGradient(QImage* image)
56{
57 QPainter painter(image);
58 painter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
59 QRect gradientRect(image->width() - FADEOUT_WIDTH, 0, FADEOUT_WIDTH, image->height());
60 QLinearGradient gradient(gradientRect.topLeft(), gradientRect.topRight());
61 gradient.setColorAt(0, Qt::white);
62 gradient.setColorAt(1, Qt::transparent);
63 painter.fillRect(gradientRect, gradient);
64}
65
66static QString getWindowTitleFontName()
67{
68 GConfItemQmlWrapper client;
69 client.setKey(WINDOW_TITLE_FONT_KEY);
70 return client.getValue().toString();
71}
72
73void CroppedLabel::paintEvent(QPaintEvent* event)
74{
75 // Create an image filled with background brush (to avoid subpixel hinting
76 // artefacts around text)
77 QImage image(width(), height(), QImage::Format_ARGB32_Premultiplied);
78 {
79 QPainter painter(&image);
80 painter.initFrom(this);
81 painter.eraseRect(rect());
82 }
83
84 // Create a pango layout
85 GObjectScopedPointer<PangoContext> pangoContext(gdk_pango_context_get());
86 GObjectScopedPointer<PangoLayout> layout(pango_layout_new(pangoContext.data()));
87
88 // Set font
89 QByteArray fontName = getWindowTitleFontName().toUtf8();
90 PangoFontDescription* desc = pango_font_description_from_string(fontName.data());
91 pango_layout_set_font_description(layout.data(), desc);
92 pango_font_description_free(desc);
93
94 // Set text
95 QByteArray utf8Text = text().toUtf8();
96 pango_layout_set_text (layout.data(), utf8Text.data(), -1);
97
98 // Get text size
99 int textWidth = 0;
100 int textHeight = 0;
101 pango_layout_get_pixel_size(layout.data(), &textWidth, &textHeight);
102
103 // Draw text
104 CairoUtils::SurfacePointer surface(CairoUtils::createSurfaceForQImage(&image));
105 CairoUtils::Pointer cr(cairo_create(surface.data()));
106
107 PanelStyle* style = PanelStyle::instance();
108 GtkStyleContext* style_context = style->styleContext();
109
110 gtk_style_context_save(style_context);
111
112 GtkWidgetPath* widget_path = gtk_widget_path_new();
113 gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_BAR);
114 gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_ITEM);
115 gtk_widget_path_iter_set_name(widget_path, -1 , "UnityPanelWidget");
116
117 gtk_style_context_set_path(style_context, widget_path);
118 gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUBAR);
119 gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUITEM);
120
121 gtk_render_layout(style_context, cr.data(),
122 contentsRect().left(),
123 contentsRect().top() + (height() - textHeight) / 2,
124 layout.data());
125
126 gtk_widget_path_free(widget_path);
127
128 gtk_style_context_restore(style_context);
129
130 // Fade if necessary
131 if (textWidth > contentsRect().width()) {
132 paintFadeoutGradient(&image);
133 }
134
135 // Paint on our widget
136 QPainter painter(this);
137 painter.drawImage(0, 0, image);
138}
139
140#include "croppedlabel.moc"
0141
=== added file 'panel/applets/appname/croppedlabel.h'
--- panel/applets/appname/croppedlabel.h 1970-01-01 00:00:00 +0000
+++ panel/applets/appname/croppedlabel.h 2011-07-27 15:51:26 +0000
@@ -0,0 +1,45 @@
1/*
2 * This file is part of unity-2d
3 *
4 * Copyright 2011 Canonical Ltd.
5 *
6 * Authors:
7 * - Aurélien Gâteau <aurelien.gateau@canonical.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; version 3.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21#ifndef CROPPEDLABEL_H
22#define CROPPEDLABEL_H
23
24// Local
25
26// Qt
27#include <QLabel>
28
29/**
30 * This label makes sure minimumSizeHint() is not set. This ensures the applet
31 * does not get wider if a window title is very long
32 */
33class CroppedLabel : public QLabel
34{
35 Q_OBJECT
36public:
37 CroppedLabel(QWidget* parent = 0);
38
39 QSize minimumSizeHint() const;
40
41protected:
42 void paintEvent(QPaintEvent*);
43};
44
45#endif /* CROPPEDLABEL_H */
046
=== added file 'panel/applets/common/cairoutils.cpp'
--- panel/applets/common/cairoutils.cpp 1970-01-01 00:00:00 +0000
+++ panel/applets/common/cairoutils.cpp 2011-07-27 15:51:26 +0000
@@ -0,0 +1,42 @@
1/*
2 * This file is part of unity-2d
3 *
4 * Copyright 2011 Canonical Ltd.
5 *
6 * Authors:
7 * - Aurélien Gâteau <aurelien.gateau@canonical.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; version 3.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21// Self
22#include "cairoutils.h"
23
24// Local
25
26// Qt
27#include <QImage>
28
29namespace CairoUtils {
30
31cairo_surface_t* createSurfaceForQImage(QImage* image)
32{
33 return cairo_image_surface_create_for_data(
34 image->bits(),
35 CAIRO_FORMAT_ARGB32,
36 image->width(),
37 image->height(),
38 image->bytesPerLine()
39 );
40}
41
42} // namespace
043
=== added file 'panel/applets/common/cairoutils.h'
--- panel/applets/common/cairoutils.h 1970-01-01 00:00:00 +0000
+++ panel/applets/common/cairoutils.h 2011-07-27 15:51:26 +0000
@@ -0,0 +1,47 @@
1/*
2 * This file is part of unity-2d
3 *
4 * Copyright 2011 Canonical Ltd.
5 *
6 * Authors:
7 * - Aurélien Gâteau <aurelien.gateau@canonical.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; version 3.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21#ifndef CAIROUTILS_H
22#define CAIROUTILS_H
23
24// Local
25#include <gscopedpointer.h>
26
27// Qt
28
29// Cairo
30#include <cairo.h>
31
32class QImage;
33
34namespace CairoUtils {
35
36typedef GScopedPointer<cairo_surface_t, cairo_surface_destroy> SurfacePointer;
37typedef GScopedPointer<cairo_t, cairo_destroy> Pointer;
38
39/**
40 * Creates a Cairo surface for a QImage.
41 * QImage format must be Format_ARGB32_Premultiplied.
42 */
43cairo_surface_t* createSurfaceForQImage(QImage*);
44
45} // namespace
46
47#endif /* CAIROUTILS_H */
048
=== removed file 'panel/applets/common/fakecairo.h'
--- panel/applets/common/fakecairo.h 2011-07-12 15:49:40 +0000
+++ panel/applets/common/fakecairo.h 1970-01-01 00:00:00 +0000
@@ -1,125 +0,0 @@
1/*
2 * This file is part of unity-2d
3 *
4 * Copyright 2011 Canonical Ltd.
5 *
6 * Authors:
7 * - Aurélien Gâteau <aurelien.gateau@canonical.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; version 3.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21#ifndef FAKECAIRO_H
22#define FAKECAIRO_H
23
24// NuxCore
25#include <NuxCore/Color.h>
26
27// Qt
28#include <QPainter>
29#include <QPainterPath>
30
31/*
32 * This module attempts to fake Cairo calls using QPainter, making it easier to
33 * port Cairo paint operations to Qt
34 */
35struct fcairo_t
36{
37 fcairo_t(QPainter* _painter)
38 : painter(_painter)
39 {
40 painter->save();
41 }
42
43 ~fcairo_t()
44 {
45 painter->restore();
46 }
47
48 QPainter* painter;
49 QPainterPath path;
50};
51
52inline void fcairo_arc(fcairo_t& cr, qreal xc, qreal yc, qreal radius, qreal angle1, qreal angle2)
53{
54 QRectF rect(xc - radius, yc - radius, radius * 2, radius * 2);
55
56 while (angle2 < angle1) {
57 angle2 += 2 * M_PI;
58 }
59
60 qreal start = (2. - angle1 / M_PI) * 180;
61 qreal stop = (2. - angle2 / M_PI) * 180;
62 cr.path.arcTo(rect, start, stop - start);
63}
64
65inline void fcairo_move_to(fcairo_t& cr, qreal x, qreal y)
66{
67 cr.path.moveTo(x, y);
68}
69
70inline void fcairo_line_to(fcairo_t& cr, qreal x, qreal y)
71{
72 cr.path.lineTo(x, y);
73}
74
75inline void fcairo_fill_preserve(fcairo_t& cr)
76{
77 cr.painter->fillPath(cr.path, cr.painter->brush());
78}
79
80inline void fcairo_stroke(fcairo_t& cr)
81{
82 QPen pen(cr.painter->brush().color(), 1);
83 cr.painter->strokePath(cr.path, pen);
84 cr.path = QPainterPath();
85}
86
87typedef QGradient fcairo_pattern_t;
88
89inline fcairo_pattern_t* fcairo_pattern_create_linear (qreal x1, qreal y1, qreal x2, qreal y2)
90{
91 return new QLinearGradient(x1, y1, x2, y2);
92}
93
94inline void fcairo_pattern_destroy(fcairo_pattern_t* pattern)
95{
96 delete pattern;
97}
98
99inline void fcairo_pattern_add_color_stop_rgba(fcairo_pattern_t* pattern, qreal offset, qreal r, qreal g, qreal b, qreal a)
100{
101 pattern->setColorAt(offset, QColor::fromRgbF(r, g, b, a));
102}
103
104inline void fcairo_set_source(fcairo_t& cr, fcairo_pattern_t* pattern)
105{
106 cr.painter->setPen(Qt::NoPen);
107 cr.painter->setBrush(*pattern);
108}
109
110inline void fcairo_set_source_rgb(fcairo_t& cr, qreal r, qreal g, qreal b)
111{
112 cr.painter->setBrush(QColor::fromRgbF(r, g, b));
113}
114
115inline nux::color::Color nuxColorFromQColor(const QColor& qColor)
116{
117 nux::color::Color color;
118 color.red = qColor.redF();
119 color.green = qColor.greenF();
120 color.blue = qColor.blueF();
121 color.alpha = qColor.alphaF();
122 return color;
123}
124
125#endif /* FAKECAIRO_H */
1260
=== modified file 'panel/applets/common/indicatorentrywidget.cpp'
--- panel/applets/common/indicatorentrywidget.cpp 2011-07-12 15:50:20 +0000
+++ panel/applets/common/indicatorentrywidget.cpp 2011-07-27 15:51:26 +0000
@@ -22,8 +22,9 @@
22#include "indicatorentrywidget.h"22#include "indicatorentrywidget.h"
2323
24// Local24// Local
25#include <cairoutils.h>
25#include <debug_p.h>26#include <debug_p.h>
26#include <fakecairo.h>27#include <gscopedpointer.h>
27#include <panelstyle.h>28#include <panelstyle.h>
2829
29// Qt30// Qt
@@ -42,56 +43,25 @@
4243
43using namespace unity::indicator;44using namespace unity::indicator;
4445
45// Copied from libdbusmenu-qt
46static QString swapMnemonicChar(const QString &in, const char src, const char dst)
47{
48 QString out;
49 bool mnemonicFound = false;
50
51 for (int pos = 0; pos < in.length(); ) {
52 QChar ch = in[pos];
53 if (ch == src) {
54 if (pos == in.length() - 1) {
55 // 'src' at the end of string, skip it
56 ++pos;
57 } else {
58 if (in[pos + 1] == src) {
59 // A real 'src'
60 out += src;
61 pos += 2;
62 } else if (!mnemonicFound) {
63 // We found the mnemonic
64 mnemonicFound = true;
65 out += dst;
66 ++pos;
67 } else {
68 // We already have a mnemonic, just skip the char
69 ++pos;
70 }
71 }
72 } else if (ch == dst) {
73 // Escape 'dst'
74 out += dst;
75 out += dst;
76 ++pos;
77 } else {
78 out += ch;
79 ++pos;
80 }
81 }
82
83 return out;
84}
85
86IndicatorEntryWidget::IndicatorEntryWidget(const Entry::Ptr& entry)46IndicatorEntryWidget::IndicatorEntryWidget(const Entry::Ptr& entry)
87: m_entry(entry)47: m_entry(entry)
88, m_padding(PADDING)48, m_padding(PADDING)
89, m_hasIcon(false)49, m_hasIcon(false)
90, m_hasLabel(false)50, m_hasLabel(false)
51, m_gtkWidgetPath(gtk_widget_path_new())
91{52{
53 gtk_widget_path_append_type(m_gtkWidgetPath, GTK_TYPE_WINDOW);
54 gtk_widget_path_iter_set_name(m_gtkWidgetPath, -1 , "UnityPanelWidget");
55 gtk_widget_path_append_type(m_gtkWidgetPath, GTK_TYPE_MENU_BAR);
56 gtk_widget_path_append_type(m_gtkWidgetPath, GTK_TYPE_MENU_ITEM);
57
92 setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);58 setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
93 m_entry->updated.connect(sigc::mem_fun(this, &IndicatorEntryWidget::updatePix));59 m_entry->updated.connect(sigc::mem_fun(this, &IndicatorEntryWidget::updatePix));
94 updatePix();60}
61
62IndicatorEntryWidget::~IndicatorEntryWidget()
63{
64 gtk_widget_path_free(m_gtkWidgetPath);
95}65}
9666
97QSize IndicatorEntryWidget::minimumSizeHint() const67QSize IndicatorEntryWidget::minimumSizeHint() const
@@ -104,105 +74,47 @@
104 return m_pix.size();74 return m_pix.size();
105}75}
10676
77void IndicatorEntryWidget::resizeEvent(QResizeEvent* event)
78{
79 QWidget::resizeEvent(event);
80 updatePix();
81}
82
107void IndicatorEntryWidget::paintEvent(QPaintEvent*)83void IndicatorEntryWidget::paintEvent(QPaintEvent*)
108{84{
109 if (!m_pix.isNull()) {85 if (!m_pix.isNull()) {
110 QPainter painter(this);86 QPainter painter(this);
111 if (m_entry->active()) {
112 paintActiveBackground(&painter);
113 }
114 painter.drawPixmap(0, 0, m_pix);87 painter.drawPixmap(0, 0, m_pix);
115 }88 }
116}89}
11790
11891
119void IndicatorEntryWidget::paintActiveBackground(QPainter* painter)92void IndicatorEntryWidget::paintActiveBackground(QImage* image)
120{93{
121 // This code should be kept in sync with the draw_menu_bg() function from94 // This code should be kept in sync with corresponding unityshell code from
122 // plugins/unityshell/src/PanelIndicatorObjectEntryView.cpp95 // plugins/unityshell/src/PanelIndicatorObjectEntryView.cpp
123 int radius = 4;96
124 double x = 0;97 // Get a surface and a context
125 double y = 0;98 CairoUtils::SurfacePointer surface(CairoUtils::createSurfaceForQImage(image));
126 double xos = 0.5;99 CairoUtils::Pointer cr(cairo_create(surface.data()));
127 double yos = 0.5;100
128 /* FIXME */101 // Init style
129 double mpi = 3.14159265358979323846;102 GtkStyleContext* styleContext = PanelStyle::instance()->styleContext();
130103
131 PanelStyle* style = PanelStyle::instance();104 gtk_style_context_save(styleContext);
132 nux::color::Color bgtop = nuxColorFromQColor(style->backgroundTopColor());105
133 nux::color::Color bgbot = nuxColorFromQColor(style->backgroundBottomColor());106 gtk_style_context_set_path(styleContext, m_gtkWidgetPath);
134 nux::color::Color line = nuxColorFromQColor(style->lineColor());107 gtk_style_context_add_class(styleContext, GTK_STYLE_CLASS_MENUBAR);
135108 gtk_style_context_add_class(styleContext, GTK_STYLE_CLASS_MENUITEM);
136 painter->setRenderHint(QPainter::Antialiasing);109 gtk_style_context_set_state(styleContext, GTK_STATE_FLAG_PRELIGHT);
137110
138 fcairo_t cr(painter);111 // Draw
139112 // FIXME(Cimi) probably some padding is needed here.
140 fcairo_move_to (cr, x+xos+radius, y+yos);113 gtk_render_background(styleContext, cr.data(), 0, 0, width(), height());
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());
142 fcairo_line_to (cr, x+xos+width()-xos*2, y+yos+height()-yos*2+2);115
143 fcairo_line_to (cr, x+xos, y+yos+height()-yos*2+2);116 // Clean up
144 fcairo_arc (cr, x+xos+radius, y+yos+radius, radius, mpi, mpi*1.5);117 gtk_style_context_restore(styleContext);
145
146 fcairo_pattern_t * pat = fcairo_pattern_create_linear (x+xos, y, x+xos, y+height()-yos*2+2);
147 fcairo_pattern_add_color_stop_rgba (pat, 0.0,
148 bgtop.red,
149 bgtop.green,
150 bgtop.blue,
151 1.0f - bgbot.red);
152 fcairo_pattern_add_color_stop_rgba (pat, 1.0,
153 bgbot.red,
154 bgbot.green,
155 bgbot.blue,
156 1.0f - bgtop.red);
157 fcairo_set_source (cr, pat);
158 fcairo_fill_preserve (cr);
159 fcairo_pattern_destroy (pat);
160
161 /*
162 pat = fcairo_pattern_create_linear (x+xos, y, x+xos, y+height()-yos*2+2);
163 fcairo_pattern_add_color_stop_rgba (pat, 0.0,
164 line.red,
165 line.green,
166 line.blue,
167 1.0f);
168 fcairo_pattern_add_color_stop_rgba (pat, 1.0,
169 line.red,
170 line.green,
171 line.blue,
172 1.0f);
173 fcairo_set_source (cr, pat);
174 */
175 fcairo_set_source_rgb (cr, line.red, line.green, line.blue);
176 fcairo_stroke (cr);
177 //fcairo_pattern_destroy (pat);
178
179 xos++;
180 yos++;
181
182 /* enlarging the area to not draw the lightborder at bottom, ugly trick :P */
183 fcairo_move_to (cr, x+radius+xos, y+yos);
184 fcairo_arc (cr, x+xos+width()-xos*2-radius, y+yos+radius, radius, mpi*1.5, mpi*2);
185 fcairo_line_to (cr, x+xos+width()-xos*2, y+yos+height()-yos*2+3);
186 fcairo_line_to (cr, x+xos, y+yos+height()-yos*2+3);
187 fcairo_arc (cr, x+xos+radius, y+yos+radius, radius, mpi, mpi*1.5);
188
189 /*
190 pat = fcairo_pattern_create_linear (x+xos, y, x+xos, y+height()-yos*2+3);
191 fcairo_pattern_add_color_stop_rgba (pat, 0.0,
192 bgbot.red,
193 bgbot.green,
194 bgbot.blue,
195 1.0f);
196 fcairo_pattern_add_color_stop_rgba (pat, 1.0,
197 bgbot.red,
198 bgbot.green,
199 bgbot.blue,
200 1.0f);
201 fcairo_set_source (cr, pat);
202 */
203 fcairo_set_source_rgb (cr, bgbot.red, bgbot.green, bgbot.blue);
204 fcairo_stroke (cr);
205 //fcairo_pattern_destroy (pat);
206}118}
207119
208void IndicatorEntryWidget::updatePix()120void IndicatorEntryWidget::updatePix()
@@ -213,6 +125,8 @@
213 int iconX = m_padding;125 int iconX = m_padding;
214 int labelX = 0;126 int labelX = 0;
215127
128 GObjectScopedPointer<PangoLayout> pangoLayout;
129
216 // Compute width, labelX and update m_has{Icon,Label}130 // Compute width, labelX and update m_has{Icon,Label}
217 QPixmap iconPix;131 QPixmap iconPix;
218 if (m_entry->image_visible()) {132 if (m_entry->image_visible()) {
@@ -225,17 +139,18 @@
225 width += iconPix.width();139 width += iconPix.width();
226 }140 }
227141
228 QString label = QString::fromUtf8(m_entry->label().c_str());142 m_hasLabel = !m_entry->label().empty() && m_entry->label_visible();
229 label = swapMnemonicChar(label, '_', '&');
230 m_hasLabel = !label.isEmpty() && m_entry->label_visible();
231 if (m_hasLabel) {143 if (m_hasLabel) {
232 if (m_hasIcon) {144 if (m_hasIcon) {
233 width += SPACING;145 width += SPACING;
234 }146 }
235 labelX = width;147 labelX = width;
236 QString visibleLabel = label;148 pangoLayout.reset(createPangoLayout());
237 visibleLabel.remove('&');149 int labelWidth;
238 width += fontMetrics().width(visibleLabel);150 int labelHeight;
151 pango_layout_get_pixel_size(pangoLayout.data(), &labelWidth, &labelHeight);
152
153 width += labelWidth;
239 }154 }
240155
241 width += m_padding;156 width += m_padding;
@@ -245,38 +160,27 @@
245 if (!m_hasIcon && !m_hasLabel) {160 if (!m_hasIcon && !m_hasLabel) {
246 m_pix = QPixmap();161 m_pix = QPixmap();
247 } else {162 } else {
248 m_pix = QPixmap(width, 24);163 QImage img(width, height(), QImage::Format_ARGB32_Premultiplied);
249 m_pix.fill(Qt::transparent);164 QPainter painter(&img);
250 QPainter painter(&m_pix);
251 painter.initFrom(this);165 painter.initFrom(this);
166 painter.eraseRect(img.rect());
167 if (m_entry->active()) {
168 paintActiveBackground(&img);
169 }
252 if (m_hasIcon) {170 if (m_hasIcon) {
253 bool disabled = !m_entry->image_sensitive();171 bool disabled = !m_entry->image_sensitive();
254 if (disabled) {172 if (disabled) {
255 painter.setOpacity(0.5);173 painter.setOpacity(0.5);
256 }174 }
257 painter.drawPixmap(iconX, 0, iconPix);175 painter.drawPixmap(iconX, (height() - iconPix.height()) / 2, iconPix);
258 if (disabled) {176 if (disabled) {
259 painter.setOpacity(1);177 painter.setOpacity(1);
260 }178 }
261 }179 }
262 if (m_hasLabel) {180 if (m_hasLabel) {
263 PanelStyle* style = PanelStyle::instance();181 paintLabel(&img, pangoLayout.data(), labelX);
264
265 int flags = Qt::AlignLeft | Qt::AlignVCenter;
266 flags |= m_entry->show_now() ? Qt::TextShowMnemonic : Qt::TextHideMnemonic;
267
268 // Shadow
269 QColor color = style->textShadowColor();
270 color.setAlphaF(1. - color.redF());
271 painter.setPen(color);
272 painter.drawText(labelX, 1, width - labelX, m_pix.height(), flags, label);
273
274 // Text
275 color = style->textColor();
276 color.setAlphaF(m_entry->label_sensitive() ? 1. : .5);
277 painter.setPen(color);
278 painter.drawText(labelX, 0, width - labelX, m_pix.height(), flags, label);
279 }182 }
183 m_pix = QPixmap::fromImage(img);
280 }184 }
281185
282 // Notify others we changed, but only trigger a layout update if necessary186 // Notify others we changed, but only trigger a layout update if necessary
@@ -294,6 +198,80 @@
294 }198 }
295}199}
296200
201PangoLayout* IndicatorEntryWidget::createPangoLayout()
202{
203 // Parse
204 PangoAttrList* attrs = NULL;
205 if (m_entry->show_now()) {
206 if (!pango_parse_markup(m_entry->label().c_str(),
207 -1,
208 '_',
209 &attrs,
210 NULL,
211 NULL,
212 NULL))
213 {
214 UQ_WARNING << "pango_parse_markup failed";
215 }
216 }
217
218 // Create layout
219 GObjectScopedPointer<PangoContext> pangoContext(gdk_pango_context_get());
220 PangoLayout* layout = pango_layout_new(pangoContext.data());
221
222 if (attrs) {
223 pango_layout_set_attributes(layout, attrs);
224 pango_attr_list_unref(attrs);
225 }
226
227 // Set font
228 char* font_description = NULL;
229 GtkSettings *settings = gtk_settings_get_default();
230 g_object_get(settings,
231 "gtk-font-name", &font_description,
232 NULL);
233 PangoFontDescription* desc = pango_font_description_from_string(font_description);
234 pango_font_description_set_weight(desc, PANGO_WEIGHT_NORMAL);
235 pango_layout_set_font_description(layout, desc);
236 pango_font_description_free(desc);
237 g_free(font_description);
238
239 // Set text
240 QString label = QString::fromUtf8(m_entry->label().c_str());
241 label.replace('_', QString());
242 QByteArray utf8Label = label.toUtf8();
243 pango_layout_set_text(layout, utf8Label.data(), -1);
244
245 return layout;
246}
247
248void IndicatorEntryWidget::paintLabel(QImage* image, PangoLayout* layout, int labelX)
249{
250 // This code should be kept in sync with corresponding unityshell code from
251 // plugins/unityshell/src/PanelIndicatorObjectEntryView.cpp
252 int labelWidth, labelHeight;
253 pango_layout_get_pixel_size(layout, &labelWidth, &labelHeight);
254 CairoUtils::SurfacePointer surface(CairoUtils::createSurfaceForQImage(image));
255 CairoUtils::Pointer cr(cairo_create(surface.data()));
256 pango_cairo_update_layout(cr.data(), layout);
257
258 PanelStyle* style = PanelStyle::instance();
259 GtkStyleContext* styleContext = style->styleContext();
260
261 gtk_style_context_save(styleContext);
262
263 gtk_style_context_set_path(styleContext, m_gtkWidgetPath);
264 gtk_style_context_add_class(styleContext, GTK_STYLE_CLASS_MENUBAR);
265 gtk_style_context_add_class(styleContext, GTK_STYLE_CLASS_MENUITEM);
266
267 if (m_entry->active()) {
268 gtk_style_context_set_state(styleContext, GTK_STATE_FLAG_PRELIGHT);
269 }
270
271 gtk_render_layout(styleContext, cr.data(), labelX, (image->height() - labelHeight) / 2, layout);
272 gtk_style_context_restore(styleContext);
273}
274
297QPixmap IndicatorEntryWidget::decodeIcon()275QPixmap IndicatorEntryWidget::decodeIcon()
298{276{
299 QPixmap pix;277 QPixmap pix;
300278
=== modified file 'panel/applets/common/indicatorentrywidget.h'
--- panel/applets/common/indicatorentrywidget.h 2011-07-26 10:11:23 +0000
+++ panel/applets/common/indicatorentrywidget.h 2011-07-27 15:51:26 +0000
@@ -29,6 +29,9 @@
29// Qt29// Qt
30#include <QWidget>30#include <QWidget>
3131
32struct _GtkWidgetPath;
33struct _PangoLayout;
34
32class QPainter;35class QPainter;
3336
34class IndicatorEntryWidget : public QWidget, public sigc::trackable37class IndicatorEntryWidget : public QWidget, public sigc::trackable
@@ -36,6 +39,7 @@
36Q_OBJECT39Q_OBJECT
37public:40public:
38 IndicatorEntryWidget(const unity::indicator::Entry::Ptr& entry);41 IndicatorEntryWidget(const unity::indicator::Entry::Ptr& entry);
42 ~IndicatorEntryWidget();
3943
40 QSize minimumSizeHint() const;44 QSize minimumSizeHint() const;
41 QSize sizeHint() const;45 QSize sizeHint() const;
@@ -61,6 +65,7 @@
61 void isEmptyChanged();65 void isEmptyChanged();
6266
63protected:67protected:
68 void resizeEvent(QResizeEvent*);
64 void paintEvent(QPaintEvent*);69 void paintEvent(QPaintEvent*);
65 void mousePressEvent(QMouseEvent*);70 void mousePressEvent(QMouseEvent*);
66 void mouseReleaseEvent(QMouseEvent*);71 void mouseReleaseEvent(QMouseEvent*);
@@ -73,9 +78,13 @@
73 int m_padding;78 int m_padding;
74 bool m_hasIcon;79 bool m_hasIcon;
75 bool m_hasLabel;80 bool m_hasLabel;
81 struct _GtkWidgetPath* m_gtkWidgetPath;
76 void updatePix();82 void updatePix();
77 QPixmap decodeIcon();83 QPixmap decodeIcon();
78 void paintActiveBackground(QPainter*);84 void paintActiveBackground(QImage*);
85
86 struct _PangoLayout* createPangoLayout();
87 void paintLabel(QImage*, struct _PangoLayout*, int labelX);
79};88};
8089
81#endif /* INDICATORENTRYWIDGET_H */90#endif /* INDICATORENTRYWIDGET_H */
8291
=== modified file 'panel/applets/common/panelstyle.cpp'
--- panel/applets/common/panelstyle.cpp 2011-07-19 09:22:55 +0000
+++ panel/applets/common/panelstyle.cpp 2011-07-27 15:51:26 +0000
@@ -22,92 +22,54 @@
22#include "panelstyle.h"22#include "panelstyle.h"
2323
24// libunity-2d24// libunity-2d
25#include <cairoutils.h>
25#include <debug_p.h>26#include <debug_p.h>
26#include <gconnector.h>27#include <gconnector.h>
27#include <gscopedpointer.h>28#include <gscopedpointer.h>
2829
29// Qt30// Qt
30#include <QApplication>31#include <QApplication>
31#include <QColor>
32#include <QFont>
33#include <QPalette>32#include <QPalette>
3433
35// GTK34// GTK
36#include <gtk/gtk.h>35#include <gtk/gtk.h>
37#include <pango/pango.h>
38
39typedef void (*ColorGetter)(GtkStyleContext*, GtkStateFlags, GdkRGBA*);
40
41inline QColor colorFromContext(ColorGetter getter, GtkStyleContext* context, GtkStateFlags state)
42{
43 GdkRGBA color;
44 getter(context, state, &color);
45 return QColor::fromRgbF(color.red, color.green, color.blue, color.alpha);
46}
4736
48class PanelStylePrivate37class PanelStylePrivate
49{38{
50public:39public:
51 PanelStyle* q;40 PanelStyle* q;
52 GtkWidget* m_offScreenWindow;41 GObjectScopedPointer<GtkStyleContext> m_styleContext;
53 GConnector m_gConnector;42 GConnector m_gConnector;
5443
55 QColor m_textColor;
56 QColor m_backgroundTopColor;
57 QColor m_backgroundBottomColor;
58 QColor m_textShadowColor;
59 QColor m_lineColor;
60 QFont m_font;
61
62 static void onThemeChanged(GObject*, GParamSpec*, gpointer data)44 static void onThemeChanged(GObject*, GParamSpec*, gpointer data)
63 {45 {
64 PanelStylePrivate* priv = reinterpret_cast<PanelStylePrivate*>(data);46 PanelStylePrivate* priv = reinterpret_cast<PanelStylePrivate*>(data);
65 priv->updatePalette();47 priv->updatePalette();
66 }48 }
6749
68 static void onFontChanged(GObject*, GParamSpec*, gpointer data)
69 {
70 PanelStylePrivate* priv = reinterpret_cast<PanelStylePrivate*>(data);
71 priv->updateFont();
72 }
73
74 void updatePalette()50 void updatePalette()
75 {51 {
76 GtkStyleContext* context = gtk_widget_get_style_context(m_offScreenWindow);52 GtkStyleContext* context = m_styleContext.data();
77 UQ_RETURN_IF_FAIL(context);53 gtk_style_context_invalidate(context);
7854
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
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
81 m_lineColor = colorFromContext(gtk_style_context_get_background_color, context, GTK_STATE_FLAG_NORMAL).darker(130);57 // brush.
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);
83 m_backgroundBottomColor = colorFromContext(gtk_style_context_get_background_color, context, GTK_STATE_FLAG_NORMAL);
8459
85 QPalette pal;60 QPalette pal;
86 pal.setColor(QPalette::Window, m_backgroundTopColor);61 pal.setBrush(QPalette::Window, generateBackgroundBrush());
87 pal.setColor(QPalette::Button, m_backgroundTopColor);
88 pal.setColor(QPalette::Text, m_textColor);
89 pal.setColor(QPalette::WindowText, m_textColor);
90 pal.setColor(QPalette::ButtonText, m_textColor);
91 QApplication::setPalette(pal);62 QApplication::setPalette(pal);
92 }63 }
9364
94 void updateFont()65 QBrush generateBackgroundBrush()
95 {66 {
96 gchar* fontName = 0;67 QImage image(100, 24, QImage::Format_ARGB32_Premultiplied); // FIXME: Hardcoded
97 g_object_get(gtk_settings_get_default(), "gtk-font-name", &fontName, NULL);68 image.fill(Qt::transparent);
98 GScopedPointer<PangoFontDescription, pango_font_description_free> fontDescription(69 CairoUtils::SurfacePointer surface(CairoUtils::createSurfaceForQImage(&image));
99 pango_font_description_from_string(fontName)70 CairoUtils::Pointer cr(cairo_create(surface.data()));
100 );71 gtk_render_background(m_styleContext.data(), cr.data(), 0, 0, image.width(), image.height());
101 g_free(fontName);72 return QBrush(image);
102
103 int size = pango_font_description_get_size(fontDescription.data());
104
105 m_font = QFont(
106 pango_font_description_get_family(fontDescription.data()),
107 size / PANGO_SCALE
108 );
109
110 QApplication::setFont(m_font);
111 }73 }
112};74};
11375
@@ -115,24 +77,26 @@
115: d(new PanelStylePrivate)77: d(new PanelStylePrivate)
116{78{
117 d->q = this;79 d->q = this;
118 d->m_offScreenWindow = gtk_offscreen_window_new();80 d->m_styleContext.reset(gtk_style_context_new());
119 gtk_widget_set_name(d->m_offScreenWindow, "UnityPanelWidget");81
120 gtk_widget_set_size_request(d->m_offScreenWindow, 100, 24);82 GtkWidgetPath* widgetPath = gtk_widget_path_new ();
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);
122 gtk_widget_show_all(d->m_offScreenWindow);84 gtk_widget_path_iter_set_name(widgetPath, -1 , "UnityPanelWidget");
85
86 gtk_style_context_set_path(d->m_styleContext.data(), widgetPath);
87 gtk_style_context_add_class(d->m_styleContext.data(), "gnome-panel-menu-bar");
88 gtk_style_context_add_class(d->m_styleContext.data(), "unity-panel");
89
90 gtk_widget_path_free (widgetPath);
12391
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",
125 G_CALLBACK(PanelStylePrivate::onThemeChanged), d);93 G_CALLBACK(PanelStylePrivate::onThemeChanged), d);
126 d->m_gConnector.connect(gtk_settings_get_default(), "notify::gtk-font-name",
127 G_CALLBACK(PanelStylePrivate::onFontChanged), d);
12894
129 d->updatePalette();95 d->updatePalette();
130 d->updateFont();
131}96}
13297
133PanelStyle::~PanelStyle()98PanelStyle::~PanelStyle()
134{99{
135 gtk_widget_destroy(d->m_offScreenWindow);
136 delete d;100 delete d;
137}101}
138102
@@ -142,34 +106,9 @@
142 return &style;106 return &style;
143}107}
144108
145QColor PanelStyle::textColor() const109GtkStyleContext* PanelStyle::styleContext() const
146{110{
147 return d->m_textColor;111 return d->m_styleContext.data();
148}
149
150QColor PanelStyle::backgroundTopColor() const
151{
152 return d->m_backgroundTopColor;
153}
154
155QColor PanelStyle::backgroundBottomColor() const
156{
157 return d->m_backgroundBottomColor;
158}
159
160QColor PanelStyle::textShadowColor() const
161{
162 return d->m_textShadowColor;
163}
164
165QColor PanelStyle::lineColor() const
166{
167 return d->m_lineColor;
168}
169
170QFont PanelStyle::font() const
171{
172 return d->m_font;
173}112}
174113
175#include "panelstyle.moc"114#include "panelstyle.moc"
176115
=== modified file 'panel/applets/common/panelstyle.h'
--- panel/applets/common/panelstyle.h 2011-06-30 16:43:27 +0000
+++ panel/applets/common/panelstyle.h 2011-07-27 15:51:26 +0000
@@ -26,12 +26,15 @@
26// Qt26// Qt
27#include <QObject>27#include <QObject>
2828
29class QColor;29struct _GtkStyleContext;
30class QFont;
3130
32class PanelStylePrivate;31class PanelStylePrivate;
33/**32/**
34 * Provides easy access to panel colors33 * Provides easy access to panel style context and track platform theme to
34 * ensure we have the correct background brush.
35 *
36 * FIXME: This class does not have a very clear focus and has side-effects
37 * (background brush handling). It should be refactored.
35 */38 */
36class PanelStyle : public QObject39class PanelStyle : public QObject
37{40{
@@ -42,13 +45,7 @@
4245
43 static PanelStyle* instance();46 static PanelStyle* instance();
4447
45 QColor textColor() const;48 struct _GtkStyleContext* styleContext() const;
46 QColor backgroundTopColor() const;
47 QColor backgroundBottomColor() const;
48 QColor textShadowColor() const;
49 QColor lineColor() const;
50
51 QFont font() const;
5249
53private:50private:
54 friend class PanelStylePrivate;51 friend class PanelStylePrivate;
5552
=== modified file 'panel/applets/homebutton/homebutton.cpp'
--- panel/applets/homebutton/homebutton.cpp 2011-05-26 16:41:04 +0000
+++ panel/applets/homebutton/homebutton.cpp 2011-07-27 15:51:26 +0000
@@ -40,8 +40,10 @@
40 setStyleSheet(40 setStyleSheet(
41 "QToolButton { border: none; margin: 0; padding: 0; width: 61 }"41 "QToolButton { border: none; margin: 0; padding: 0; width: 61 }"
42 "QToolButton:checked, QToolButton:pressed {"42 "QToolButton:checked, QToolButton:pressed {"
43 // Use border-image here, not background-image, because bfb_bg_active.png is 56px wide43 " padding-top: 1px;"
44 " border-image: url(theme:/bfb_bg_active.png);"44 " padding-left: 1px;"
45 " padding-right: -1px;"
46 " padding-bottom: -1px;"
45 "}"47 "}"
46 );48 );
47}49}

Subscribers

People subscribed via source and target branches