Mercurial > hg > orthanc-stone
annotate Applications/Samples/SingleFrameEditorApplication.h @ 343:712acc87fa2e am-2
text layer
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 22 Oct 2018 14:20:39 +0200 |
parents | 4297d6c5eef9 |
children | fdec8e6893cb |
rev | line source |
---|---|
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1 /** |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2 * Stone of Orthanc |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
4 * Department, University Hospital of Liege, Belgium |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
5 * Copyright (C) 2017-2018 Osimis S.A., Belgium |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
6 * |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
7 * This program is free software: you can redistribute it and/or |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
8 * modify it under the terms of the GNU Affero General Public License |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
9 * as published by the Free Software Foundation, either version 3 of |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
10 * the License, or (at your option) any later version. |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
11 * |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
12 * This program is distributed in the hope that it will be useful, but |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
13 * WITHOUT ANY WARRANTY; without even the implied warranty of |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
15 * Affero General Public License for more details. |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
16 * |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
17 * You should have received a copy of the GNU Affero General Public License |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
19 **/ |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
20 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
21 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
22 #pragma once |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
23 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
24 #include "SampleApplicationBase.h" |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
25 |
339 | 26 #include "../../Framework/Toolbox/GeometryToolbox.h" |
27 #include "../../Framework/Toolbox/ImageGeometry.h" | |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
28 #include "../../Framework/Layers/OrthancFrameLayerSource.h" |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
29 |
338 | 30 #include <Core/DicomFormat/DicomArray.h> |
343 | 31 #include <Core/Images/FontRegistry.h> |
339 | 32 #include <Core/Images/ImageProcessing.h> |
338 | 33 #include <Core/Images/PamReader.h> |
343 | 34 #include <Core/Images/PngWriter.h> //TODO |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
35 #include <Core/Logging.h> |
338 | 36 #include <Plugins/Samples/Common/FullOrthancDataset.h> |
339 | 37 #include <Plugins/Samples/Common/DicomDatasetReader.h> |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
38 |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
39 |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
40 #include <boost/math/constants/constants.hpp> |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
41 |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
42 namespace OrthancStone |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
43 { |
338 | 44 class BitmapStack : |
337 | 45 public IObserver, |
336
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
46 public IObservable |
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
47 { |
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
48 public: |
338 | 49 typedef OriginMessage<MessageType_Widget_GeometryChanged, BitmapStack> GeometryChangedMessage; |
50 typedef OriginMessage<MessageType_Widget_ContentChanged, BitmapStack> ContentChangedMessage; | |
336
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
51 |
337 | 52 private: |
338 | 53 class Bitmap : public boost::noncopyable |
54 { | |
55 private: | |
343 | 56 bool visible_; |
57 bool hasSize_; | |
58 unsigned int width_; | |
59 unsigned int height_; | |
60 bool hasCrop_; | |
61 unsigned int cropX_; | |
62 unsigned int cropY_; | |
63 unsigned int cropWidth_; | |
64 unsigned int cropHeight_; | |
65 Matrix transform_; | |
66 double pixelSpacingX_; | |
67 double pixelSpacingY_; | |
68 double panX_; | |
69 double panY_; | |
338 | 70 |
342 | 71 |
72 void UpdateTransform() | |
73 { | |
74 transform_ = LinearAlgebra::IdentityMatrix(3); | |
75 | |
76 transform_(0, 0) = pixelSpacingX_; | |
77 transform_(1, 1) = pixelSpacingY_; | |
78 transform_(0, 2) = panX_; | |
79 transform_(1, 2) = panY_; | |
80 | |
81 | |
82 #if 0 | |
83 double a = 10.0 / 180.0 * boost::math::constants::pi<double>(); | |
84 Matrix m; | |
85 const double v[] = { cos(a), -sin(a), 0, | |
86 sin(a), cos(a), 0, | |
87 0, 0, 1 }; | |
88 LinearAlgebra::FillMatrix(m, 3, 3, v); | |
89 transform_ = LinearAlgebra::Product(m, transform_); | |
90 #endif | |
91 } | |
92 | |
93 | |
339 | 94 void AddToExtent(Extent2D& extent, |
95 double x, | |
96 double y) const | |
97 { | |
98 Vector p; | |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
99 LinearAlgebra::AssignVector(p, x, y, 1); |
339 | 100 |
101 Vector q = LinearAlgebra::Product(transform_, p); | |
102 | |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
103 if (!LinearAlgebra::IsNear(q[2], 1.0)) |
339 | 104 { |
105 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | |
106 } | |
107 else | |
108 { | |
109 extent.AddPoint(q[0], q[1]); | |
110 } | |
111 } | |
112 | |
113 | |
338 | 114 public: |
341 | 115 Bitmap() : |
339 | 116 visible_(true), |
343 | 117 hasSize_(false), |
339 | 118 width_(0), |
119 height_(0), | |
120 hasCrop_(false), | |
342 | 121 pixelSpacingX_(1), |
122 pixelSpacingY_(1), | |
123 panX_(0), | |
124 panY_(0) | |
339 | 125 { |
342 | 126 UpdateTransform(); |
339 | 127 } |
128 | |
343 | 129 virtual ~Bitmap() |
130 { | |
131 } | |
132 | |
339 | 133 void ResetCrop() |
134 { | |
135 hasCrop_ = false; | |
136 } | |
137 | |
138 void Crop(unsigned int x, | |
139 unsigned int y, | |
140 unsigned int width, | |
141 unsigned int height) | |
142 { | |
143 hasCrop_ = true; | |
144 cropX_ = x; | |
145 cropY_ = y; | |
146 cropWidth_ = width; | |
147 cropHeight_ = height; | |
148 } | |
149 | |
150 void GetCrop(unsigned int& x, | |
151 unsigned int& y, | |
152 unsigned int& width, | |
153 unsigned int& height) const | |
338 | 154 { |
339 | 155 if (hasCrop_) |
156 { | |
157 x = cropX_; | |
158 y = cropY_; | |
159 width = cropWidth_; | |
160 height = cropHeight_; | |
161 } | |
162 else | |
163 { | |
164 x = 0; | |
165 y = 0; | |
166 width = width_; | |
167 height = height_; | |
168 } | |
169 } | |
170 | |
171 bool IsVisible() const | |
172 { | |
173 return visible_; | |
174 } | |
175 | |
176 void SetVisible(bool visible) | |
177 { | |
178 visible_ = visible; | |
179 } | |
180 | |
181 | |
343 | 182 void SetSize(unsigned int width, |
183 unsigned int height) | |
338 | 184 { |
343 | 185 if (hasSize_ && |
186 (width != width_ || | |
187 height != height_)) | |
339 | 188 { |
343 | 189 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageSize); |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
190 } |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
191 |
343 | 192 hasSize_ = true; |
193 width_ = width; | |
194 height_ = height; | |
338 | 195 } |
196 | |
343 | 197 |
198 void CheckSize(unsigned int width, | |
199 unsigned int height) | |
338 | 200 { |
343 | 201 if (hasSize_ && |
202 (width != width_ || | |
203 height != height_)) | |
338 | 204 { |
343 | 205 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageSize); |
339 | 206 } |
207 } | |
343 | 208 |
339 | 209 |
210 Extent2D GetExtent() const | |
211 { | |
212 Extent2D extent; | |
213 | |
214 unsigned int x, y, width, height; | |
215 GetCrop(x, y, width, height); | |
216 | |
217 double dx = static_cast<double>(x) - 0.5; | |
218 double dy = static_cast<double>(y) - 0.5; | |
219 double dwidth = static_cast<double>(width); | |
220 double dheight = static_cast<double>(height); | |
342 | 221 |
339 | 222 AddToExtent(extent, dx, dy); |
223 AddToExtent(extent, dx + dwidth, dy); | |
224 AddToExtent(extent, dx, dy + dheight); | |
225 AddToExtent(extent, dx + dwidth, dy + dheight); | |
226 | |
227 return extent; | |
228 } | |
229 | |
230 | |
343 | 231 virtual void Render(Orthanc::ImageAccessor& buffer, |
232 const ViewportGeometry& view) const = 0; | |
341 | 233 |
234 | |
235 bool Contains(double x, | |
236 double y) const | |
237 { | |
238 Matrix inv; | |
239 LinearAlgebra::InvertMatrix(inv, transform_); | |
240 | |
241 Vector p; | |
242 LinearAlgebra::AssignVector(p, x, y, 1); | |
243 | |
244 Vector q = LinearAlgebra::Product(inv, p); | |
245 | |
246 if (!LinearAlgebra::IsNear(q[2], 1.0)) | |
247 { | |
248 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | |
249 } | |
250 else | |
251 { | |
342 | 252 printf("at: (%.02f, %.02f)\n", q[0], q[1]); |
341 | 253 return (q[0] >= 0 && |
254 q[1] >= 0 && | |
255 q[0] <= static_cast<double>(width_) && | |
256 q[1] <= static_cast<double>(height_)); | |
257 } | |
258 } | |
342 | 259 |
260 | |
261 void SetPan(double x, | |
262 double y) | |
263 { | |
264 panX_ = x; | |
265 panY_ = y; | |
266 UpdateTransform(); | |
267 } | |
268 | |
269 | |
343 | 270 void SetPixelSpacing(double x, |
271 double y) | |
272 { | |
273 pixelSpacingX_ = x; | |
274 pixelSpacingY_ = y; | |
275 UpdateTransform(); | |
276 } | |
277 | |
278 | |
342 | 279 double GetPanX() const |
280 { | |
281 return panX_; | |
282 } | |
283 | |
284 | |
285 double GetPanY() const | |
286 { | |
287 return panY_; | |
288 } | |
343 | 289 |
290 | |
291 virtual bool GetDefaultWindowing(float& center, | |
292 float& width) const | |
293 { | |
294 return false; | |
295 } | |
296 | |
297 | |
298 const Matrix& GetTransform() const | |
299 { | |
300 return transform_; | |
301 } | |
338 | 302 }; |
303 | |
304 | |
343 | 305 |
306 class DicomBitmap : public Bitmap | |
307 { | |
308 private: | |
309 std::auto_ptr<Orthanc::ImageAccessor> source_; // Content of PixelData | |
310 std::auto_ptr<DicomFrameConverter> converter_; | |
311 std::auto_ptr<Orthanc::ImageAccessor> converted_; // Float32 or RGB24 | |
312 | |
313 | |
314 void ApplyConverter() | |
315 { | |
316 if (source_.get() != NULL && | |
317 converter_.get() != NULL) | |
318 { | |
319 converted_.reset(converter_->ConvertFrame(*source_)); | |
320 } | |
321 } | |
322 | |
323 public: | |
324 static OrthancPlugins::DicomTag ConvertTag(const Orthanc::DicomTag& tag) | |
325 { | |
326 return OrthancPlugins::DicomTag(tag.GetGroup(), tag.GetElement()); | |
327 } | |
328 | |
329 void SetDicomTags(const OrthancPlugins::FullOrthancDataset& dataset) | |
330 { | |
331 converter_.reset(new DicomFrameConverter); | |
332 converter_->ReadParameters(dataset); | |
333 ApplyConverter(); | |
334 | |
335 std::string tmp; | |
336 Vector pixelSpacing; | |
337 | |
338 if (dataset.GetStringValue(tmp, ConvertTag(Orthanc::DICOM_TAG_PIXEL_SPACING)) && | |
339 LinearAlgebra::ParseVector(pixelSpacing, tmp) && | |
340 pixelSpacing.size() == 2) | |
341 { | |
342 SetPixelSpacing(pixelSpacing[0], pixelSpacing[1]); | |
343 } | |
344 | |
345 static unsigned int c = 0; | |
346 if (c == 0) | |
347 { | |
348 SetPan(400, 0); | |
349 c ++; | |
350 } | |
351 | |
352 OrthancPlugins::DicomDatasetReader reader(dataset); | |
353 | |
354 unsigned int width, height; | |
355 if (!reader.GetUnsignedIntegerValue(width, ConvertTag(Orthanc::DICOM_TAG_COLUMNS)) || | |
356 !reader.GetUnsignedIntegerValue(height, ConvertTag(Orthanc::DICOM_TAG_ROWS))) | |
357 { | |
358 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); | |
359 } | |
360 else | |
361 { | |
362 SetSize(width, height); | |
363 } | |
364 } | |
365 | |
366 | |
367 void SetSourceImage(Orthanc::ImageAccessor* image) // Takes ownership | |
368 { | |
369 std::auto_ptr<Orthanc::ImageAccessor> raii(image); | |
370 | |
371 if (image == NULL) | |
372 { | |
373 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); | |
374 } | |
375 | |
376 SetSize(image->GetWidth(), image->GetHeight()); | |
377 | |
378 source_ = raii; | |
379 ApplyConverter(); | |
380 } | |
381 | |
382 | |
383 virtual void Render(Orthanc::ImageAccessor& buffer, | |
384 const ViewportGeometry& view) const | |
385 { | |
386 if (converted_.get() != NULL) | |
387 { | |
388 Matrix m = LinearAlgebra::Product(view.GetMatrix(), GetTransform()); | |
389 //ApplyProjectiveTransform(buffer, *converted_, m, ImageInterpolation_Bilinear, false); | |
390 ApplyProjectiveTransform(buffer, *converted_, m, ImageInterpolation_Nearest, false); | |
391 } | |
392 } | |
393 | |
394 | |
395 virtual bool GetDefaultWindowing(float& center, | |
396 float& width) const | |
397 { | |
398 if (converter_.get() != NULL && | |
399 converter_->HasDefaultWindow()) | |
400 { | |
401 center = static_cast<float>(converter_->GetDefaultWindowCenter()); | |
402 width = static_cast<float>(converter_->GetDefaultWindowWidth()); | |
403 return true; | |
404 } | |
405 else | |
406 { | |
407 return false; | |
408 } | |
409 } | |
410 }; | |
411 | |
412 | |
413 | |
414 | |
415 class AlphaBitmap : public Bitmap | |
416 { | |
417 private: | |
418 const BitmapStack& stack_; | |
419 std::auto_ptr<Orthanc::ImageAccessor> alpha_; // Grayscale8 | |
420 bool useWindowing_; | |
421 float foreground_; | |
422 | |
423 public: | |
424 AlphaBitmap(const BitmapStack& stack) : | |
425 stack_(stack), | |
426 useWindowing_(true), | |
427 foreground_(0) | |
428 { | |
429 } | |
430 | |
431 | |
432 void SetForegroundValue(float foreground) | |
433 { | |
434 useWindowing_ = false; | |
435 foreground_ = foreground; | |
436 } | |
437 | |
438 | |
439 void SetAlpha(Orthanc::ImageAccessor* image) | |
440 { | |
441 std::auto_ptr<Orthanc::ImageAccessor> raii(image); | |
442 | |
443 if (image == NULL) | |
444 { | |
445 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); | |
446 } | |
447 | |
448 if (image->GetFormat() != Orthanc::PixelFormat_Grayscale8) | |
449 { | |
450 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat); | |
451 } | |
452 | |
453 SetSize(image->GetWidth(), image->GetHeight()); | |
454 alpha_ = raii; | |
455 } | |
456 | |
457 | |
458 void LoadText(const Orthanc::Font& font, | |
459 const std::string& utf8) | |
460 { | |
461 SetAlpha(font.RenderAlpha(utf8)); | |
462 } | |
463 | |
464 | |
465 virtual void Render(Orthanc::ImageAccessor& buffer, | |
466 const ViewportGeometry& view) const | |
467 { | |
468 if (buffer.GetFormat() != Orthanc::PixelFormat_Float32) | |
469 { | |
470 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat); | |
471 } | |
472 | |
473 Matrix m = LinearAlgebra::Product(view.GetMatrix(), GetTransform()); | |
474 | |
475 Orthanc::Image tmp(Orthanc::PixelFormat_Grayscale8, buffer.GetWidth(), buffer.GetHeight(), false); | |
476 ApplyProjectiveTransform(tmp, *alpha_, m, ImageInterpolation_Nearest, true /* clear */); | |
477 | |
478 // Blit | |
479 const unsigned int width = buffer.GetWidth(); | |
480 const unsigned int height = buffer.GetHeight(); | |
481 | |
482 float value = foreground_; | |
483 | |
484 if (useWindowing_) | |
485 { | |
486 float center, width; | |
487 if (stack_.GetWindowing(center, width)) | |
488 { | |
489 value = center + width / 2.0f; | |
490 } | |
491 } | |
492 | |
493 for (unsigned int y = 0; y < height; y++) | |
494 { | |
495 float *q = reinterpret_cast<float*>(buffer.GetRow(y)); | |
496 const uint8_t *p = reinterpret_cast<uint8_t*>(tmp.GetRow(y)); | |
497 | |
498 for (unsigned int x = 0; x < width; x++, p++, q++) | |
499 { | |
500 float a = static_cast<float>(*p) / 255.0f; | |
501 | |
502 *q = (a * value + (1.0f - a) * (*q)); | |
503 } | |
504 } | |
505 } | |
506 }; | |
507 | |
508 | |
509 | |
341 | 510 typedef std::map<size_t, Bitmap*> Bitmaps; |
338 | 511 |
341 | 512 OrthancApiClient& orthanc_; |
513 size_t countBitmaps_; | |
514 bool hasWindowing_; | |
515 float windowingCenter_; | |
516 float windowingWidth_; | |
517 Bitmaps bitmaps_; | |
338 | 518 |
519 public: | |
520 BitmapStack(MessageBroker& broker, | |
521 OrthancApiClient& orthanc) : | |
522 IObserver(broker), | |
523 IObservable(broker), | |
524 orthanc_(orthanc), | |
341 | 525 countBitmaps_(0), |
338 | 526 hasWindowing_(false), |
527 windowingCenter_(0), // Dummy initialization | |
528 windowingWidth_(0) // Dummy initialization | |
529 { | |
530 } | |
531 | |
532 | |
533 virtual ~BitmapStack() | |
534 { | |
535 for (Bitmaps::iterator it = bitmaps_.begin(); it != bitmaps_.end(); it++) | |
536 { | |
537 assert(it->second != NULL); | |
538 delete it->second; | |
539 } | |
540 } | |
339 | 541 |
542 | |
343 | 543 bool GetWindowing(float& center, |
544 float& width) const | |
339 | 545 { |
546 if (hasWindowing_) | |
547 { | |
548 center = windowingCenter_; | |
549 width = windowingWidth_; | |
343 | 550 return true; |
339 | 551 } |
552 else | |
553 { | |
343 | 554 return false; |
339 | 555 } |
556 } | |
338 | 557 |
558 | |
343 | 559 size_t LoadText(const Orthanc::Font& font, |
560 const std::string& utf8, | |
561 double x, | |
562 double y) | |
563 { | |
564 std::auto_ptr<AlphaBitmap> alpha(new AlphaBitmap(*this)); | |
565 alpha->LoadText(font, utf8); | |
566 | |
567 size_t bitmap = countBitmaps_++; | |
568 | |
569 bitmaps_[bitmap] = alpha.release(); | |
570 | |
571 return bitmap; | |
572 } | |
573 | |
574 | |
341 | 575 size_t LoadFrame(const std::string& instance, |
576 unsigned int frame, | |
577 bool httpCompression) | |
338 | 578 { |
341 | 579 size_t bitmap = countBitmaps_++; |
338 | 580 |
343 | 581 bitmaps_[bitmap] = new DicomBitmap; |
338 | 582 |
583 | |
584 { | |
585 IWebService::Headers headers; | |
586 std::string uri = "/instances/" + instance + "/tags"; | |
587 orthanc_.GetBinaryAsync(uri, headers, | |
588 new Callable<BitmapStack, OrthancApiClient::BinaryResponseReadyMessage> | |
589 (*this, &BitmapStack::OnTagsReceived), NULL, | |
341 | 590 new Orthanc::SingleValueObject<size_t>(bitmap)); |
338 | 591 } |
592 | |
593 { | |
594 IWebService::Headers headers; | |
595 headers["Accept"] = "image/x-portable-arbitrarymap"; | |
596 | |
597 if (httpCompression) | |
598 { | |
599 headers["Accept-Encoding"] = "gzip"; | |
600 } | |
601 | |
602 std::string uri = "/instances/" + instance + "/frames/" + boost::lexical_cast<std::string>(frame) + "/image-uint16"; | |
603 orthanc_.GetBinaryAsync(uri, headers, | |
604 new Callable<BitmapStack, OrthancApiClient::BinaryResponseReadyMessage> | |
605 (*this, &BitmapStack::OnFrameReceived), NULL, | |
341 | 606 new Orthanc::SingleValueObject<size_t>(bitmap)); |
338 | 607 } |
608 | |
341 | 609 return bitmap; |
338 | 610 } |
611 | |
612 | |
613 void OnTagsReceived(const OrthancApiClient::BinaryResponseReadyMessage& message) | |
614 { | |
341 | 615 size_t index = dynamic_cast<Orthanc::SingleValueObject<size_t>*>(message.Payload)->GetValue(); |
338 | 616 |
341 | 617 printf("JSON received: [%s] (%ld bytes) for bitmap %ld\n", |
618 message.Uri.c_str(), message.AnswerSize, index); | |
338 | 619 |
341 | 620 Bitmaps::iterator bitmap = bitmaps_.find(index); |
338 | 621 if (bitmap != bitmaps_.end()) |
622 { | |
623 assert(bitmap->second != NULL); | |
624 | |
625 OrthancPlugins::FullOrthancDataset dicom(message.Answer, message.AnswerSize); | |
343 | 626 dynamic_cast<DicomBitmap*>(bitmap->second)->SetDicomTags(dicom); |
338 | 627 |
628 float c, w; | |
629 if (!hasWindowing_ && | |
630 bitmap->second->GetDefaultWindowing(c, w)) | |
631 { | |
632 hasWindowing_ = true; | |
633 windowingCenter_ = c; | |
634 windowingWidth_ = w; | |
635 } | |
636 | |
637 EmitMessage(GeometryChangedMessage(*this)); | |
638 } | |
639 } | |
640 | |
641 | |
642 void OnFrameReceived(const OrthancApiClient::BinaryResponseReadyMessage& message) | |
643 { | |
341 | 644 size_t index = dynamic_cast<Orthanc::SingleValueObject<size_t>*>(message.Payload)->GetValue(); |
338 | 645 |
341 | 646 printf("Frame received: [%s] (%ld bytes) for bitmap %ld\n", |
647 message.Uri.c_str(), message.AnswerSize, index); | |
648 | |
649 Bitmaps::iterator bitmap = bitmaps_.find(index); | |
338 | 650 if (bitmap != bitmaps_.end()) |
651 { | |
652 assert(bitmap->second != NULL); | |
653 | |
654 std::string content; | |
655 if (message.AnswerSize > 0) | |
656 { | |
657 content.assign(reinterpret_cast<const char*>(message.Answer), message.AnswerSize); | |
658 } | |
659 | |
660 std::auto_ptr<Orthanc::PamReader> reader(new Orthanc::PamReader); | |
661 reader->ReadFromMemory(content); | |
343 | 662 dynamic_cast<DicomBitmap*>(bitmap->second)->SetSourceImage(reader.release()); |
338 | 663 |
664 EmitMessage(ContentChangedMessage(*this)); | |
665 } | |
666 } | |
339 | 667 |
668 | |
669 Extent2D GetSceneExtent() const | |
670 { | |
671 Extent2D extent; | |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
672 |
339 | 673 for (Bitmaps::const_iterator it = bitmaps_.begin(); |
674 it != bitmaps_.end(); ++it) | |
675 { | |
676 assert(it->second != NULL); | |
677 extent.Union(it->second->GetExtent()); | |
678 } | |
679 | |
680 return extent; | |
681 } | |
682 | |
683 | |
684 void Render(Orthanc::ImageAccessor& buffer, | |
342 | 685 const ViewportGeometry& view) const |
339 | 686 { |
687 Orthanc::ImageProcessing::Set(buffer, 0); | |
688 | |
689 for (Bitmaps::const_iterator it = bitmaps_.begin(); | |
690 it != bitmaps_.end(); ++it) | |
691 { | |
692 assert(it->second != NULL); | |
693 it->second->Render(buffer, view); | |
694 } | |
695 } | |
342 | 696 |
697 | |
698 bool LookupBitmap(size_t& index /* out */, | |
699 double x, | |
700 double y) const | |
701 { | |
702 for (Bitmaps::const_iterator it = bitmaps_.begin(); | |
703 it != bitmaps_.end(); ++it) | |
704 { | |
705 assert(it->second != NULL); | |
706 if (it->second->Contains(x, y)) | |
707 { | |
708 index = it->first; | |
709 return true; | |
710 } | |
711 } | |
712 | |
713 return false; | |
714 } | |
715 | |
716 | |
717 void SetPan(size_t index, | |
718 double panX, | |
719 double panY) | |
720 { | |
721 Bitmaps::iterator bitmap = bitmaps_.find(index); | |
722 if (bitmap != bitmaps_.end()) | |
723 { | |
724 assert(bitmap->second != NULL); | |
725 bitmap->second->SetPan(panX, panY); | |
726 } | |
727 } | |
728 | |
729 | |
730 void GetPan(double& panX, | |
731 double& panY, | |
732 size_t index) const | |
733 { | |
734 Bitmaps::const_iterator bitmap = bitmaps_.find(index); | |
735 if (bitmap != bitmaps_.end()) | |
736 { | |
737 assert(bitmap->second != NULL); | |
738 panX = bitmap->second->GetPanX(); | |
739 panY = bitmap->second->GetPanY(); | |
740 } | |
741 else | |
742 { | |
743 panX = 0; | |
744 panY = 0; | |
745 } | |
746 } | |
338 | 747 }; |
748 | |
341 | 749 |
750 class BitmapStackInteractor : public IWorldSceneInteractor | |
751 { | |
342 | 752 private: |
753 BitmapStack& stack_; | |
754 | |
755 | |
756 class MoveBitmapTracker : public IWorldSceneMouseTracker | |
757 { | |
758 private: | |
759 BitmapStack& stack_; | |
760 size_t bitmap_; | |
761 double clickX_; | |
762 double clickY_; | |
343 | 763 double panX_; |
764 double panY_; | |
765 bool oneAxis_; | |
342 | 766 |
767 public: | |
343 | 768 MoveBitmapTracker(BitmapStack& stack, |
342 | 769 size_t bitmap, |
770 double x, | |
343 | 771 double y, |
772 bool oneAxis) : | |
342 | 773 stack_(stack), |
774 bitmap_(bitmap), | |
775 clickX_(x), | |
343 | 776 clickY_(y), |
777 oneAxis_(oneAxis) | |
342 | 778 { |
343 | 779 stack.GetPan(panX_, panY_, bitmap_); |
342 | 780 } |
781 | |
782 virtual bool HasRender() const | |
783 { | |
784 return false; | |
785 } | |
786 | |
787 virtual void Render(CairoContext& context, | |
788 double zoom) | |
789 { | |
790 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | |
791 } | |
792 | |
793 virtual void MouseUp() | |
794 { | |
795 } | |
796 | |
797 virtual void MouseMove(int displayX, | |
798 int displayY, | |
799 double sceneX, | |
800 double sceneY) | |
801 { | |
343 | 802 double dx = sceneX - clickX_; |
803 double dy = sceneY - clickY_; | |
804 | |
805 if (oneAxis_) | |
806 { | |
807 if (fabs(dx) > fabs(dy)) | |
808 { | |
809 stack_.SetPan(bitmap_, dx + panX_, panY_); | |
810 } | |
811 else | |
812 { | |
813 stack_.SetPan(bitmap_, panX_, dy + panY_); | |
814 } | |
815 } | |
816 else | |
817 { | |
818 stack_.SetPan(bitmap_, dx + panX_, dy + panY_); | |
819 } | |
342 | 820 } |
821 }; | |
822 | |
823 | |
341 | 824 public: |
342 | 825 BitmapStackInteractor(BitmapStack& stack) : |
826 stack_(stack) | |
827 { | |
828 } | |
829 | |
341 | 830 virtual IWorldSceneMouseTracker* CreateMouseTracker(WorldSceneWidget& widget, |
831 const ViewportGeometry& view, | |
832 MouseButton button, | |
833 KeyboardModifiers modifiers, | |
834 double x, | |
835 double y, | |
836 IStatusBar* statusBar) | |
837 { | |
342 | 838 if (button == MouseButton_Left) |
839 { | |
840 size_t bitmap; | |
841 if (stack_.LookupBitmap(bitmap, x, y)) | |
842 { | |
843 printf("CLICK on bitmap %d\n", bitmap); | |
343 | 844 return new MoveBitmapTracker(stack_, bitmap, x, y, |
845 (modifiers & KeyboardModifiers_Shift)); | |
342 | 846 } |
847 else | |
848 { | |
849 printf("CLICK outside\n"); | |
850 return NULL; | |
851 } | |
852 } | |
853 else | |
854 { | |
855 return NULL; | |
856 } | |
341 | 857 } |
858 | |
859 virtual void MouseOver(CairoContext& context, | |
860 WorldSceneWidget& widget, | |
861 const ViewportGeometry& view, | |
862 double x, | |
863 double y, | |
864 IStatusBar* statusBar) | |
865 { | |
866 } | |
867 | |
868 virtual void MouseWheel(WorldSceneWidget& widget, | |
869 MouseWheelDirection direction, | |
870 KeyboardModifiers modifiers, | |
871 IStatusBar* statusBar) | |
872 { | |
873 } | |
874 | |
875 virtual void KeyPressed(WorldSceneWidget& widget, | |
876 KeyboardKeys key, | |
877 char keyChar, | |
878 KeyboardModifiers modifiers, | |
879 IStatusBar* statusBar) | |
880 { | |
342 | 881 if (keyChar == 's') |
882 widget.FitContent(); | |
341 | 883 } |
884 }; | |
885 | |
886 | |
338 | 887 |
888 class BitmapStackWidget : | |
889 public WorldSceneWidget, | |
890 public IObservable, | |
891 public IObserver | |
892 { | |
893 private: | |
341 | 894 BitmapStack& stack_; |
895 BitmapStackInteractor myInteractor_; | |
337 | 896 |
336
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
897 protected: |
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
898 virtual Extent2D GetSceneExtent() |
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
899 { |
339 | 900 printf("Get extent\n"); |
901 return stack_.GetSceneExtent(); | |
336
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
902 } |
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
903 |
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
904 virtual bool RenderScene(CairoContext& context, |
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
905 const ViewportGeometry& view) |
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
906 { |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
907 // "Render()" has been replaced |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
908 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
909 } |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
910 |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
911 public: |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
912 BitmapStackWidget(MessageBroker& broker, |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
913 BitmapStack& stack, |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
914 const std::string& name) : |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
915 WorldSceneWidget(name), |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
916 IObservable(broker), |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
917 IObserver(broker), |
342 | 918 stack_(stack), |
919 myInteractor_(stack_) | |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
920 { |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
921 stack.RegisterObserverCallback(new Callable<BitmapStackWidget, BitmapStack::GeometryChangedMessage>(*this, &BitmapStackWidget::OnGeometryChanged)); |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
922 stack.RegisterObserverCallback(new Callable<BitmapStackWidget, BitmapStack::ContentChangedMessage>(*this, &BitmapStackWidget::OnContentChanged)); |
341 | 923 |
924 SetInteractor(myInteractor_); | |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
925 } |
339 | 926 |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
927 void OnGeometryChanged(const BitmapStack::GeometryChangedMessage& message) |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
928 { |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
929 printf("Geometry has changed\n"); |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
930 FitContent(); |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
931 } |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
932 |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
933 void OnContentChanged(const BitmapStack::ContentChangedMessage& message) |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
934 { |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
935 printf("Content has changed\n"); |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
936 NotifyContentChanged(); |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
937 } |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
938 |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
939 virtual bool Render(Orthanc::ImageAccessor& target) |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
940 { |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
941 Orthanc::Image buffer(Orthanc::PixelFormat_Float32, target.GetWidth(), target.GetHeight(), false); |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
942 stack_.Render(buffer, GetView()); |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
943 |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
944 // As in GrayscaleFrameRenderer => TODO MERGE |
339 | 945 |
946 float windowCenter, windowWidth; | |
343 | 947 if (!stack_.GetWindowing(windowCenter, windowWidth)) |
948 { | |
949 windowCenter = 128; | |
950 windowWidth = 256; | |
951 } | |
339 | 952 |
953 float x0 = windowCenter - windowWidth / 2.0f; | |
954 float x1 = windowCenter + windowWidth / 2.0f; | |
955 | |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
956 const unsigned int width = target.GetWidth(); |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
957 const unsigned int height = target.GetHeight(); |
339 | 958 |
959 for (unsigned int y = 0; y < height; y++) | |
960 { | |
961 const float* p = reinterpret_cast<const float*>(buffer.GetConstRow(y)); | |
962 uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y)); | |
963 | |
964 for (unsigned int x = 0; x < width; x++, p++, q += 4) | |
965 { | |
966 uint8_t v = 0; | |
967 if (windowWidth >= 0.001f) // Avoid division by zero | |
968 { | |
969 if (*p >= x1) | |
970 { | |
971 v = 255; | |
972 } | |
973 else if (*p <= x0) | |
974 { | |
975 v = 0; | |
976 } | |
977 else | |
978 { | |
979 // https://en.wikipedia.org/wiki/Linear_interpolation | |
980 v = static_cast<uint8_t>(255.0f * (*p - x0) / (x1 - x0)); | |
981 } | |
982 | |
983 // TODO MONOCHROME1 | |
984 /*if (invert_) | |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
985 { |
339 | 986 v = 255 - v; |
987 }*/ | |
988 } | |
989 | |
990 q[3] = 255; | |
991 q[2] = v; | |
992 q[1] = v; | |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
993 q[0] = v; |
339 | 994 } |
995 } | |
996 | |
337 | 997 return true; |
336
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
998 } |
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
999 |
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
1000 }; |
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
1001 |
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
1002 |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1003 namespace Samples |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1004 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1005 class SingleFrameEditorApplication : |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1006 public SampleSingleCanvasApplicationBase, |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1007 public IObserver |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1008 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1009 enum Tools |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1010 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1011 Tools_Crop, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1012 Tools_Windowing, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1013 Tools_Zoom, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1014 Tools_Pan |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1015 }; |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1016 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1017 enum Actions |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1018 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1019 Actions_Invert, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1020 Actions_RotateLeft, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1021 Actions_RotateRight |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1022 }; |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1023 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1024 private: |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1025 class Interactor : public IWorldSceneInteractor |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1026 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1027 private: |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1028 SingleFrameEditorApplication& application_; |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1029 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1030 public: |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1031 Interactor(SingleFrameEditorApplication& application) : |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1032 application_(application) |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1033 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1034 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1035 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1036 virtual IWorldSceneMouseTracker* CreateMouseTracker(WorldSceneWidget& widget, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1037 const ViewportGeometry& view, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1038 MouseButton button, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1039 KeyboardModifiers modifiers, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1040 double x, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1041 double y, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1042 IStatusBar* statusBar) |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1043 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1044 switch (application_.currentTool_) { |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1045 case Tools_Zoom: |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1046 printf("ZOOM\n"); |
329
b10dfdb96866
removing WorldSceneWidget::IWorldObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
327
diff
changeset
|
1047 |
b10dfdb96866
removing WorldSceneWidget::IWorldObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
327
diff
changeset
|
1048 case Tools_Crop: |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1049 case Tools_Windowing: |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1050 case Tools_Pan: |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1051 // TODO return the right mouse tracker |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1052 return NULL; |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1053 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1054 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1055 return NULL; |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1056 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1057 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1058 virtual void MouseOver(CairoContext& context, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1059 WorldSceneWidget& widget, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1060 const ViewportGeometry& view, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1061 double x, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1062 double y, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1063 IStatusBar* statusBar) |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1064 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1065 if (statusBar != NULL) |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1066 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1067 char buf[64]; |
336
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
1068 sprintf(buf, "X = %.02f Y = %.02f (in cm)", x / 10.0, y / 10.0); |
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
1069 statusBar->SetMessage(buf); |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1070 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1071 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1072 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1073 virtual void MouseWheel(WorldSceneWidget& widget, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1074 MouseWheelDirection direction, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1075 KeyboardModifiers modifiers, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1076 IStatusBar* statusBar) |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1077 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1078 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1079 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1080 virtual void KeyPressed(WorldSceneWidget& widget, |
327 | 1081 KeyboardKeys key, |
1082 char keyChar, | |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1083 KeyboardModifiers modifiers, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1084 IStatusBar* statusBar) |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1085 { |
327 | 1086 switch (keyChar) |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1087 { |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1088 case 's': |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1089 widget.FitContent(); |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1090 break; |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1091 case 'p': |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1092 application_.currentTool_ = Tools_Pan; |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1093 break; |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1094 case 'z': |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1095 application_.currentTool_ = Tools_Zoom; |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1096 break; |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1097 case 'c': |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1098 application_.currentTool_ = Tools_Crop; |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1099 break; |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1100 case 'w': |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1101 application_.currentTool_ = Tools_Windowing; |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1102 break; |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1103 case 'i': |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1104 application_.Invert(); |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1105 break; |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1106 case 'r': |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1107 if (modifiers == KeyboardModifiers_None) |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1108 application_.Rotate(90); |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1109 else |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1110 application_.Rotate(-90); |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1111 break; |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1112 case 'e': |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1113 application_.Export(); |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1114 break; |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1115 default: |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1116 break; |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1117 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1118 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1119 }; |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1120 |
334
c34784e5f299
compatibility fixes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
330
diff
changeset
|
1121 std::auto_ptr<Interactor> mainWidgetInteractor_; |
c34784e5f299
compatibility fixes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
330
diff
changeset
|
1122 std::auto_ptr<OrthancApiClient> orthancApiClient_; |
338 | 1123 std::auto_ptr<BitmapStack> stack_; |
334
c34784e5f299
compatibility fixes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
330
diff
changeset
|
1124 Tools currentTool_; |
c34784e5f299
compatibility fixes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
330
diff
changeset
|
1125 const OrthancFrameLayerSource* source_; |
c34784e5f299
compatibility fixes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
330
diff
changeset
|
1126 unsigned int slice_; |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1127 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1128 public: |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1129 SingleFrameEditorApplication(MessageBroker& broker) : |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1130 IObserver(broker), |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1131 currentTool_(Tools_Zoom), |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1132 source_(NULL), |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1133 slice_(0) |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1134 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1135 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1136 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1137 virtual void DeclareStartupOptions(boost::program_options::options_description& options) |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1138 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1139 boost::program_options::options_description generic("Sample options"); |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1140 generic.add_options() |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1141 ("instance", boost::program_options::value<std::string>(), |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1142 "Orthanc ID of the instance") |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1143 ("frame", boost::program_options::value<unsigned int>()->default_value(0), |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1144 "Number of the frame, for multi-frame DICOM instances") |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1145 ; |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1146 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1147 options.add(generic); |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1148 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1149 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1150 virtual void Initialize(StoneApplicationContext* context, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1151 IStatusBar& statusBar, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1152 const boost::program_options::variables_map& parameters) |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1153 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1154 using namespace OrthancStone; |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1155 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1156 context_ = context; |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1157 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1158 statusBar.SetMessage("Use the key \"s\" to reinitialize the layout, \"p\" to pan, \"z\" to zoom, \"c\" to crop, \"i\" to invert, \"w\" to change windowing, \"r\" to rotate cw, \"shift+r\" to rotate ccw"); |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1159 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1160 if (parameters.count("instance") != 1) |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1161 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1162 LOG(ERROR) << "The instance ID is missing"; |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1163 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1164 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1165 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1166 std::string instance = parameters["instance"].as<std::string>(); |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1167 int frame = parameters["frame"].as<unsigned int>(); |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1168 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1169 orthancApiClient_.reset(new OrthancApiClient(IObserver::broker_, context_->GetWebService())); |
337 | 1170 |
343 | 1171 Orthanc::FontRegistry fonts; |
1172 fonts.AddFromResource(Orthanc::EmbeddedResources::FONT_UBUNTU_MONO_BOLD_16); | |
1173 | |
338 | 1174 stack_.reset(new BitmapStack(IObserver::broker_, *orthancApiClient_)); |
1175 stack_->LoadFrame(instance, frame, false); | |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1176 stack_->LoadFrame("61f3143e-96f34791-ad6bbb8d-62559e75-45943e1b", frame, false); |
343 | 1177 stack_->LoadText(fonts.GetFont(0), "Hello\nworld\nBonjour, Alain", 0, -50); |
337 | 1178 |
338 | 1179 mainWidget_ = new BitmapStackWidget(IObserver::broker_, *stack_, "main-widget"); |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1180 mainWidget_->SetTransmitMouseOver(true); |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1181 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1182 mainWidgetInteractor_.reset(new Interactor(*this)); |
341 | 1183 //mainWidget_->SetInteractor(*mainWidgetInteractor_); |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1184 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1185 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1186 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1187 void Invert() |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1188 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1189 // TODO |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1190 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1191 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1192 void Rotate(int degrees) |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1193 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1194 // TODO |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1195 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1196 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1197 void Export() |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1198 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1199 // TODO: export dicom file to a temporary file |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1200 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1201 }; |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1202 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1203 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1204 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
1205 } |