comparison Applications/Samples/SimpleViewerApplication.h @ 235:ce4405d98b92 am

Added SimpleViewerApplication (working in SDL)
author am@osimis.io
date Tue, 19 Jun 2018 16:02:41 +0200
parents
children b4642964c355
comparison
equal deleted inserted replaced
234:9afb50d1ac14 235:ce4405d98b92
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.
16 *
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"
29
30 #include <Core/Logging.h>
31
32 namespace OrthancStone
33 {
34 namespace Samples
35 {
36 class SimpleViewerApplication :
37 public SampleApplicationBase,
38 private ILayerSource::IObserver
39 {
40 private:
41 class Interactor : public IWorldSceneInteractor
42 {
43 private:
44 SimpleViewerApplication& application_;
45
46 public:
47 Interactor(SimpleViewerApplication& application) :
48 application_(application)
49 {
50 }
51
52 virtual IWorldSceneMouseTracker* CreateMouseTracker(WorldSceneWidget& widget,
53 const ViewportGeometry& view,
54 MouseButton button,
55 double x,
56 double y,
57 IStatusBar* statusBar)
58 {
59 return NULL;
60 }
61
62 virtual void MouseOver(CairoContext& context,
63 WorldSceneWidget& widget,
64 const ViewportGeometry& view,
65 double x,
66 double y,
67 IStatusBar* statusBar)
68 {
69 if (statusBar != NULL)
70 {
71 Vector p = dynamic_cast<LayerWidget&>(widget).GetSlice().MapSliceToWorldCoordinates(x, y);
72
73 char buf[64];
74 sprintf(buf, "X = %.02f Y = %.02f Z = %.02f (in cm)",
75 p[0] / 10.0, p[1] / 10.0, p[2] / 10.0);
76 statusBar->SetMessage(buf);
77 }
78 }
79
80 virtual void MouseWheel(WorldSceneWidget& widget,
81 MouseWheelDirection direction,
82 KeyboardModifiers modifiers,
83 IStatusBar* statusBar)
84 {
85 // int scale = (modifiers & KeyboardModifiers_Control ? 10 : 1);
86
87 // switch (direction)
88 // {
89 // case MouseWheelDirection_Up:
90 // application_.OffsetSlice(-scale);
91 // break;
92
93 // case MouseWheelDirection_Down:
94 // application_.OffsetSlice(scale);
95 // break;
96
97 // default:
98 // break;
99 // }
100 }
101
102 virtual void KeyPressed(WorldSceneWidget& widget,
103 char key,
104 KeyboardModifiers modifiers,
105 IStatusBar* statusBar)
106 {
107 switch (key)
108 {
109 case 's':
110 widget.SetDefaultView();
111 break;
112
113 default:
114 break;
115 }
116 }
117 };
118
119
120 // void OffsetSlice(int offset)
121 // {
122 // if (source_ != NULL)
123 // {
124 // int slice = static_cast<int>(slice_) + offset;
125
126 // if (slice < 0)
127 // {
128 // slice = 0;
129 // }
130
131 // if (slice >= static_cast<int>(source_->GetSliceCount()))
132 // {
133 // slice = source_->GetSliceCount() - 1;
134 // }
135
136 // if (slice != static_cast<int>(slice_))
137 // {
138 // SetSlice(slice);
139 // }
140 // }
141 // }
142
143
144 // void SetSlice(size_t index)
145 // {
146 // if (source_ != NULL &&
147 // index < source_->GetSliceCount())
148 // {
149 // slice_ = index;
150
151 //#if 1
152 // widget_->SetSlice(source_->GetSlice(slice_).GetGeometry());
153 //#else
154 // // TEST for scene extents - Rotate the axes
155 // double a = 15.0 / 180.0 * M_PI;
156
157 //#if 1
158 // Vector x; GeometryToolbox::AssignVector(x, cos(a), sin(a), 0);
159 // Vector y; GeometryToolbox::AssignVector(y, -sin(a), cos(a), 0);
160 //#else
161 // // Flip the normal
162 // Vector x; GeometryToolbox::AssignVector(x, cos(a), sin(a), 0);
163 // Vector y; GeometryToolbox::AssignVector(y, sin(a), -cos(a), 0);
164 //#endif
165
166 // SliceGeometry s(source_->GetSlice(slice_).GetGeometry().GetOrigin(), x, y);
167 // widget_->SetSlice(s);
168 //#endif
169 // }
170 // }
171
172
173 virtual void NotifyGeometryReady(const ILayerSource& source)
174 {
175 // Once the geometry of the series is downloaded from Orthanc,
176 // display its first slice, and adapt the viewport to fit this
177 // slice
178 if (source_ == &source)
179 {
180 //SetSlice(source_->GetSliceCount() / 2);
181 }
182
183 mainLayout_->SetDefaultView();
184 }
185
186 virtual void NotifyGeometryError(const ILayerSource& source)
187 {
188 }
189
190 virtual void NotifyContentChange(const ILayerSource& source)
191 {
192 }
193
194 virtual void NotifySliceChange(const ILayerSource& source,
195 const Slice& slice)
196 {
197 }
198
199 virtual void NotifyLayerReady(std::auto_ptr<ILayerRenderer>& layer,
200 const ILayerSource& source,
201 const CoordinateSystem3D& slice,
202 bool isError)
203 {
204 }
205
206 LayoutWidget* mainLayout_;
207 LayoutWidget* thumbnailsLayout_;
208 LayerWidget* mainViewport_;
209 std::vector<LayerWidget*> thumbnails_;
210 std::vector<std::string> instances_;
211 unsigned int currentInstanceIndex_;
212
213 OrthancFrameLayerSource* source_;
214 unsigned int slice_;
215
216 public:
217 SimpleViewerApplication() :
218 mainLayout_(NULL),
219 currentInstanceIndex_(0),
220 source_(NULL),
221 slice_(0)
222 {
223 }
224
225 virtual void DeclareStartupOptions(boost::program_options::options_description& options)
226 {
227 boost::program_options::options_description generic("Sample options");
228 generic.add_options()
229 // ("study", boost::program_options::value<std::string>(),
230 // "Orthanc ID of the study")
231 ("instance1", boost::program_options::value<std::string>(),
232 "Orthanc ID of the instances")
233 ("instance2", boost::program_options::value<std::string>(),
234 "Orthanc ID of the instances")
235 ;
236
237 options.add(generic);
238 }
239
240 virtual void Initialize(IStatusBar& statusBar,
241 const boost::program_options::variables_map& parameters)
242 {
243 using namespace OrthancStone;
244
245 statusBar.SetMessage("Use the key \"s\" to reinitialize the layout");
246
247 if (parameters.count("instance1") < 1)
248 {
249 LOG(ERROR) << "The instance ID is missing";
250 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
251 }
252 if (parameters.count("instance2") < 1)
253 {
254 LOG(ERROR) << "The instance ID is missing";
255 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
256 }
257 instances_.push_back(parameters["instance1"].as<std::string>());
258 instances_.push_back(parameters["instance2"].as<std::string>());
259
260 mainLayout_ = new LayoutWidget();
261 mainLayout_->SetPadding(10);
262 mainLayout_->SetBackgroundCleared(true);
263 mainLayout_->SetBackgroundColor(0, 0, 0);
264 mainLayout_->SetHorizontal();
265
266 thumbnailsLayout_ = new LayoutWidget();
267 thumbnailsLayout_->SetPadding(10);
268 thumbnailsLayout_->SetBackgroundCleared(true);
269 thumbnailsLayout_->SetBackgroundColor(50, 50, 50);
270 thumbnailsLayout_->SetVertical();
271
272 mainViewport_ = new LayerWidget();
273 thumbnails_.push_back(new LayerWidget());
274 thumbnails_.push_back(new LayerWidget());
275
276 // hierarchy
277 mainLayout_->AddWidget(thumbnailsLayout_);
278 mainLayout_->AddWidget(mainViewport_);
279 thumbnailsLayout_->AddWidget(thumbnails_[0]);
280 thumbnailsLayout_->AddWidget(thumbnails_[1]);
281
282 // sources
283 source_ = new OrthancFrameLayerSource(context_->GetWebService());
284 source_->LoadFrame(instances_[currentInstanceIndex_], 0);
285
286 mainViewport_->AddLayer(source_);
287
288 OrthancFrameLayerSource* thumb0 = new OrthancFrameLayerSource(context_->GetWebService());
289 thumb0->LoadFrame(instances_[0], 0);
290 OrthancFrameLayerSource* thumb1 = new OrthancFrameLayerSource(context_->GetWebService());
291 thumb1->LoadFrame(instances_[1], 0);
292
293 thumbnails_[0]->AddLayer(thumb0);
294 thumbnails_[1]->AddLayer(thumb1);
295
296 mainLayout_->SetTransmitMouseOver(true);
297 mainViewport_->SetInteractor(context_->AddInteractor(new Interactor(*this)));
298 context_->SetCentralWidget(mainLayout_);
299 }
300 };
301 }
302 }