summaryrefslogtreecommitdiff
path: root/src/pmview/modlist.cpp
diff options
context:
space:
mode:
authorIgor Pashev <pashev.igor@gmail.com>2014-10-26 12:33:50 +0400
committerIgor Pashev <pashev.igor@gmail.com>2014-10-26 12:33:50 +0400
commit47e6e7c84f008a53061e661f31ae96629bc694ef (patch)
tree648a07f3b5b9d67ce19b0fd72e8caa1175c98f1a /src/pmview/modlist.cpp
downloadpcp-debian.tar.gz
Debian 3.9.10debian/3.9.10debian
Diffstat (limited to 'src/pmview/modlist.cpp')
-rw-r--r--src/pmview/modlist.cpp471
1 files changed, 471 insertions, 0 deletions
diff --git a/src/pmview/modlist.cpp b/src/pmview/modlist.cpp
new file mode 100644
index 0000000..05a9c3d
--- /dev/null
+++ b/src/pmview/modlist.cpp
@@ -0,0 +1,471 @@
+/*
+ * Copyright (c) 1997 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2009 Aconex. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program 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 General Public License
+ * for more details.
+ */
+#include <QtCore/QSettings>
+#include <Inventor/SoPath.h>
+#include <Inventor/SoPickedPoint.h>
+#include <Inventor/events/SoLocation2Event.h>
+#include <Inventor/nodes/SoEventCallback.h>
+#include <Inventor/nodes/SoSelection.h>
+#include <Inventor/nodes/SoIndexedFaceSet.h>
+#include <Inventor/actions/SoBoxHighlightRenderAction.h>
+#include <Inventor/Qt/viewers/SoQtExaminerViewer.h>
+#include "modlist.h"
+
+#include <iostream>
+using namespace std;
+
+const QString ModList::theBogusId = "TOP";
+const char ModList::theModListId = 'i';
+
+ModList *theModList;
+SoNodeList elementalNodeList;
+
+ModList::~ModList()
+{
+}
+
+ModList::ModList(SoQtViewer *viewer,
+ SelCallBack selCB,
+ SelInvCallBack selInvCB,
+ SelInvCallBack deselInvCB)
+: _viewer(viewer),
+ _selCB(selCB),
+ _selInvCB(selInvCB),
+ _deselInvCB(deselInvCB),
+ _root(0),
+ _selection(0),
+ _motion(0),
+ _rendAct(0),
+ _list(),
+ _selList(),
+ _current(1),
+ _numSel(0),
+ _oneSel(0),
+ _allFlag(false),
+ _allId(0)
+{
+ QSettings modSettings;
+ modSettings.beginGroup(pmProgname);
+ QString sval = modSettings.value("saturation", QString("")).toString();
+ modSettings.endGroup();
+
+ bool ok;
+ double err = sval.toFloat(&ok);
+ if (!ok || err > 0.0)
+ theNormError = err;
+
+ _root = new SoSeparator;
+ _root->ref();
+}
+
+void
+ModList::setRoot(SoSeparator *root)
+{
+ _selection = new SoSelection;
+ _root->addChild(_selection);
+
+ _selection->policy = SoSelection::SHIFT;
+ _selection->addSelectionCallback(&ModList::selCB, this);
+ _selection->addDeselectionCallback(&ModList::deselectCB, this);
+
+ _motion = new SoEventCallback;
+ _motion->addEventCallback(SoLocation2Event::getClassTypeId(),
+ &ModList::motionCB, this);
+ _selection->addChild(_motion);
+
+ root->setName((SbName)(const char *)theBogusId.toAscii());
+ _selection->addChild(root);
+
+ SoBoxHighlightRenderAction *rendAct = new SoBoxHighlightRenderAction;
+ _viewer->setGLRenderAction(rendAct);
+ _viewer->redrawOnSelectionChange(_selection);
+}
+
+const char *
+ModList::add(Modulate *obj)
+{
+ static char buf[32];
+ int len = _list.size();
+ int zero = 0;
+
+ _list.append(obj);
+ _selList.append(zero);
+
+ if (_current >= len)
+ _current = _list.size();
+
+ sprintf(buf, "%c%d", theModListId, _list.size() - 1);
+ return buf;
+}
+
+void
+ModList::refresh(bool fetchFlag)
+{
+ for (int i = 0; i < _list.size(); i++)
+ _list[i]->refresh(fetchFlag);
+ for (int n=elementalNodeList.getLength()-1; n >= 0; n--) {
+ elementalNodeList[n]->doAction(_viewer->getGLRenderAction());
+ }
+}
+
+void
+ModList::dumpSelections(QTextStream &os) const
+{
+ int i;
+ int count = 0;
+
+ os << _numSel << " selections (SoSelections.numSelections = "
+ << _selection->getNumSelected() << "), allFlag = "
+ << (_allFlag == true ? "true" : "false") << endl;
+ for (i = 0; i < _selList.size(); i++)
+ if (_selList[i] > 0) {
+ count += _selList[i];
+ os << '[' << i << "]: ";
+ if (_numSel == 1 && _oneSel == i)
+ os << '*';
+ os << *(_list[i]) << endl;
+ }
+
+ assert(count == _numSel);
+}
+
+QTextStream &
+operator<<(QTextStream &os, const ModList &rhs)
+{
+ int i;
+
+ for (i = 0; i < rhs._list.size(); i++)
+ os << '[' << i << "]: " << rhs[i] << endl;
+ return os;
+}
+
+int
+ModList::findToken(const SoPath *path)
+{
+ SoNode *node = NULL;
+ char *str = NULL;
+ int id = -1;
+ int i;
+ char c;
+
+ for (i = path->getLength() - 1; i >= 0; --i) {
+ node = path->getNode(i);
+ str = (char *)(node->getName().getString());
+ if (strlen(str) && str[0] == theModListId) {
+ sscanf(str, "%c%d", &c, &id);
+ break;
+ }
+ }
+
+ return id;
+}
+
+void
+ModList::selCB(void *ptrToThis, SoPath *path)
+{
+ ModList *me = (ModList *)ptrToThis;
+ Modulate *obj;
+ int oldCount;
+ int id;
+
+ if (!me->_allFlag)
+ id = ModList::findToken(path);
+ else
+ id = me->_allId;
+
+ if (id < 0) {
+
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL1)
+ cerr << "ModList::selCB: Nothing selected" << endl;
+#endif
+
+ return;
+ /*NOTREACHED*/
+ }
+ else if (!me->_allFlag) {
+
+ obj = me->_list[id];
+ oldCount = me->_selList[id];
+
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL1)
+ cerr << "ModList::selCB: Before Selected [" << id << "] = "
+ << *obj << endl
+ << "oldCount = " << oldCount << ", _numSel = "
+ << me->_numSel << ", _allFlag = false" << endl;
+#endif
+
+ me->_selList[id] = obj->select(path);
+
+ me->_numSel += me->_selList[id] - oldCount;
+ if (me->_numSel == 1)
+ me->_oneSel = id;
+ }
+
+ if (!me->_allFlag)
+ (*(me->_selCB))(me, true);
+
+ if (me->_selInvCB != NULL)
+ (*(me->_selInvCB))(me, path);
+
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL1) {
+ cerr << "ModList::selCB: After Selected [" << id << "] " << endl
+ << "oldCount = " << oldCount << ", _numSel = "
+ << me->_numSel << ", _allFlag = "
+ << (me->_allFlag == true ? "true" : "false") << ", _allId = "
+ << me->_allId << endl;
+ cerr << "ModList::selCB: selection state:" << endl;
+ me->dumpSelections(cerr);
+ }
+#endif
+}
+
+void
+ModList::deselectCB(void *ptrToThis, SoPath *path)
+{
+ ModList *me = (ModList *)ptrToThis;
+ Modulate *obj;
+ int oldCount;
+ int i;
+ int id;
+
+ id = findToken(path);
+
+ if (id < 0) {
+
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL1)
+ cerr << "ModList::deselectCB: Nothing deselected" << endl;
+#endif
+
+ return;
+ /*NOTREACHED*/
+ }
+
+ obj = me->_list[id];
+
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL1)
+ cerr << "ModList::deselectCB: Deselected [" << id << "] = "
+ << *obj << endl;
+#endif
+
+ oldCount = me->_selList[id];
+ me->_selList[id] = obj->remove(path);
+ me->_numSel -= oldCount - me->_selList[id];
+ if (me->_numSel == 1) {
+ for (i = 0; i < me->_selList.size(); i++)
+ if (me->_selList[i] == 1)
+ me->_oneSel = i;
+ }
+
+ if (me->_numSel == 0)
+ me->_current = me->_list.size();
+
+ if (me->_numSel < 2)
+ (*(me->_selCB))(me, true);
+
+ if (me->_deselInvCB != NULL)
+ (*(me->_deselInvCB))(me, path);
+
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL1) {
+ cerr << "ModList::deselectCB: selection state:" << endl;
+ me->dumpSelections(cerr);
+ }
+#endif
+}
+
+void
+ModList::motionCB(void *ptrToThis, SoEventCallback *theEvent)
+{
+ ModList *me = (ModList *)ptrToThis;
+ const SoPickedPoint *pick = NULL;
+ SoPath *path = NULL;
+ int id = -1;
+
+ // If one item is selected, return as we aren't interested
+ if (me->_numSel == 1)
+ return;
+
+ pick = theEvent->getPickedPoint();
+ if (pick != NULL) {
+ path = pick->getPath();
+ if (path != NULL)
+ id = ModList::findToken(path);
+ }
+
+ // Nothing selected that we are interested in
+ if (id < 0) {
+ // Deselect anything selected
+ if (me->_current < me->size()) {
+ (*me)[me->_current].removeInfo(path);
+ me->_current = me->size();
+
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL1)
+ cerr << "ModList::motionCB: remove object " << id << endl;
+#endif
+ }
+ }
+ else if (me->_current != id) {
+ if (me->_current < me->size())
+ (*me)[me->_current].removeInfo(path);
+ me->_current = id;
+ (*me)[me->_current].selectInfo(path);
+
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL1)
+ cerr << "ModList::motionCB: new object " << id << endl;
+#endif
+ }
+ else {
+ (*me)[me->_current].selectInfo(path);
+
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL1)
+ cerr << "ModList::motionCB: same object " << id << endl;
+#endif
+ }
+
+ // Note: the call to _selCB below used to only be done if the guard
+ // if (old != me->_current)
+ // is true. But this does not work for stacked bars because
+ // the object is the same even though the mouse has moved over
+ // a different block in the same stack. Hence the metric info
+ // text window was not being updated for the mouse motion CB.
+ // Since the render method for the metricLabel only updates the
+ // text widget if the text has actually changed, it seems to me
+ // that it is safe to call the selCB unconditionally and there
+ // wont be any "flicker" problems.
+ // -- markgw 15 oct 1997
+ //
+ (*(me->_selCB))(me, false);
+}
+
+void
+ModList::infoText(QString &str) const
+{
+ if (_current >= _list.size() && _numSel != 1)
+ str = "";
+ else if (_numSel == 1)
+ _list[_oneSel]->infoText(str, true);
+ else
+ _list[_current]->infoText(str, false);
+}
+
+void
+ModList::launch(Launch &launch, bool all) const
+{
+ int i;
+
+ if (all == false && _numSel > 0) {
+
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL1)
+ cerr << "ModList::launch: launching for " << _numSel
+ << " objects" << endl;
+#endif
+
+ for (i = 0; i < _selList.size(); i++) {
+ if (_selList[i] > 0)
+ _list[i]->launch(launch, false);
+ }
+ }
+ else {
+
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL1)
+ cerr << "ModList::launch: launching for all objects" << endl;
+#endif
+
+ for (i = 0; i < _list.size(); i++)
+ _list[i]->launch(launch, true);
+ }
+}
+
+void
+ModList::record(Record &rec) const
+{
+ int i;
+
+ for (i = 0; i < _list.size(); i++)
+ _list[i]->record(rec);
+}
+
+bool
+ModList::selections() const
+{
+ if (_numSel)
+ return true;
+
+ return false;
+}
+
+const SoPath *
+ModList::oneSelPath() const
+{
+ return (_numSel == 1 ? _selection->getPath(0) : NULL);
+}
+
+void
+ModList::deselectPath(SoPath *path)
+{
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL1)
+ cerr << "ModList::deselectPath:" << endl;
+#endif
+
+ _selection->deselect(path);
+ deselectCB(this, path);
+}
+
+void
+ModList::selectAllId(SoNode *node, int count)
+{
+ SoPath *path = new SoPath(node);
+
+ _allId = findToken(path);
+
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL1)
+ cerr << "ModList::selectAllId: Select All on " << _allId << endl;
+#endif
+
+ if (_allId > 0) {
+ _numSel += count - _selList[_allId];
+ _selList[_allId] = count;
+ if (_numSel == 1)
+ _oneSel = _allId;
+ }
+
+ path->unref();
+}
+
+void
+ModList::selectSingle(SoNode *node)
+{
+ _selection->select(node);
+}
+
+void
+ModList::selectAllOff()
+{
+ _allFlag = false;
+ _allId = _list.size();
+ (*_selCB)(this, true);
+}