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