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