void CutTool::updateHoverState(QPointF cursor_pos_screen, MapWidget* widget) { HoverState new_hover_state = HoverFlag::OverNothing; const Object* new_hover_object = nullptr; MapCoordVector::size_type new_hover_point = 0; if (map()->selectedObjects().size() <= max_objects_for_handle_display) { auto best_distance_sq = std::numeric_limits<double>::max(); for (const auto object : map()->selectedObjects()) { MapCoordF handle_pos; auto hover_point = findHoverPoint(cursor_pos_screen, widget, object, false, &handle_pos); if (hover_point == std::numeric_limits<MapCoordVector::size_type>::max()) continue; auto distance_sq = widget->viewportToMapF(cursor_pos_screen).distanceSquaredTo(handle_pos); if (distance_sq < best_distance_sq) { new_hover_state = HoverFlag::OverObjectNode; new_hover_object = object; new_hover_point = hover_point; best_distance_sq = distance_sq; } } } if (new_hover_state != hover_state || new_hover_object != hover_object || new_hover_point != hover_point) { hover_state = new_hover_state; // We have got a Map*, so we may get a Object*. hover_object = const_cast<Object*>(new_hover_object); hover_point = new_hover_point; updateDirtyRect(); } }
void EditPointTool::updateHoverState(MapCoordF cursor_pos) { HoverState new_hover_state = OverNothing; const Object* new_hover_object = nullptr; MapCoordVector::size_type new_hover_point = no_point; if (text_editor) { handle_offset = MapCoordF(0, 0); } else if (!map()->selectedObjects().empty()) { if (map()->selectedObjects().size() <= max_objects_for_handle_display) { // Try to find object node. auto best_distance_sq = std::numeric_limits<double>::max(); for (const auto object : map()->selectedObjects()) { MapCoordF handle_pos; auto hover_point = findHoverPoint(cur_map_widget->mapToViewport(cursor_pos), cur_map_widget, object, true, &handle_pos); if (hover_point == no_point) continue; auto distance_sq = cursor_pos.distanceSquaredTo(handle_pos); if (distance_sq < best_distance_sq) { new_hover_state |= OverObjectNode; new_hover_object = object; new_hover_point = hover_point; best_distance_sq = distance_sq; handle_offset = handle_pos - cursor_pos; } } if (!new_hover_state.testFlag(OverObjectNode)) { // No object node found. Try to find path object edge. /// \todo De-duplicate: Copied from EditLineTool auto click_tolerance_sq = qPow(0.001 * cur_map_widget->getMapView()->pixelToLength(clickTolerance()), 2); for (auto object : map()->selectedObjects()) { if (object->getType() == Object::Path) { PathObject* path = object->asPath(); float distance_sq; PathCoord path_coord; path->calcClosestPointOnPath(cursor_pos, distance_sq, path_coord); if (distance_sq >= +0.0 && distance_sq < best_distance_sq && distance_sq < qMax(click_tolerance_sq, qPow(path->getSymbol()->calculateLargestLineExtent(map()), 2))) { new_hover_state |= OverPathEdge; new_hover_object = path; new_hover_point = path_coord.index; best_distance_sq = distance_sq; handle_offset = path_coord.pos - cursor_pos; } } } } } if (!new_hover_state.testFlag(OverObjectNode) && selection_extent.isValid()) { QRectF selection_extent_viewport = cur_map_widget->mapToViewport(selection_extent); if (pointOverRectangle(cur_map_widget->mapToViewport(cursor_pos), selection_extent_viewport)) { new_hover_state |= OverFrame; handle_offset = closestPointOnRect(cursor_pos, selection_extent) - cursor_pos; } } } if (new_hover_state != hover_state || new_hover_object != hover_object || new_hover_point != hover_point) { hover_state = new_hover_state; // We have got a Map*, so we may get an non-const Object*. hover_object = const_cast<Object*>(new_hover_object); hover_point = new_hover_point; if (hover_state != OverNothing) start_drag_distance = 0; else start_drag_distance = Settings::getInstance().getStartDragDistancePx(); updateDirtyRect(); } Q_ASSERT((hover_state.testFlag(OverObjectNode) || hover_state.testFlag(OverPathEdge)) == (hover_object != nullptr)); }