1
/***************************************************************************
2
* Copyright (c) 2005 Werner Mayer <wmayer[at]users.sourceforge.net> *
4
* This file is part of the FreeCAD CAx development system. *
6
* This library is free software; you can redistribute it and/or *
7
* modify it under the terms of the GNU Library General Public *
8
* License as published by the Free Software Foundation; either *
9
* version 2 of the License, or (at your option) any later version. *
11
* This library is distributed in the hope that it will be useful, *
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14
* GNU Library General Public License for more details. *
16
* You should have received a copy of the GNU Library General Public *
17
* License along with this library; see the file COPYING.LIB. If not, *
18
* write to the Free Software Foundation, Inc., 59 Temple Place, *
19
* Suite 330, Boston, MA 02111-1307, USA *
21
***************************************************************************/
23
#include "PreCompiled.h"
26
# include <boost/core/ignore_unused.hpp>
27
# include <Inventor/actions/SoGetBoundingBoxAction.h>
28
# include <Inventor/actions/SoGLRenderAction.h>
29
# include <Inventor/events/SoMouseButtonEvent.h>
30
# include <Inventor/nodes/SoEventCallback.h>
31
# include <Inventor/nodes/SoOrthographicCamera.h>
32
# include <Inventor/nodes/SoSwitch.h>
33
# include <QApplication>
37
#include "SoFCColorBar.h"
38
#include "SoFCColorGradient.h"
39
#include "SoFCColorLegend.h"
44
SO_NODE_ABSTRACT_SOURCE(SoFCColorBarBase)
49
SoFCColorBarBase::SoFCColorBarBase() : _windowSize(0,0)
51
SO_NODE_CONSTRUCTOR(SoFCColorBarBase);
57
SoFCColorBarBase::~SoFCColorBarBase() = default;
60
void SoFCColorBarBase::initClass()
62
SO_NODE_INIT_ABSTRACT_CLASS(SoFCColorBarBase,SoSeparator,"Separator");
65
void SoFCColorBarBase::finish()
70
void SoFCColorBarBase::GLRenderBelowPath(SoGLRenderAction * action)
72
const SbViewportRegion& vp = action->getViewportRegion();
73
const SbVec2s& size = vp.getWindowSize();
74
if (_windowSize != size) {
76
setViewportSize(size);
78
SoSeparator::GLRenderBelowPath(action);
81
void SoFCColorBarBase::setModified()
86
void SoFCColorBarBase::setFormat(const SoLabelTextFormat& fmt)
92
SoLabelTextFormat SoFCColorBarBase::getFormat() const
97
void SoFCColorBarBase::applyFormat(const SoLabelTextFormat& fmt)
99
boost::ignore_unused(fmt);
102
float SoFCColorBarBase::getBoundingWidth(const SbVec2s& size)
104
float fRatio = static_cast<float>(size[0]) / static_cast<float>(size[1]);
105
if (fRatio >= 1.0f && _boxWidth >= 0.0f) {
109
// These are the same camera settings for front nodes as defined in the 3d view
110
auto cam = new SoOrthographicCamera;
111
cam->position = SbVec3f(0, 0, 5); // the 5 is just a value > 0
112
cam->height = 10; // sets the coordinate range of the screen to [-5, +5]
113
cam->nearDistance = 0;
114
cam->farDistance = 10;
116
auto group = new SoGroup();
118
group->addChild(cam);
119
group->addChild(this);
121
SbViewportRegion vpr(size);
122
SoGetBoundingBoxAction bbact(vpr);
124
SbBox3f box = bbact.getBoundingBox();
125
SbVec3f minPt, maxPt;
126
box.getBounds(minPt, maxPt);
129
float boxWidth = maxPt[0] - minPt[0];
130
_boxWidth = boxWidth;
134
float SoFCColorBarBase::getBounds(const SbVec2s& size, float& fMinX, float&fMinY, float& fMaxX, float& fMaxY)
136
// ratio of window width / height
137
float fRatio = static_cast<float>(size[0]) / static_cast<float>(size[1]);
139
// The cam height is set in SoFCColorBarBase::getBoundingWidth to 10.
140
// Therefore the normalized coordinates are in the range [-5, +5] x [-5ratio, +5ratio] if ratio > 1
141
// and [-5ratio, +5ratio] x [-5, +5] if ratio < 1.
142
// We don't want the whole height covered by the color bar (to have e.g space to the axis cross
143
// and the Navigation Cube) thus we take as base 3 or if the height reduces significantly it is 2.5.
152
float barWidth = 0.5f;
154
// we want the color bar at the rightmost position, therefore we take 4.95 as base
155
fMinX = 4.95f * fRatio; // must be scaled with the ratio to assure it stays at the right
157
fMaxX = fMinX + barWidth;
158
fMinY = -baseYValue - 0.6f; // Extend shortened bar towards axis cross
159
fMaxY = baseYValue; // bar has the height of almost whole window height
162
// must be adjusted to assure that the size of the bar doesn't shrink
165
fMinY = -baseYValue / fRatio;
166
fMaxY = baseYValue / fRatio;
169
// get the bounding box width of the color bar and labels
170
float boxWidth = getBoundingWidth(size);
174
// --------------------------------------------------------------------------
177
// Proxy class that receives an asynchronous custom event
178
class SoFCColorBarProxyObject : public QObject
181
explicit SoFCColorBarProxyObject(SoFCColorBar* b)
182
: QObject(nullptr), bar(b) {}
183
~SoFCColorBarProxyObject() override = default;
184
void customEvent(QEvent *) override
186
bar->customize(bar->getActiveBar());
195
SO_NODE_SOURCE(SoFCColorBar)
200
SoFCColorBar::SoFCColorBar()
202
SO_NODE_CONSTRUCTOR(SoFCColorBar);
204
// SoEventCallback * cb = new SoEventCallback;
205
// cb->addEventCallback(SoMouseButtonEvent::getClassTypeId(), eventCallback, this);
206
// insertChild(cb, 0);
208
pColorMode = new SoSwitch;
209
addChild(pColorMode);
211
_colorBars.push_back( new SoFCColorGradient );
212
_colorBars.push_back( new SoFCColorLegend );
214
for (auto it : _colorBars)
215
pColorMode->addChild(it);
216
pColorMode->whichChild = 0;
222
SoFCColorBar::~SoFCColorBar() = default;
225
void SoFCColorBar::initClass()
227
SO_NODE_INIT_CLASS(SoFCColorBar,SoFCColorBarBase,"Separator");
230
void SoFCColorBar::finish()
235
SoFCColorBarBase* SoFCColorBar::getActiveBar() const
237
int child = pColorMode->whichChild.getValue();
238
return _colorBars[child];
241
void SoFCColorBar::setFormat(const SoLabelTextFormat& fmt)
243
for (auto it : _colorBars)
247
void SoFCColorBar::setViewportSize( const SbVec2s& size )
249
boost::ignore_unused(size);
252
void SoFCColorBar::setRange( float fMin, float fMax, int prec )
254
for (auto it : _colorBars)
255
it->setRange(fMin, fMax, prec);
258
void SoFCColorBar::setOutsideGrayed (bool bVal)
260
for (auto it : _colorBars)
261
it->setOutsideGrayed(bVal);
264
bool SoFCColorBar::isVisible (float fVal) const
266
return this->getActiveBar()->isVisible(fVal);
269
float SoFCColorBar::getMinValue () const
271
return this->getActiveBar()->getMinValue();
274
float SoFCColorBar::getMaxValue () const
276
return this->getActiveBar()->getMaxValue();
279
void SoFCColorBar::triggerChange(SoFCColorBarBase*)
284
void SoFCColorBar::customize(SoFCColorBarBase* child)
287
return child->customize(this);
289
catch (const Base::ValueError& e) {
294
App::Color SoFCColorBar::getColor( float fVal ) const
296
return this->getActiveBar()->getColor( fVal );
299
void SoFCColorBar::eventCallback(void * /*userdata*/, SoEventCallback * node)
301
const SoEvent * event = node->getEvent();
302
if (event->getTypeId().isDerivedFrom(SoMouseButtonEvent::getClassTypeId())) {
303
const auto e = static_cast<const SoMouseButtonEvent*>(event);
304
if ((e->getButton() == SoMouseButtonEvent::BUTTON2)) {
305
if (e->getState() == SoButtonEvent::UP) {
312
void SoFCColorBar::handleEvent (SoHandleEventAction *action)
314
const SoEvent * event = action->getEvent();
316
// check for mouse button events
317
if (event->getTypeId().isDerivedFrom(SoMouseButtonEvent::getClassTypeId())) {
318
const auto e = static_cast<const SoMouseButtonEvent*>(event);
320
// check if the cursor is near to the color bar
321
if (!action->getPickedPoint())
322
return; // not inside the rectangle
324
// left mouse pressed
325
action->setHandled();
326
if ((e->getButton() == SoMouseButtonEvent::BUTTON1)) {
327
if (e->getState() == SoButtonEvent::DOWN) {
328
// double click event
329
if (!_timer.isValid()) {
332
else if (_timer.restart() < QApplication::doubleClickInterval()) {
333
QApplication::postEvent(
334
new SoFCColorBarProxyObject(this),
335
new QEvent(QEvent::User));
339
// right mouse pressed
340
else if ((e->getButton() == SoMouseButtonEvent::BUTTON2)) {
341
if (e->getState() == SoButtonEvent::UP) {
342
SoFCColorBarBase* current = getActiveBar();
345
for (auto it : _colorBars) {
346
QAction* item = menu.addAction(QObject::tr(it->getColorBarName()));
347
item->setCheckable(true);
348
item->setChecked(it == current);
349
item->setData(QVariant(i++));
353
QAction* option = menu.addAction(QObject::tr("Options..."));
354
QAction* select = menu.exec(QCursor::pos());
356
if (select == option) {
357
QApplication::postEvent(
358
new SoFCColorBarProxyObject(this),
359
new QEvent(QEvent::User));
362
int id = select->data().toInt();
363
pColorMode->whichChild = id;