/*************************************************************************** * Copyright (c) 2005 Werner Mayer * * * * This file is part of the FreeCAD CAx development system. * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Library General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this library; see the file COPYING.LIB. If not, * * write to the Free Software Foundation, Inc., 59 Temple Place, * * Suite 330, Boston, MA 02111-1307, USA * * * ***************************************************************************/ #include "PreCompiled.h" #ifndef _PreComp_ # include # include # include # include # include # include #endif #include "SoFCColorBar.h" #include "SoFCColorGradient.h" #include "SoFCColorLegend.h" using namespace Gui; SO_NODE_ABSTRACT_SOURCE(SoFCColorBarBase); /*! Constructor. */ SoFCColorBarBase::SoFCColorBarBase() { SO_NODE_CONSTRUCTOR(SoFCColorBarBase); } /*! Destructor. */ SoFCColorBarBase::~SoFCColorBarBase() { //delete THIS; } // doc from parent void SoFCColorBarBase::initClass(void) { SO_NODE_INIT_ABSTRACT_CLASS(SoFCColorBarBase,SoSeparator,"Separator"); } void SoFCColorBarBase::finish() { atexit_cleanup(); } void SoFCColorBarBase::GLRenderBelowPath(SoGLRenderAction * action) { const SbViewportRegion& vp = action->getViewportRegion(); const SbVec2s& size = vp.getWindowSize(); if (_windowSize != size) { _windowSize = size; setViewportSize(size); } SoSeparator::GLRenderBelowPath(action); } // -------------------------------------------------------------------------- namespace Gui { // Proxy class that receives an asynchronous custom event class SoFCColorBarProxyObject : public QObject { public: SoFCColorBarProxyObject(SoFCColorBar* b) : QObject(0), bar(b) {} ~SoFCColorBarProxyObject() {} void customEvent(QEvent *) { if (bar->customize()) bar->Notify(0); this->deleteLater(); } private: SoFCColorBar* bar; }; } SO_NODE_SOURCE(SoFCColorBar); /*! Constructor. */ SoFCColorBar::SoFCColorBar() { SO_NODE_CONSTRUCTOR(SoFCColorBar); _fMaxX = 0; _fMinX = 0; _fMaxY = 0; _fMinY = 0; // SoEventCallback * cb = new SoEventCallback; // cb->addEventCallback(SoMouseButtonEvent::getClassTypeId(), eventCallback, this); // insertChild(cb, 0); pColorMode = new SoSwitch; addChild(pColorMode); _colorBars.push_back( new SoFCColorGradient ); _colorBars.push_back( new SoFCColorLegend ); for (std::vector::const_iterator it = _colorBars.begin(); it != _colorBars.end(); ++it) pColorMode->addChild( *it ); pColorMode->whichChild = 0; } /*! Destructor. */ SoFCColorBar::~SoFCColorBar() { //delete THIS; } // doc from parent void SoFCColorBar::initClass(void) { SO_NODE_INIT_CLASS(SoFCColorBar,SoFCColorBarBase,"Separator"); } void SoFCColorBar::finish() { atexit_cleanup(); } SoFCColorBarBase* SoFCColorBar::getActiveBar() const { int child = pColorMode->whichChild.getValue(); return _colorBars[child]; } void SoFCColorBar::setViewportSize( const SbVec2s& size ) { // don't know why the parameter range isn't between [-1,+1] float fRatio = ((float)size[0])/((float)size[1]); _fMinX= 4.0f, _fMaxX=4.5f; _fMinY= -4.0f, _fMaxY=4.0f; if (fRatio > 1.0f) { _fMinX = 4.0f * fRatio; _fMaxX = _fMinX+0.5f; } else if (fRatio < 1.0f) { _fMinY = -4.0f / fRatio; _fMaxY = 4.0f / fRatio; } } void SoFCColorBar::setRange( float fMin, float fMax, int prec ) { for (std::vector::const_iterator it = _colorBars.begin(); it != _colorBars.end(); ++it) (*it)->setRange(fMin, fMax, prec); } void SoFCColorBar::setOutsideGrayed (bool bVal) { for (std::vector::const_iterator it = _colorBars.begin(); it != _colorBars.end(); ++it) (*it)->setOutsideGrayed(bVal); } bool SoFCColorBar::isVisible (float fVal) const { return this->getActiveBar()->isVisible(fVal); } float SoFCColorBar::getMinValue (void) const { return this->getActiveBar()->getMinValue(); } float SoFCColorBar::getMaxValue (void) const { return this->getActiveBar()->getMaxValue(); } bool SoFCColorBar::customize() { return this->getActiveBar()->customize(); } App::Color SoFCColorBar::getColor( float fVal ) const { return this->getActiveBar()->getColor( fVal ); } void SoFCColorBar::eventCallback(void * /*userdata*/, SoEventCallback * node) { const SoEvent * event = node->getEvent(); if (event->getTypeId().isDerivedFrom(SoMouseButtonEvent::getClassTypeId())) { const SoMouseButtonEvent* e = static_cast(event); if ((e->getButton() == SoMouseButtonEvent::BUTTON2)) { if (e->getState() == SoButtonEvent::UP) { } } } } void SoFCColorBar::handleEvent (SoHandleEventAction *action) { const SoEvent * event = action->getEvent(); // check for mouse button events if (event->getTypeId().isDerivedFrom(SoMouseButtonEvent::getClassTypeId())) { const SoMouseButtonEvent* e = static_cast(event); // calculate the mouse position relative to the colorbar // const SbViewportRegion& vp = action->getViewportRegion(); float fRatio = vp.getViewportAspectRatio(); SbVec2f pos = event->getNormalizedPosition(vp); float pX,pY; pos.getValue(pX,pY); pX = pX*10.0f-5.0f; pY = pY*10.0f-5.0f; // now calculate the real points respecting aspect ratio information // if (fRatio > 1.0f) { pX = pX * fRatio; } else if (fRatio < 1.0f) { pY = pY / fRatio; } // check if the cursor is near to the color bar if (_fMinX > pX || pX > _fMaxX || _fMinY > pY || pY > _fMaxY) return; // not inside the rectangle // left mouse pressed action->setHandled(); if ((e->getButton() == SoMouseButtonEvent::BUTTON1)) { if (e->getState() == SoButtonEvent::DOWN) { // double click event if (_timer.restart() < QApplication::doubleClickInterval()) { QApplication::postEvent( new SoFCColorBarProxyObject(this), new QEvent(QEvent::User)); } } } // right mouse pressed else if ((e->getButton() == SoMouseButtonEvent::BUTTON2)) { if (e->getState() == SoButtonEvent::UP) { SoFCColorBarBase* current = getActiveBar(); QMenu menu; int i=0; for (std::vector::const_iterator it = _colorBars.begin(); it != _colorBars.end(); ++it) { QAction* item = menu.addAction(QLatin1String((*it)->getColorBarName())); item->setCheckable(true); item->setChecked((*it) == current); item->setData(QVariant(i++)); } menu.addSeparator(); QAction* option = menu.addAction(QObject::tr("Options...")); QAction* action = menu.exec(QCursor::pos()); if (action == option) { QApplication::postEvent( new SoFCColorBarProxyObject(this), new QEvent(QEvent::User)); } else if (action) { int id = action->data().toInt(); pColorMode->whichChild = id; } } } } }