Mercurial > hg > orthanc-stone
annotate Applications/Samples/SimpleViewerApplication.h @ 254:abc1c6231947 am-2
cleanup
author | am@osimis.io |
---|---|
date | Tue, 03 Jul 2018 11:49:02 +0200 |
parents | 8ff70c04c6df |
children | 9afafb192180 |
rev | line source |
---|---|
235 | 1 /** |
2 * Stone of Orthanc | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
5 * Copyright (C) 2017-2018 Osimis S.A., Belgium | |
6 * | |
7 * This program is free software: you can redistribute it and/or | |
8 * modify it under the terms of the GNU Affero General Public License | |
9 * as published by the Free Software Foundation, either version 3 of | |
10 * the License, or (at your option) any later version. | |
11 * | |
12 * This program is distributed in the hope that it will be useful, but | |
13 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Affero General Public License for more details. | |
249 | 16 * |
235 | 17 * You should have received a copy of the GNU Affero General Public License |
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
19 **/ | |
20 | |
21 | |
22 #pragma once | |
23 | |
24 #include "SampleApplicationBase.h" | |
25 | |
26 #include "../../Framework/Layers/OrthancFrameLayerSource.h" | |
27 #include "../../Framework/Widgets/LayerWidget.h" | |
28 #include "../../Framework/Widgets/LayoutWidget.h" | |
251
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
249
diff
changeset
|
29 #include "../../Framework/Messages/IObserver.h" |
235 | 30 |
31 #include <Core/Logging.h> | |
32 | |
33 namespace OrthancStone | |
34 { | |
35 namespace Samples | |
36 { | |
37 class SimpleViewerApplication : | |
249 | 38 public SampleApplicationBase, |
251
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
249
diff
changeset
|
39 public IObserver |
235 | 40 { |
41 private: | |
42 class Interactor : public IWorldSceneInteractor | |
43 { | |
44 private: | |
45 SimpleViewerApplication& application_; | |
46 | |
47 public: | |
48 Interactor(SimpleViewerApplication& application) : | |
49 application_(application) | |
50 { | |
51 } | |
52 | |
53 virtual IWorldSceneMouseTracker* CreateMouseTracker(WorldSceneWidget& widget, | |
54 const ViewportGeometry& view, | |
55 MouseButton button, | |
56 double x, | |
57 double y, | |
58 IStatusBar* statusBar) | |
59 { | |
60 return NULL; | |
61 } | |
62 | |
63 virtual void MouseOver(CairoContext& context, | |
64 WorldSceneWidget& widget, | |
65 const ViewportGeometry& view, | |
66 double x, | |
67 double y, | |
68 IStatusBar* statusBar) | |
69 { | |
70 if (statusBar != NULL) | |
71 { | |
72 Vector p = dynamic_cast<LayerWidget&>(widget).GetSlice().MapSliceToWorldCoordinates(x, y); | |
73 | |
74 char buf[64]; | |
249 | 75 sprintf(buf, "X = %.02f Y = %.02f Z = %.02f (in cm)", |
235 | 76 p[0] / 10.0, p[1] / 10.0, p[2] / 10.0); |
77 statusBar->SetMessage(buf); | |
78 } | |
79 } | |
80 | |
81 virtual void MouseWheel(WorldSceneWidget& widget, | |
82 MouseWheelDirection direction, | |
83 KeyboardModifiers modifiers, | |
84 IStatusBar* statusBar) | |
85 { | |
249 | 86 // int scale = (modifiers & KeyboardModifiers_Control ? 10 : 1); |
235 | 87 |
249 | 88 // switch (direction) |
89 // { | |
90 // case MouseWheelDirection_Up: | |
91 // application_.OffsetSlice(-scale); | |
92 // break; | |
235 | 93 |
249 | 94 // case MouseWheelDirection_Down: |
95 // application_.OffsetSlice(scale); | |
96 // break; | |
235 | 97 |
249 | 98 // default: |
99 // break; | |
100 // } | |
235 | 101 } |
102 | |
103 virtual void KeyPressed(WorldSceneWidget& widget, | |
104 char key, | |
105 KeyboardModifiers modifiers, | |
106 IStatusBar* statusBar) | |
107 { | |
108 switch (key) | |
109 { | |
249 | 110 case 's': |
111 widget.SetDefaultView(); | |
112 break; | |
113 case 'n': | |
114 application_.NextImage(widget); | |
115 break; | |
235 | 116 |
249 | 117 default: |
118 break; | |
235 | 119 } |
120 } | |
121 }; | |
122 | |
123 | |
249 | 124 // void OffsetSlice(int offset) |
125 // { | |
126 // if (source_ != NULL) | |
127 // { | |
128 // int slice = static_cast<int>(slice_) + offset; | |
235 | 129 |
249 | 130 // if (slice < 0) |
131 // { | |
132 // slice = 0; | |
133 // } | |
235 | 134 |
249 | 135 // if (slice >= static_cast<int>(source_->GetSliceCount())) |
136 // { | |
137 // slice = source_->GetSliceCount() - 1; | |
138 // } | |
235 | 139 |
249 | 140 // if (slice != static_cast<int>(slice_)) |
141 // { | |
142 // SetSlice(slice); | |
143 // } | |
144 // } | |
145 // } | |
235 | 146 |
147 | |
249 | 148 // void SetSlice(size_t index) |
149 // { | |
150 // if (source_ != NULL && | |
151 // index < source_->GetSliceCount()) | |
152 // { | |
153 // slice_ = index; | |
154 | |
155 //#if 1 | |
156 // widget_->SetSlice(source_->GetSlice(slice_).GetGeometry()); | |
157 //#else | |
158 // // TEST for scene extents - Rotate the axes | |
159 // double a = 15.0 / 180.0 * M_PI; | |
235 | 160 |
249 | 161 //#if 1 |
162 // Vector x; GeometryToolbox::AssignVector(x, cos(a), sin(a), 0); | |
163 // Vector y; GeometryToolbox::AssignVector(y, -sin(a), cos(a), 0); | |
164 //#else | |
165 // // Flip the normal | |
166 // Vector x; GeometryToolbox::AssignVector(x, cos(a), sin(a), 0); | |
167 // Vector y; GeometryToolbox::AssignVector(y, sin(a), -cos(a), 0); | |
168 //#endif | |
169 | |
170 // SliceGeometry s(source_->GetSlice(slice_).GetGeometry().GetOrigin(), x, y); | |
171 // widget_->SetSlice(s); | |
172 //#endif | |
173 // } | |
174 // } | |
175 | |
251
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
249
diff
changeset
|
176 |
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
249
diff
changeset
|
177 virtual void HandleMessage(IObservable& from, const IMessage& message) { |
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
249
diff
changeset
|
178 switch (message.GetType()) { |
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
249
diff
changeset
|
179 case MessageType_GeometryReady: |
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
249
diff
changeset
|
180 mainLayout_->SetDefaultView(); |
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
249
diff
changeset
|
181 break; |
253 | 182 default: |
183 VLOG("unhandled message type" << message.GetType()); | |
235 | 184 } |
185 } | |
186 | |
242 | 187 std::unique_ptr<Interactor> interactor_; |
235 | 188 LayoutWidget* mainLayout_; |
189 LayoutWidget* thumbnailsLayout_; | |
190 LayerWidget* mainViewport_; | |
191 std::vector<LayerWidget*> thumbnails_; | |
192 std::vector<std::string> instances_; | |
193 unsigned int currentInstanceIndex_; | |
237
b4642964c355
SimpleViewer demo running both with SDL and Wasm
am@osimis.io
parents:
235
diff
changeset
|
194 OrthancStone::WidgetViewport* wasmViewport1_; |
b4642964c355
SimpleViewer demo running both with SDL and Wasm
am@osimis.io
parents:
235
diff
changeset
|
195 OrthancStone::WidgetViewport* wasmViewport2_; |
235 | 196 |
254 | 197 IStatusBar* statusBar_; |
235 | 198 OrthancFrameLayerSource* source_; |
199 unsigned int slice_; | |
251
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
249
diff
changeset
|
200 |
235 | 201 public: |
251
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
249
diff
changeset
|
202 SimpleViewerApplication(MessageBroker& broker) : |
235 | 203 mainLayout_(NULL), |
204 currentInstanceIndex_(0), | |
205 source_(NULL), | |
237
b4642964c355
SimpleViewer demo running both with SDL and Wasm
am@osimis.io
parents:
235
diff
changeset
|
206 slice_(0), |
242 | 207 wasmViewport1_(NULL), |
251
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
249
diff
changeset
|
208 wasmViewport2_(NULL), |
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
249
diff
changeset
|
209 IObserver(broker) |
235 | 210 { |
211 } | |
251
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
249
diff
changeset
|
212 |
237
b4642964c355
SimpleViewer demo running both with SDL and Wasm
am@osimis.io
parents:
235
diff
changeset
|
213 virtual void Finalize() {} |
b4642964c355
SimpleViewer demo running both with SDL and Wasm
am@osimis.io
parents:
235
diff
changeset
|
214 virtual IWidget* GetCentralWidget() {return mainLayout_;} |
b4642964c355
SimpleViewer demo running both with SDL and Wasm
am@osimis.io
parents:
235
diff
changeset
|
215 |
235 | 216 virtual void DeclareStartupOptions(boost::program_options::options_description& options) |
217 { | |
218 boost::program_options::options_description generic("Sample options"); | |
219 generic.add_options() | |
249 | 220 // ("study", boost::program_options::value<std::string>(), |
221 // "Orthanc ID of the study") | |
222 ("instance1", boost::program_options::value<std::string>(), | |
223 "Orthanc ID of the instances") | |
235 | 224 ("instance2", boost::program_options::value<std::string>(), |
225 "Orthanc ID of the instances") | |
249 | 226 ; |
235 | 227 |
249 | 228 options.add(generic); |
235 | 229 } |
230 | |
242 | 231 virtual void Initialize(BasicApplicationContext* context, |
232 IStatusBar& statusBar, | |
235 | 233 const boost::program_options::variables_map& parameters) |
234 { | |
235 using namespace OrthancStone; | |
236 | |
242 | 237 context_ = context; |
254 | 238 statusBar_ = &statusBar; |
235 | 239 statusBar.SetMessage("Use the key \"s\" to reinitialize the layout"); |
254 | 240 statusBar.SetMessage("Use the key \"n\" to go to next image in the main viewport"); |
235 | 241 |
242 if (parameters.count("instance1") < 1) | |
243 { | |
244 LOG(ERROR) << "The instance ID is missing"; | |
245 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
246 } | |
247 if (parameters.count("instance2") < 1) | |
248 { | |
249 LOG(ERROR) << "The instance ID is missing"; | |
250 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
251 } | |
252 instances_.push_back(parameters["instance1"].as<std::string>()); | |
253 instances_.push_back(parameters["instance2"].as<std::string>()); | |
254 | |
255 mainLayout_ = new LayoutWidget(); | |
256 mainLayout_->SetPadding(10); | |
257 mainLayout_->SetBackgroundCleared(true); | |
258 mainLayout_->SetBackgroundColor(0, 0, 0); | |
259 mainLayout_->SetHorizontal(); | |
260 | |
261 thumbnailsLayout_ = new LayoutWidget(); | |
262 thumbnailsLayout_->SetPadding(10); | |
263 thumbnailsLayout_->SetBackgroundCleared(true); | |
264 thumbnailsLayout_->SetBackgroundColor(50, 50, 50); | |
265 thumbnailsLayout_->SetVertical(); | |
266 | |
251
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
249
diff
changeset
|
267 mainViewport_ = new LayerWidget(broker_); |
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
249
diff
changeset
|
268 thumbnails_.push_back(new LayerWidget(broker_)); |
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
249
diff
changeset
|
269 thumbnails_.push_back(new LayerWidget(broker_)); |
235 | 270 |
271 // hierarchy | |
272 mainLayout_->AddWidget(thumbnailsLayout_); | |
273 mainLayout_->AddWidget(mainViewport_); | |
274 thumbnailsLayout_->AddWidget(thumbnails_[0]); | |
275 thumbnailsLayout_->AddWidget(thumbnails_[1]); | |
276 | |
277 // sources | |
251
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
249
diff
changeset
|
278 source_ = new OrthancFrameLayerSource(broker_, context_->GetWebService()); |
254 | 279 source_->RegisterObserver(*this); |
235 | 280 source_->LoadFrame(instances_[currentInstanceIndex_], 0); |
281 | |
282 mainViewport_->AddLayer(source_); | |
283 | |
251
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
249
diff
changeset
|
284 OrthancFrameLayerSource* thumb0 = new OrthancFrameLayerSource(broker_, context_->GetWebService()); |
254 | 285 thumb0->RegisterObserver(*this); |
235 | 286 thumb0->LoadFrame(instances_[0], 0); |
251
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
249
diff
changeset
|
287 OrthancFrameLayerSource* thumb1 = new OrthancFrameLayerSource(broker_, context_->GetWebService()); |
254 | 288 thumb1->RegisterObserver(*this); |
235 | 289 thumb1->LoadFrame(instances_[1], 0); |
290 | |
291 thumbnails_[0]->AddLayer(thumb0); | |
292 thumbnails_[1]->AddLayer(thumb1); | |
293 | |
294 mainLayout_->SetTransmitMouseOver(true); | |
242 | 295 interactor_.reset(new Interactor(*this)); |
296 mainViewport_->SetInteractor(*interactor_); | |
297 } | |
237
b4642964c355
SimpleViewer demo running both with SDL and Wasm
am@osimis.io
parents:
235
diff
changeset
|
298 |
242 | 299 #if ORTHANC_ENABLE_SDL==0 |
300 virtual void InitializeWasm() { | |
301 | |
302 AttachWidgetToWasmViewport("canvas", thumbnailsLayout_); | |
303 AttachWidgetToWasmViewport("canvas2", mainViewport_); | |
304 } | |
237
b4642964c355
SimpleViewer demo running both with SDL and Wasm
am@osimis.io
parents:
235
diff
changeset
|
305 #endif |
249 | 306 |
307 void NextImage(WorldSceneWidget& widget) { | |
308 assert(context_); | |
254 | 309 statusBar_->SetMessage("displaying next image"); |
249 | 310 |
311 currentInstanceIndex_ = (currentInstanceIndex_ + 1) % instances_.size(); | |
312 | |
313 std::auto_ptr<OrthancFrameLayerSource> layer | |
251
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
249
diff
changeset
|
314 (new OrthancFrameLayerSource(broker_, context_->GetWebService())); |
254 | 315 layer->RegisterObserver(*this); |
249 | 316 layer->LoadFrame(instances_[currentInstanceIndex_], 0); |
317 | |
318 mainViewport_->ReplaceLayer(0, layer.release()); | |
319 } | |
235 | 320 }; |
249 | 321 |
322 | |
235 | 323 } |
324 } |