kdualcolorbutton.cpp
00001 /* This file is part of the KDE libraries 00002 Copyright (C) 1999 Daniel M. Duley <mosfet@kde.org> 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License version 2 as published by the Free Software Foundation. 00007 00008 This library is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00011 Library General Public License for more details. 00012 00013 You should have received a copy of the GNU Library General Public License 00014 along with this library; see the file COPYING.LIB. If not, write to 00015 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00016 Boston, MA 02110-1301, USA. 00017 */ 00018 00019 #include "kdualcolorbutton.h" 00020 #include "kcolordialog.h" 00021 #include "kcolordrag.h" 00022 #include "dcolorarrow.xbm" 00023 #include "dcolorreset.xpm" 00024 #include <kglobalsettings.h> 00025 #include <qpainter.h> 00026 #include <qbitmap.h> 00027 #include <qdrawutil.h> 00028 00029 class KDualColorButton::KDualColorPrivate 00030 { 00031 public: 00032 QWidget* dialogParent; 00033 }; 00034 00035 KDualColorButton::KDualColorButton(QWidget *parent, const char *name, QWidget* dialogParent) 00036 : QWidget(parent, name), 00037 d (new KDualColorPrivate) 00038 { 00039 if (!dialogParent && parent) { 00040 d->dialogParent = parent; 00041 } else { 00042 d->dialogParent = dialogParent; 00043 } 00044 00045 arrowBitmap = new QBitmap(dcolorarrow_width, dcolorarrow_height, 00046 (const unsigned char *)dcolorarrow_bits, true); 00047 arrowBitmap->setMask(*arrowBitmap); // heh 00048 resetPixmap = new QPixmap((const char **)dcolorreset_xpm); 00049 fg = QBrush(Qt::black, SolidPattern); 00050 bg = QBrush(Qt::white, SolidPattern); 00051 curColor = Foreground; 00052 dragFlag = false; 00053 miniCtlFlag = false; 00054 if(sizeHint().isValid()) 00055 setMinimumSize(sizeHint()); 00056 setAcceptDrops(true); 00057 } 00058 00059 KDualColorButton::KDualColorButton(const QColor &fgColor, const QColor &bgColor, 00060 QWidget *parent, const char *name, QWidget* dialogParent) 00061 : QWidget(parent, name), 00062 d (new KDualColorPrivate) 00063 { 00064 d->dialogParent = dialogParent; 00065 00066 arrowBitmap = new QBitmap(dcolorarrow_width, dcolorarrow_height, 00067 (const unsigned char *)dcolorarrow_bits, true); 00068 arrowBitmap->setMask(*arrowBitmap); 00069 resetPixmap = new QPixmap((const char **)dcolorreset_xpm); 00070 fg = QBrush(fgColor, SolidPattern); 00071 bg = QBrush(bgColor, SolidPattern); 00072 curColor = Foreground; 00073 dragFlag = false; 00074 miniCtlFlag = false; 00075 if(sizeHint().isValid()) 00076 setMinimumSize(sizeHint()); 00077 setAcceptDrops(true); 00078 } 00079 00080 KDualColorButton::~KDualColorButton() 00081 { 00082 delete d; 00083 delete arrowBitmap; 00084 delete resetPixmap; 00085 } 00086 00087 QColor KDualColorButton::foreground() const 00088 { 00089 return fg.color(); 00090 } 00091 00092 QColor KDualColorButton::background() const 00093 { 00094 return bg.color(); 00095 } 00096 00097 KDualColorButton::DualColor KDualColorButton::current() const 00098 { 00099 return curColor; 00100 } 00101 00102 QColor KDualColorButton::currentColor() const 00103 { 00104 return (curColor == Background ? bg.color() : fg.color()); 00105 } 00106 00107 QSize KDualColorButton::sizeHint() const 00108 { 00109 return QSize(34, 34); 00110 } 00111 00112 void KDualColorButton::setForeground(const QColor &c) 00113 { 00114 fg = QBrush(c, SolidPattern); 00115 repaint(false); 00116 00117 emit fgChanged(fg.color()); 00118 } 00119 00120 void KDualColorButton::setBackground(const QColor &c) 00121 { 00122 bg = QBrush(c, SolidPattern); 00123 repaint(false); 00124 00125 emit bgChanged(bg.color()); 00126 } 00127 00128 void KDualColorButton::setCurrentColor(const QColor &c) 00129 { 00130 if(curColor == Background) 00131 bg = QBrush(c, SolidPattern); 00132 else 00133 fg = QBrush(c, SolidPattern); 00134 repaint(false); 00135 } 00136 00137 void KDualColorButton::setCurrent(DualColor s) 00138 { 00139 curColor = s; 00140 repaint(false); 00141 } 00142 00143 void KDualColorButton::metrics(QRect &fgRect, QRect &bgRect) 00144 { 00145 fgRect = QRect(0, 0, width()-14, height()-14); 00146 bgRect = QRect(14, 14, width()-14, height()-14); 00147 } 00148 00149 void KDualColorButton::paintEvent(QPaintEvent *) 00150 { 00151 QRect fgRect, bgRect; 00152 QPainter p(this); 00153 00154 metrics(fgRect, bgRect); 00155 QBrush defBrush = colorGroup().brush(QColorGroup::Button); 00156 00157 qDrawShadeRect(&p, bgRect, colorGroup(), curColor == Background, 2, 0, 00158 isEnabled() ? &bg : &defBrush); 00159 qDrawShadeRect(&p, fgRect, colorGroup(), curColor == Foreground, 2, 0, 00160 isEnabled() ? &fg : &defBrush); 00161 p.setPen(colorGroup().shadow()); 00162 p.drawPixmap(fgRect.right()+2, 0, *arrowBitmap); 00163 p.drawPixmap(0, fgRect.bottom()+2, *resetPixmap); 00164 00165 } 00166 00167 void KDualColorButton::dragEnterEvent(QDragEnterEvent *ev) 00168 { 00169 ev->accept(isEnabled() && KColorDrag::canDecode(ev)); 00170 } 00171 00172 void KDualColorButton::dropEvent(QDropEvent *ev) 00173 { 00174 QColor c; 00175 if(KColorDrag::decode(ev, c)){ 00176 if(curColor == Foreground){ 00177 fg.setColor(c); 00178 emit fgChanged(c); 00179 } 00180 else{ 00181 bg.setColor(c); 00182 emit(bgChanged(c)); 00183 } 00184 repaint(false); 00185 } 00186 } 00187 00188 void KDualColorButton::mousePressEvent(QMouseEvent *ev) 00189 { 00190 QRect fgRect, bgRect; 00191 metrics(fgRect, bgRect); 00192 mPos = ev->pos(); 00193 tmpColor = curColor; 00194 dragFlag = false; 00195 if(fgRect.contains(mPos)){ 00196 curColor = Foreground; 00197 miniCtlFlag = false; 00198 } 00199 else if(bgRect.contains(mPos)){ 00200 curColor = Background; 00201 miniCtlFlag = false; 00202 } 00203 else if(ev->pos().x() > fgRect.width()){ 00204 // We handle the swap and reset controls as soon as the mouse is 00205 // is pressed and ignore further events on this click (mosfet). 00206 QBrush c = fg; 00207 fg = bg; 00208 bg = c; 00209 emit fgChanged(fg.color()); 00210 emit bgChanged(bg.color()); 00211 miniCtlFlag = true; 00212 } 00213 else if(ev->pos().x() < bgRect.x()){ 00214 fg.setColor(Qt::black); 00215 bg.setColor(Qt::white); 00216 emit fgChanged(fg.color()); 00217 emit bgChanged(bg.color()); 00218 miniCtlFlag = true; 00219 } 00220 repaint(false); 00221 } 00222 00223 00224 void KDualColorButton::mouseMoveEvent(QMouseEvent *ev) 00225 { 00226 if(!miniCtlFlag){ 00227 int delay = KGlobalSettings::dndEventDelay(); 00228 if(ev->x() >= mPos.x()+delay || ev->x() <= mPos.x()-delay || 00229 ev->y() >= mPos.y()+delay || ev->y() <= mPos.y()-delay) { 00230 KColorDrag *d = new KColorDrag( curColor == Foreground ? 00231 fg.color() : bg.color(), 00232 this); 00233 d->dragCopy(); 00234 dragFlag = true; 00235 } 00236 } 00237 } 00238 00239 void KDualColorButton::mouseReleaseEvent(QMouseEvent *ev) 00240 { 00241 if(!miniCtlFlag){ 00242 QRect fgRect, bgRect; 00243 00244 metrics(fgRect, bgRect); 00245 if(dragFlag) 00246 curColor = tmpColor; 00247 else if(fgRect.contains(ev->pos()) && curColor == Foreground){ 00248 if(tmpColor == Background){ 00249 curColor = Foreground; 00250 emit currentChanged(Foreground); 00251 } 00252 else{ 00253 QColor newColor = fg.color(); 00254 if(KColorDialog::getColor(newColor, d->dialogParent) != QDialog::Rejected){ 00255 fg.setColor(newColor); 00256 emit fgChanged(newColor); 00257 } 00258 } 00259 } 00260 else if(bgRect.contains(ev->pos()) && curColor == Background){ 00261 if(tmpColor == Foreground){ 00262 curColor = Background; 00263 emit currentChanged(Background); 00264 } 00265 else{ 00266 QColor newColor = bg.color(); 00267 if(KColorDialog::getColor(newColor, d->dialogParent) != QDialog::Rejected){ 00268 bg.setColor(newColor); 00269 emit bgChanged(newColor); 00270 } 00271 } 00272 } 00273 repaint(false); 00274 dragFlag = false; 00275 } 00276 else 00277 miniCtlFlag = false; 00278 } 00279 00280 void KDualColorButton::virtual_hook( int, void* ) 00281 { /*BASE::virtual_hook( id, data );*/ } 00282 00283 #include "kdualcolorbutton.moc"