PeriDyno 1.0.0
Loading...
Searching...
No Matches
WMainWindow.cpp
Go to the documentation of this file.
1#include "WMainWindow.h"
2#include "WSceneDataModel.h"
3#include "WSimulationCanvas.h"
4#include "WSampleWidget.h"
6#include "WPythonWidget.h"
8
9#include <Wt/WVBoxLayout.h>
10#include <Wt/WHBoxLayout.h>
11#include <Wt/WBorderLayout.h>
12#include <Wt/WPushButton.h>
13#include <Wt/WPanel.h>
14#include <Wt/WApplication.h>
15#include <Wt/WMenu.h>
16#include <Wt/WPopupMenu.h>
17#include <Wt/WNavigationBar.h>
18#include <Wt/WTreeView.h>
19#include <Wt/WTableView.h>
20#include <Wt/WStackedWidget.h>
21#include <Wt/WText.h>
22#include <Wt/WTable.h>
23#include <Wt/WColorPicker.h>
24#include <Wt/WLogger.h>
25
26#include <fstream>
27
28#include <SceneGraph.h>
29#include <SceneGraphFactory.h>
30
31#include <filesystem>
32
34 : WContainerWidget(), bRunFlag(false)
35{
36 // disable page margin...
37 setMargin(0);
38
39 auto layout = this->setLayout(std::make_unique<Wt::WBorderLayout>());
40 layout->setContentsMargins(0, 0, 0, 0);
41
42 //create a navigation bar
43 auto naviBar = layout->addWidget(std::make_unique<Wt::WNavigationBar>(), Wt::LayoutPosition::North);
44 naviBar->addStyleClass("main-nav");
45 naviBar->setTitle("PeriDyno", "https://github.com/peridyno/peridyno");
46 naviBar->setMargin(0);
47
48 // central canvas
49 mSceneCanvas = layout->addWidget(std::make_unique<WSimulationCanvas>(), Wt::LayoutPosition::Center);
50
51 // scene info panel
52 auto widget0 = layout->addWidget(std::make_unique<Wt::WContainerWidget>(), Wt::LayoutPosition::West);
53 widget0->setWidth(400);
54 initLeftPanel(widget0);
55
56 // menu
57 auto widget1 = layout->addWidget(std::make_unique<Wt::WStackedWidget>(), Wt::LayoutPosition::East);
58 auto menu = naviBar->addMenu(std::make_unique<Wt::WMenu>(widget1), Wt::AlignmentFlag::Right);
59 initMenu(menu);
60}
61
63{
64 Wt::log("warning") << "stop WMainWindows";
65}
66
67void WMainWindow::initMenu(Wt::WMenu* menu)
68{
69 menu->setMargin(5, Wt::Side::Right);
70
71 auto sampleWidget = new WSampleWidget();
72 auto pythonWidget = new WPythonWidget;
73
74 //auto paramsWidget = new WRenderParamsWidget(&mSceneCanvas->getRenderParams());
75 //menu->addItem("Settings", std::unique_ptr<WRenderParamsWidget>(paramsWidget));
76
77 /*paramsWidget->valueChanged().connect([=]() {
78 mSceneCanvas->update();
79 });*/
80
81 menu->addItem("Samples", std::unique_ptr<WSampleWidget>(sampleWidget));
82
83 auto pythonItem = menu->addItem("Python", std::unique_ptr<WPythonWidget>(pythonWidget));
84
85 pythonWidget->updateSceneGraph().connect([=](std::shared_ptr<dyno::SceneGraph> scene) {
86 if (scene) setScene(scene);
87 });
88
89 sampleWidget->clicked().connect([=](Sample* sample)
90 {
91 if (sample != NULL)
92 {
93 pythonItem->select();
94
95 std::string path = sample->source();
96 std::ifstream ifs(path);
97 if (ifs.is_open())
98 {
99 std::string content((std::istreambuf_iterator<char>(ifs)),
100 (std::istreambuf_iterator<char>()));
101 pythonWidget->setText(content);
102 pythonWidget->execute(content);
103 //menu->contentsStack()->setCurrentWidget(0);
104 }
105 else
106 {
107 std::string content = "Error: Not Find The Python File";
108 pythonWidget->setText(content);
109 }
110 }
111 });
112
113 auto hide = menu->addItem(">>", 0);
114 hide->select();
115 hide->clicked().connect([=]() {
116 menu->contentsStack()->setCurrentWidget(0);
117 });
118}
119
120void WMainWindow::initLeftPanel(Wt::WContainerWidget* parent)
121{
122 // create data model
123 mNodeDataModel = std::make_shared<WNodeDataModel>();
124 mModuleDataModel = std::make_shared<WModuleDataModel>();
125 mParameterDataNode = std::make_shared<WParameterDataNode>();
126
127 mParameterDataNode->changeValue().connect(this, &WMainWindow::updateCanvas);
128
129 // vertical layout
130
131 auto layout = parent->setLayout(std::make_unique<Wt::WVBoxLayout>());
132 layout->setContentsMargins(0, 0, 0, 0);
133 parent->setMargin(0);
134
135 // node tree
136 auto panel0 = layout->addWidget(std::make_unique<Wt::WPanel>(), 2);
137 panel0->setTitle("Node Tree");
138 panel0->setCollapsible(true);
139 panel0->setMargin(0);
140 //panel0->setStyleClass("scrollable-content");
141
142 auto treeView = panel0->setCentralWidget(std::make_unique<Wt::WTreeView>());
143 treeView->setMargin(0);
144 treeView->setSortingEnabled(false);
145 treeView->setSelectionMode(Wt::SelectionMode::Single);
146 treeView->setEditTriggers(Wt::EditTrigger::None);
147 treeView->setColumnResizeEnabled(true);
148 treeView->setModel(mNodeDataModel);
149 treeView->setColumnWidth(0, 100);
150 treeView->setColumnWidth(1, 280);
151
152 // module list
153 auto panel1 = layout->addWidget(std::make_unique<Wt::WPanel>(), 2);
154 panel1->setTitle("Module List");
155 panel1->setCollapsible(true);
156 panel1->setStyleClass("scrollable-content");
157 auto tableView = panel1->setCentralWidget(std::make_unique<Wt::WTableView>());
158 treeView->setSortingEnabled(false);
159 tableView->setSortingEnabled(false);
160 tableView->setSelectionMode(Wt::SelectionMode::Single);
161 tableView->setEditTriggers(Wt::EditTrigger::None);
162 tableView->setModel(mModuleDataModel);
163
164 // Parameter list
165 auto panel2 = layout->addWidget(std::make_unique<Wt::WPanel>(), 6);
166 panel2->setTitle("Control Variable");
167 panel2->setCollapsible(true);
168 panel2->setStyleClass("scrollable-content");
169
170 // action for selection change
171 treeView->clicked().connect([=](const Wt::WModelIndex& idx, const Wt::WMouseEvent& evt)
172 {
173 auto node = mNodeDataModel->getNode(idx);
174 mModuleDataModel->setNode(node);
175 mParameterDataNode->setNode(node);
176 mParameterDataNode->createParameterPanel(panel2);
177 });
178
179 tableView->clicked().connect([=](const Wt::WModelIndex& idx, const Wt::WMouseEvent& evt)
180 {
181 auto module = mModuleDataModel->getModule(idx);
182 mParameterDataNode->setModule(module);
183 mParameterDataNode->createParameterPanelModule(panel2);
184 });
185
186 tableView->doubleClicked().connect([=](const Wt::WModelIndex& idx, const Wt::WMouseEvent& evt)
187 {
188 auto mod = mModuleDataModel->getModule(idx);
189 if (mod->getModuleType() == "VisualModule")
190 {
191 Wt::log("info") << mod->getName();
192 }
193 });
194
195 // simulation control
196 auto panel3 = layout->addWidget(std::make_unique<Wt::WPanel>(), 1);
197 panel3->setTitle("Simulation Control");
198 panel3->setCollapsible(false);
199 //panel3->setHeight(50);
200 auto widget2 = panel3->setCentralWidget(std::make_unique<Wt::WContainerWidget>());
201 auto layout2 = widget2->setLayout(std::make_unique<Wt::WHBoxLayout>());
202 //widget2->setHeight(5);
203 layout2->setContentsMargins(0, 0, 0, 0);
204 startButton = layout2->addWidget(std::make_unique<Wt::WPushButton>("Start"));
205 auto stopButton = layout2->addWidget(std::make_unique<Wt::WPushButton>("Stop"));
206 auto stepButton = layout2->addWidget(std::make_unique<Wt::WPushButton>("Step"));
207 auto resetButton = layout2->addWidget(std::make_unique<Wt::WPushButton>("Reset"));
208
209 startButton->setId("startButton");
210 stopButton->setId("stopButton");
211 stepButton->setId("stepButton");
212 resetButton->setId("resetButton");
213
214 // actions
215 startButton->clicked().connect(this, &WMainWindow::start);
216 stopButton->clicked().connect(this, &WMainWindow::stop);
217 stepButton->clicked().connect(this, &WMainWindow::step);
218 resetButton->clicked().connect(this, &WMainWindow::reset);
219
220 //startButton->clicked().connect([=] {
221 // startButton->doJavaScript("var startButton = document.getElementById('startButton');"
222 // "startButton.blur();");
223 // });
224
225 stopButton->clicked().connect([=] {
226 stopButton->doJavaScript("var stopButton = document.getElementById('stopButton');"
227 "stopButton.blur();");
228 });
229 stepButton->clicked().connect([=] {
230 stepButton->doJavaScript("var stepButton = document.getElementById('stepButton');"
231 "stepButton.blur();");
232 });
233 resetButton->clicked().connect([=] {
234 resetButton->doJavaScript("var resetButton = document.getElementById('resetButton');"
235 "resetButton.blur();");
236 });
237}
238
240{
241 startButton->doJavaScript("var startButton = document.getElementById('startButton');"
242 "startButton.blur();");
243 if (mScene)
244 {
245 mSceneCanvas->setFocus();
246 if (mReset)
247 {
248 mScene->reset();
249 mReset = false;
250 }
251 this->bRunFlag = true;
252 Wt::WApplication* app = Wt::WApplication::instance();
253 while (this->bRunFlag)
254 {
255 mScene->takeOneFrame();
256 mSceneCanvas->update();
257 Wt::log("info") << "Step!!!";
258 Wt::log("info") << mScene->getFrameNumber();
259 app->processEvents();
260 }
261 }
262}
263
265{
266 mSceneCanvas->setFocus(true);
267 this->bRunFlag = false;
268}
269
271{
272 if (mScene)
273 {
274 stop();
275 mScene->takeOneFrame();
276 mSceneCanvas->update();
277 }
278
279 Wt::log("info") << "Step!!!";
280 Wt::log("info") << mScene->getFrameNumber();
281}
282
284{
285 if (mScene)
286 {
287 this->bRunFlag = false;
288
289 mScene->setFrameNumber(0);
290 mScene->reset();
291 mSceneCanvas->update();
292
293 mSceneCanvas->update();
294
295 mReset = true;
296 }
297
298 Wt::log("info") << mScene->getFrameNumber();
299}
300
302{
303 if (mScene)
304 {
305 mSceneCanvas->update();
306 }
307 Wt::log("info") << "updateCanvas!!!";
308 Wt::log("info") << mScene->getFrameNumber();
309}
310
311void WMainWindow::setScene(std::shared_ptr<dyno::SceneGraph> scene)
312{
313 // try to stop the simulation
314 stop();
315
316 // setup scene graph
317 mScene = scene;
318 mSceneCanvas->setScene(mScene);
319 mNodeDataModel->setScene(mScene);
320 mModuleDataModel->setNode(NULL);
321}
virtual std::string source() const =0
WSimulationCanvas * mSceneCanvas
Definition WMainWindow.h:40
std::shared_ptr< WNodeDataModel > mNodeDataModel
Definition WMainWindow.h:43
void updateCanvas()
Wt::WPushButton * startButton
Definition WMainWindow.h:53
std::shared_ptr< dyno::SceneGraph > mScene
Definition WMainWindow.h:50
void initMenu(Wt::WMenu *)
void initLeftPanel(Wt::WContainerWidget *)
std::shared_ptr< WParameterDataNode > mParameterDataNode
Definition WMainWindow.h:45
void setScene(std::shared_ptr< dyno::SceneGraph > scene)
std::shared_ptr< WModuleDataModel > mModuleDataModel
Definition WMainWindow.h:44
Wt::Signal< std::shared_ptr< dyno::SceneGraph > > & updateSceneGraph()