2 * Copyright 2007 by Alex Merry <alex.merry@kdemail.net>
3 * Copyright 2008 by Alexis Ménard <darktears31@gmail.com>
4 * Copyright 2008 by Aaron Seigo <aseigo@kde.org>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Library General Public License version 2,
8 * or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details
15 * You should have received a copy of the GNU Library General Public
16 * License along with this program; if not, write to the
17 * Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25 #include <QApplication>
26 #include <QGraphicsLinearLayout>
29 #include <QDesktopWidget>
30 #include <QGridLayout>
34 #include <QGraphicsLayout>
40 #include <KIntNumInput>
41 #include <KMessageBox>
43 #include <Plasma/Corona>
44 #include <Plasma/FrameSvg>
45 #include <Plasma/Theme>
46 #include <Plasma/View>
48 using namespace Plasma
;
50 static const int CONTROL_BAR_HEIGHT
= 22;
52 Panel::Panel(QObject
*parent
, const QVariantList
&args
)
53 : Containment(parent
, args
),
56 m_background
= new Plasma::FrameSvg(this);
57 m_background
->setImagePath("widgets/panel-background");
58 m_background
->setEnabledBorders(Plasma::FrameSvg::AllBorders
);
59 connect(m_background
, SIGNAL(repaintNeeded()), this, SLOT(backgroundChanged()));
61 setContainmentType(Containment::PanelContainment
);
63 QSize size
= QSize(args
.count() ? args
[0].toInt() : 1024, 22);
64 kDebug() << "**********" << size
;
68 setDrawWallpaper(false);
70 connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), this, SLOT(themeUpdated()));
71 connect(this, SIGNAL(appletAdded(Plasma::Applet
*,QPointF
)),
72 this, SLOT(layoutApplet(Plasma::Applet
*,QPointF
)));
73 connect(this, SIGNAL(appletRemoved(Plasma::Applet
*)),
74 this, SLOT(appletRemoved(Plasma::Applet
*)));
86 QList
<QAction
*> Panel::contextualActions()
88 if (!m_configureAction
) {
89 m_configureAction
= new QAction(i18n("Panel Settings"), this);
90 m_configureAction
->setIcon(KIcon("configure"));
91 connect(m_configureAction
, SIGNAL(triggered()), this, SIGNAL(toolBoxToggled()));
94 QList
<QAction
*> actions
;
95 actions
<< action("add widgets") << m_configureAction
;
99 void Panel::backgroundChanged()
101 constraintsEvent(Plasma::LocationConstraint
);
104 void Panel::layoutApplet(Plasma::Applet
* applet
, const QPointF
&pos
)
106 // this gets called whenever an applet is added, and we add it to our layout
107 QGraphicsLinearLayout
*lay
= dynamic_cast<QGraphicsLinearLayout
*>(layout());
113 Plasma::FormFactor f
= formFactor();
114 int insertIndex
= -1;
116 //Enlarge the panel if possible
117 if (f
== Plasma::Horizontal
) {
118 resize(size().width() + applet
->preferredWidth(), size().height());
120 resize(size().width(), size().height() + applet
->preferredHeight());
122 layout()->setMaximumSize(size());
124 //if pos is (-1,-1) insert at the end of the panel
125 if (pos
!= QPoint(-1, -1)) {
126 for (int i
= 0; i
< lay
->count(); ++i
) {
127 QRectF siblingGeometry
= lay
->itemAt(i
)->geometry();
128 if (f
== Plasma::Horizontal
) {
129 qreal middle
= (siblingGeometry
.left() + siblingGeometry
.right()) / 2.0;
130 if (pos
.x() < middle
) {
133 } else if (pos
.x() <= siblingGeometry
.right()) {
137 } else { // Plasma::Vertical
138 qreal middle
= (siblingGeometry
.top() + siblingGeometry
.bottom()) / 2.0;
139 if (pos
.y() < middle
) {
142 } else if (pos
.y() <= siblingGeometry
.bottom()) {
150 if (insertIndex
== -1) {
151 lay
->addItem(applet
);
153 lay
->insertItem(insertIndex
, applet
);
156 connect(applet
, SIGNAL(sizeHintChanged(Qt::SizeHint
)), this, SLOT(updateSize()));
159 void Panel::appletRemoved(Plasma::Applet
* applet
)
161 //shrink the panel if possible
162 if (formFactor() == Plasma::Horizontal
) {
163 resize(size().width() - applet
->size().width(), size().height());
165 resize(size().width(), size().height() - applet
->size().height());
167 layout()->setMaximumSize(size());
170 void Panel::updateSize()
172 Plasma::Applet
*applet
= qobject_cast
<Plasma::Applet
*>(sender());
175 if (formFactor() == Plasma::Horizontal
) {
176 const int delta
= applet
->preferredWidth() - applet
->size().width();
177 //setting the preferred width when delta = 0 and preferredWidth() < minimumWidth()
178 // leads to the same thing as setPreferredWidth(minimumWidth())
180 setPreferredWidth(preferredWidth() + delta
);
182 } else if (formFactor() == Plasma::Vertical
) {
183 const int delta
= applet
->preferredHeight() - applet
->size().height();
185 setPreferredHeight(preferredHeight() + delta
);
189 resize(preferredSize());
193 void Panel::updateBorders()
195 FrameSvg::EnabledBorders enabledBorders
= FrameSvg::AllBorders
;
197 kDebug() << "!!!!!!!!!!!!!!!! location be:" << location();
198 switch (location()) {
200 enabledBorders
= FrameSvg::TopBorder
;
203 enabledBorders
= FrameSvg::BottomBorder
;
206 enabledBorders
= FrameSvg::RightBorder
;
209 enabledBorders
= FrameSvg::LeftBorder
;
216 qreal bottomHeight
= 0;
218 qreal rightWidth
= 0;
220 //activate borders and fetch sizes again
221 m_background
->setEnabledBorders(enabledBorders
);
222 m_background
->getMargins(leftWidth
, topHeight
, rightWidth
, bottomHeight
);
224 //calculation of extra margins has to be done after getMargins
225 if (formFactor() == Vertical
) {
226 //hardcoded extra margin for the toolbox right now
227 if (immutability() == Mutable
) {
230 //Default to horizontal for now
232 //hardcoded extra margin for the toolbox for now
233 if (immutability() == Mutable
) {
234 if (QApplication::layoutDirection() == Qt::RightToLeft
) {
243 //invalidate the layout and set again
245 layout()->setContentsMargins(leftWidth
, topHeight
, rightWidth
, bottomHeight
);
246 layout()->invalidate();
252 void Panel::constraintsEvent(Plasma::Constraints constraints
)
254 kDebug() << "constraints updated with" << constraints
<< "!!!!!!";
256 if (constraints
& Plasma::FormFactorConstraint
) {
257 Plasma::FormFactor form
= formFactor();
258 Qt::Orientation layoutDirection
= form
== Plasma::Vertical
? Qt::Vertical
: Qt::Horizontal
;
260 // create our layout!
262 QGraphicsLayout
*lay
= layout();
263 QGraphicsLinearLayout
* linearLay
= dynamic_cast<QGraphicsLinearLayout
*>(lay
);
265 linearLay
->setOrientation(layoutDirection
);
268 QGraphicsLinearLayout
*lay
= new QGraphicsLinearLayout(this);
269 lay
->setOrientation(layoutDirection
);
270 lay
->setContentsMargins(0, 0, 0, 0);
272 lay
->setSizePolicy(QSizePolicy(QSizePolicy::Expanding
,QSizePolicy::Expanding
));
276 foreach (Applet
*applet
, applets()) {
277 lay
->addItem(applet
);
282 //we need to know if the width or height is 100%
283 if (constraints
& Plasma::LocationConstraint
|| constraints
& Plasma::SizeConstraint
) {
284 QSize size
= geometry().size().toSize();
285 QRectF screenRect
= screen() >= 0 ? QApplication::desktop()->screenGeometry(screen()) : geometry();
287 if ((formFactor() == Horizontal
&& size
.width() >= screenRect
.width()) ||
288 (formFactor() == Vertical
&& size
.height() >= screenRect
.height())) {
289 m_background
->setElementPrefix(location());
291 m_background
->setElementPrefix(QString());
294 m_background
->resizeFrame(size
);
298 //FIXME: this seems the only way to correctly resize the layout the first time when the
299 // saved panel size is less than the default is to setting a maximum size.
300 // this shouldn't happen. maybe even a qgraphicslayout bug?
301 if (layout() && (constraints
& Plasma::SizeConstraint
)) {
302 layout()->setMaximumSize(size());
305 if (constraints
& Plasma::LocationConstraint
) {
306 setFormFactorFromLocation(location());
309 if (constraints
& Plasma::ImmutableConstraint
) {
310 bool unlocked
= immutability() == Plasma::Mutable
;
312 if (m_configureAction
) {
313 m_configureAction
->setEnabled(unlocked
);
314 m_configureAction
->setVisible(unlocked
);
321 void Panel::saveState(KConfigGroup
&config
) const
323 config
.writeEntry("minimumSize", minimumSize());
324 config
.writeEntry("maximumSize", maximumSize());
327 void Panel::themeUpdated()
329 //if the theme is changed all the calculations needs to be done again
330 //and resize based on the change in the theme bordersize
338 qreal oldBottomHeight
;
339 qreal newBottomHeight
;
341 layout()->getContentsMargins(&oldLeftWidth
, &oldTopHeight
, &oldRightWidth
, &oldBottomHeight
);
342 m_background
->getMargins(newLeftWidth
, newTopHeight
, newRightWidth
, newBottomHeight
);
344 QSize
newSize(size().width()-(oldLeftWidth
- newLeftWidth
)-(oldRightWidth
- newRightWidth
),
345 size().height()-(oldTopHeight
- newTopHeight
)-(oldBottomHeight
- newBottomHeight
));
349 if (formFactor() == Plasma::Vertical
) {
350 setMaximumWidth(newSize
.width());
351 setMinimumWidth(newSize
.width());
353 setMaximumHeight(newSize
.height());
354 setMinimumHeight(newSize
.height());
360 void Panel::paintInterface(QPainter
*painter
,
361 const QStyleOptionGraphicsItem
*option
,
362 const QRect
& contentsRect
)
364 Q_UNUSED(contentsRect
)
366 //FIXME: this background drawing is bad and ugly =)
367 // draw the background untransformed (saves lots of per-pixel-math)
369 painter
->resetTransform();
371 const Containment::StyleOption
*containmentOpt
= qstyleoption_cast
<const Containment::StyleOption
*>(option
);
374 if (containmentOpt
) {
375 viewGeom
= containmentOpt
->view
->geometry();
378 // blit the background (saves all the per-pixel-products that blending does)
379 painter
->setCompositionMode(QPainter::CompositionMode_Source
);
380 painter
->setRenderHint(QPainter::Antialiasing
);
382 m_background
->paintFrame(painter
, option
->exposedRect
, option
->exposedRect
);
384 if (containmentOpt
&& containmentOpt
->view
) {
385 containmentOpt
->view
->setMask(m_background
->mask());
388 // restore transformation and composition mode
392 void Panel::setFormFactorFromLocation(Plasma::Location loc
) {
396 //kDebug() << "setting horizontal form factor";
397 setFormFactor(Plasma::Horizontal
);
401 //kDebug() << "setting vertical form factor";
402 setFormFactor(Plasma::Vertical
);
405 //TODO: implement a form factor for floating panels
406 kDebug() << "Floating is unimplemented.";
409 kDebug() << "invalid location!!";
413 K_EXPORT_PLASMA_APPLET(panel
, Panel
)