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());