annotate Framework/Widgets/WorldSceneWidget.cpp @ 323:dbfe2e9e5020 am-2

playing with LambdaCallable
author am@osimis.io
date Mon, 15 Oct 2018 23:36:43 +0200
parents 8bdc6112bc2e
children 8716176ff7f0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
1 /**
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
2 * Stone of Orthanc
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
4 * Department, University Hospital of Liege, Belgium
134
4cff7b1ed31d upgrade to year 2018
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 47
diff changeset
5 * Copyright (C) 2017-2018 Osimis S.A., Belgium
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
6 *
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
7 * This program is free software: you can redistribute it and/or
47
28956ed68280 agpl license
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 40
diff changeset
8 * modify it under the terms of the GNU Affero General Public License
28956ed68280 agpl license
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 40
diff changeset
9 * as published by the Free Software Foundation, either version 3 of
28956ed68280 agpl license
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 40
diff changeset
10 * the License, or (at your option) any later version.
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
11 *
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
12 * This program is distributed in the hope that it will be useful, but
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
47
28956ed68280 agpl license
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 40
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28956ed68280 agpl license
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 40
diff changeset
15 * Affero General Public License for more details.
281
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
16 *
47
28956ed68280 agpl license
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 40
diff changeset
17 * You should have received a copy of the GNU Affero General Public License
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
19 **/
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
20
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
21
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
22 #include "WorldSceneWidget.h"
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
23
110
53025eecbc95 renamed SliceGeometry as CoordinateSystem3D
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 109
diff changeset
24 #include <math.h>
53025eecbc95 renamed SliceGeometry as CoordinateSystem3D
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 109
diff changeset
25 #include <memory>
53025eecbc95 renamed SliceGeometry as CoordinateSystem3D
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 109
diff changeset
26 #include <cassert>
313
8bdc6112bc2e initial resize of canvas
am@osimis.io
parents: 281
diff changeset
27 #include "Core/Logging.h"
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
28
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
29 namespace OrthancStone
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
30 {
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
31 static void MapMouseToScene(double& sceneX,
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
32 double& sceneY,
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
33 const ViewportGeometry& view,
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
34 int mouseX,
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
35 int mouseY)
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
36 {
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
37 // Take the center of the pixel
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
38 double x, y;
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
39 x = static_cast<double>(mouseX) + 0.5;
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
40 y = static_cast<double>(mouseY) + 0.5;
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
41
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
42 view.MapDisplayToScene(sceneX, sceneY, x, y);
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
43 }
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
44
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
45
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
46 struct WorldSceneWidget::SizeChangeFunctor
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
47 {
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
48 ViewportGeometry& view_;
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
49
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
50 SizeChangeFunctor(ViewportGeometry& view) :
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
51 view_(view)
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
52 {
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
53 }
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
54
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
55 void operator() (IWorldObserver& observer,
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
56 const WorldSceneWidget& source)
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
57 {
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
58 observer.NotifySizeChange(source, view_);
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
59 }
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
60 };
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
61
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
62
281
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
63 // this is an adapter between a IWorldSceneMouseTracker
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
64 // that is tracking a mouse in scene coordinates/mm and
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
65 // an IMouseTracker that is tracking a mouse
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
66 // in screen coordinates/pixels.
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
67 class WorldSceneWidget::SceneMouseTracker : public IMouseTracker
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
68 {
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
69 private:
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
70 ViewportGeometry view_;
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
71 std::auto_ptr<IWorldSceneMouseTracker> tracker_;
281
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
72
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
73 public:
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
74 SceneMouseTracker(const ViewportGeometry& view,
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
75 IWorldSceneMouseTracker* tracker) :
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
76 view_(view),
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
77 tracker_(tracker)
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
78 {
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
79 assert(tracker != NULL);
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
80 }
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
81
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
82 virtual void Render(Orthanc::ImageAccessor& target)
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
83 {
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
84 CairoSurface surface(target);
281
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
85 CairoContext context(surface);
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
86 view_.ApplyTransform(context);
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
87 tracker_->Render(context, view_.GetZoom());
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
88 }
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
89
281
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
90 virtual void MouseUp()
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
91 {
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
92 tracker_->MouseUp();
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
93 }
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
94
281
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
95 virtual void MouseMove(int x,
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
96 int y)
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
97 {
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
98 double sceneX, sceneY;
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
99 MapMouseToScene(sceneX, sceneY, view_, x, y);
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
100 tracker_->MouseMove(sceneX, sceneY);
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
101 }
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
102 };
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
103
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
104
281
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
105 WorldSceneWidget::PanMouseTracker::PanMouseTracker(WorldSceneWidget& that,
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
106 int x,
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
107 int y) :
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
108 that_(that),
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
109 downX_(x),
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
110 downY_(y)
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
111 {
281
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
112 that_.view_.GetPan(previousPanX_, previousPanY_);
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
113 }
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
114
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
115 void WorldSceneWidget::PanMouseTracker::MouseMove(int x, int y)
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
116 {
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
117 that_.view_.SetPan(previousPanX_ + x - downX_,
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
118 previousPanY_ + y - downY_);
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
119
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
120 that_.observers_.Apply(that_, &IWorldObserver::NotifyViewChange, that_.view_);
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
121 }
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
122
281
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
123 WorldSceneWidget::ZoomMouseTracker::ZoomMouseTracker(WorldSceneWidget& that,
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
124 int x,
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
125 int y) :
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
126 that_(that),
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
127 downX_(x),
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
128 downY_(y)
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
129 {
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
130 oldZoom_ = that_.view_.GetZoom();
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
131 MapMouseToScene(centerX_, centerY_, that_.view_, downX_, downY_);
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
132 }
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
133
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
134 void WorldSceneWidget::ZoomMouseTracker::MouseMove(int x,
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
135 int y)
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
136 {
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
137 static const double MIN_ZOOM = -4;
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
138 static const double MAX_ZOOM = 4;
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
139
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
140 if (that_.view_.GetDisplayHeight() <= 3)
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
141 {
313
8bdc6112bc2e initial resize of canvas
am@osimis.io
parents: 281
diff changeset
142 LOG(WARNING) << "image is too small to zoom (current height = " << that_.view_.GetDisplayHeight() << ")";
8bdc6112bc2e initial resize of canvas
am@osimis.io
parents: 281
diff changeset
143 return;
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
144 }
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
145
281
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
146 double dy = (static_cast<double>(y - downY_) /
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
147 static_cast<double>(that_.view_.GetDisplayHeight() - 1)); // In the range [-1,1]
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
148 double z;
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
149
281
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
150 // Linear interpolation from [-1, 1] to [MIN_ZOOM, MAX_ZOOM]
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
151 if (dy < -1.0)
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
152 {
281
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
153 z = MIN_ZOOM;
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
154 }
281
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
155 else if (dy > 1.0)
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
156 {
281
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
157 z = MAX_ZOOM;
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
158 }
281
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
159 else
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
160 {
281
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
161 z = MIN_ZOOM + (MAX_ZOOM - MIN_ZOOM) * (dy + 1.0) / 2.0;
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
162 }
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
163
281
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
164 z = pow(2.0, z);
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
165
281
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
166 that_.view_.SetZoom(oldZoom_ * z);
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
167
281
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
168 // Correct the pan so that the original click point is kept at
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
169 // the same location on the display
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
170 double panX, panY;
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
171 that_.view_.GetPan(panX, panY);
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
172
281
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
173 int tx, ty;
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
174 that_.view_.MapSceneToDisplay(tx, ty, centerX_, centerY_);
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
175 that_.view_.SetPan(panX + static_cast<double>(downX_ - tx),
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
176 panY + static_cast<double>(downY_ - ty));
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
177
281
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
178 that_.observers_.Apply(that_, &IWorldObserver::NotifyViewChange, that_.view_);
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
179 }
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
180
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
181
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
182 bool WorldSceneWidget::RenderCairo(CairoContext& context)
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
183 {
53
c2dc924f1a63 removing threading out of the framework
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 48
diff changeset
184 view_.ApplyTransform(context);
c2dc924f1a63 removing threading out of the framework
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 48
diff changeset
185 return RenderScene(context, view_);
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
186 }
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
187
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
188
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
189 void WorldSceneWidget::RenderMouseOverCairo(CairoContext& context,
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
190 int x,
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
191 int y)
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
192 {
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
193 ViewportGeometry view = GetView();
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
194 view.ApplyTransform(context);
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
195
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
196 double sceneX, sceneY;
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
197 MapMouseToScene(sceneX, sceneY, view, x, y);
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
198 RenderSceneMouseOver(context, view, sceneX, sceneY);
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
199 }
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
200
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
201
53
c2dc924f1a63 removing threading out of the framework
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 48
diff changeset
202 void WorldSceneWidget::SetSceneExtent(ViewportGeometry& view)
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
203 {
109
53bd9277b025 using the Extent class
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 91
diff changeset
204 view.SetSceneExtent(GetSceneExtent());
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
205 }
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
206
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
207
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
208 void WorldSceneWidget::SetSize(unsigned int width,
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
209 unsigned int height)
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
210 {
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
211 CairoWidget::SetSize(width, height);
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
212
53
c2dc924f1a63 removing threading out of the framework
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 48
diff changeset
213 view_.SetDisplaySize(width, height);
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
214
53
c2dc924f1a63 removing threading out of the framework
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 48
diff changeset
215 if (observers_.IsEmpty())
c2dc924f1a63 removing threading out of the framework
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 48
diff changeset
216 {
66
298f375dcb68 LayerWidget
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 61
diff changeset
217 // Without a size observer, reset to the default view
298f375dcb68 LayerWidget
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 61
diff changeset
218 // view_.SetDefaultView();
53
c2dc924f1a63 removing threading out of the framework
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 48
diff changeset
219 }
c2dc924f1a63 removing threading out of the framework
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 48
diff changeset
220 else
c2dc924f1a63 removing threading out of the framework
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 48
diff changeset
221 {
c2dc924f1a63 removing threading out of the framework
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 48
diff changeset
222 // With a size observer, let it decide which view to use
c2dc924f1a63 removing threading out of the framework
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 48
diff changeset
223 SizeChangeFunctor functor(view_);
91
81f73efd81a1 cleaning up
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 85
diff changeset
224 observers_.Notify(*this, functor);
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
225 }
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
226 }
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
227
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
228
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
229 void WorldSceneWidget::SetInteractor(IWorldSceneInteractor& interactor)
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
230 {
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
231 interactor_ = &interactor;
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
232 }
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
233
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
234
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
235 void WorldSceneWidget::SetDefaultView()
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
236 {
53
c2dc924f1a63 removing threading out of the framework
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 48
diff changeset
237 SetSceneExtent(view_);
c2dc924f1a63 removing threading out of the framework
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 48
diff changeset
238 view_.SetDefaultView();
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
239
278
8a86695fcbc3 renamings
am@osimis.io
parents: 196
diff changeset
240 NotifyContentChanged();
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
241
91
81f73efd81a1 cleaning up
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 85
diff changeset
242 observers_.Apply(*this, &IWorldObserver::NotifyViewChange, view_);
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
243 }
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
244
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
245
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
246 void WorldSceneWidget::SetView(const ViewportGeometry& view)
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
247 {
53
c2dc924f1a63 removing threading out of the framework
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 48
diff changeset
248 view_ = view;
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
249
278
8a86695fcbc3 renamings
am@osimis.io
parents: 196
diff changeset
250 NotifyContentChanged();
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
251
91
81f73efd81a1 cleaning up
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 85
diff changeset
252 observers_.Apply(*this, &IWorldObserver::NotifyViewChange, view_);
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
253 }
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
254
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
255
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
256 ViewportGeometry WorldSceneWidget::GetView()
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
257 {
53
c2dc924f1a63 removing threading out of the framework
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 48
diff changeset
258 return view_;
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
259 }
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
260
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
261
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
262 IMouseTracker* WorldSceneWidget::CreateMouseTracker(MouseButton button,
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
263 int x,
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
264 int y,
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
265 KeyboardModifiers modifiers)
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
266 {
53
c2dc924f1a63 removing threading out of the framework
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 48
diff changeset
267 double sceneX, sceneY;
c2dc924f1a63 removing threading out of the framework
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 48
diff changeset
268 MapMouseToScene(sceneX, sceneY, view_, x, y);
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
269
281
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
270 // asks the Widget Interactor to provide a mouse tracker
53
c2dc924f1a63 removing threading out of the framework
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 48
diff changeset
271 std::auto_ptr<IWorldSceneMouseTracker> tracker
281
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
272 (CreateMouseSceneTracker(view_, button, sceneX, sceneY, modifiers));
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
273
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
274 if (tracker.get() != NULL)
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
275 {
53
c2dc924f1a63 removing threading out of the framework
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 48
diff changeset
276 return new SceneMouseTracker(view_, tracker.release());
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
277 }
281
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
278 //TODO: allow Interactor to create Pan & Zoom
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
279 switch (button)
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
280 {
281
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
281 case MouseButton_Middle:
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
282 return new PanMouseTracker(*this, x, y);
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
283
281
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
284 case MouseButton_Right:
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
285 return new ZoomMouseTracker(*this, x, y);
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
286
281
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
287 default:
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
288 return NULL;
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
289 }
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
290 }
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
291
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
292
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
293 void WorldSceneWidget::RenderSceneMouseOver(CairoContext& context,
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
294 const ViewportGeometry& view,
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
295 double x,
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
296 double y)
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
297 {
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
298 if (interactor_)
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
299 {
59
d2adc6189a95 refactoring
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 55
diff changeset
300 interactor_->MouseOver(context, *this, view, x, y, GetStatusBar());
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
301 }
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
302 }
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
303
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
304 IWorldSceneMouseTracker* WorldSceneWidget::CreateMouseSceneTracker(const ViewportGeometry& view,
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
305 MouseButton button,
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
306 double x,
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
307 double y,
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
308 KeyboardModifiers modifiers)
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
309 {
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
310 if (interactor_)
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
311 {
281
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
312 return interactor_->CreateMouseTracker(*this, view, button, modifiers, x, y, GetStatusBar());
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
313 }
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
314 else
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
315 {
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
316 return NULL;
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
317 }
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
318 }
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
319
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
320
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
321 void WorldSceneWidget::MouseWheel(MouseWheelDirection direction,
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
322 int x,
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
323 int y,
281
300d8b8c48b3 mouse tracker tuning
am@osimis.io
parents: 278
diff changeset
324 KeyboardModifiers modifiers)
0
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
325 {
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
326 if (interactor_)
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
327 {
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
328 interactor_->MouseWheel(*this, direction, modifiers, GetStatusBar());
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
329 }
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
330 }
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
331
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
332
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
333 void WorldSceneWidget::KeyPressed(char key,
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
334 KeyboardModifiers modifiers)
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
335 {
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
336 if (interactor_)
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
337 {
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
338 interactor_->KeyPressed(*this, key, modifiers, GetStatusBar());
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
339 }
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
340 }
351ab0da0150 initial commit
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
341 }