Mercurial > hg > orthanc-stone
comparison Framework/Scene2DViewport/LineMeasureTool.cpp @ 880:9953f16c304d am-dev
Merge
author | Alain Mazy <alain@mazy.be> |
---|---|
date | Fri, 05 Jul 2019 15:33:02 +0200 |
parents | c71ef52602a0 |
children | 0aff28f15ea2 |
comparison
equal
deleted
inserted
replaced
879:12b591d5d63c | 880:9953f16c304d |
---|---|
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. | 18 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
19 **/ | 19 **/ |
20 | 20 |
21 #include "LineMeasureTool.h" | 21 #include "LineMeasureTool.h" |
22 #include "MeasureToolsToolbox.h" | 22 #include "MeasureToolsToolbox.h" |
23 #include "EditLineMeasureTracker.h" | |
23 #include "LayerHolder.h" | 24 #include "LayerHolder.h" |
24 | 25 |
25 #include <Core/Logging.h> | 26 #include <Core/Logging.h> |
26 | 27 |
27 #include <boost/make_shared.hpp> | 28 #include <boost/make_shared.hpp> |
31 | 32 |
32 LineMeasureTool::LineMeasureTool( | 33 LineMeasureTool::LineMeasureTool( |
33 MessageBroker& broker, boost::weak_ptr<ViewportController> controllerW) | 34 MessageBroker& broker, boost::weak_ptr<ViewportController> controllerW) |
34 : MeasureTool(broker, controllerW) | 35 : MeasureTool(broker, controllerW) |
35 , layerHolder_(boost::make_shared<LayerHolder>(controllerW, 1, 5)) | 36 , layerHolder_(boost::make_shared<LayerHolder>(controllerW, 1, 5)) |
37 , lineHighlightArea_(LineHighlightArea_None) | |
36 { | 38 { |
37 | 39 |
38 } | 40 } |
39 | 41 |
40 LineMeasureTool::~LineMeasureTool() | 42 LineMeasureTool::~LineMeasureTool() |
70 start_ = start; | 72 start_ = start; |
71 end_ = end; | 73 end_ = end; |
72 RefreshScene(); | 74 RefreshScene(); |
73 } | 75 } |
74 | 76 |
75 | 77 void LineMeasureTool::SetLineHighlightArea(LineHighlightArea area) |
76 | 78 { |
77 bool LineMeasureTool::HitTest(ScenePoint2D p) const | 79 if (lineHighlightArea_ != area) |
80 { | |
81 lineHighlightArea_ = area; | |
82 RefreshScene(); | |
83 } | |
84 } | |
85 | |
86 void LineMeasureTool::ResetHighlightState() | |
87 { | |
88 SetLineHighlightArea(LineHighlightArea_None); | |
89 } | |
90 | |
91 void LineMeasureTool::Highlight(ScenePoint2D p) | |
92 { | |
93 LineHighlightArea lineHighlightArea = LineHitTest(p); | |
94 SetLineHighlightArea(lineHighlightArea); | |
95 } | |
96 | |
97 LineMeasureTool::LineHighlightArea LineMeasureTool::LineHitTest(ScenePoint2D p) const | |
78 { | 98 { |
79 const double pixelToScene = | 99 const double pixelToScene = |
80 GetScene()->GetCanvasToSceneTransform().ComputeZoom(); | 100 GetScene()->GetCanvasToSceneTransform().ComputeZoom(); |
81 | 101 const double SQUARED_HIT_TEST_MAX_DISTANCE_SCENE_COORD = pixelToScene * HIT_TEST_MAX_DISTANCE_CANVAS_COORD * pixelToScene * HIT_TEST_MAX_DISTANCE_CANVAS_COORD; |
82 // the hit test will return true if the supplied point (in scene coords) | 102 |
83 // is close to the handle or to the line. | 103 const double sqDistanceFromStart = ScenePoint2D::SquaredDistancePtPt(p, start_); |
84 | 104 if (sqDistanceFromStart <= SQUARED_HIT_TEST_MAX_DISTANCE_SCENE_COORD) |
85 // since the handle is small, a nice approximation is to defined this | 105 return LineHighlightArea_Start; |
86 // as a threshold on the distance between the point and the handle center. | 106 |
87 | 107 const double sqDistanceFromEnd = ScenePoint2D::SquaredDistancePtPt(p, end_); |
88 // this threshold is defined as a constant value in CANVAS units. | 108 if (sqDistanceFromEnd <= SQUARED_HIT_TEST_MAX_DISTANCE_SCENE_COORD) |
89 | 109 return LineHighlightArea_End; |
90 | 110 |
91 // line equation from two points (non-normalized) | 111 const double sqDistanceFromPtSegment = ScenePoint2D::SquaredDistancePtSegment(start_, end_, p); |
92 // (y0-y1)*x + (x1-x0)*xy + (x0*y1 - x1*y0) = 0 | 112 if (sqDistanceFromPtSegment <= SQUARED_HIT_TEST_MAX_DISTANCE_SCENE_COORD) |
93 // | 113 return LineHighlightArea_Segment; |
94 return false; | 114 |
115 return LineHighlightArea_None; | |
116 } | |
117 | |
118 bool LineMeasureTool::HitTest(ScenePoint2D p) const | |
119 { | |
120 return LineHitTest(p) != LineHighlightArea_None; | |
121 } | |
122 | |
123 boost::shared_ptr<IFlexiblePointerTracker> LineMeasureTool::CreateEditionTracker(const PointerEvent& e) | |
124 { | |
125 ScenePoint2D scenePos = e.GetMainPosition().Apply( | |
126 GetScene()->GetCanvasToSceneTransform()); | |
127 | |
128 if (!HitTest(scenePos)) | |
129 return boost::shared_ptr<IFlexiblePointerTracker>(); | |
130 | |
131 /** | |
132 new EditLineMeasureTracker( | |
133 boost::shared_ptr<LineMeasureTool> measureTool; | |
134 MessageBroker & broker, | |
135 boost::weak_ptr<ViewportController> controllerW, | |
136 const PointerEvent & e); | |
137 */ | |
138 boost::shared_ptr<EditLineMeasureTracker> editLineMeasureTracker( | |
139 new EditLineMeasureTracker(shared_from_this(), GetBroker(), GetController(), e)); | |
140 return editLineMeasureTracker; | |
141 } | |
142 | |
143 | |
144 boost::shared_ptr<MeasureToolMemento> LineMeasureTool::GetMemento() const | |
145 { | |
146 boost::shared_ptr<LineMeasureToolMemento> memento(new LineMeasureToolMemento()); | |
147 memento->start_ = start_; | |
148 memento->end_ = end_; | |
149 return memento; | |
150 } | |
151 | |
152 void LineMeasureTool::SetMemento(boost::shared_ptr<MeasureToolMemento> mementoBase) | |
153 { | |
154 boost::shared_ptr<LineMeasureToolMemento> memento = boost::dynamic_pointer_cast<LineMeasureToolMemento>(mementoBase); | |
155 ORTHANC_ASSERT(memento.get() != NULL, "Internal error: wrong (or bad) memento"); | |
156 start_ = memento->start_; | |
157 end_ = memento->end_; | |
158 RefreshScene(); | |
95 } | 159 } |
96 | 160 |
97 void LineMeasureTool::RefreshScene() | 161 void LineMeasureTool::RefreshScene() |
98 { | 162 { |
99 if (IsSceneAlive()) | 163 if (IsSceneAlive()) |
110 | 174 |
111 const Color color(TOOL_LINES_COLOR_RED, | 175 const Color color(TOOL_LINES_COLOR_RED, |
112 TOOL_LINES_COLOR_GREEN, | 176 TOOL_LINES_COLOR_GREEN, |
113 TOOL_LINES_COLOR_BLUE); | 177 TOOL_LINES_COLOR_BLUE); |
114 | 178 |
179 const Color highlightColor(TOOL_LINES_HL_COLOR_RED, | |
180 TOOL_LINES_HL_COLOR_GREEN, | |
181 TOOL_LINES_HL_COLOR_BLUE); | |
182 | |
115 { | 183 { |
116 PolylineSceneLayer::Chain chain; | 184 PolylineSceneLayer::Chain chain; |
117 chain.push_back(start_); | 185 chain.push_back(start_); |
118 chain.push_back(end_); | 186 chain.push_back(end_); |
119 polylineLayer->AddChain(chain, false, color); | 187 if(lineHighlightArea_ == LineHighlightArea_Segment) |
188 polylineLayer->AddChain(chain, false, highlightColor); | |
189 else | |
190 polylineLayer->AddChain(chain, false, color); | |
120 } | 191 } |
121 | 192 |
122 // handles | 193 // handles |
123 { | 194 { |
124 { | 195 { |
126 | 197 |
127 //TODO: take DPI into account | 198 //TODO: take DPI into account |
128 AddSquare(chain, GetScene(), start_, | 199 AddSquare(chain, GetScene(), start_, |
129 GetController()->GetHandleSideLengthS()); | 200 GetController()->GetHandleSideLengthS()); |
130 | 201 |
131 polylineLayer->AddChain(chain, true, color); | 202 if (lineHighlightArea_ == LineHighlightArea_Start) |
203 polylineLayer->AddChain(chain, true, highlightColor); | |
204 else | |
205 polylineLayer->AddChain(chain, true, color); | |
132 } | 206 } |
133 | 207 |
134 { | 208 { |
135 PolylineSceneLayer::Chain chain; | 209 PolylineSceneLayer::Chain chain; |
136 | 210 |
137 //TODO: take DPI into account | 211 //TODO: take DPI into account |
138 AddSquare(chain, GetScene(), end_, | 212 AddSquare(chain, GetScene(), end_, |
139 GetController()->GetHandleSideLengthS()); | 213 GetController()->GetHandleSideLengthS()); |
140 | 214 |
141 polylineLayer->AddChain(chain, true, color); | 215 if (lineHighlightArea_ == LineHighlightArea_End) |
216 polylineLayer->AddChain(chain, true, highlightColor); | |
217 else | |
218 polylineLayer->AddChain(chain, true, color); | |
142 } | 219 } |
143 } | 220 } |
144 | 221 |
145 } | 222 } |
146 { | 223 { |
148 double deltaX = end_.GetX() - start_.GetX(); | 225 double deltaX = end_.GetX() - start_.GetX(); |
149 double deltaY = end_.GetY() - start_.GetY(); | 226 double deltaY = end_.GetY() - start_.GetY(); |
150 double squareDist = deltaX * deltaX + deltaY * deltaY; | 227 double squareDist = deltaX * deltaX + deltaY * deltaY; |
151 double dist = sqrt(squareDist); | 228 double dist = sqrt(squareDist); |
152 char buf[64]; | 229 char buf[64]; |
153 sprintf(buf, "%0.02f units", dist); | 230 sprintf(buf, "%0.02f mm", dist); |
154 | 231 |
155 // TODO: for now we simply position the text overlay at the middle | 232 // TODO: for now we simply position the text overlay at the middle |
156 // of the measuring segment | 233 // of the measuring segment |
157 double midX = 0.5 * (end_.GetX() + start_.GetX()); | 234 double midX = 0.5 * (end_.GetX() + start_.GetX()); |
158 double midY = 0.5 * (end_.GetY() + start_.GetY()); | 235 double midY = 0.5 * (end_.GetY() + start_.GetY()); |