Plasma
combobox.cpp
Go to the documentation of this file.
00001 /* 00002 * Copyright 2008 Aaron Seigo <aseigo@kde.org> 00003 * 00004 * This program is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU Library General Public License as 00006 * published by the Free Software Foundation; either version 2, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details 00013 * 00014 * You should have received a copy of the GNU Library General Public 00015 * License along with this program; if not, write to the 00016 * Free Software Foundation, Inc., 00017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00018 */ 00019 00020 #include "combobox.h" 00021 00022 #include <QPainter> 00023 #include <QGraphicsView> 00024 00025 #include <kcombobox.h> 00026 #include <kiconeffect.h> 00027 #include <kiconloader.h> 00028 #include <kmimetype.h> 00029 00030 #include "applet.h" 00031 #include "framesvg.h" 00032 #include "private/style_p.h" 00033 #include "private/focusindicator_p.h" 00034 #include "private/themedwidgetinterface_p.h" 00035 #include "theme.h" 00036 00037 namespace Plasma 00038 { 00039 00040 class ComboBoxPrivate : public ThemedWidgetInterface<ComboBox> 00041 { 00042 public: 00043 ComboBoxPrivate(ComboBox *comboBox) 00044 : ThemedWidgetInterface<ComboBox>(comboBox), 00045 background(0), 00046 underMouse(false) 00047 { 00048 } 00049 00050 ~ComboBoxPrivate() 00051 { 00052 } 00053 00054 void syncActiveRect(); 00055 void syncBorders(); 00056 00057 FrameSvg *background; 00058 FrameSvg *lineEditBackground; 00059 FocusIndicator *focusIndicator; 00060 int animId; 00061 qreal opacity; 00062 QRectF activeRect; 00063 Style::Ptr style; 00064 bool underMouse; 00065 }; 00066 00067 void ComboBoxPrivate::syncActiveRect() 00068 { 00069 background->setElementPrefix("normal"); 00070 00071 qreal left, top, right, bottom; 00072 background->getMargins(left, top, right, bottom); 00073 00074 background->setElementPrefix("active"); 00075 qreal activeLeft, activeTop, activeRight, activeBottom; 00076 background->getMargins(activeLeft, activeTop, activeRight, activeBottom); 00077 00078 activeRect = QRectF(QPointF(0, 0), q->size()); 00079 activeRect.adjust(left - activeLeft, top - activeTop, 00080 -(right - activeRight), -(bottom - activeBottom)); 00081 00082 background->setElementPrefix("normal"); 00083 } 00084 00085 void ComboBoxPrivate::syncBorders() 00086 { 00087 //set margins from the normal element 00088 qreal left, top, right, bottom; 00089 00090 background->setElementPrefix("normal"); 00091 background->getMargins(left, top, right, bottom); 00092 q->setContentsMargins(left, top, right, bottom); 00093 00094 //calc the rect for the over effect 00095 syncActiveRect(); 00096 00097 if (customFont) { 00098 q->setFont(q->font()); 00099 } else { 00100 q->setFont(Theme::defaultTheme()->font(Theme::DefaultFont)); 00101 customFont = false; 00102 } 00103 00104 if (q->nativeWidget()->isEditable()) { 00105 focusIndicator->setFrameSvg(lineEditBackground); 00106 } else { 00107 focusIndicator->setFrameSvg(background); 00108 } 00109 focusIndicator->setFlag(QGraphicsItem::ItemStacksBehindParent, !q->nativeWidget()->isEditable() || !lineEditBackground->hasElement("hint-focus-over-base")); 00110 } 00111 00112 00113 ComboBox::ComboBox(QGraphicsWidget *parent) 00114 : QGraphicsProxyWidget(parent), 00115 d(new ComboBoxPrivate(this)) 00116 { 00117 d->background = new FrameSvg(this); 00118 d->background->setImagePath("widgets/button"); 00119 d->background->setCacheAllRenderedFrames(true); 00120 d->background->setElementPrefix("normal"); 00121 d->lineEditBackground = new FrameSvg(this); 00122 d->lineEditBackground->setImagePath("widgets/lineedit"); 00123 d->lineEditBackground->setCacheAllRenderedFrames(true); 00124 setZValue(900); 00125 00126 setAcceptHoverEvents(true); 00127 00128 d->style = Style::sharedStyle(); 00129 00130 d->focusIndicator = new FocusIndicator(this, d->background); 00131 setNativeWidget(new KComboBox); 00132 connect(d->background, SIGNAL(repaintNeeded()), SLOT(syncBorders())); 00133 d->initTheming(); 00134 } 00135 00136 ComboBox::~ComboBox() 00137 { 00138 delete d; 00139 Style::doneWithSharedStyle(); 00140 } 00141 00142 QString ComboBox::text() const 00143 { 00144 return static_cast<KComboBox*>(widget())->currentText(); 00145 } 00146 00147 void ComboBox::setStyleSheet(const QString &stylesheet) 00148 { 00149 widget()->setStyleSheet(stylesheet); 00150 } 00151 00152 QString ComboBox::styleSheet() 00153 { 00154 return widget()->styleSheet(); 00155 } 00156 00157 void ComboBox::setNativeWidget(KComboBox *nativeWidget) 00158 { 00159 if (widget()) { 00160 widget()->deleteLater(); 00161 } 00162 00163 connect(nativeWidget, SIGNAL(activated(QString)), this, SIGNAL(activated(QString))); 00164 connect(nativeWidget, SIGNAL(currentIndexChanged(int)), 00165 this, SIGNAL(currentIndexChanged(int))); 00166 connect(nativeWidget, SIGNAL(currentIndexChanged(QString)), 00167 this, SIGNAL(textChanged(QString))); 00168 00169 d->setWidget(nativeWidget); 00170 nativeWidget->setWindowIcon(QIcon()); 00171 00172 nativeWidget->setAttribute(Qt::WA_NoSystemBackground); 00173 nativeWidget->setStyle(d->style.data()); 00174 00175 d->syncBorders(); 00176 } 00177 00178 KComboBox *ComboBox::nativeWidget() const 00179 { 00180 return static_cast<KComboBox*>(widget()); 00181 } 00182 00183 void ComboBox::addItem(const QString &text) 00184 { 00185 static_cast<KComboBox*>(widget())->addItem(text); 00186 } 00187 00188 void ComboBox::clear() 00189 { 00190 static_cast<KComboBox*>(widget())->clear(); 00191 } 00192 00193 void ComboBox::resizeEvent(QGraphicsSceneResizeEvent *event) 00194 { 00195 if (d->background) { 00196 //resize needed panels 00197 d->syncActiveRect(); 00198 00199 d->background->setElementPrefix("focus"); 00200 d->background->resizeFrame(size()); 00201 00202 d->background->setElementPrefix("active"); 00203 d->background->resizeFrame(d->activeRect.size()); 00204 00205 d->background->setElementPrefix("normal"); 00206 d->background->resizeFrame(size()); 00207 } 00208 00209 QGraphicsProxyWidget::resizeEvent(event); 00210 } 00211 00212 void ComboBox::paint(QPainter *painter, 00213 const QStyleOptionGraphicsItem *option, 00214 QWidget *widget) 00215 { 00216 00217 if (!styleSheet().isNull() || 00218 Theme::defaultTheme()->useNativeWidgetStyle()) { 00219 QGraphicsProxyWidget::paint(painter, option, widget); 00220 return; 00221 } 00222 00223 if (nativeWidget()->isEditable()) { 00224 QGraphicsProxyWidget::paint(painter, option, widget); 00225 return; 00226 } 00227 00228 QPixmap bufferPixmap; 00229 00230 //normal button 00231 if (isEnabled()) { 00232 d->background->setElementPrefix("normal"); 00233 00234 d->background->paintFrame(painter); 00235 //disabled widget 00236 } else { 00237 bufferPixmap = QPixmap(rect().size().toSize()); 00238 bufferPixmap.fill(Qt::transparent); 00239 00240 QPainter buffPainter(&bufferPixmap); 00241 d->background->paintFrame(&buffPainter); 00242 buffPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn); 00243 buffPainter.fillRect(bufferPixmap.rect(), QColor(0, 0, 0, 128)); 00244 00245 painter->drawPixmap(0, 0, bufferPixmap); 00246 } 00247 00248 painter->setPen(Theme::defaultTheme()->color(Theme::ButtonTextColor)); 00249 00250 QStyleOptionComboBox comboOpt; 00251 00252 comboOpt.initFrom(nativeWidget()); 00253 00254 comboOpt.palette.setColor( 00255 QPalette::ButtonText, Theme::defaultTheme()->color(Theme::ButtonTextColor)); 00256 comboOpt.currentIcon = nativeWidget()->itemIcon( 00257 nativeWidget()->currentIndex()); 00258 comboOpt.currentText = nativeWidget()->itemText( 00259 nativeWidget()->currentIndex()); 00260 comboOpt.editable = false; 00261 00262 nativeWidget()->style()->drawControl( 00263 QStyle::CE_ComboBoxLabel, &comboOpt, painter, nativeWidget()); 00264 comboOpt.rect = nativeWidget()->style()->subControlRect( 00265 QStyle::CC_ComboBox, &comboOpt, QStyle::SC_ComboBoxArrow, nativeWidget()); 00266 nativeWidget()->style()->drawPrimitive( 00267 QStyle::PE_IndicatorArrowDown, &comboOpt, painter, nativeWidget()); 00268 } 00269 00270 void ComboBox::focusInEvent(QFocusEvent *event) 00271 { 00272 QGraphicsProxyWidget::focusInEvent(event); 00273 } 00274 00275 void ComboBox::focusOutEvent(QFocusEvent *event) 00276 { 00277 QGraphicsWidget *widget = parentWidget(); 00278 Plasma::Applet *applet = qobject_cast<Plasma::Applet *>(widget); 00279 00280 while (!applet && widget) { 00281 widget = widget->parentWidget(); 00282 applet = qobject_cast<Plasma::Applet *>(widget); 00283 } 00284 00285 if (applet) { 00286 applet->setStatus(Plasma::UnknownStatus); 00287 } 00288 00289 if (nativeWidget()->isEditable()) { 00290 QEvent closeEvent(QEvent::CloseSoftwareInputPanel); 00291 if (qApp) { 00292 if (QGraphicsView *view = qobject_cast<QGraphicsView*>(qApp->focusWidget())) { 00293 if (view->scene() && view->scene() == scene()) { 00294 QApplication::sendEvent(view, &closeEvent); 00295 } 00296 } 00297 } 00298 } 00299 00300 QGraphicsProxyWidget::focusOutEvent(event); 00301 } 00302 00303 void ComboBox::hoverEnterEvent(QGraphicsSceneHoverEvent *event) 00304 { 00305 d->underMouse = true; 00306 QGraphicsProxyWidget::hoverEnterEvent(event); 00307 } 00308 00309 void ComboBox::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) 00310 { 00311 d->underMouse = false; 00312 QGraphicsProxyWidget::hoverLeaveEvent(event); 00313 } 00314 00315 void ComboBox::changeEvent(QEvent *event) 00316 { 00317 d->changeEvent(event); 00318 QGraphicsProxyWidget::changeEvent(event); 00319 } 00320 00321 void ComboBox::mousePressEvent(QGraphicsSceneMouseEvent *event) 00322 { 00323 QGraphicsWidget *widget = parentWidget(); 00324 Plasma::Applet *applet = qobject_cast<Plasma::Applet *>(widget); 00325 00326 while (!applet && widget) { 00327 widget = widget->parentWidget(); 00328 applet = qobject_cast<Plasma::Applet *>(widget); 00329 } 00330 00331 if (applet) { 00332 applet->setStatus(Plasma::AcceptingInputStatus); 00333 } 00334 QGraphicsProxyWidget::mousePressEvent(event); 00335 } 00336 00337 int ComboBox::count() const 00338 { 00339 return nativeWidget()->count(); 00340 } 00341 00342 int ComboBox::currentIndex() const 00343 { 00344 return nativeWidget()->currentIndex(); 00345 } 00346 00347 void ComboBox::setCurrentIndex(int index) 00348 { 00349 nativeWidget()->setCurrentIndex(index); 00350 } 00351 00352 } // namespace Plasma 00353 00354 #include <combobox.moc> 00355
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Wed May 2 2012 17:35:59 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2012 The KDE developers.
Generated on Wed May 2 2012 17:35:59 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.