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 int animId; 00060 qreal opacity; 00061 QRectF activeRect; 00062 Style::Ptr style; 00063 bool underMouse; 00064 }; 00065 00066 void ComboBoxPrivate::syncActiveRect() 00067 { 00068 background->setElementPrefix("normal"); 00069 00070 qreal left, top, right, bottom; 00071 background->getMargins(left, top, right, bottom); 00072 00073 background->setElementPrefix("active"); 00074 qreal activeLeft, activeTop, activeRight, activeBottom; 00075 background->getMargins(activeLeft, activeTop, activeRight, activeBottom); 00076 00077 activeRect = QRectF(QPointF(0, 0), q->size()); 00078 activeRect.adjust(left - activeLeft, top - activeTop, 00079 -(right - activeRight), -(bottom - activeBottom)); 00080 00081 background->setElementPrefix("normal"); 00082 } 00083 00084 void ComboBoxPrivate::syncBorders() 00085 { 00086 //set margins from the normal element 00087 qreal left, top, right, bottom; 00088 00089 background->setElementPrefix("normal"); 00090 background->getMargins(left, top, right, bottom); 00091 q->setContentsMargins(left, top, right, bottom); 00092 00093 //calc the rect for the over effect 00094 syncActiveRect(); 00095 00096 if (customFont) { 00097 q->setFont(q->font()); 00098 } else { 00099 q->setFont(Theme::defaultTheme()->font(Theme::DefaultFont)); 00100 customFont = false; 00101 } 00102 } 00103 00104 00105 ComboBox::ComboBox(QGraphicsWidget *parent) 00106 : QGraphicsProxyWidget(parent), 00107 d(new ComboBoxPrivate(this)) 00108 { 00109 d->background = new FrameSvg(this); 00110 d->background->setImagePath("widgets/button"); 00111 d->background->setCacheAllRenderedFrames(true); 00112 d->background->setElementPrefix("normal"); 00113 d->lineEditBackground = new FrameSvg(this); 00114 d->lineEditBackground->setImagePath("widgets/lineedit"); 00115 d->lineEditBackground->setCacheAllRenderedFrames(true); 00116 setZValue(900); 00117 00118 setAcceptHoverEvents(true); 00119 00120 d->style = Style::sharedStyle(); 00121 00122 new FocusIndicator(this, d->background); 00123 setNativeWidget(new KComboBox); 00124 connect(d->background, SIGNAL(repaintNeeded()), SLOT(syncBorders())); 00125 d->initTheming(); 00126 } 00127 00128 ComboBox::~ComboBox() 00129 { 00130 delete d; 00131 Style::doneWithSharedStyle(); 00132 } 00133 00134 QString ComboBox::text() const 00135 { 00136 return static_cast<KComboBox*>(widget())->currentText(); 00137 } 00138 00139 void ComboBox::setStyleSheet(const QString &stylesheet) 00140 { 00141 widget()->setStyleSheet(stylesheet); 00142 } 00143 00144 QString ComboBox::styleSheet() 00145 { 00146 return widget()->styleSheet(); 00147 } 00148 00149 void ComboBox::setNativeWidget(KComboBox *nativeWidget) 00150 { 00151 if (widget()) { 00152 widget()->deleteLater(); 00153 } 00154 00155 connect(nativeWidget, SIGNAL(activated(const QString &)), this, SIGNAL(activated(const QString &))); 00156 connect(nativeWidget, SIGNAL(currentIndexChanged(int)), 00157 this, SIGNAL(currentIndexChanged(int))); 00158 connect(nativeWidget, SIGNAL(currentIndexChanged(const QString &)), 00159 this, SIGNAL(textChanged(const QString &))); 00160 00161 setWidget(nativeWidget); 00162 nativeWidget->setWindowIcon(QIcon()); 00163 00164 nativeWidget->setAttribute(Qt::WA_NoSystemBackground); 00165 nativeWidget->setStyle(d->style.data()); 00166 00167 d->syncBorders(); 00168 } 00169 00170 KComboBox *ComboBox::nativeWidget() const 00171 { 00172 return static_cast<KComboBox*>(widget()); 00173 } 00174 00175 void ComboBox::addItem(const QString &text) 00176 { 00177 static_cast<KComboBox*>(widget())->addItem(text); 00178 } 00179 00180 void ComboBox::clear() 00181 { 00182 static_cast<KComboBox*>(widget())->clear(); 00183 } 00184 00185 void ComboBox::resizeEvent(QGraphicsSceneResizeEvent *event) 00186 { 00187 if (d->background) { 00188 //resize needed panels 00189 d->syncActiveRect(); 00190 00191 d->background->setElementPrefix("focus"); 00192 d->background->resizeFrame(size()); 00193 00194 d->background->setElementPrefix("active"); 00195 d->background->resizeFrame(d->activeRect.size()); 00196 00197 d->background->setElementPrefix("normal"); 00198 d->background->resizeFrame(size()); 00199 } 00200 00201 QGraphicsProxyWidget::resizeEvent(event); 00202 } 00203 00204 void ComboBox::paint(QPainter *painter, 00205 const QStyleOptionGraphicsItem *option, 00206 QWidget *widget) 00207 { 00208 00209 if (!styleSheet().isNull() || 00210 Theme::defaultTheme()->useNativeWidgetStyle()) { 00211 QGraphicsProxyWidget::paint(painter, option, widget); 00212 return; 00213 } 00214 00215 if (nativeWidget()->isEditable()) { 00216 QGraphicsProxyWidget::paint(painter, option, widget); 00217 return; 00218 } 00219 00220 QPixmap bufferPixmap; 00221 00222 //normal button 00223 if (isEnabled()) { 00224 d->background->setElementPrefix("normal"); 00225 00226 d->background->paintFrame(painter); 00227 //disabled widget 00228 } else { 00229 bufferPixmap = QPixmap(rect().size().toSize()); 00230 bufferPixmap.fill(Qt::transparent); 00231 00232 QPainter buffPainter(&bufferPixmap); 00233 d->background->paintFrame(&buffPainter); 00234 buffPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn); 00235 buffPainter.fillRect(bufferPixmap.rect(), QColor(0, 0, 0, 128)); 00236 00237 painter->drawPixmap(0, 0, bufferPixmap); 00238 } 00239 00240 painter->setPen(Theme::defaultTheme()->color(Theme::ButtonTextColor)); 00241 00242 QStyleOptionComboBox comboOpt; 00243 00244 comboOpt.initFrom(nativeWidget()); 00245 00246 comboOpt.palette.setColor( 00247 QPalette::ButtonText, Theme::defaultTheme()->color(Theme::ButtonTextColor)); 00248 comboOpt.currentIcon = nativeWidget()->itemIcon( 00249 nativeWidget()->currentIndex()); 00250 comboOpt.currentText = nativeWidget()->itemText( 00251 nativeWidget()->currentIndex()); 00252 comboOpt.editable = false; 00253 00254 nativeWidget()->style()->drawControl( 00255 QStyle::CE_ComboBoxLabel, &comboOpt, painter, nativeWidget()); 00256 comboOpt.rect = nativeWidget()->style()->subControlRect( 00257 QStyle::CC_ComboBox, &comboOpt, QStyle::SC_ComboBoxArrow, nativeWidget()); 00258 nativeWidget()->style()->drawPrimitive( 00259 QStyle::PE_IndicatorArrowDown, &comboOpt, painter, nativeWidget()); 00260 } 00261 00262 void ComboBox::focusInEvent(QFocusEvent *event) 00263 { 00264 QGraphicsProxyWidget::focusInEvent(event); 00265 } 00266 00267 void ComboBox::focusOutEvent(QFocusEvent *event) 00268 { 00269 QGraphicsWidget *widget = parentWidget(); 00270 Plasma::Applet *applet = qobject_cast<Plasma::Applet *>(widget); 00271 00272 while (!applet && widget) { 00273 widget = widget->parentWidget(); 00274 applet = qobject_cast<Plasma::Applet *>(widget); 00275 } 00276 00277 if (applet) { 00278 applet->setStatus(Plasma::UnknownStatus); 00279 } 00280 00281 if (nativeWidget()->isEditable()) { 00282 QEvent closeEvent(QEvent::CloseSoftwareInputPanel); 00283 if (qApp) { 00284 if (QGraphicsView *view = qobject_cast<QGraphicsView*>(qApp->focusWidget())) { 00285 if (view->scene() && view->scene() == scene()) { 00286 QApplication::sendEvent(view, &closeEvent); 00287 } 00288 } 00289 } 00290 } 00291 00292 QGraphicsProxyWidget::focusOutEvent(event); 00293 } 00294 00295 void ComboBox::hoverEnterEvent(QGraphicsSceneHoverEvent *event) 00296 { 00297 d->underMouse = true; 00298 QGraphicsProxyWidget::hoverEnterEvent(event); 00299 } 00300 00301 void ComboBox::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) 00302 { 00303 d->underMouse = false; 00304 QGraphicsProxyWidget::hoverLeaveEvent(event); 00305 } 00306 00307 void ComboBox::changeEvent(QEvent *event) 00308 { 00309 d->changeEvent(event); 00310 QGraphicsProxyWidget::changeEvent(event); 00311 } 00312 00313 void ComboBox::mousePressEvent(QGraphicsSceneMouseEvent *event) 00314 { 00315 QGraphicsWidget *widget = parentWidget(); 00316 Plasma::Applet *applet = qobject_cast<Plasma::Applet *>(widget); 00317 00318 while (!applet && widget) { 00319 widget = widget->parentWidget(); 00320 applet = qobject_cast<Plasma::Applet *>(widget); 00321 } 00322 00323 if (applet) { 00324 applet->setStatus(Plasma::AcceptingInputStatus); 00325 } 00326 QGraphicsProxyWidget::mousePressEvent(event); 00327 } 00328 00329 int ComboBox::count() const 00330 { 00331 return nativeWidget()->count(); 00332 } 00333 00334 int ComboBox::currentIndex() const 00335 { 00336 return nativeWidget()->currentIndex(); 00337 } 00338 00339 void ComboBox::setCurrentIndex(int index) 00340 { 00341 nativeWidget()->setCurrentIndex(index); 00342 } 00343 00344 } // namespace Plasma 00345 00346 #include <combobox.moc> 00347
KDE 4.7 API Reference