Mercurial > hg > orthanc-stone
annotate Applications/Samples/SingleFrameEditorApplication.h @ 355:d2468dd75b3f am-2
undo redo for all tools
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 29 Oct 2018 14:29:45 +0100 |
parents | f806779bd40f |
children | 885f0a5eaa49 |
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 |
350
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
52 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
53 enum Corner |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
54 { |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
55 Corner_TopLeft, |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
56 Corner_TopRight, |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
57 Corner_BottomLeft, |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
58 Corner_BottomRight |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
59 }; |
354 | 60 |
350
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
61 |
355
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
62 |
338 | 63 class Bitmap : public boost::noncopyable |
64 { | |
65 private: | |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
66 size_t index_; |
343 | 67 bool hasSize_; |
68 unsigned int width_; | |
69 unsigned int height_; | |
70 bool hasCrop_; | |
71 unsigned int cropX_; | |
72 unsigned int cropY_; | |
73 unsigned int cropWidth_; | |
74 unsigned int cropHeight_; | |
75 Matrix transform_; | |
350
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
76 Matrix transformInverse_; |
343 | 77 double pixelSpacingX_; |
78 double pixelSpacingY_; | |
79 double panX_; | |
80 double panY_; | |
346 | 81 double angle_; |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
82 bool resizeable_; |
338 | 83 |
342 | 84 |
348 | 85 protected: |
346 | 86 static Matrix CreateOffsetMatrix(double dx, |
87 double dy) | |
342 | 88 { |
346 | 89 Matrix m = LinearAlgebra::IdentityMatrix(3); |
90 m(0, 2) = dx; | |
91 m(1, 2) = dy; | |
92 return m; | |
93 } | |
94 | |
342 | 95 |
346 | 96 static Matrix CreateScalingMatrix(double sx, |
97 double sy) | |
98 { | |
99 Matrix m = LinearAlgebra::IdentityMatrix(3); | |
100 m(0, 0) = sx; | |
101 m(1, 1) = sy; | |
102 return m; | |
103 } | |
104 | |
105 | |
106 static Matrix CreateRotationMatrix(double angle) | |
107 { | |
342 | 108 Matrix m; |
346 | 109 const double v[] = { cos(angle), -sin(angle), 0, |
110 sin(angle), cos(angle), 0, | |
342 | 111 0, 0, 1 }; |
112 LinearAlgebra::FillMatrix(m, 3, 3, v); | |
346 | 113 return m; |
342 | 114 } |
346 | 115 |
345 | 116 |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
117 const Matrix& GetTransform() const |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
118 { |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
119 return transform_; |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
120 } |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
121 |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
122 |
348 | 123 private: |
346 | 124 static void ApplyTransform(double& x /* inout */, |
125 double& y /* inout */, | |
126 const Matrix& transform) | |
339 | 127 { |
128 Vector p; | |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
129 LinearAlgebra::AssignVector(p, x, y, 1); |
339 | 130 |
346 | 131 Vector q = LinearAlgebra::Product(transform, p); |
339 | 132 |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
133 if (!LinearAlgebra::IsNear(q[2], 1.0)) |
339 | 134 { |
135 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | |
136 } | |
137 else | |
138 { | |
345 | 139 x = q[0]; |
140 y = q[1]; | |
339 | 141 } |
142 } | |
143 | |
345 | 144 |
346 | 145 void UpdateTransform() |
146 { | |
147 transform_ = CreateScalingMatrix(pixelSpacingX_, pixelSpacingY_); | |
148 | |
347
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
149 double centerX, centerY; |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
150 GetCenter(centerX, centerY); |
346 | 151 |
152 transform_ = LinearAlgebra::Product( | |
347
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
153 CreateOffsetMatrix(panX_ + centerX, panY_ + centerY), |
346 | 154 CreateRotationMatrix(angle_), |
347
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
155 CreateOffsetMatrix(-centerX, -centerY), |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
156 transform_); |
350
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
157 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
158 LinearAlgebra::InvertMatrix(transformInverse_, transform_); |
346 | 159 } |
160 | |
161 | |
345 | 162 void AddToExtent(Extent2D& extent, |
163 double x, | |
164 double y) const | |
165 { | |
346 | 166 ApplyTransform(x, y, transform_); |
345 | 167 extent.AddPoint(x, y); |
168 } | |
350
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
169 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
170 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
171 void GetCornerInternal(double& x, |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
172 double& y, |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
173 Corner corner, |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
174 unsigned int cropX, |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
175 unsigned int cropY, |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
176 unsigned int cropWidth, |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
177 unsigned int cropHeight) const |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
178 { |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
179 double dx = static_cast<double>(cropX); |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
180 double dy = static_cast<double>(cropY); |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
181 double dwidth = static_cast<double>(cropWidth); |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
182 double dheight = static_cast<double>(cropHeight); |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
183 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
184 switch (corner) |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
185 { |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
186 case Corner_TopLeft: |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
187 x = dx; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
188 y = dy; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
189 break; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
190 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
191 case Corner_TopRight: |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
192 x = dx + dwidth; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
193 y = dy; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
194 break; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
195 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
196 case Corner_BottomLeft: |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
197 x = dx; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
198 y = dy + dheight; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
199 break; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
200 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
201 case Corner_BottomRight: |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
202 x = dx + dwidth; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
203 y = dy + dheight; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
204 break; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
205 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
206 default: |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
207 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
208 } |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
209 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
210 ApplyTransform(x, y, transform_); |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
211 } |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
212 |
339 | 213 |
338 | 214 public: |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
215 Bitmap(size_t index) : |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
216 index_(index), |
343 | 217 hasSize_(false), |
339 | 218 width_(0), |
219 height_(0), | |
220 hasCrop_(false), | |
342 | 221 pixelSpacingX_(1), |
222 pixelSpacingY_(1), | |
223 panX_(0), | |
346 | 224 panY_(0), |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
225 angle_(0), |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
226 resizeable_(false) |
339 | 227 { |
342 | 228 UpdateTransform(); |
339 | 229 } |
230 | |
343 | 231 virtual ~Bitmap() |
232 { | |
233 } | |
234 | |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
235 size_t GetIndex() const |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
236 { |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
237 return index_; |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
238 } |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
239 |
339 | 240 void ResetCrop() |
241 { | |
242 hasCrop_ = false; | |
243 } | |
244 | |
348 | 245 void SetCrop(unsigned int x, |
246 unsigned int y, | |
247 unsigned int width, | |
248 unsigned int height) | |
339 | 249 { |
348 | 250 if (!hasSize_) |
251 { | |
252 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); | |
253 } | |
254 | |
255 if (x + width > width_ || | |
256 y + height > height_) | |
257 { | |
258 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
259 } | |
260 | |
339 | 261 hasCrop_ = true; |
262 cropX_ = x; | |
263 cropY_ = y; | |
264 cropWidth_ = width; | |
265 cropHeight_ = height; | |
348 | 266 |
267 UpdateTransform(); | |
339 | 268 } |
269 | |
270 void GetCrop(unsigned int& x, | |
271 unsigned int& y, | |
272 unsigned int& width, | |
273 unsigned int& height) const | |
338 | 274 { |
339 | 275 if (hasCrop_) |
276 { | |
277 x = cropX_; | |
278 y = cropY_; | |
279 width = cropWidth_; | |
280 height = cropHeight_; | |
281 } | |
282 else | |
283 { | |
284 x = 0; | |
285 y = 0; | |
286 width = width_; | |
287 height = height_; | |
288 } | |
289 } | |
290 | |
346 | 291 void SetAngle(double angle) |
292 { | |
293 angle_ = angle; | |
294 UpdateTransform(); | |
295 } | |
296 | |
297 double GetAngle() const | |
298 { | |
299 return angle_; | |
300 } | |
301 | |
343 | 302 void SetSize(unsigned int width, |
303 unsigned int height) | |
338 | 304 { |
343 | 305 if (hasSize_ && |
306 (width != width_ || | |
307 height != height_)) | |
339 | 308 { |
343 | 309 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageSize); |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
310 } |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
311 |
343 | 312 hasSize_ = true; |
313 width_ = width; | |
314 height_ = height; | |
346 | 315 |
316 UpdateTransform(); | |
338 | 317 } |
318 | |
343 | 319 |
351
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
320 unsigned int GetWidth() const |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
321 { |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
322 return width_; |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
323 } |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
324 |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
325 |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
326 unsigned int GetHeight() const |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
327 { |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
328 return height_; |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
329 } |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
330 |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
331 |
343 | 332 void CheckSize(unsigned int width, |
333 unsigned int height) | |
338 | 334 { |
343 | 335 if (hasSize_ && |
336 (width != width_ || | |
337 height != height_)) | |
338 | 338 { |
343 | 339 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageSize); |
339 | 340 } |
341 } | |
343 | 342 |
339 | 343 |
344 Extent2D GetExtent() const | |
345 { | |
346 Extent2D extent; | |
347 | |
348 unsigned int x, y, width, height; | |
349 GetCrop(x, y, width, height); | |
350 | |
350
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
351 double dx = static_cast<double>(x); |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
352 double dy = static_cast<double>(y); |
339 | 353 double dwidth = static_cast<double>(width); |
354 double dheight = static_cast<double>(height); | |
342 | 355 |
339 | 356 AddToExtent(extent, dx, dy); |
357 AddToExtent(extent, dx + dwidth, dy); | |
358 AddToExtent(extent, dx, dy + dheight); | |
359 AddToExtent(extent, dx + dwidth, dy + dheight); | |
360 | |
361 return extent; | |
362 } | |
363 | |
364 | |
343 | 365 virtual void Render(Orthanc::ImageAccessor& buffer, |
345 | 366 const ViewportGeometry& view, |
367 ImageInterpolation interpolation) const = 0; | |
341 | 368 |
369 | |
370 bool Contains(double x, | |
371 double y) const | |
372 { | |
350
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
373 ApplyTransform(x, y, transformInverse_); |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
374 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
375 unsigned int cropX, cropY, cropWidth, cropHeight; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
376 GetCrop(cropX, cropY, cropWidth, cropHeight); |
341 | 377 |
350
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
378 return (x >= cropX && x <= cropX + cropWidth && |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
379 y >= cropY && y <= cropY + cropHeight); |
341 | 380 } |
342 | 381 |
382 | |
351
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
383 bool GetPixel(unsigned int& pixelX, |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
384 unsigned int& pixelY, |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
385 double sceneX, |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
386 double sceneY) const |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
387 { |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
388 if (width_ == 0 || |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
389 height_ == 0) |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
390 { |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
391 return false; |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
392 } |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
393 else |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
394 { |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
395 ApplyTransform(sceneX, sceneY, transformInverse_); |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
396 |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
397 int x = static_cast<int>(std::floor(sceneX)); |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
398 int y = static_cast<int>(std::floor(sceneY)); |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
399 |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
400 if (x < 0) |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
401 { |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
402 pixelX = 0; |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
403 } |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
404 else if (x >= static_cast<int>(width_)) |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
405 { |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
406 pixelX = width_; |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
407 } |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
408 else |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
409 { |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
410 pixelX = static_cast<unsigned int>(x); |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
411 } |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
412 |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
413 if (y < 0) |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
414 { |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
415 pixelY = 0; |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
416 } |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
417 else if (y >= static_cast<int>(height_)) |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
418 { |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
419 pixelY = height_; |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
420 } |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
421 else |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
422 { |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
423 pixelY = static_cast<unsigned int>(y); |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
424 } |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
425 |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
426 return true; |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
427 } |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
428 } |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
429 |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
430 |
342 | 431 void SetPan(double x, |
432 double y) | |
433 { | |
434 panX_ = x; | |
435 panY_ = y; | |
436 UpdateTransform(); | |
437 } | |
438 | |
439 | |
343 | 440 void SetPixelSpacing(double x, |
441 double y) | |
442 { | |
443 pixelSpacingX_ = x; | |
444 pixelSpacingY_ = y; | |
445 UpdateTransform(); | |
446 } | |
447 | |
345 | 448 double GetPixelSpacingX() const |
449 { | |
450 return pixelSpacingX_; | |
451 } | |
452 | |
453 double GetPixelSpacingY() const | |
454 { | |
455 return pixelSpacingY_; | |
456 } | |
343 | 457 |
342 | 458 double GetPanX() const |
459 { | |
460 return panX_; | |
461 } | |
462 | |
463 double GetPanY() const | |
464 { | |
465 return panY_; | |
466 } | |
343 | 467 |
468 virtual bool GetDefaultWindowing(float& center, | |
469 float& width) const | |
470 { | |
471 return false; | |
472 } | |
473 | |
347
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
474 void GetCenter(double& centerX, |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
475 double& centerY) const |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
476 { |
351
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
477 centerX = static_cast<double>(width_) / 2.0; |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
478 centerY = static_cast<double>(height_) / 2.0; |
347
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
479 ApplyTransform(centerX, centerY, transform_); |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
480 } |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
481 |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
482 |
345 | 483 void DrawBorders(CairoContext& context, |
484 double zoom) | |
485 { | |
486 unsigned int cx, cy, width, height; | |
487 GetCrop(cx, cy, width, height); | |
488 | |
489 double dx = static_cast<double>(cx); | |
490 double dy = static_cast<double>(cy); | |
491 double dwidth = static_cast<double>(width); | |
492 double dheight = static_cast<double>(height); | |
493 | |
494 cairo_t* cr = context.GetObject(); | |
495 cairo_set_line_width(cr, 2.0 / zoom); | |
496 | |
497 double x, y; | |
498 x = dx; | |
499 y = dy; | |
346 | 500 ApplyTransform(x, y, transform_); |
345 | 501 cairo_move_to(cr, x, y); |
502 | |
503 x = dx + dwidth; | |
504 y = dy; | |
346 | 505 ApplyTransform(x, y, transform_); |
345 | 506 cairo_line_to(cr, x, y); |
507 | |
508 x = dx + dwidth; | |
509 y = dy + dheight; | |
346 | 510 ApplyTransform(x, y, transform_); |
345 | 511 cairo_line_to(cr, x, y); |
512 | |
513 x = dx; | |
514 y = dy + dheight; | |
346 | 515 ApplyTransform(x, y, transform_); |
345 | 516 cairo_line_to(cr, x, y); |
517 | |
518 x = dx; | |
519 y = dy; | |
346 | 520 ApplyTransform(x, y, transform_); |
345 | 521 cairo_line_to(cr, x, y); |
522 | |
523 cairo_stroke(cr); | |
524 } | |
350
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
525 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
526 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
527 static double Square(double x) |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
528 { |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
529 return x * x; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
530 } |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
531 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
532 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
533 void GetCorner(double& x /* out */, |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
534 double& y /* out */, |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
535 Corner corner) const |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
536 { |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
537 unsigned int cropX, cropY, cropWidth, cropHeight; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
538 GetCrop(cropX, cropY, cropWidth, cropHeight); |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
539 GetCornerInternal(x, y, corner, cropX, cropY, cropWidth, cropHeight); |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
540 } |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
541 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
542 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
543 bool LookupCorner(Corner& corner /* out */, |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
544 double x, |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
545 double y, |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
546 double zoom, |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
547 double viewportDistance) const |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
548 { |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
549 static const Corner CORNERS[] = { |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
550 Corner_TopLeft, |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
551 Corner_TopRight, |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
552 Corner_BottomLeft, |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
553 Corner_BottomRight |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
554 }; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
555 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
556 unsigned int cropX, cropY, cropWidth, cropHeight; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
557 GetCrop(cropX, cropY, cropWidth, cropHeight); |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
558 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
559 double threshold = Square(viewportDistance / zoom); |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
560 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
561 for (size_t i = 0; i < 4; i++) |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
562 { |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
563 double cx, cy; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
564 GetCornerInternal(cx, cy, CORNERS[i], cropX, cropY, cropWidth, cropHeight); |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
565 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
566 double d = Square(cx - x) + Square(cy - y); |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
567 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
568 if (d <= threshold) |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
569 { |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
570 corner = CORNERS[i]; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
571 return true; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
572 } |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
573 } |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
574 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
575 return false; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
576 } |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
577 |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
578 bool IsResizeable() const |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
579 { |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
580 return resizeable_; |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
581 } |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
582 |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
583 void SetResizeable(bool resizeable) |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
584 { |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
585 resizeable_ = resizeable; |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
586 } |
338 | 587 }; |
588 | |
589 | |
347
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
590 class BitmapAccessor : public boost::noncopyable |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
591 { |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
592 private: |
354 | 593 BitmapStack& stack_; |
594 size_t index_; | |
595 Bitmap* bitmap_; | |
343 | 596 |
347
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
597 public: |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
598 BitmapAccessor(BitmapStack& stack, |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
599 size_t index) : |
354 | 600 stack_(stack), |
347
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
601 index_(index) |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
602 { |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
603 Bitmaps::iterator bitmap = stack.bitmaps_.find(index); |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
604 if (bitmap == stack.bitmaps_.end()) |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
605 { |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
606 bitmap_ = NULL; |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
607 } |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
608 else |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
609 { |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
610 assert(bitmap->second != NULL); |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
611 bitmap_ = bitmap->second; |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
612 } |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
613 } |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
614 |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
615 BitmapAccessor(BitmapStack& stack, |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
616 double x, |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
617 double y) : |
354 | 618 stack_(stack), |
347
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
619 index_(0) // Dummy initialization |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
620 { |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
621 if (stack.LookupBitmap(index_, x, y)) |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
622 { |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
623 Bitmaps::iterator bitmap = stack.bitmaps_.find(index_); |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
624 |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
625 if (bitmap == stack.bitmaps_.end()) |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
626 { |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
627 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
628 } |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
629 else |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
630 { |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
631 assert(bitmap->second != NULL); |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
632 bitmap_ = bitmap->second; |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
633 } |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
634 } |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
635 else |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
636 { |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
637 bitmap_ = NULL; |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
638 } |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
639 } |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
640 |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
641 void Invalidate() |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
642 { |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
643 bitmap_ = NULL; |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
644 } |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
645 |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
646 bool IsValid() const |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
647 { |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
648 return bitmap_ != NULL; |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
649 } |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
650 |
354 | 651 BitmapStack& GetStack() const |
652 { | |
653 if (IsValid()) | |
654 { | |
655 return stack_; | |
656 } | |
657 else | |
658 { | |
659 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); | |
660 } | |
661 } | |
662 | |
347
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
663 size_t GetIndex() const |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
664 { |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
665 if (IsValid()) |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
666 { |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
667 return index_; |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
668 } |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
669 else |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
670 { |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
671 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
672 } |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
673 } |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
674 |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
675 Bitmap& GetBitmap() const |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
676 { |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
677 if (IsValid()) |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
678 { |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
679 return *bitmap_; |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
680 } |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
681 else |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
682 { |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
683 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
684 } |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
685 } |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
686 }; |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
687 |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
688 |
354 | 689 class AlphaBitmap : public Bitmap |
690 { | |
691 private: | |
692 const BitmapStack& stack_; | |
693 std::auto_ptr<Orthanc::ImageAccessor> alpha_; // Grayscale8 | |
694 bool useWindowing_; | |
695 float foreground_; | |
696 | |
697 public: | |
698 AlphaBitmap(size_t index, | |
699 const BitmapStack& stack) : | |
700 Bitmap(index), | |
701 stack_(stack), | |
702 useWindowing_(true), | |
703 foreground_(0) | |
704 { | |
705 } | |
706 | |
707 | |
708 void SetForegroundValue(float foreground) | |
709 { | |
710 useWindowing_ = false; | |
711 foreground_ = foreground; | |
712 } | |
713 | |
714 | |
715 void SetAlpha(Orthanc::ImageAccessor* image) | |
716 { | |
717 std::auto_ptr<Orthanc::ImageAccessor> raii(image); | |
718 | |
719 if (image == NULL) | |
720 { | |
721 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); | |
722 } | |
723 | |
724 if (image->GetFormat() != Orthanc::PixelFormat_Grayscale8) | |
725 { | |
726 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat); | |
727 } | |
728 | |
729 SetSize(image->GetWidth(), image->GetHeight()); | |
730 alpha_ = raii; | |
731 } | |
732 | |
733 | |
734 void LoadText(const Orthanc::Font& font, | |
735 const std::string& utf8) | |
736 { | |
737 SetAlpha(font.RenderAlpha(utf8)); | |
738 } | |
739 | |
740 | |
741 virtual void Render(Orthanc::ImageAccessor& buffer, | |
742 const ViewportGeometry& view, | |
743 ImageInterpolation interpolation) const | |
744 { | |
745 if (buffer.GetFormat() != Orthanc::PixelFormat_Float32) | |
746 { | |
747 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat); | |
748 } | |
749 | |
750 unsigned int cropX, cropY, cropWidth, cropHeight; | |
751 GetCrop(cropX, cropY, cropWidth, cropHeight); | |
752 | |
753 Matrix m = LinearAlgebra::Product(view.GetMatrix(), | |
754 GetTransform(), | |
755 CreateOffsetMatrix(cropX, cropY)); | |
756 | |
757 Orthanc::ImageAccessor cropped; | |
758 alpha_->GetRegion(cropped, cropX, cropY, cropWidth, cropHeight); | |
759 | |
760 Orthanc::Image tmp(Orthanc::PixelFormat_Grayscale8, buffer.GetWidth(), buffer.GetHeight(), false); | |
761 ApplyProjectiveTransform(tmp, cropped, m, interpolation, true /* clear */); | |
762 | |
763 // Blit | |
764 const unsigned int width = buffer.GetWidth(); | |
765 const unsigned int height = buffer.GetHeight(); | |
766 | |
767 float value = foreground_; | |
768 | |
769 if (useWindowing_) | |
770 { | |
771 float center, width; | |
772 if (stack_.GetWindowing(center, width)) | |
773 { | |
774 value = center + width / 2.0f; | |
775 } | |
776 } | |
777 | |
778 for (unsigned int y = 0; y < height; y++) | |
779 { | |
780 float *q = reinterpret_cast<float*>(buffer.GetRow(y)); | |
781 const uint8_t *p = reinterpret_cast<uint8_t*>(tmp.GetRow(y)); | |
782 | |
783 for (unsigned int x = 0; x < width; x++, p++, q++) | |
784 { | |
785 float a = static_cast<float>(*p) / 255.0f; | |
786 | |
787 *q = (a * value + (1.0f - a) * (*q)); | |
788 } | |
789 } | |
790 } | |
791 }; | |
792 | |
793 | |
794 | |
347
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
795 private: |
343 | 796 class DicomBitmap : public Bitmap |
797 { | |
798 private: | |
799 std::auto_ptr<Orthanc::ImageAccessor> source_; // Content of PixelData | |
800 std::auto_ptr<DicomFrameConverter> converter_; | |
801 std::auto_ptr<Orthanc::ImageAccessor> converted_; // Float32 or RGB24 | |
802 | |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
803 static OrthancPlugins::DicomTag ConvertTag(const Orthanc::DicomTag& tag) |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
804 { |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
805 return OrthancPlugins::DicomTag(tag.GetGroup(), tag.GetElement()); |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
806 } |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
807 |
343 | 808 |
809 void ApplyConverter() | |
810 { | |
811 if (source_.get() != NULL && | |
812 converter_.get() != NULL) | |
813 { | |
814 converted_.reset(converter_->ConvertFrame(*source_)); | |
815 } | |
816 } | |
817 | |
818 public: | |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
819 DicomBitmap(size_t index) : |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
820 Bitmap(index) |
343 | 821 { |
822 } | |
823 | |
824 void SetDicomTags(const OrthancPlugins::FullOrthancDataset& dataset) | |
825 { | |
826 converter_.reset(new DicomFrameConverter); | |
827 converter_->ReadParameters(dataset); | |
828 ApplyConverter(); | |
829 | |
830 std::string tmp; | |
831 Vector pixelSpacing; | |
832 | |
833 if (dataset.GetStringValue(tmp, ConvertTag(Orthanc::DICOM_TAG_PIXEL_SPACING)) && | |
834 LinearAlgebra::ParseVector(pixelSpacing, tmp) && | |
835 pixelSpacing.size() == 2) | |
836 { | |
837 SetPixelSpacing(pixelSpacing[0], pixelSpacing[1]); | |
838 } | |
839 | |
348 | 840 //SetPan(-0.5 * GetPixelSpacingX(), -0.5 * GetPixelSpacingY()); |
345 | 841 |
343 | 842 static unsigned int c = 0; |
843 if (c == 0) | |
844 { | |
845 SetPan(400, 0); | |
846 c ++; | |
847 } | |
848 | |
849 OrthancPlugins::DicomDatasetReader reader(dataset); | |
850 | |
851 unsigned int width, height; | |
852 if (!reader.GetUnsignedIntegerValue(width, ConvertTag(Orthanc::DICOM_TAG_COLUMNS)) || | |
853 !reader.GetUnsignedIntegerValue(height, ConvertTag(Orthanc::DICOM_TAG_ROWS))) | |
854 { | |
855 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); | |
856 } | |
857 else | |
858 { | |
859 SetSize(width, height); | |
860 } | |
861 } | |
862 | |
863 | |
864 void SetSourceImage(Orthanc::ImageAccessor* image) // Takes ownership | |
865 { | |
866 std::auto_ptr<Orthanc::ImageAccessor> raii(image); | |
867 | |
868 if (image == NULL) | |
869 { | |
870 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); | |
871 } | |
872 | |
873 SetSize(image->GetWidth(), image->GetHeight()); | |
874 | |
875 source_ = raii; | |
876 ApplyConverter(); | |
877 } | |
878 | |
879 | |
880 virtual void Render(Orthanc::ImageAccessor& buffer, | |
345 | 881 const ViewportGeometry& view, |
882 ImageInterpolation interpolation) const | |
343 | 883 { |
884 if (converted_.get() != NULL) | |
885 { | |
351
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
886 if (converted_->GetFormat() != Orthanc::PixelFormat_Float32) |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
887 { |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
888 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
889 } |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
890 |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
891 unsigned int cropX, cropY, cropWidth, cropHeight; |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
892 GetCrop(cropX, cropY, cropWidth, cropHeight); |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
893 |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
894 Matrix m = LinearAlgebra::Product(view.GetMatrix(), |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
895 GetTransform(), |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
896 CreateOffsetMatrix(cropX, cropY)); |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
897 |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
898 Orthanc::ImageAccessor cropped; |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
899 converted_->GetRegion(cropped, cropX, cropY, cropWidth, cropHeight); |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
900 |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
901 ApplyProjectiveTransform(buffer, cropped, m, interpolation, false); |
343 | 902 } |
903 } | |
904 | |
905 | |
906 virtual bool GetDefaultWindowing(float& center, | |
907 float& width) const | |
908 { | |
909 if (converter_.get() != NULL && | |
910 converter_->HasDefaultWindow()) | |
911 { | |
912 center = static_cast<float>(converter_->GetDefaultWindowCenter()); | |
913 width = static_cast<float>(converter_->GetDefaultWindowWidth()); | |
914 return true; | |
915 } | |
916 else | |
917 { | |
918 return false; | |
919 } | |
920 } | |
921 }; | |
922 | |
923 | |
924 | |
925 | |
341 | 926 typedef std::map<size_t, Bitmap*> Bitmaps; |
338 | 927 |
341 | 928 OrthancApiClient& orthanc_; |
929 size_t countBitmaps_; | |
930 bool hasWindowing_; | |
931 float windowingCenter_; | |
932 float windowingWidth_; | |
933 Bitmaps bitmaps_; | |
345 | 934 bool hasSelection_; |
935 size_t selectedBitmap_; | |
338 | 936 |
937 public: | |
938 BitmapStack(MessageBroker& broker, | |
939 OrthancApiClient& orthanc) : | |
940 IObserver(broker), | |
941 IObservable(broker), | |
942 orthanc_(orthanc), | |
341 | 943 countBitmaps_(0), |
338 | 944 hasWindowing_(false), |
945 windowingCenter_(0), // Dummy initialization | |
345 | 946 windowingWidth_(0), // Dummy initialization |
947 hasSelection_(false), | |
948 selectedBitmap_(0) // Dummy initialization | |
338 | 949 { |
950 } | |
951 | |
345 | 952 |
953 void Unselect() | |
954 { | |
955 hasSelection_ = false; | |
956 } | |
957 | |
958 | |
959 void Select(size_t bitmap) | |
960 { | |
961 hasSelection_ = true; | |
962 selectedBitmap_ = bitmap; | |
963 } | |
346 | 964 |
965 | |
966 bool GetSelectedBitmap(size_t& bitmap) const | |
967 { | |
968 if (hasSelection_) | |
969 { | |
970 bitmap = selectedBitmap_; | |
971 return true; | |
972 } | |
973 else | |
974 { | |
975 return false; | |
976 } | |
977 } | |
345 | 978 |
338 | 979 |
980 virtual ~BitmapStack() | |
981 { | |
982 for (Bitmaps::iterator it = bitmaps_.begin(); it != bitmaps_.end(); it++) | |
983 { | |
984 assert(it->second != NULL); | |
985 delete it->second; | |
986 } | |
987 } | |
339 | 988 |
989 | |
343 | 990 bool GetWindowing(float& center, |
991 float& width) const | |
339 | 992 { |
993 if (hasWindowing_) | |
994 { | |
995 center = windowingCenter_; | |
996 width = windowingWidth_; | |
343 | 997 return true; |
339 | 998 } |
999 else | |
1000 { | |
343 | 1001 return false; |
339 | 1002 } |
1003 } | |
350
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
1004 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
1005 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
1006 void SetWindowing(float center, |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
1007 float width) |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
1008 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
1009 { |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
1010 hasWindowing_ = true; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
1011 windowingCenter_ = center; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
1012 windowingWidth_ = width; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
1013 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
1014 EmitMessage(ContentChangedMessage(*this)); |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
1015 } |
338 | 1016 |
1017 | |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1018 Bitmap& LoadText(const Orthanc::Font& font, |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1019 const std::string& utf8) |
343 | 1020 { |
348 | 1021 size_t bitmap = countBitmaps_++; |
1022 | |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1023 std::auto_ptr<AlphaBitmap> alpha(new AlphaBitmap(bitmap, *this)); |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1024 alpha->LoadText(font, utf8); |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1025 |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1026 AlphaBitmap* ptr = alpha.get(); |
348 | 1027 bitmaps_[bitmap] = alpha.release(); |
1028 | |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1029 return *ptr; |
348 | 1030 } |
1031 | |
1032 | |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1033 Bitmap& LoadTestBlock(unsigned int width, |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1034 unsigned int height) |
348 | 1035 { |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1036 size_t bitmap = countBitmaps_++; |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1037 |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1038 std::auto_ptr<AlphaBitmap> alpha(new AlphaBitmap(bitmap, *this)); |
348 | 1039 |
1040 std::auto_ptr<Orthanc::Image> block(new Orthanc::Image(Orthanc::PixelFormat_Grayscale8, width, height, false)); | |
1041 | |
1042 for (unsigned int padding = 0; | |
1043 (width > 2 * padding) && (height > 2 * padding); | |
1044 padding++) | |
1045 { | |
1046 uint8_t color; | |
1047 if (255 > 10 * padding) | |
1048 { | |
1049 color = 255 - 10 * padding; | |
1050 } | |
1051 else | |
1052 { | |
1053 color = 0; | |
1054 } | |
1055 | |
1056 Orthanc::ImageAccessor region; | |
1057 block->GetRegion(region, padding, padding, width - 2 * padding, height - 2 * padding); | |
1058 Orthanc::ImageProcessing::Set(region, color); | |
1059 } | |
1060 | |
1061 alpha->SetAlpha(block.release()); | |
343 | 1062 |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1063 AlphaBitmap* ptr = alpha.get(); |
343 | 1064 bitmaps_[bitmap] = alpha.release(); |
1065 | |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1066 return *ptr; |
343 | 1067 } |
1068 | |
1069 | |
354 | 1070 Bitmap& LoadFrame(const std::string& instance, |
341 | 1071 unsigned int frame, |
1072 bool httpCompression) | |
338 | 1073 { |
341 | 1074 size_t bitmap = countBitmaps_++; |
338 | 1075 |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1076 bitmaps_[bitmap] = new DicomBitmap(bitmap); |
338 | 1077 |
1078 { | |
1079 IWebService::Headers headers; | |
1080 std::string uri = "/instances/" + instance + "/tags"; | |
1081 orthanc_.GetBinaryAsync(uri, headers, | |
1082 new Callable<BitmapStack, OrthancApiClient::BinaryResponseReadyMessage> | |
1083 (*this, &BitmapStack::OnTagsReceived), NULL, | |
341 | 1084 new Orthanc::SingleValueObject<size_t>(bitmap)); |
338 | 1085 } |
1086 | |
1087 { | |
1088 IWebService::Headers headers; | |
1089 headers["Accept"] = "image/x-portable-arbitrarymap"; | |
1090 | |
1091 if (httpCompression) | |
1092 { | |
1093 headers["Accept-Encoding"] = "gzip"; | |
1094 } | |
1095 | |
1096 std::string uri = "/instances/" + instance + "/frames/" + boost::lexical_cast<std::string>(frame) + "/image-uint16"; | |
1097 orthanc_.GetBinaryAsync(uri, headers, | |
1098 new Callable<BitmapStack, OrthancApiClient::BinaryResponseReadyMessage> | |
1099 (*this, &BitmapStack::OnFrameReceived), NULL, | |
341 | 1100 new Orthanc::SingleValueObject<size_t>(bitmap)); |
338 | 1101 } |
1102 | |
354 | 1103 return *bitmaps_[bitmap]; |
338 | 1104 } |
1105 | |
1106 | |
1107 void OnTagsReceived(const OrthancApiClient::BinaryResponseReadyMessage& message) | |
1108 { | |
347
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
1109 size_t index = dynamic_cast<Orthanc::SingleValueObject<size_t>*>(message.Payload.get())->GetValue(); |
338 | 1110 |
341 | 1111 printf("JSON received: [%s] (%ld bytes) for bitmap %ld\n", |
1112 message.Uri.c_str(), message.AnswerSize, index); | |
338 | 1113 |
341 | 1114 Bitmaps::iterator bitmap = bitmaps_.find(index); |
338 | 1115 if (bitmap != bitmaps_.end()) |
1116 { | |
1117 assert(bitmap->second != NULL); | |
1118 | |
1119 OrthancPlugins::FullOrthancDataset dicom(message.Answer, message.AnswerSize); | |
343 | 1120 dynamic_cast<DicomBitmap*>(bitmap->second)->SetDicomTags(dicom); |
338 | 1121 |
1122 float c, w; | |
1123 if (!hasWindowing_ && | |
1124 bitmap->second->GetDefaultWindowing(c, w)) | |
1125 { | |
1126 hasWindowing_ = true; | |
1127 windowingCenter_ = c; | |
1128 windowingWidth_ = w; | |
1129 } | |
1130 | |
1131 EmitMessage(GeometryChangedMessage(*this)); | |
1132 } | |
1133 } | |
1134 | |
1135 | |
1136 void OnFrameReceived(const OrthancApiClient::BinaryResponseReadyMessage& message) | |
1137 { | |
347
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
1138 size_t index = dynamic_cast<Orthanc::SingleValueObject<size_t>*>(message.Payload.get())->GetValue(); |
338 | 1139 |
341 | 1140 printf("Frame received: [%s] (%ld bytes) for bitmap %ld\n", |
1141 message.Uri.c_str(), message.AnswerSize, index); | |
1142 | |
1143 Bitmaps::iterator bitmap = bitmaps_.find(index); | |
338 | 1144 if (bitmap != bitmaps_.end()) |
1145 { | |
1146 assert(bitmap->second != NULL); | |
1147 | |
1148 std::string content; | |
1149 if (message.AnswerSize > 0) | |
1150 { | |
1151 content.assign(reinterpret_cast<const char*>(message.Answer), message.AnswerSize); | |
1152 } | |
1153 | |
1154 std::auto_ptr<Orthanc::PamReader> reader(new Orthanc::PamReader); | |
1155 reader->ReadFromMemory(content); | |
343 | 1156 dynamic_cast<DicomBitmap*>(bitmap->second)->SetSourceImage(reader.release()); |
338 | 1157 |
1158 EmitMessage(ContentChangedMessage(*this)); | |
1159 } | |
1160 } | |
339 | 1161 |
1162 | |
1163 Extent2D GetSceneExtent() const | |
1164 { | |
1165 Extent2D extent; | |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
1166 |
339 | 1167 for (Bitmaps::const_iterator it = bitmaps_.begin(); |
1168 it != bitmaps_.end(); ++it) | |
1169 { | |
1170 assert(it->second != NULL); | |
1171 extent.Union(it->second->GetExtent()); | |
1172 } | |
1173 | |
1174 return extent; | |
1175 } | |
1176 | |
1177 | |
1178 void Render(Orthanc::ImageAccessor& buffer, | |
345 | 1179 const ViewportGeometry& view, |
1180 ImageInterpolation interpolation) const | |
339 | 1181 { |
1182 Orthanc::ImageProcessing::Set(buffer, 0); | |
1183 | |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
1184 // Render layers in the background-to-foreground order |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
1185 for (size_t index = 0; index < countBitmaps_; index++) |
339 | 1186 { |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
1187 Bitmaps::const_iterator it = bitmaps_.find(index); |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
1188 if (it != bitmaps_.end()) |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
1189 { |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
1190 assert(it->second != NULL); |
345 | 1191 it->second->Render(buffer, view, interpolation); |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
1192 } |
339 | 1193 } |
1194 } | |
342 | 1195 |
1196 | |
1197 bool LookupBitmap(size_t& index /* out */, | |
1198 double x, | |
1199 double y) const | |
1200 { | |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
1201 // Render layers in the foreground-to-background order |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
1202 for (size_t i = countBitmaps_; i > 0; i--) |
342 | 1203 { |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
1204 index = i - 1; |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
1205 Bitmaps::const_iterator it = bitmaps_.find(index); |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
1206 if (it != bitmaps_.end()) |
342 | 1207 { |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
1208 assert(it->second != NULL); |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
1209 if (it->second->Contains(x, y)) |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
1210 { |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
1211 return true; |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
1212 } |
342 | 1213 } |
1214 } | |
1215 | |
1216 return false; | |
1217 } | |
1218 | |
345 | 1219 void DrawControls(CairoSurface& surface, |
1220 const ViewportGeometry& view) | |
1221 { | |
1222 if (hasSelection_) | |
1223 { | |
1224 Bitmaps::const_iterator bitmap = bitmaps_.find(selectedBitmap_); | |
1225 | |
1226 if (bitmap != bitmaps_.end()) | |
1227 { | |
1228 CairoContext context(surface); | |
1229 | |
1230 context.SetSourceColor(255, 0, 0); | |
1231 view.ApplyTransform(context); | |
1232 bitmap->second->DrawBorders(context, view.GetZoom()); | |
1233 } | |
1234 } | |
1235 } | |
338 | 1236 }; |
1237 | |
341 | 1238 |
354 | 1239 class UndoRedoStack : public boost::noncopyable |
1240 { | |
1241 public: | |
1242 class ICommand : public boost::noncopyable | |
1243 { | |
1244 public: | |
1245 virtual ~ICommand() | |
1246 { | |
1247 } | |
1248 | |
1249 virtual void Undo() const = 0; | |
1250 | |
1251 virtual void Redo() const = 0; | |
1252 }; | |
1253 | |
1254 private: | |
1255 typedef std::list<ICommand*> Stack; | |
1256 | |
1257 Stack stack_; | |
1258 Stack::iterator current_; | |
1259 | |
1260 void Clear(Stack::iterator from) | |
1261 { | |
1262 for (Stack::iterator it = from; it != stack_.end(); ++it) | |
1263 { | |
1264 assert(*it != NULL); | |
1265 delete *it; | |
1266 } | |
1267 | |
1268 stack_.erase(from, stack_.end()); | |
1269 } | |
1270 | |
1271 public: | |
1272 UndoRedoStack() : | |
1273 current_(stack_.end()) | |
1274 { | |
1275 } | |
1276 | |
1277 ~UndoRedoStack() | |
1278 { | |
1279 Clear(stack_.begin()); | |
1280 } | |
1281 | |
1282 void Add(ICommand* command) | |
1283 { | |
1284 if (command == NULL) | |
1285 { | |
1286 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); | |
1287 } | |
1288 | |
1289 Clear(current_); | |
1290 | |
1291 stack_.push_back(command); | |
1292 current_ = stack_.end(); | |
1293 } | |
1294 | |
1295 void Undo() | |
1296 { | |
1297 if (current_ != stack_.begin()) | |
1298 { | |
1299 --current_; | |
1300 | |
1301 assert(*current_ != NULL); | |
1302 (*current_)->Undo(); | |
1303 } | |
1304 } | |
1305 | |
1306 void Redo() | |
1307 { | |
1308 if (current_ != stack_.end()) | |
1309 { | |
1310 assert(*current_ != NULL); | |
1311 (*current_)->Redo(); | |
1312 | |
1313 ++current_; | |
1314 } | |
1315 } | |
1316 }; | |
1317 | |
1318 | |
1319 class BitmapCommandBase : public UndoRedoStack::ICommand | |
1320 { | |
1321 private: | |
1322 BitmapStack& stack_; | |
1323 size_t bitmap_; | |
1324 | |
1325 protected: | |
1326 virtual void UndoInternal(BitmapStack::Bitmap& bitmap) const = 0; | |
1327 | |
1328 virtual void RedoInternal(BitmapStack::Bitmap& bitmap) const = 0; | |
1329 | |
1330 public: | |
1331 BitmapCommandBase(BitmapStack& stack, | |
1332 size_t bitmap) : | |
1333 stack_(stack), | |
1334 bitmap_(bitmap) | |
1335 { | |
1336 } | |
1337 | |
355
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1338 BitmapCommandBase(const BitmapStack::BitmapAccessor& accessor) : |
354 | 1339 stack_(accessor.GetStack()), |
1340 bitmap_(accessor.GetIndex()) | |
1341 { | |
1342 } | |
1343 | |
1344 virtual void Undo() const | |
1345 { | |
1346 BitmapStack::BitmapAccessor accessor(stack_, bitmap_); | |
1347 | |
1348 if (accessor.IsValid()) | |
1349 { | |
1350 UndoInternal(accessor.GetBitmap()); | |
1351 } | |
1352 } | |
1353 | |
1354 virtual void Redo() const | |
1355 { | |
1356 BitmapStack::BitmapAccessor accessor(stack_, bitmap_); | |
1357 | |
1358 if (accessor.IsValid()) | |
1359 { | |
1360 RedoInternal(accessor.GetBitmap()); | |
1361 } | |
1362 } | |
1363 }; | |
1364 | |
1365 | |
1366 class RotateBitmapTracker : public IWorldSceneMouseTracker | |
1367 { | |
1368 private: | |
1369 UndoRedoStack& undoRedoStack_; | |
1370 BitmapStack::BitmapAccessor accessor_; | |
1371 double centerX_; | |
1372 double centerY_; | |
1373 double originalAngle_; | |
1374 double clickAngle_; | |
1375 bool roundAngles_; | |
1376 | |
1377 bool ComputeAngle(double& angle /* out */, | |
1378 double sceneX, | |
1379 double sceneY) const | |
1380 { | |
1381 Vector u; | |
1382 LinearAlgebra::AssignVector(u, sceneX - centerX_, sceneY - centerY_); | |
1383 | |
1384 double nu = boost::numeric::ublas::norm_2(u); | |
1385 | |
1386 if (!LinearAlgebra::IsCloseToZero(nu)) | |
1387 { | |
1388 u /= nu; | |
1389 angle = atan2(u[1], u[0]); | |
1390 return true; | |
1391 } | |
1392 else | |
1393 { | |
1394 return false; | |
1395 } | |
1396 } | |
1397 | |
1398 | |
1399 class UndoRedoCommand : public BitmapCommandBase | |
1400 { | |
1401 private: | |
1402 double sourceAngle_; | |
1403 double targetAngle_; | |
1404 | |
1405 static int ToDegrees(double angle) | |
1406 { | |
1407 return static_cast<int>(round(angle * 180.0 / boost::math::constants::pi<double>())); | |
1408 } | |
1409 | |
1410 protected: | |
1411 virtual void UndoInternal(BitmapStack::Bitmap& bitmap) const | |
1412 { | |
1413 LOG(INFO) << "Undo - Set angle to " << ToDegrees(sourceAngle_) << " degrees"; | |
1414 bitmap.SetAngle(sourceAngle_); | |
1415 } | |
1416 | |
1417 virtual void RedoInternal(BitmapStack::Bitmap& bitmap) const | |
1418 { | |
1419 LOG(INFO) << "Redo - Set angle to " << ToDegrees(sourceAngle_) << " degrees"; | |
1420 bitmap.SetAngle(targetAngle_); | |
1421 } | |
1422 | |
1423 public: | |
355
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1424 UndoRedoCommand(const RotateBitmapTracker& tracker) : |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1425 BitmapCommandBase(tracker.accessor_), |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1426 sourceAngle_(tracker.originalAngle_), |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1427 targetAngle_(tracker.accessor_.GetBitmap().GetAngle()) |
354 | 1428 { |
1429 } | |
1430 }; | |
1431 | |
1432 | |
1433 public: | |
1434 RotateBitmapTracker(UndoRedoStack& undoRedoStack, | |
1435 BitmapStack& stack, | |
1436 const ViewportGeometry& view, | |
1437 size_t bitmap, | |
1438 double x, | |
1439 double y, | |
1440 bool roundAngles) : | |
1441 undoRedoStack_(undoRedoStack), | |
1442 accessor_(stack, bitmap), | |
1443 roundAngles_(roundAngles) | |
1444 { | |
1445 if (accessor_.IsValid()) | |
1446 { | |
1447 accessor_.GetBitmap().GetCenter(centerX_, centerY_); | |
1448 originalAngle_ = accessor_.GetBitmap().GetAngle(); | |
1449 | |
1450 double sceneX, sceneY; | |
1451 view.MapDisplayToScene(sceneX, sceneY, x, y); | |
1452 | |
1453 if (!ComputeAngle(clickAngle_, x, y)) | |
1454 { | |
1455 accessor_.Invalidate(); | |
1456 } | |
1457 } | |
1458 } | |
1459 | |
1460 virtual bool HasRender() const | |
1461 { | |
1462 return false; | |
1463 } | |
1464 | |
1465 virtual void Render(CairoContext& context, | |
1466 double zoom) | |
1467 { | |
1468 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | |
1469 } | |
1470 | |
1471 virtual void MouseUp() | |
1472 { | |
1473 if (accessor_.IsValid()) | |
1474 { | |
355
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1475 undoRedoStack_.Add(new UndoRedoCommand(*this)); |
354 | 1476 } |
1477 } | |
1478 | |
1479 virtual void MouseMove(int displayX, | |
1480 int displayY, | |
1481 double sceneX, | |
1482 double sceneY) | |
1483 { | |
1484 static const double ROUND_ANGLE = 15.0 / 180.0 * boost::math::constants::pi<double>(); | |
1485 | |
1486 double angle; | |
1487 | |
1488 if (accessor_.IsValid() && | |
1489 ComputeAngle(angle, sceneX, sceneY)) | |
1490 { | |
1491 angle = angle - clickAngle_ + originalAngle_; | |
1492 | |
1493 if (roundAngles_) | |
1494 { | |
1495 angle = round(angle / ROUND_ANGLE) * ROUND_ANGLE; | |
1496 } | |
1497 | |
1498 accessor_.GetBitmap().SetAngle(angle); | |
1499 } | |
1500 } | |
1501 }; | |
1502 | |
1503 | |
1504 class MoveBitmapTracker : public IWorldSceneMouseTracker | |
1505 { | |
1506 private: | |
1507 UndoRedoStack& undoRedoStack_; | |
1508 BitmapStack::BitmapAccessor accessor_; | |
1509 double clickX_; | |
1510 double clickY_; | |
1511 double panX_; | |
1512 double panY_; | |
1513 bool oneAxis_; | |
1514 | |
1515 class UndoRedoCommand : public BitmapCommandBase | |
1516 { | |
1517 private: | |
1518 double sourceX_; | |
1519 double sourceY_; | |
1520 double targetX_; | |
1521 double targetY_; | |
1522 | |
1523 protected: | |
1524 virtual void UndoInternal(BitmapStack::Bitmap& bitmap) const | |
1525 { | |
1526 bitmap.SetPan(sourceX_, sourceY_); | |
1527 } | |
1528 | |
1529 virtual void RedoInternal(BitmapStack::Bitmap& bitmap) const | |
1530 { | |
1531 bitmap.SetPan(targetX_, targetY_); | |
1532 } | |
1533 | |
1534 public: | |
355
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1535 UndoRedoCommand(const MoveBitmapTracker& tracker) : |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1536 BitmapCommandBase(tracker.accessor_), |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1537 sourceX_(tracker.panX_), |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1538 sourceY_(tracker.panY_), |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1539 targetX_(tracker.accessor_.GetBitmap().GetPanX()), |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1540 targetY_(tracker.accessor_.GetBitmap().GetPanY()) |
354 | 1541 { |
1542 } | |
1543 }; | |
1544 | |
1545 | |
1546 public: | |
1547 MoveBitmapTracker(UndoRedoStack& undoRedoStack, | |
1548 BitmapStack& stack, | |
1549 size_t bitmap, | |
1550 double x, | |
1551 double y, | |
1552 bool oneAxis) : | |
1553 undoRedoStack_(undoRedoStack), | |
1554 accessor_(stack, bitmap), | |
1555 clickX_(x), | |
1556 clickY_(y), | |
1557 oneAxis_(oneAxis) | |
1558 { | |
1559 if (accessor_.IsValid()) | |
1560 { | |
1561 panX_ = accessor_.GetBitmap().GetPanX(); | |
1562 panY_ = accessor_.GetBitmap().GetPanY(); | |
1563 } | |
1564 } | |
1565 | |
1566 virtual bool HasRender() const | |
1567 { | |
1568 return false; | |
1569 } | |
1570 | |
1571 virtual void Render(CairoContext& context, | |
1572 double zoom) | |
1573 { | |
1574 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | |
1575 } | |
1576 | |
1577 virtual void MouseUp() | |
1578 { | |
1579 if (accessor_.IsValid()) | |
1580 { | |
355
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1581 undoRedoStack_.Add(new UndoRedoCommand(*this)); |
354 | 1582 } |
1583 } | |
1584 | |
1585 virtual void MouseMove(int displayX, | |
1586 int displayY, | |
1587 double sceneX, | |
1588 double sceneY) | |
1589 { | |
1590 if (accessor_.IsValid()) | |
1591 { | |
1592 double dx = sceneX - clickX_; | |
1593 double dy = sceneY - clickY_; | |
1594 | |
1595 if (oneAxis_) | |
1596 { | |
1597 if (fabs(dx) > fabs(dy)) | |
1598 { | |
1599 accessor_.GetBitmap().SetPan(dx + panX_, panY_); | |
1600 } | |
1601 else | |
1602 { | |
1603 accessor_.GetBitmap().SetPan(panX_, dy + panY_); | |
1604 } | |
1605 } | |
1606 else | |
1607 { | |
1608 accessor_.GetBitmap().SetPan(dx + panX_, dy + panY_); | |
1609 } | |
1610 } | |
1611 } | |
1612 }; | |
1613 | |
1614 | |
1615 class CropBitmapTracker : public IWorldSceneMouseTracker | |
1616 { | |
1617 private: | |
355
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1618 UndoRedoStack& undoRedoStack_; |
354 | 1619 BitmapStack::BitmapAccessor accessor_; |
1620 BitmapStack::Corner corner_; | |
1621 unsigned int cropX_; | |
1622 unsigned int cropY_; | |
1623 unsigned int cropWidth_; | |
1624 unsigned int cropHeight_; | |
1625 | |
355
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1626 class UndoRedoCommand : public BitmapCommandBase |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1627 { |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1628 private: |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1629 unsigned int sourceCropX_; |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1630 unsigned int sourceCropY_; |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1631 unsigned int sourceCropWidth_; |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1632 unsigned int sourceCropHeight_; |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1633 unsigned int targetCropX_; |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1634 unsigned int targetCropY_; |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1635 unsigned int targetCropWidth_; |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1636 unsigned int targetCropHeight_; |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1637 |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1638 protected: |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1639 virtual void UndoInternal(BitmapStack::Bitmap& bitmap) const |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1640 { |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1641 bitmap.SetCrop(sourceCropX_, sourceCropY_, sourceCropWidth_, sourceCropHeight_); |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1642 } |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1643 |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1644 virtual void RedoInternal(BitmapStack::Bitmap& bitmap) const |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1645 { |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1646 bitmap.SetCrop(targetCropX_, targetCropY_, targetCropWidth_, targetCropHeight_); |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1647 } |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1648 |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1649 public: |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1650 UndoRedoCommand(const CropBitmapTracker& tracker) : |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1651 BitmapCommandBase(tracker.accessor_), |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1652 sourceCropX_(tracker.cropX_), |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1653 sourceCropY_(tracker.cropY_), |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1654 sourceCropWidth_(tracker.cropWidth_), |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1655 sourceCropHeight_(tracker.cropHeight_) |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1656 { |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1657 tracker.accessor_.GetBitmap().GetCrop(targetCropX_, targetCropY_, |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1658 targetCropWidth_, targetCropHeight_); |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1659 } |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1660 }; |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1661 |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1662 |
354 | 1663 public: |
355
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1664 CropBitmapTracker(UndoRedoStack& undoRedoStack, |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1665 BitmapStack& stack, |
354 | 1666 const ViewportGeometry& view, |
1667 size_t bitmap, | |
1668 double x, | |
1669 double y, | |
1670 BitmapStack::Corner corner) : | |
355
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1671 undoRedoStack_(undoRedoStack), |
354 | 1672 accessor_(stack, bitmap), |
1673 corner_(corner) | |
1674 { | |
1675 if (accessor_.IsValid()) | |
1676 { | |
1677 accessor_.GetBitmap().GetCrop(cropX_, cropY_, cropWidth_, cropHeight_); | |
1678 } | |
1679 } | |
1680 | |
1681 virtual bool HasRender() const | |
1682 { | |
1683 return false; | |
1684 } | |
1685 | |
1686 virtual void Render(CairoContext& context, | |
1687 double zoom) | |
1688 { | |
1689 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | |
1690 } | |
1691 | |
1692 virtual void MouseUp() | |
1693 { | |
355
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1694 if (accessor_.IsValid()) |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1695 { |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1696 undoRedoStack_.Add(new UndoRedoCommand(*this)); |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1697 } |
354 | 1698 } |
1699 | |
1700 virtual void MouseMove(int displayX, | |
1701 int displayY, | |
1702 double sceneX, | |
1703 double sceneY) | |
1704 { | |
1705 if (accessor_.IsValid()) | |
1706 { | |
1707 unsigned int x, y; | |
1708 | |
1709 BitmapStack::Bitmap& bitmap = accessor_.GetBitmap(); | |
1710 if (bitmap.GetPixel(x, y, sceneX, sceneY)) | |
1711 { | |
1712 unsigned int targetX, targetWidth; | |
1713 | |
1714 if (corner_ == BitmapStack::Corner_TopLeft || | |
1715 corner_ == BitmapStack::Corner_BottomLeft) | |
1716 { | |
1717 targetX = std::min(x, cropX_ + cropWidth_); | |
1718 targetWidth = cropX_ + cropWidth_ - targetX; | |
1719 } | |
1720 else | |
1721 { | |
1722 targetX = cropX_; | |
1723 targetWidth = std::max(x, cropX_) - cropX_; | |
1724 } | |
1725 | |
1726 unsigned int targetY, targetHeight; | |
1727 | |
1728 if (corner_ == BitmapStack::Corner_TopLeft || | |
1729 corner_ == BitmapStack::Corner_TopRight) | |
1730 { | |
1731 targetY = std::min(y, cropY_ + cropHeight_); | |
1732 targetHeight = cropY_ + cropHeight_ - targetY; | |
1733 } | |
1734 else | |
1735 { | |
1736 targetY = cropY_; | |
1737 targetHeight = std::max(y, cropY_) - cropY_; | |
1738 } | |
1739 | |
1740 bitmap.SetCrop(targetX, targetY, targetWidth, targetHeight); | |
1741 } | |
1742 } | |
1743 } | |
1744 }; | |
1745 | |
1746 | |
1747 class ResizeBitmapTracker : public IWorldSceneMouseTracker | |
1748 { | |
1749 private: | |
355
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1750 UndoRedoStack& undoRedoStack_; |
354 | 1751 BitmapStack::BitmapAccessor accessor_; |
1752 bool roundScaling_; | |
1753 double originalSpacingX_; | |
1754 double originalSpacingY_; | |
355
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1755 double originalPanX_; |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1756 double originalPanY_; |
354 | 1757 BitmapStack::Corner oppositeCorner_; |
1758 double oppositeX_; | |
1759 double oppositeY_; | |
1760 double baseScaling_; | |
1761 | |
1762 static double ComputeDistance(double x1, | |
1763 double y1, | |
1764 double x2, | |
1765 double y2) | |
1766 { | |
1767 double dx = x1 - x2; | |
1768 double dy = y1 - y2; | |
1769 return sqrt(dx * dx + dy * dy); | |
1770 } | |
1771 | |
355
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1772 class UndoRedoCommand : public BitmapCommandBase |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1773 { |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1774 private: |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1775 double sourceSpacingX_; |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1776 double sourceSpacingY_; |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1777 double sourcePanX_; |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1778 double sourcePanY_; |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1779 double targetSpacingX_; |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1780 double targetSpacingY_; |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1781 double targetPanX_; |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1782 double targetPanY_; |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1783 |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1784 protected: |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1785 virtual void UndoInternal(BitmapStack::Bitmap& bitmap) const |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1786 { |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1787 bitmap.SetPixelSpacing(sourceSpacingX_, sourceSpacingY_); |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1788 bitmap.SetPan(sourcePanX_, sourcePanY_); |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1789 } |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1790 |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1791 virtual void RedoInternal(BitmapStack::Bitmap& bitmap) const |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1792 { |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1793 bitmap.SetPixelSpacing(targetSpacingX_, targetSpacingY_); |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1794 bitmap.SetPan(targetPanX_, targetPanY_); |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1795 } |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1796 |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1797 public: |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1798 UndoRedoCommand(const ResizeBitmapTracker& tracker) : |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1799 BitmapCommandBase(tracker.accessor_), |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1800 sourceSpacingX_(tracker.originalSpacingX_), |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1801 sourceSpacingY_(tracker.originalSpacingY_), |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1802 sourcePanX_(tracker.originalPanX_), |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1803 sourcePanY_(tracker.originalPanY_), |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1804 targetSpacingX_(tracker.accessor_.GetBitmap().GetPixelSpacingX()), |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1805 targetSpacingY_(tracker.accessor_.GetBitmap().GetPixelSpacingY()), |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1806 targetPanX_(tracker.accessor_.GetBitmap().GetPanX()), |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1807 targetPanY_(tracker.accessor_.GetBitmap().GetPanY()) |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1808 { |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1809 } |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1810 }; |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1811 |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1812 |
354 | 1813 public: |
355
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1814 ResizeBitmapTracker(UndoRedoStack& undoRedoStack, |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1815 BitmapStack& stack, |
354 | 1816 size_t bitmap, |
1817 double x, | |
1818 double y, | |
1819 BitmapStack::Corner corner, | |
1820 bool roundScaling) : | |
355
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1821 undoRedoStack_(undoRedoStack), |
354 | 1822 accessor_(stack, bitmap), |
1823 roundScaling_(roundScaling) | |
1824 { | |
1825 if (accessor_.IsValid() && | |
1826 accessor_.GetBitmap().IsResizeable()) | |
1827 { | |
1828 originalSpacingX_ = accessor_.GetBitmap().GetPixelSpacingX(); | |
1829 originalSpacingY_ = accessor_.GetBitmap().GetPixelSpacingY(); | |
355
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1830 originalPanX_ = accessor_.GetBitmap().GetPanX(); |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1831 originalPanY_ = accessor_.GetBitmap().GetPanY(); |
354 | 1832 |
1833 switch (corner) | |
1834 { | |
1835 case BitmapStack::Corner_TopLeft: | |
1836 oppositeCorner_ = BitmapStack::Corner_BottomRight; | |
1837 break; | |
1838 | |
1839 case BitmapStack::Corner_TopRight: | |
1840 oppositeCorner_ = BitmapStack::Corner_BottomLeft; | |
1841 break; | |
1842 | |
1843 case BitmapStack::Corner_BottomLeft: | |
1844 oppositeCorner_ = BitmapStack::Corner_TopRight; | |
1845 break; | |
1846 | |
1847 case BitmapStack::Corner_BottomRight: | |
1848 oppositeCorner_ = BitmapStack::Corner_TopLeft; | |
1849 break; | |
1850 | |
1851 default: | |
1852 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | |
1853 } | |
1854 | |
1855 accessor_.GetBitmap().GetCorner(oppositeX_, oppositeY_, oppositeCorner_); | |
1856 | |
1857 double d = ComputeDistance(x, y, oppositeX_, oppositeY_); | |
1858 if (d >= std::numeric_limits<float>::epsilon()) | |
1859 { | |
1860 baseScaling_ = 1.0 / d; | |
1861 } | |
1862 else | |
1863 { | |
1864 // Avoid division by zero in extreme cases | |
1865 accessor_.Invalidate(); | |
1866 } | |
1867 } | |
1868 } | |
1869 | |
1870 virtual bool HasRender() const | |
1871 { | |
1872 return false; | |
1873 } | |
1874 | |
1875 virtual void Render(CairoContext& context, | |
1876 double zoom) | |
1877 { | |
1878 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | |
1879 } | |
1880 | |
1881 virtual void MouseUp() | |
1882 { | |
355
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1883 if (accessor_.IsValid()) |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1884 { |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1885 undoRedoStack_.Add(new UndoRedoCommand(*this)); |
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1886 } |
354 | 1887 } |
1888 | |
1889 virtual void MouseMove(int displayX, | |
1890 int displayY, | |
1891 double sceneX, | |
1892 double sceneY) | |
1893 { | |
1894 static const double ROUND_SCALING = 0.1; | |
1895 | |
1896 if (accessor_.IsValid() && | |
1897 accessor_.GetBitmap().IsResizeable()) | |
1898 { | |
1899 double scaling = ComputeDistance(oppositeX_, oppositeY_, sceneX, sceneY) * baseScaling_; | |
1900 | |
1901 if (roundScaling_) | |
1902 { | |
1903 scaling = round(scaling / ROUND_SCALING) * ROUND_SCALING; | |
1904 } | |
1905 | |
1906 BitmapStack::Bitmap& bitmap = accessor_.GetBitmap(); | |
1907 bitmap.SetPixelSpacing(scaling * originalSpacingX_, | |
1908 scaling * originalSpacingY_); | |
1909 | |
1910 // Keep the opposite corner at a fixed location | |
1911 double ox, oy; | |
1912 bitmap.GetCorner(ox, oy, oppositeCorner_); | |
1913 bitmap.SetPan(bitmap.GetPanX() + oppositeX_ - ox, | |
1914 bitmap.GetPanY() + oppositeY_ - oy); | |
1915 } | |
1916 } | |
1917 }; | |
1918 | |
1919 | |
341 | 1920 class BitmapStackInteractor : public IWorldSceneInteractor |
1921 { | |
342 | 1922 private: |
347
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
1923 enum Tool |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
1924 { |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
1925 Tool_Move, |
350
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
1926 Tool_Rotate, |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1927 Tool_Crop, |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1928 Tool_Resize |
347
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
1929 }; |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
1930 |
351
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
1931 static double GetHandleSize() |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
1932 { |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
1933 return 10.0; |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
1934 } |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
1935 |
342 | 1936 |
354 | 1937 BitmapStack& stack_; |
1938 UndoRedoStack undoRedoStack_; | |
1939 Tool tool_; | |
347
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
1940 |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1941 |
341 | 1942 public: |
342 | 1943 BitmapStackInteractor(BitmapStack& stack) : |
347
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
1944 stack_(stack), |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1945 tool_(Tool_Move) |
342 | 1946 { |
1947 } | |
1948 | |
341 | 1949 virtual IWorldSceneMouseTracker* CreateMouseTracker(WorldSceneWidget& widget, |
1950 const ViewportGeometry& view, | |
1951 MouseButton button, | |
1952 KeyboardModifiers modifiers, | |
1953 double x, | |
1954 double y, | |
1955 IStatusBar* statusBar) | |
1956 { | |
342 | 1957 if (button == MouseButton_Left) |
1958 { | |
351
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
1959 size_t selected; |
346 | 1960 |
351
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
1961 if (!stack_.GetSelectedBitmap(selected)) |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
1962 { |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
1963 size_t bitmap; |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
1964 if (stack_.LookupBitmap(bitmap, x, y)) |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
1965 { |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
1966 printf("CLICK on bitmap %ld\n", bitmap); |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
1967 stack_.Select(bitmap); |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
1968 } |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
1969 |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
1970 return NULL; |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
1971 } |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1972 else if (tool_ == Tool_Crop || |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1973 tool_ == Tool_Resize) |
342 | 1974 { |
351
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
1975 BitmapStack::BitmapAccessor accessor(stack_, selected); |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
1976 BitmapStack::Corner corner; |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
1977 if (accessor.GetBitmap().LookupCorner(corner, x, y, view.GetZoom(), GetHandleSize())) |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
1978 { |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1979 switch (tool_) |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1980 { |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1981 case Tool_Crop: |
355
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1982 return new CropBitmapTracker(undoRedoStack_, stack_, view, selected, x, y, corner); |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1983 |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1984 case Tool_Resize: |
355
d2468dd75b3f
undo redo for all tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
1985 return new ResizeBitmapTracker(undoRedoStack_, stack_, selected, x, y, corner, |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1986 (modifiers & KeyboardModifiers_Shift)); |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1987 |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1988 default: |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1989 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
1990 } |
351
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
1991 } |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
1992 else |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
1993 { |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
1994 size_t bitmap; |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
1995 |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
1996 if (!stack_.LookupBitmap(bitmap, x, y) || |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
1997 bitmap != selected) |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
1998 { |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
1999 stack_.Unselect(); |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
2000 } |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
2001 |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
2002 return NULL; |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
2003 } |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
2004 } |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
2005 else |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
2006 { |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
2007 size_t bitmap; |
346 | 2008 |
351
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
2009 if (stack_.LookupBitmap(bitmap, x, y) && |
346 | 2010 bitmap == selected) |
2011 { | |
347
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
2012 switch (tool_) |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
2013 { |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
2014 case Tool_Move: |
354 | 2015 return new MoveBitmapTracker(undoRedoStack_, stack_, bitmap, x, y, |
347
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
2016 (modifiers & KeyboardModifiers_Shift)); |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
2017 |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
2018 case Tool_Rotate: |
354 | 2019 return new RotateBitmapTracker(undoRedoStack_, stack_, view, bitmap, x, y, |
347
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
2020 (modifiers & KeyboardModifiers_Shift)); |
351
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
2021 |
347
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
2022 default: |
351
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
2023 break; |
347
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
2024 } |
351
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
2025 |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
2026 return NULL; |
346 | 2027 } |
2028 else | |
2029 { | |
351
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
2030 printf("CLICK outside\n"); |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
2031 stack_.Unselect(); |
346 | 2032 return NULL; |
2033 } | |
342 | 2034 } |
2035 } | |
2036 else | |
2037 { | |
2038 return NULL; | |
2039 } | |
341 | 2040 } |
2041 | |
2042 virtual void MouseOver(CairoContext& context, | |
2043 WorldSceneWidget& widget, | |
2044 const ViewportGeometry& view, | |
2045 double x, | |
2046 double y, | |
2047 IStatusBar* statusBar) | |
2048 { | |
350
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
2049 size_t selected; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
2050 if (stack_.GetSelectedBitmap(selected) && |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
2051 (tool_ == Tool_Crop || |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
2052 tool_ == Tool_Resize)) |
350
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
2053 { |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
2054 BitmapStack::BitmapAccessor accessor(stack_, selected); |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
2055 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
2056 BitmapStack::Corner corner; |
351
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
2057 if (accessor.GetBitmap().LookupCorner(corner, x, y, view.GetZoom(), GetHandleSize())) |
350
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
2058 { |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
2059 accessor.GetBitmap().GetCorner(x, y, corner); |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
2060 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
2061 double z = 1.0 / view.GetZoom(); |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
2062 |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
2063 context.SetSourceColor(255, 0, 0); |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
2064 cairo_t* cr = context.GetObject(); |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
2065 cairo_set_line_width(cr, 2.0 * z); |
351
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
2066 cairo_move_to(cr, x - GetHandleSize() * z, y - GetHandleSize() * z); |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
2067 cairo_line_to(cr, x + GetHandleSize() * z, y - GetHandleSize() * z); |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
2068 cairo_line_to(cr, x + GetHandleSize() * z, y + GetHandleSize() * z); |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
2069 cairo_line_to(cr, x - GetHandleSize() * z, y + GetHandleSize() * z); |
da25d2423314
CornerBitmapTracker to crop images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
350
diff
changeset
|
2070 cairo_line_to(cr, x - GetHandleSize() * z, y - GetHandleSize() * z); |
350
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
2071 cairo_stroke(cr); |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
2072 } |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
2073 } |
341 | 2074 } |
2075 | |
2076 virtual void MouseWheel(WorldSceneWidget& widget, | |
2077 MouseWheelDirection direction, | |
2078 KeyboardModifiers modifiers, | |
2079 IStatusBar* statusBar) | |
2080 { | |
2081 } | |
2082 | |
2083 virtual void KeyPressed(WorldSceneWidget& widget, | |
2084 KeyboardKeys key, | |
2085 char keyChar, | |
2086 KeyboardModifiers modifiers, | |
2087 IStatusBar* statusBar) | |
2088 { | |
347
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
2089 switch (keyChar) |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
2090 { |
350
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
2091 case 'c': |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
2092 tool_ = Tool_Crop; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
2093 break; |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
2094 |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
2095 case 'a': |
347
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
2096 widget.FitContent(); |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
2097 break; |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
2098 |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
2099 case 'm': |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
2100 tool_ = Tool_Move; |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
2101 break; |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
2102 |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
2103 case 'r': |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
2104 tool_ = Tool_Rotate; |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
2105 break; |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
2106 |
352
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
2107 case 's': |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
2108 tool_ = Tool_Resize; |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
2109 break; |
d95e65ebe0b9
ResizeBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
351
diff
changeset
|
2110 |
354 | 2111 case 'z': |
2112 if (modifiers & KeyboardModifiers_Control) | |
2113 { | |
2114 undoRedoStack_.Undo(); | |
2115 widget.NotifyContentChanged(); | |
2116 } | |
2117 break; | |
2118 | |
2119 case 'y': | |
2120 if (modifiers & KeyboardModifiers_Control) | |
2121 { | |
2122 undoRedoStack_.Redo(); | |
2123 widget.NotifyContentChanged(); | |
2124 } | |
2125 break; | |
2126 | |
347
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
2127 default: |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
2128 break; |
cd65103c9172
RotateBitmapTracker
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
346
diff
changeset
|
2129 } |
341 | 2130 } |
2131 }; | |
2132 | |
2133 | |
338 | 2134 |
2135 class BitmapStackWidget : | |
2136 public WorldSceneWidget, | |
2137 public IObservable, | |
2138 public IObserver | |
2139 { | |
2140 private: | |
341 | 2141 BitmapStack& stack_; |
2142 BitmapStackInteractor myInteractor_; | |
337 | 2143 |
336
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
2144 protected: |
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
2145 virtual Extent2D GetSceneExtent() |
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
2146 { |
339 | 2147 return stack_.GetSceneExtent(); |
336
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
2148 } |
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
2149 |
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
2150 virtual bool RenderScene(CairoContext& context, |
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
2151 const ViewportGeometry& view) |
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
2152 { |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2153 // "Render()" has been replaced |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2154 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2155 } |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2156 |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2157 public: |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2158 BitmapStackWidget(MessageBroker& broker, |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2159 BitmapStack& stack, |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2160 const std::string& name) : |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2161 WorldSceneWidget(name), |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2162 IObservable(broker), |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2163 IObserver(broker), |
342 | 2164 stack_(stack), |
2165 myInteractor_(stack_) | |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2166 { |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2167 stack.RegisterObserverCallback(new Callable<BitmapStackWidget, BitmapStack::GeometryChangedMessage>(*this, &BitmapStackWidget::OnGeometryChanged)); |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2168 stack.RegisterObserverCallback(new Callable<BitmapStackWidget, BitmapStack::ContentChangedMessage>(*this, &BitmapStackWidget::OnContentChanged)); |
341 | 2169 |
2170 SetInteractor(myInteractor_); | |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2171 } |
339 | 2172 |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2173 void OnGeometryChanged(const BitmapStack::GeometryChangedMessage& message) |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2174 { |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2175 printf("Geometry has changed\n"); |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2176 FitContent(); |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2177 } |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2178 |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2179 void OnContentChanged(const BitmapStack::ContentChangedMessage& message) |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2180 { |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2181 printf("Content has changed\n"); |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2182 NotifyContentChanged(); |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2183 } |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2184 |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2185 virtual bool Render(Orthanc::ImageAccessor& target) |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2186 { |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
2187 Orthanc::Image buffer(Orthanc::PixelFormat_Float32, target.GetWidth(), |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
2188 target.GetHeight(), false); |
345 | 2189 |
2190 // TODO => rendering quality | |
348 | 2191 stack_.Render(buffer, GetView(), ImageInterpolation_Nearest); |
2192 //stack_.Render(buffer, GetView(), ImageInterpolation_Bilinear); | |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2193 |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
2194 // As in GrayscaleFrameRenderer => TODO MERGE? |
339 | 2195 |
2196 float windowCenter, windowWidth; | |
343 | 2197 if (!stack_.GetWindowing(windowCenter, windowWidth)) |
2198 { | |
2199 windowCenter = 128; | |
2200 windowWidth = 256; | |
2201 } | |
339 | 2202 |
2203 float x0 = windowCenter - windowWidth / 2.0f; | |
2204 float x1 = windowCenter + windowWidth / 2.0f; | |
2205 | |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
2206 if (windowWidth >= 0.001f) // Avoid division by zero at (*) |
339 | 2207 { |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
2208 const unsigned int width = target.GetWidth(); |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
2209 const unsigned int height = target.GetHeight(); |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
2210 |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
2211 for (unsigned int y = 0; y < height; y++) |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
2212 { |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
2213 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
|
2214 uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y)); |
339 | 2215 |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
2216 for (unsigned int x = 0; x < width; x++, p++, q += 4) |
339 | 2217 { |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
2218 uint8_t v = 0; |
339 | 2219 if (*p >= x1) |
2220 { | |
2221 v = 255; | |
2222 } | |
2223 else if (*p <= x0) | |
2224 { | |
2225 v = 0; | |
2226 } | |
2227 else | |
2228 { | |
2229 // https://en.wikipedia.org/wiki/Linear_interpolation | |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
2230 v = static_cast<uint8_t>(255.0f * (*p - x0) / (x1 - x0)); // (*) |
339 | 2231 } |
2232 | |
2233 // TODO MONOCHROME1 | |
2234 /*if (invert_) | |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2235 { |
339 | 2236 v = 255 - v; |
2237 }*/ | |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
2238 |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
2239 q[0] = v; |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
2240 q[1] = v; |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
2241 q[2] = v; |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
2242 q[3] = 255; |
339 | 2243 } |
2244 } | |
2245 } | |
344
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
2246 else |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
2247 { |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
2248 Orthanc::ImageProcessing::Set(target, 0, 0, 0, 255); |
fdec8e6893cb
ordering of bitmap layers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
343
diff
changeset
|
2249 } |
339 | 2250 |
345 | 2251 { |
2252 // TODO => REFACTOR | |
2253 CairoSurface surface(target); | |
2254 stack_.DrawControls(surface, GetView()); | |
2255 } | |
2256 | |
337 | 2257 return true; |
336
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
2258 } |
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
2259 |
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
2260 }; |
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
2261 |
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
2262 |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2263 namespace Samples |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2264 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2265 class SingleFrameEditorApplication : |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2266 public SampleSingleCanvasApplicationBase, |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2267 public IObserver |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2268 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2269 enum Tools |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2270 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2271 Tools_Crop, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2272 Tools_Windowing, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2273 Tools_Zoom, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2274 Tools_Pan |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2275 }; |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2276 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2277 enum Actions |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2278 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2279 Actions_Invert, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2280 Actions_RotateLeft, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2281 Actions_RotateRight |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2282 }; |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2283 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2284 private: |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2285 class Interactor : public IWorldSceneInteractor |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2286 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2287 private: |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2288 SingleFrameEditorApplication& application_; |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2289 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2290 public: |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2291 Interactor(SingleFrameEditorApplication& application) : |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2292 application_(application) |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2293 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2294 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2295 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2296 virtual IWorldSceneMouseTracker* CreateMouseTracker(WorldSceneWidget& widget, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2297 const ViewportGeometry& view, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2298 MouseButton button, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2299 KeyboardModifiers modifiers, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2300 double x, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2301 double y, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2302 IStatusBar* statusBar) |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2303 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2304 switch (application_.currentTool_) { |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2305 case Tools_Zoom: |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2306 printf("ZOOM\n"); |
329
b10dfdb96866
removing WorldSceneWidget::IWorldObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
327
diff
changeset
|
2307 |
b10dfdb96866
removing WorldSceneWidget::IWorldObserver
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
327
diff
changeset
|
2308 case Tools_Crop: |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2309 case Tools_Windowing: |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2310 case Tools_Pan: |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2311 // TODO return the right mouse tracker |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2312 return NULL; |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2313 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2314 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2315 return NULL; |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2316 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2317 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2318 virtual void MouseOver(CairoContext& context, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2319 WorldSceneWidget& widget, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2320 const ViewportGeometry& view, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2321 double x, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2322 double y, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2323 IStatusBar* statusBar) |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2324 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2325 if (statusBar != NULL) |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2326 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2327 char buf[64]; |
336
c7fdc8bac581
creating GrayscaleBitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
334
diff
changeset
|
2328 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
|
2329 statusBar->SetMessage(buf); |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2330 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2331 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2332 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2333 virtual void MouseWheel(WorldSceneWidget& widget, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2334 MouseWheelDirection direction, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2335 KeyboardModifiers modifiers, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2336 IStatusBar* statusBar) |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2337 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2338 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2339 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2340 virtual void KeyPressed(WorldSceneWidget& widget, |
327 | 2341 KeyboardKeys key, |
2342 char keyChar, | |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2343 KeyboardModifiers modifiers, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2344 IStatusBar* statusBar) |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2345 { |
327 | 2346 switch (keyChar) |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2347 { |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2348 case 's': |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2349 widget.FitContent(); |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2350 break; |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2351 case 'p': |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2352 application_.currentTool_ = Tools_Pan; |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2353 break; |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2354 case 'z': |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2355 application_.currentTool_ = Tools_Zoom; |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2356 break; |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2357 case 'c': |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2358 application_.currentTool_ = Tools_Crop; |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2359 break; |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2360 case 'w': |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2361 application_.currentTool_ = Tools_Windowing; |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2362 break; |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2363 case 'i': |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2364 application_.Invert(); |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2365 break; |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2366 case 'r': |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2367 if (modifiers == KeyboardModifiers_None) |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2368 application_.Rotate(90); |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2369 else |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2370 application_.Rotate(-90); |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2371 break; |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2372 case 'e': |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2373 application_.Export(); |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2374 break; |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2375 default: |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2376 break; |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2377 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2378 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2379 }; |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2380 |
334
c34784e5f299
compatibility fixes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
330
diff
changeset
|
2381 std::auto_ptr<Interactor> mainWidgetInteractor_; |
c34784e5f299
compatibility fixes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
330
diff
changeset
|
2382 std::auto_ptr<OrthancApiClient> orthancApiClient_; |
338 | 2383 std::auto_ptr<BitmapStack> stack_; |
334
c34784e5f299
compatibility fixes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
330
diff
changeset
|
2384 Tools currentTool_; |
c34784e5f299
compatibility fixes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
330
diff
changeset
|
2385 const OrthancFrameLayerSource* source_; |
c34784e5f299
compatibility fixes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
330
diff
changeset
|
2386 unsigned int slice_; |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2387 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2388 public: |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2389 SingleFrameEditorApplication(MessageBroker& broker) : |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2390 IObserver(broker), |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2391 currentTool_(Tools_Zoom), |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2392 source_(NULL), |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2393 slice_(0) |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2394 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2395 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2396 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2397 virtual void DeclareStartupOptions(boost::program_options::options_description& options) |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2398 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2399 boost::program_options::options_description generic("Sample options"); |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2400 generic.add_options() |
340
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2401 ("instance", boost::program_options::value<std::string>(), |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2402 "Orthanc ID of the instance") |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2403 ("frame", boost::program_options::value<unsigned int>()->default_value(0), |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2404 "Number of the frame, for multi-frame DICOM instances") |
f5d5814a41a0
rendering BitmapStack
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
339
diff
changeset
|
2405 ; |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2406 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2407 options.add(generic); |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2408 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2409 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2410 virtual void Initialize(StoneApplicationContext* context, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2411 IStatusBar& statusBar, |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2412 const boost::program_options::variables_map& parameters) |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2413 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2414 using namespace OrthancStone; |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2415 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2416 context_ = context; |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2417 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2418 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
|
2419 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2420 if (parameters.count("instance") != 1) |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2421 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2422 LOG(ERROR) << "The instance ID is missing"; |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2423 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2424 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2425 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2426 std::string instance = parameters["instance"].as<std::string>(); |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2427 int frame = parameters["frame"].as<unsigned int>(); |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2428 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2429 orthancApiClient_.reset(new OrthancApiClient(IObserver::broker_, context_->GetWebService())); |
337 | 2430 |
343 | 2431 Orthanc::FontRegistry fonts; |
2432 fonts.AddFromResource(Orthanc::EmbeddedResources::FONT_UBUNTU_MONO_BOLD_16); | |
2433 | |
338 | 2434 stack_.reset(new BitmapStack(IObserver::broker_, *orthancApiClient_)); |
354 | 2435 //stack_->LoadFrame(instance, frame, false); |
2436 //stack_->LoadFrame("61f3143e-96f34791-ad6bbb8d-62559e75-45943e1b", frame, false); | |
2437 | |
2438 { | |
2439 BitmapStack::Bitmap& bitmap = stack_->LoadText(fonts.GetFont(0), "Hello\nworld\nBonjour, Alain"); | |
2440 dynamic_cast<BitmapStack::AlphaBitmap&>(bitmap).SetForegroundValue(256); | |
2441 dynamic_cast<BitmapStack::AlphaBitmap&>(bitmap).SetResizeable(true); | |
2442 } | |
2443 | |
2444 { | |
2445 BitmapStack::Bitmap& bitmap = stack_->LoadTestBlock(100, 50); | |
2446 dynamic_cast<BitmapStack::AlphaBitmap&>(bitmap).SetForegroundValue(256); | |
2447 dynamic_cast<BitmapStack::AlphaBitmap&>(bitmap).SetResizeable(true); | |
2448 } | |
2449 | |
337 | 2450 |
338 | 2451 mainWidget_ = new BitmapStackWidget(IObserver::broker_, *stack_, "main-widget"); |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2452 mainWidget_->SetTransmitMouseOver(true); |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2453 |
350
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
2454 //stack_->SetWindowing(128, 256); |
c57e049ed079
drawing corners for cropping
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
348
diff
changeset
|
2455 |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2456 mainWidgetInteractor_.reset(new Interactor(*this)); |
341 | 2457 //mainWidget_->SetInteractor(*mainWidgetInteractor_); |
325
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2458 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2459 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2460 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2461 void Invert() |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2462 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2463 // TODO |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2464 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2465 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2466 void Rotate(int degrees) |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2467 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2468 // TODO |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2469 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2470 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2471 void Export() |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2472 { |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2473 // TODO: export dicom file to a temporary file |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2474 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2475 }; |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2476 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2477 |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2478 } |
37ab9d83dc9b
reactivate SingleFrameApplication sample + Added SingleFrameEditorApplication (SDL only)
am@osimis.io
parents:
diff
changeset
|
2479 } |