Mixxx

/home/maxime/Projets/Mixxx/1.10/mixxx/src/widget/wpushbutton.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           wpushbutton.cpp  -  description
00003                              -------------------
00004     begin                : Fri Jun 21 2002
00005     copyright            : (C) 2002 by Tue & Ken Haste Andersen
00006     email                : haste@diku.dk
00007 ***************************************************************************/
00008 
00009 /***************************************************************************
00010 *                                                                         *
00011 *   This program is free software; you can redistribute it and/or modify  *
00012 *   it under the terms of the GNU General Public License as published by  *
00013 *   the Free Software Foundation; either version 2 of the License, or     *
00014 *   (at your option) any later version.                                   *
00015 *                                                                         *
00016 ***************************************************************************/
00017 
00018 #include "wpushbutton.h"
00019 #include "wpixmapstore.h"
00020 #include "controlobject.h"
00021 #include "controlpushbutton.h"
00022 //Added by qt3to4:
00023 #include <QPixmap>
00024 #include <QtDebug>
00025 #include <QMouseEvent>
00026 #include <QPaintEvent>
00027 
00028 WPushButton::WPushButton(QWidget * parent) : WWidget(parent)
00029 {
00030     m_pPixmaps = 0;
00031     m_pPixmapBack = 0;
00032     setStates(0);
00033     //setBackgroundMode(Qt::NoBackground); //obsolete? removal doesn't seem to change anything on the GUI --kousu 2009/03
00034 }
00035 
00036 WPushButton::~WPushButton()
00037 {
00038     for (int i = 0; i < 2*m_iNoStates; i++) {
00039         WPixmapStore::deletePixmap(m_pPixmaps[i]);
00040     }
00041 
00042     delete [] m_pPixmaps;
00043 
00044     WPixmapStore::deletePixmap(m_pPixmapBack);
00045 }
00046 
00047 void WPushButton::setup(QDomNode node)
00048 {
00049     // Number of states
00050     int iNumStates = selectNodeInt(node, "NumberStates");
00051     setStates(iNumStates);
00052 
00053     // Set background pixmap if available
00054     if (!selectNode(node, "BackPath").isNull())
00055         setPixmapBackground(getPath(selectNodeQString(node, "BackPath")));
00056 
00057     // Load pixmaps for associated states
00058     QDomNode state = selectNode(node, "State");
00059     while (!state.isNull())
00060     {
00061         if (state.isElement() && state.nodeName() == "State")
00062         {
00063             setPixmap(selectNodeInt(state, "Number"), true, getPath(selectNodeQString(state, "Pressed")));
00064             setPixmap(selectNodeInt(state, "Number"), false, getPath(selectNodeQString(state, "Unpressed")));
00065         }
00066         state = state.nextSibling();
00067     }
00068 
00069     m_bLeftClickForcePush = false;
00070     if (selectNodeQString(node, "LeftClickIsPushButton").contains("true", Qt::CaseInsensitive))
00071         m_bLeftClickForcePush = true;
00072 
00073     m_bRightClickForcePush = false;
00074     if (selectNodeQString(node, "RightClickIsPushButton").contains("true", Qt::CaseInsensitive))
00075         m_bRightClickForcePush = true;
00076 
00077     //--------
00078     //This next big block allows each ControlPushButton to know whether or not it's
00079     //a "toggle" button.
00080 
00081     // For each connection
00082     QDomNode con = selectNode(node, "Connection");
00083     while (!con.isNull())
00084     {
00085         // Get ConfigKey
00086         QString key = selectNodeQString(con, "ConfigKey");
00087 
00088         ConfigKey configKey;
00089         configKey.group = key.left(key.indexOf(","));
00090         configKey.item = key.mid(key.indexOf(",")+1);
00091 
00092         //Find out if we're a push button...
00093         if (node.nodeName() == "PushButton")
00094         {
00095             ControlPushButton* p = dynamic_cast<ControlPushButton*>(
00096                 ControlObject::getControl(configKey));
00097 
00098             if (p == NULL) {
00099                 // A NULL here either means that this control is not a
00100                 // ControlPushButton or it does not exist. This logic is
00101                 // specific to push-buttons, so skip it either way.
00102                 con = con.nextSibling();
00103                 continue;
00104             }
00105 
00106             bool isLeftButton = false;
00107             bool isRightButton = false;
00108             if (!selectNode(con, "ButtonState").isNull())
00109             {
00110                 if (selectNodeQString(con, "ButtonState").contains("LeftButton", Qt::CaseInsensitive)) {
00111                     isLeftButton = true;
00112                 }
00113                 else if (selectNodeQString(con, "ButtonState").contains("RightButton", Qt::CaseInsensitive)) {
00114                     isRightButton = true;
00115                 }
00116             }
00117 
00118             // If we have 2 states, tell my controlpushbutton object that we're
00119             // a toggle button. Only set the control as a toggle button if it
00120             // has not been forced to remain a push button by the
00121             // Right/LeftClickIsPushButton directive above. Do this by checking
00122             // whether this control is mapped to the RightButton or LeftButton
00123             // and check it against the value of m_bLeft/RightClickForcePush. We
00124             // have to handle the case where no ButtonState is provided for the
00125             // control. If no button is provided, then we have to assume the
00126             // connected control should be a toggle.
00127 
00128             //bool setAsToggleButton = iNumStates == 2 &&
00129             //       ((!isLeftButton && !isRightButton) ||
00130             //        ( (isLeftButton && !m_bLeftClickForcePush) ||
00131             //          (isRightButton && !m_bRightClickForcePush) ) );
00132 
00133             // if (setAsToggleButton)
00134             //     p->setToggleButton(true);
00135 
00136             // BJW: Removed this so that buttons that are hardcoded as toggle in the source
00137             // don't get overridden if a skin fails to set them to 2-state. Buttons still
00138             // default to non-toggle otherwise.
00139             // else
00140             //  p->setToggleButton(false);
00141         }
00142 
00143         con = con.nextSibling();
00144     }
00145 
00146     //End of toggle button stuff.
00147     //--------
00148 }
00149 
00150 void WPushButton::setStates(int iStates)
00151 {
00152     m_iNoStates = iStates;
00153     m_fValue = 0.;
00154     m_bPressed = false;
00155 
00156     // If pixmap array is already allocated, delete it
00157     delete [] m_pPixmaps;
00158     m_pPixmaps = NULL;
00159 
00160     if (iStates>0)
00161     {
00162         m_pPixmaps = new QPixmap*[2*m_iNoStates];
00163         for (int i=0; i<2*m_iNoStates; ++i)
00164             m_pPixmaps[i] = 0;
00165     }
00166 }
00167 
00168 void WPushButton::setPixmap(int iState, bool bPressed, const QString &filename)
00169 {
00170     int pixIdx = (iState*2)+bPressed;
00171     m_pPixmaps[pixIdx] = WPixmapStore::getPixmap(filename);
00172     if (!m_pPixmaps[pixIdx])
00173         qDebug() << "WPushButton: Error loading pixmap:" << filename;
00174 
00175     // Set size of widget equal to pixmap size
00176     setFixedSize(m_pPixmaps[pixIdx]->size());
00177 }
00178 
00179 void WPushButton::setPixmapBackground(const QString &filename)
00180 {
00181     // Load background pixmap
00182     m_pPixmapBack = WPixmapStore::getPixmap(filename);
00183     if (!m_pPixmapBack)
00184         qDebug() << "WPushButton: Error loading background pixmap:" << filename;
00185 }
00186 
00187 void WPushButton::setValue(double v)
00188 {
00189     m_fValue = v;
00190 
00191     if (m_iNoStates==1)
00192     {
00193         if (m_fValue==1.)
00194             m_bPressed = true;
00195         else
00196             m_bPressed = false;
00197     }
00198 
00199     update();
00200 }
00201 
00202 void WPushButton::paintEvent(QPaintEvent *)
00203 {
00204     if (m_iNoStates>0)
00205     {
00206         int idx = (((int)m_fValue%m_iNoStates)*2)+m_bPressed;
00207         if (m_pPixmaps[idx])
00208         {
00209             QPainter p(this);
00210             if(m_pPixmapBack) p.drawPixmap(0, 0, *m_pPixmapBack);
00211             p.drawPixmap(0, 0, *m_pPixmaps[idx]);
00212         }
00213     }
00214 }
00215 
00216 void WPushButton::mousePressEvent(QMouseEvent * e)
00217 {
00218     m_bPressed = true;
00219 
00220     bool leftClick = e->button() == Qt::LeftButton;
00221     bool rightClick = e->button() == Qt::RightButton;
00222 
00223     // The value to emit.
00224     double emitValue = m_fValue;
00225 
00226     // Calculate new state if it is a one state button
00227     if (m_iNoStates == 1) {
00228         m_fValue = emitValue = (m_fValue == 0.0f) ? 1.0f : 0.0f;
00229     }
00230     // Update state on press if it is a n-state button and not a pushbutton
00231     else if (leftClick) {
00232         if (m_bLeftClickForcePush) {
00233             emitValue = 1.0f;
00234         } else {
00235             m_fValue = emitValue = (int)(m_fValue+1.)%m_iNoStates;
00236         }
00237     }
00238 
00239     // Do not allow right-clicks to change the state of the button. This is how
00240     // Mixxx <1.8.0 worked so keep it that way. For a multi-state button, really
00241     // only one click type (left/right) should be able to change the state. One
00242     // problem with this is that you can get the button out of sync with its
00243     // underlying control. For example the PFL buttons on Jus's skins could get
00244     // out of sync with the button state. rryan 9/2010
00245 
00246     // else if (rightClick) {
00247     //     if (m_bRightClickForcePush) {
00248     //         emitValue = 1.0f;
00249     //     } else {
00250     //         m_fValue = emitValue = (int)(m_fValue+1.)%m_iNoStates;
00251     //     }
00252     // }
00253 
00254     if (leftClick) {
00255         emit(valueChangedLeftDown(emitValue));
00256     } else if (rightClick) {
00257         emit(valueChangedRightDown(emitValue));
00258     }
00259 
00260     update();
00261 }
00262 
00263 void WPushButton::focusOutEvent(QFocusEvent* e) {
00264     m_bPressed = false;
00265     update();
00266 }
00267 
00268 void WPushButton::mouseReleaseEvent(QMouseEvent * e)
00269 {
00270     m_bPressed = false;
00271 
00272     bool leftClick = e->button() == Qt::LeftButton;
00273     bool rightClick = e->button() == Qt::RightButton;
00274 
00275     // The value to emit
00276     double emitValue = m_fValue;
00277 
00278     // Update state if it is a one state button.
00279     if (m_iNoStates==1) // && e->button()==Qt::LeftButton)
00280     {
00281         m_fValue = emitValue = (m_fValue == 0.0f) ? 1.0f : 0.0f;
00282     } else if ((leftClick && m_bLeftClickForcePush) || (rightClick && m_bRightClickForcePush)) {
00283         emitValue = 0.0f;
00284     }
00285 
00286     if (leftClick) {
00287         emit(valueChangedLeftUp(emitValue));
00288     } else if (rightClick) {
00289         emit(valueChangedRightUp(emitValue));
00290     }
00291 
00292     update();
00293 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines