FreeCAD

Форк
0
/
SoFCColorBar.cpp 
368 строк · 10.7 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2005 Werner Mayer <wmayer[at]users.sourceforge.net>     *
3
 *                                                                         *
4
 *   This file is part of the FreeCAD CAx development system.              *
5
 *                                                                         *
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.      *
10
 *                                                                         *
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.                  *
15
 *                                                                         *
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                                *
20
 *                                                                         *
21
 ***************************************************************************/
22

23
#include "PreCompiled.h"
24

25
#ifndef _PreComp_
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>
34
# include <QMenu>
35
#endif
36

37
#include "SoFCColorBar.h"
38
#include "SoFCColorGradient.h"
39
#include "SoFCColorLegend.h"
40

41

42
using namespace Gui;
43

44
SO_NODE_ABSTRACT_SOURCE(SoFCColorBarBase)
45

46
/*!
47
  Constructor.
48
*/
49
SoFCColorBarBase::SoFCColorBarBase() : _windowSize(0,0)
50
{
51
    SO_NODE_CONSTRUCTOR(SoFCColorBarBase);
52
}
53

54
/*!
55
  Destructor.
56
*/
57
SoFCColorBarBase::~SoFCColorBarBase() = default;
58

59
// doc from parent
60
void SoFCColorBarBase::initClass()
61
{
62
    SO_NODE_INIT_ABSTRACT_CLASS(SoFCColorBarBase,SoSeparator,"Separator");
63
}
64

65
void SoFCColorBarBase::finish()
66
{
67
    atexit_cleanup();
68
}
69

70
void SoFCColorBarBase::GLRenderBelowPath(SoGLRenderAction *  action)
71
{
72
    const SbViewportRegion& vp = action->getViewportRegion();
73
    const SbVec2s&  size = vp.getWindowSize();
74
    if (_windowSize != size) {
75
        _windowSize = size;
76
        setViewportSize(size);
77
    }
78
    SoSeparator::GLRenderBelowPath(action);
79
}
80

81
void SoFCColorBarBase::setModified()
82
{
83
    _boxWidth = -1.0f;
84
}
85

86
void SoFCColorBarBase::setFormat(const SoLabelTextFormat& fmt)
87
{
88
    format = fmt;
89
    applyFormat(fmt);
90
}
91

92
SoLabelTextFormat SoFCColorBarBase::getFormat() const
93
{
94
    return format;
95
}
96

97
void SoFCColorBarBase::applyFormat(const SoLabelTextFormat& fmt)
98
{
99
    boost::ignore_unused(fmt);
100
}
101

102
float SoFCColorBarBase::getBoundingWidth(const SbVec2s& size)
103
{
104
    float fRatio = static_cast<float>(size[0]) / static_cast<float>(size[1]);
105
    if (fRatio >= 1.0f && _boxWidth >= 0.0f) {
106
        return _boxWidth;
107
    }
108

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;
115

116
    auto group = new SoGroup();
117
    group->ref();
118
    group->addChild(cam);
119
    group->addChild(this);
120

121
    SbViewportRegion vpr(size);
122
    SoGetBoundingBoxAction bbact(vpr);
123
    bbact.apply(group);
124
    SbBox3f box = bbact.getBoundingBox();
125
    SbVec3f minPt, maxPt;
126
    box.getBounds(minPt, maxPt);
127
    group->unref();
128

129
    float boxWidth = maxPt[0] - minPt[0];
130
    _boxWidth = boxWidth;
131
    return boxWidth;
132
}
133

134
float SoFCColorBarBase::getBounds(const SbVec2s& size, float& fMinX, float&fMinY, float& fMaxX, float& fMaxY)
135
{
136
    // ratio of window width / height
137
    float fRatio = static_cast<float>(size[0]) / static_cast<float>(size[1]);
138

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.
144

145
    float baseYValue;
146
    if (fRatio > 3.0f) {
147
        baseYValue = 2.5f;
148
    }
149
    else {
150
        baseYValue = 3.0f;
151
    }
152
    float barWidth = 0.5f;
153

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
156

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
160

161
    if (fRatio < 1.0f) {
162
        // must be adjusted to assure that the size of the bar doesn't shrink
163
        fMinX /= fRatio;
164
        fMaxX /= fRatio;
165
        fMinY = -baseYValue / fRatio;
166
        fMaxY = baseYValue / fRatio;
167
    }
168

169
    // get the bounding box width of the color bar and labels
170
    float boxWidth = getBoundingWidth(size);
171
    return boxWidth;
172
}
173

174
// --------------------------------------------------------------------------
175

176
namespace Gui {
177
// Proxy class that receives an asynchronous custom event
178
class SoFCColorBarProxyObject : public QObject
179
{
180
public:
181
    explicit SoFCColorBarProxyObject(SoFCColorBar* b)
182
        : QObject(nullptr), bar(b) {}
183
    ~SoFCColorBarProxyObject() override = default;
184
    void customEvent(QEvent *) override
185
    {
186
        bar->customize(bar->getActiveBar());
187
        this->deleteLater();
188
    }
189

190
private:
191
    SoFCColorBar* bar;
192
};
193
}
194

195
SO_NODE_SOURCE(SoFCColorBar)
196

197
/*!
198
  Constructor.
199
*/
200
SoFCColorBar::SoFCColorBar()
201
{
202
    SO_NODE_CONSTRUCTOR(SoFCColorBar);
203

204
//  SoEventCallback * cb = new SoEventCallback;
205
//  cb->addEventCallback(SoMouseButtonEvent::getClassTypeId(), eventCallback, this);
206
//  insertChild(cb, 0);
207

208
    pColorMode = new SoSwitch;
209
    addChild(pColorMode);
210

211
    _colorBars.push_back( new SoFCColorGradient );
212
    _colorBars.push_back( new SoFCColorLegend );
213

214
    for (auto it : _colorBars)
215
        pColorMode->addChild(it);
216
    pColorMode->whichChild = 0;
217
}
218

219
/*!
220
  Destructor.
221
*/
222
SoFCColorBar::~SoFCColorBar() = default;
223

224
// doc from parent
225
void SoFCColorBar::initClass()
226
{
227
    SO_NODE_INIT_CLASS(SoFCColorBar,SoFCColorBarBase,"Separator");
228
}
229

230
void SoFCColorBar::finish()
231
{
232
    atexit_cleanup();
233
}
234

235
SoFCColorBarBase* SoFCColorBar::getActiveBar() const
236
{
237
    int child = pColorMode->whichChild.getValue();
238
    return _colorBars[child];
239
}
240

241
void SoFCColorBar::setFormat(const SoLabelTextFormat& fmt)
242
{
243
    for (auto it : _colorBars)
244
        it->setFormat(fmt);
245
}
246

247
void SoFCColorBar::setViewportSize( const SbVec2s& size )
248
{
249
    boost::ignore_unused(size);
250
}
251

252
void SoFCColorBar::setRange( float fMin, float fMax, int prec )
253
{
254
    for (auto it : _colorBars)
255
        it->setRange(fMin, fMax, prec);
256
}
257

258
void SoFCColorBar::setOutsideGrayed (bool bVal)
259
{
260
    for (auto it : _colorBars)
261
        it->setOutsideGrayed(bVal);
262
}
263

264
bool SoFCColorBar::isVisible (float fVal) const
265
{
266
    return this->getActiveBar()->isVisible(fVal);
267
}
268

269
float SoFCColorBar::getMinValue () const
270
{
271
    return this->getActiveBar()->getMinValue();
272
}
273

274
float SoFCColorBar::getMaxValue () const
275
{
276
    return this->getActiveBar()->getMaxValue();
277
}
278

279
void SoFCColorBar::triggerChange(SoFCColorBarBase*)
280
{
281
    Notify(0);
282
}
283

284
void SoFCColorBar::customize(SoFCColorBarBase* child)
285
{
286
    try {
287
        return child->customize(this);
288
    }
289
    catch (const Base::ValueError& e) {
290
        e.ReportException();
291
    }
292
}
293

294
App::Color SoFCColorBar::getColor( float fVal ) const
295
{
296
    return this->getActiveBar()->getColor( fVal );
297
}
298

299
void SoFCColorBar::eventCallback(void * /*userdata*/, SoEventCallback * node)
300
{
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) {
306
                // do nothing here
307
            }
308
        }
309
    }
310
}
311

312
void SoFCColorBar::handleEvent (SoHandleEventAction *action)
313
{
314
    const SoEvent * event = action->getEvent();
315

316
    // check for mouse button events
317
    if (event->getTypeId().isDerivedFrom(SoMouseButtonEvent::getClassTypeId())) {
318
        const auto e = static_cast<const SoMouseButtonEvent*>(event);
319

320
        // check if the cursor is near to the color bar
321
        if (!action->getPickedPoint())
322
            return; // not inside the rectangle
323

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()) {
330
                    _timer.start();
331
                }
332
                else if (_timer.restart() < QApplication::doubleClickInterval()) {
333
                    QApplication::postEvent(
334
                        new SoFCColorBarProxyObject(this),
335
                        new QEvent(QEvent::User));
336
                }
337
            }
338
        }
339
        // right mouse pressed
340
        else if ((e->getButton() == SoMouseButtonEvent::BUTTON2)) {
341
            if (e->getState() == SoButtonEvent::UP) {
342
                SoFCColorBarBase* current = getActiveBar();
343
                QMenu menu;
344
                int i=0;
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++));
350
                }
351

352
                menu.addSeparator();
353
                QAction* option = menu.addAction(QObject::tr("Options..."));
354
                QAction* select = menu.exec(QCursor::pos());
355

356
                if (select == option) {
357
                    QApplication::postEvent(
358
                        new SoFCColorBarProxyObject(this),
359
                        new QEvent(QEvent::User));
360
                }
361
                else if (select) {
362
                    int id = select->data().toInt();
363
                    pColorMode->whichChild = id;
364
                }
365
            }
366
        }
367
    }
368
}
369

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.