Mercurial > hg > orthanc-stone
comparison Framework/Scene2DViewport/LineMeasureTool.cpp @ 865:a29c13497557
Added operators to ScenePoint2D + highlight support on MouseOver for measuring tools
author | Benjamin Golinvaux <bgo@osimis.io> |
---|---|
date | Tue, 25 Jun 2019 15:24:13 +0200 |
parents | ff3559c489c9 |
children | c71ef52602a0 |
comparison
equal
deleted
inserted
replaced
864:ae3eccd0f545 | 865:a29c13497557 |
---|---|
31 | 31 |
32 LineMeasureTool::LineMeasureTool( | 32 LineMeasureTool::LineMeasureTool( |
33 MessageBroker& broker, boost::weak_ptr<ViewportController> controllerW) | 33 MessageBroker& broker, boost::weak_ptr<ViewportController> controllerW) |
34 : MeasureTool(broker, controllerW) | 34 : MeasureTool(broker, controllerW) |
35 , layerHolder_(boost::make_shared<LayerHolder>(controllerW, 1, 5)) | 35 , layerHolder_(boost::make_shared<LayerHolder>(controllerW, 1, 5)) |
36 , lineHighlightArea_(LineHighlightArea_None) | |
36 { | 37 { |
37 | 38 |
38 } | 39 } |
39 | 40 |
40 LineMeasureTool::~LineMeasureTool() | 41 LineMeasureTool::~LineMeasureTool() |
70 start_ = start; | 71 start_ = start; |
71 end_ = end; | 72 end_ = end; |
72 RefreshScene(); | 73 RefreshScene(); |
73 } | 74 } |
74 | 75 |
75 | 76 void LineMeasureTool::SetLineHighlightArea(LineHighlightArea area) |
76 | 77 { |
77 bool LineMeasureTool::HitTest(ScenePoint2D p) const | 78 if (lineHighlightArea_ != area) |
79 { | |
80 lineHighlightArea_ = area; | |
81 RefreshScene(); | |
82 } | |
83 } | |
84 | |
85 void LineMeasureTool::ResetHighlightState() | |
86 { | |
87 SetLineHighlightArea(LineHighlightArea_None); | |
88 } | |
89 | |
90 void LineMeasureTool::Highlight(ScenePoint2D p) | |
91 { | |
92 LineHighlightArea lineHighlightArea = LineHitTest(p); | |
93 SetLineHighlightArea(lineHighlightArea); | |
94 } | |
95 | |
96 LineMeasureTool::LineHighlightArea LineMeasureTool::LineHitTest(ScenePoint2D p) const | |
78 { | 97 { |
79 const double pixelToScene = | 98 const double pixelToScene = |
80 GetScene()->GetCanvasToSceneTransform().ComputeZoom(); | 99 GetScene()->GetCanvasToSceneTransform().ComputeZoom(); |
81 | 100 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) | 101 |
83 // is close to the handle or to the line. | 102 const double sqDistanceFromStart = ScenePoint2D::SquaredDistancePtPt(p, start_); |
84 | 103 if (sqDistanceFromStart <= SQUARED_HIT_TEST_MAX_DISTANCE_SCENE_COORD) |
85 // since the handle is small, a nice approximation is to defined this | 104 return LineHighlightArea_Start; |
86 // as a threshold on the distance between the point and the handle center. | 105 |
87 | 106 const double sqDistanceFromEnd = ScenePoint2D::SquaredDistancePtPt(p, end_); |
88 // this threshold is defined as a constant value in CANVAS units. | 107 if (sqDistanceFromEnd <= SQUARED_HIT_TEST_MAX_DISTANCE_SCENE_COORD) |
89 | 108 return LineHighlightArea_End; |
90 | 109 |
91 // line equation from two points (non-normalized) | 110 const double sqDistanceFromPtSegment = ScenePoint2D::SquaredDistancePtSegment(start_, end_, p); |
92 // (y0-y1)*x + (x1-x0)*xy + (x0*y1 - x1*y0) = 0 | 111 if (sqDistanceFromPtSegment <= SQUARED_HIT_TEST_MAX_DISTANCE_SCENE_COORD) |
93 // | 112 return LineHighlightArea_Segment; |
94 return false; | 113 |
114 return LineHighlightArea_None; | |
115 } | |
116 | |
117 bool LineMeasureTool::HitTest(ScenePoint2D p) const | |
118 { | |
119 return LineHitTest(p) != LineHighlightArea_None; | |
95 } | 120 } |
96 | 121 |
97 void LineMeasureTool::RefreshScene() | 122 void LineMeasureTool::RefreshScene() |
98 { | 123 { |
99 if (IsSceneAlive()) | 124 if (IsSceneAlive()) |
110 | 135 |
111 const Color color(TOOL_LINES_COLOR_RED, | 136 const Color color(TOOL_LINES_COLOR_RED, |
112 TOOL_LINES_COLOR_GREEN, | 137 TOOL_LINES_COLOR_GREEN, |
113 TOOL_LINES_COLOR_BLUE); | 138 TOOL_LINES_COLOR_BLUE); |
114 | 139 |
140 const Color highlightColor(TOOL_LINES_HL_COLOR_RED, | |
141 TOOL_LINES_HL_COLOR_GREEN, | |
142 TOOL_LINES_HL_COLOR_BLUE); | |
143 | |
115 { | 144 { |
116 PolylineSceneLayer::Chain chain; | 145 PolylineSceneLayer::Chain chain; |
117 chain.push_back(start_); | 146 chain.push_back(start_); |
118 chain.push_back(end_); | 147 chain.push_back(end_); |
119 polylineLayer->AddChain(chain, false, color); | 148 if(lineHighlightArea_ == LineHighlightArea_Segment) |
149 polylineLayer->AddChain(chain, false, highlightColor); | |
150 else | |
151 polylineLayer->AddChain(chain, false, color); | |
120 } | 152 } |
121 | 153 |
122 // handles | 154 // handles |
123 { | 155 { |
124 { | 156 { |
126 | 158 |
127 //TODO: take DPI into account | 159 //TODO: take DPI into account |
128 AddSquare(chain, GetScene(), start_, | 160 AddSquare(chain, GetScene(), start_, |
129 GetController()->GetHandleSideLengthS()); | 161 GetController()->GetHandleSideLengthS()); |
130 | 162 |
131 polylineLayer->AddChain(chain, true, color); | 163 if (lineHighlightArea_ == LineHighlightArea_Start) |
164 polylineLayer->AddChain(chain, true, highlightColor); | |
165 else | |
166 polylineLayer->AddChain(chain, true, color); | |
132 } | 167 } |
133 | 168 |
134 { | 169 { |
135 PolylineSceneLayer::Chain chain; | 170 PolylineSceneLayer::Chain chain; |
136 | 171 |
137 //TODO: take DPI into account | 172 //TODO: take DPI into account |
138 AddSquare(chain, GetScene(), end_, | 173 AddSquare(chain, GetScene(), end_, |
139 GetController()->GetHandleSideLengthS()); | 174 GetController()->GetHandleSideLengthS()); |
140 | 175 |
141 polylineLayer->AddChain(chain, true, color); | 176 if (lineHighlightArea_ == LineHighlightArea_End) |
177 polylineLayer->AddChain(chain, true, highlightColor); | |
178 else | |
179 polylineLayer->AddChain(chain, true, color); | |
142 } | 180 } |
143 } | 181 } |
144 | 182 |
145 } | 183 } |
146 { | 184 { |