Mercurial > hg > orthanc-stone
annotate Applications/Samples/SimpleViewerApplication.h @ 251:192e6e349e69 am-2
first usage of new message system (in SDL only)
author | am@osimis.io |
---|---|
date | Mon, 02 Jul 2018 18:13:46 +0200 |
parents | 54c7284b0eff |
children | 8ff70c04c6df |
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; |
235 | 182 } |
183 } | |
184 | |
242 | 185 std::unique_ptr<Interactor> interactor_; |
235 | 186 LayoutWidget* mainLayout_; |
187 LayoutWidget* thumbnailsLayout_; | |
188 LayerWidget* mainViewport_; | |
189 std::vector<LayerWidget*> thumbnails_; | |
190 std::vector<std::string> instances_; | |
191 unsigned int currentInstanceIndex_; | |
237
b4642964c355
SimpleViewer demo running both with SDL and Wasm
am@osimis.io
parents:
235
diff
changeset
|
192 OrthancStone::WidgetViewport* wasmViewport1_; |
b4642964c355
SimpleViewer demo running both with SDL and Wasm
am@osimis.io
parents:
235
diff
changeset
|
193 OrthancStone::WidgetViewport* wasmViewport2_; |
235 | 194 |
195 OrthancFrameLayerSource* source_; | |
196 unsigned int slice_; | |
251
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
249
diff
changeset
|
197 |
235 | 198 public: |
251
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
249
diff
changeset
|
199 SimpleViewerApplication(MessageBroker& broker) : |
235 | 200 mainLayout_(NULL), |
201 currentInstanceIndex_(0), | |
202 source_(NULL), | |
237
b4642964c355
SimpleViewer demo running both with SDL and Wasm
am@osimis.io
parents:
235
diff
changeset
|
203 slice_(0), |
242 | 204 wasmViewport1_(NULL), |
251
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
249
diff
changeset
|
205 wasmViewport2_(NULL), |
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
249
diff
changeset
|
206 IObserver(broker) |
235 | 207 { |
208 } | |
251
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
249
diff
changeset
|
209 |
237
b4642964c355
SimpleViewer demo running both with SDL and Wasm
am@osimis.io
parents:
235
diff
changeset
|
210 virtual void Finalize() {} |
b4642964c355
SimpleViewer demo running both with SDL and Wasm
am@osimis.io
parents:
235
diff
changeset
|
211 virtual IWidget* GetCentralWidget() {return mainLayout_;} |
b4642964c355
SimpleViewer demo running both with SDL and Wasm
am@osimis.io
parents:
235
diff
changeset
|
212 |
235 | 213 virtual void DeclareStartupOptions(boost::program_options::options_description& options) |
214 { | |
215 boost::program_options::options_description generic("Sample options"); | |
216 generic.add_options() | |
249 | 217 // ("study", boost::program_options::value<std::string>(), |
218 // "Orthanc ID of the study") | |
219 ("instance1", boost::program_options::value<std::string>(), | |
220 "Orthanc ID of the instances") | |
235 | 221 ("instance2", boost::program_options::value<std::string>(), |
222 "Orthanc ID of the instances") | |
249 | 223 ; |
235 | 224 |
249 | 225 options.add(generic); |
235 | 226 } |
227 | |
242 | 228 virtual void Initialize(BasicApplicationContext* context, |
229 IStatusBar& statusBar, | |
235 | 230 const boost::program_options::variables_map& parameters) |
231 { | |
232 using namespace OrthancStone; | |
233 | |
242 | 234 context_ = context; |
235 | 235 statusBar.SetMessage("Use the key \"s\" to reinitialize the layout"); |
236 | |
237 if (parameters.count("instance1") < 1) | |
238 { | |
239 LOG(ERROR) << "The instance ID is missing"; | |
240 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
241 } | |
242 if (parameters.count("instance2") < 1) | |
243 { | |
244 LOG(ERROR) << "The instance ID is missing"; | |
245 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
246 } | |
247 instances_.push_back(parameters["instance1"].as<std::string>()); | |
248 instances_.push_back(parameters["instance2"].as<std::string>()); | |
249 | |
250 mainLayout_ = new LayoutWidget(); | |
251 mainLayout_->SetPadding(10); | |
252 mainLayout_->SetBackgroundCleared(true); | |
253 mainLayout_->SetBackgroundColor(0, 0, 0); | |
254 mainLayout_->SetHorizontal(); | |
255 | |
256 thumbnailsLayout_ = new LayoutWidget(); | |
257 thumbnailsLayout_->SetPadding(10); | |
258 thumbnailsLayout_->SetBackgroundCleared(true); | |
259 thumbnailsLayout_->SetBackgroundColor(50, 50, 50); | |
260 thumbnailsLayout_->SetVertical(); | |
261 | |
251
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
249
diff
changeset
|
262 mainViewport_ = new LayerWidget(broker_); |
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
249
diff
changeset
|
263 thumbnails_.push_back(new LayerWidget(broker_)); |
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
249
diff
changeset
|
264 thumbnails_.push_back(new LayerWidget(broker_)); |
235 | 265 |
266 // hierarchy | |
267 mainLayout_->AddWidget(thumbnailsLayout_); | |
268 mainLayout_->AddWidget(mainViewport_); | |
269 thumbnailsLayout_->AddWidget(thumbnails_[0]); | |
270 thumbnailsLayout_->AddWidget(thumbnails_[1]); | |
271 | |
272 // sources | |
251
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
249
diff
changeset
|
273 source_ = new OrthancFrameLayerSource(broker_, context_->GetWebService()); |
235 | 274 source_->LoadFrame(instances_[currentInstanceIndex_], 0); |
245 | 275 source_->Register(*this); |
235 | 276 |
277 mainViewport_->AddLayer(source_); | |
278 | |
251
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
249
diff
changeset
|
279 OrthancFrameLayerSource* thumb0 = new OrthancFrameLayerSource(broker_, context_->GetWebService()); |
235 | 280 thumb0->LoadFrame(instances_[0], 0); |
251
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
249
diff
changeset
|
281 OrthancFrameLayerSource* thumb1 = new OrthancFrameLayerSource(broker_, context_->GetWebService()); |
235 | 282 thumb1->LoadFrame(instances_[1], 0); |
283 | |
284 thumbnails_[0]->AddLayer(thumb0); | |
285 thumbnails_[1]->AddLayer(thumb1); | |
286 | |
287 mainLayout_->SetTransmitMouseOver(true); | |
242 | 288 interactor_.reset(new Interactor(*this)); |
289 mainViewport_->SetInteractor(*interactor_); | |
290 } | |
237
b4642964c355
SimpleViewer demo running both with SDL and Wasm
am@osimis.io
parents:
235
diff
changeset
|
291 |
242 | 292 #if ORTHANC_ENABLE_SDL==0 |
293 virtual void InitializeWasm() { | |
294 | |
295 AttachWidgetToWasmViewport("canvas", thumbnailsLayout_); | |
296 AttachWidgetToWasmViewport("canvas2", mainViewport_); | |
297 } | |
237
b4642964c355
SimpleViewer demo running both with SDL and Wasm
am@osimis.io
parents:
235
diff
changeset
|
298 #endif |
249 | 299 |
300 void NextImage(WorldSceneWidget& widget) { | |
301 assert(context_); | |
302 | |
303 currentInstanceIndex_ = (currentInstanceIndex_ + 1) % instances_.size(); | |
304 | |
305 std::auto_ptr<OrthancFrameLayerSource> layer | |
251
192e6e349e69
first usage of new message system (in SDL only)
am@osimis.io
parents:
249
diff
changeset
|
306 (new OrthancFrameLayerSource(broker_, context_->GetWebService())); |
249 | 307 layer->LoadFrame(instances_[currentInstanceIndex_], 0); |
308 | |
309 mainViewport_->ReplaceLayer(0, layer.release()); | |
310 // source_->LoadFrame("45b7e6bc-168e8ed1-063dc08d-cffd6431-133a276a", 0); | |
311 } | |
235 | 312 }; |
249 | 313 |
314 | |
235 | 315 } |
316 } |