1 /* 2 mind_navigator.h MindForger thinking notebook 3 4 Copyright (C) 2016-2020 Martin Dvorak <martin.dvorak@mindforger.com> 5 6 This program is free software; you can redistribute it and/or 7 modify it under the terms of the GNU General Public License 8 as published by the Free Software Foundation; either version 2 9 of the License, or (at your option) any later version. 10 11 This program 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 General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program. If not, see <http://www.gnu.org/licenses/>. 18 19 **************************************************************************** 20 ** 21 ** Copyright (C) 2016 The Qt Company Ltd. 22 ** Contact: https://www.qt.io/licensing/ 23 ** 24 ** This file is part of the examples of the Qt Toolkit. 25 ** 26 ** $QT_BEGIN_LICENSE:BSD$ 27 ** Commercial License Usage 28 ** Licensees holding valid commercial Qt licenses may use this file in 29 ** accordance with the commercial license agreement provided with the 30 ** Software or, alternatively, in accordance with the terms contained in 31 ** a written agreement between you and The Qt Company. For licensing terms 32 ** and conditions see https://www.qt.io/terms-conditions. For further 33 ** information use the contact form at https://www.qt.io/contact-us. 34 ** 35 ** BSD License Usage 36 ** Alternatively, you may use this file under the terms of the BSD license 37 ** as follows: 38 ** 39 ** "Redistribution and use in source and binary forms, with or without 40 ** modification, are permitted provided that the following conditions are 41 ** met: 42 ** * Redistributions of source code must retain the above copyright 43 ** notice, this list of conditions and the following disclaimer. 44 ** * Redistributions in binary form must reproduce the above copyright 45 ** notice, this list of conditions and the following disclaimer in 46 ** the documentation and/or other materials provided with the 47 ** distribution. 48 ** * Neither the name of The Qt Company Ltd nor the names of its 49 ** contributors may be used to endorse or promote products derived 50 ** from this software without specific prior written permission. 51 ** 52 ** 53 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 54 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 55 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 56 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 57 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 58 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 59 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 60 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 61 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 62 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 63 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." 64 ** 65 ** $QT_END_LICENSE$ 66 ** 67 ****************************************************************************/ 68 69 #ifndef M8R_NAVIGATOR_VIEW_H 70 #define M8R_NAVIGATOR_VIEW_H 71 72 #include <mutex> 73 74 #include <QGraphicsView> 75 76 #include "../../../../lib/src/mind/knowledge_graph.h" 77 #include "../../../../lib/src/model/outline.h" 78 #include "../look_n_feel.h" 79 80 namespace m8r { 81 82 class NavigatorNode; 83 84 // IMPROVE enjoy improving this class to achieve maximum rendering performance, there 85 // is a lot of space for improvement 86 87 /** 88 * @brief Knowledge graph navigator view. 89 * 90 * Knowledge graph is based on force-directed graph based (FDB) - magnets and rubber bands. 91 * 92 * Synchronization & UI threads: selected node sets subgraph, timerEvent() 93 * then refreshes view which avoids the need for extra synchronization. 94 * 95 * @see http://doc.qt.io/qt-5/qtwidgets-graphicsview-elasticnodes-example.html 96 */ 97 class NavigatorView : public QGraphicsView 98 { 99 Q_OBJECT 100 101 static constexpr qreal EDGE_LENGTH_DEFAULT = 300.0; 102 static constexpr qreal EDGE_LENGTH_DELTA = 30.0; 103 static constexpr qreal EDGE_LENGTH_MAX = 5000.0; 104 static constexpr qreal EDGE_LENGTH_MIN = EDGE_LENGTH_DELTA*2.0; 105 106 private: 107 QGraphicsScene* navigatorScene; 108 109 // IMPROVE is mutex still needed? 110 std::mutex refreshMutex; 111 112 int timerId, w, h; 113 114 // stupid and ugly: multi-threading & weak Qt API 115 std::vector<QGraphicsItem*> garbageItems; 116 117 // subgraph to be rendered 118 KnowledgeSubGraph* subgraph; 119 120 qreal initialEdgeLenght; 121 122 bool isDashboardlet; 123 124 public: 125 NavigatorView(QWidget* parent, bool isDashboardlet=false); 126 ~NavigatorView(); 127 getInitialEdgeLenght()128 qreal getInitialEdgeLenght() const { return initialEdgeLenght; } 129 void checkAndFixInitialEdgeLength(qreal& l); 130 131 void itemMoved(); 132 133 void iWasSelected(NavigatorNode* selectedNode); refreshOnNextTimerTick(KnowledgeSubGraph * subgraph)134 void refreshOnNextTimerTick(KnowledgeSubGraph* subgraph) { 135 std::lock_guard<std::mutex> criticalSection{refreshMutex}; 136 137 updateNavigatorView(); 138 this->subgraph = subgraph; 139 itemMoved(); // kick timer if not running 140 } refreshOnNextTimerTick()141 void refreshOnNextTimerTick() { 142 refreshOnNextTimerTick(subgraph); 143 } 144 145 void cleanupBeforeHide(); 146 147 protected: 148 void scaleView(qreal scaleFactor); 149 150 void resizeEvent(QResizeEvent *event) override; 151 void keyPressEvent(QKeyEvent *event) override; 152 void timerEvent(QTimerEvent *event) override; 153 #ifndef QT_NO_WHEELEVENT 154 void wheelEvent(QWheelEvent *event) override; 155 #endif 156 void mousePressEvent(QMouseEvent* mouseEvent) override; 157 158 private: 159 void updateNavigatorView(); 160 void clearGarbageItems(); 161 162 signals: 163 void nodeSelectedSignal(NavigatorNode* selectedNode); 164 void clickToSwitchFacet(); 165 166 public slots: 167 void shuffle(); 168 void zoomIn(); 169 void zoomOut(); 170 }; 171 172 } 173 #endif // M8R_NAVIGATOR_VIEW_H 174