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