void DrawPathTool::finishDrawing() { Q_ASSERT(editingInProgress()); // Does the symbols contain only areas? If so, auto-close the path if not done yet bool contains_only_areas = !is_helper_tool && (drawing_symbol->getContainedTypes() & ~(Symbol::Area | Symbol::Combined)) == 0 && (drawing_symbol->getContainedTypes() & Symbol::Area); if (contains_only_areas && !preview_path->parts().empty()) preview_path->parts().front().setClosed(true, true); // Remove last point if closed and first and last points are equal, or if the last point was just a preview if (path_has_preview_point && !dragging) preview_path->deleteCoordinate(preview_path->getCoordinateCount() - (preview_path->parts().front().isClosed() ? 2 : 1), false); if (preview_path->getCoordinateCount() < (contains_only_areas ? 3 : 2)) { renderables->removeRenderablesOfObject(preview_path, false); delete preview_path; preview_path = NULL; } dragging = false; following = false; setEditingInProgress(false); if (!ctrl_pressed) angle_helper->setActive(false); updateSnapHelper(); updateStatusText(); hidePreviewPoints(); DrawLineAndAreaTool::finishDrawing(appending ? append_to_object : NULL); finished_path_is_selected = true; }
void DrawPathTool::updateFollowing() { PathCoord path_coord; float distance_sq; const auto& part = follow_object->parts()[follow_helper->getPartIndex()]; follow_object->calcClosestPointOnPath(cur_pos_map, distance_sq, path_coord, part.first_index, part.last_index); auto followed_path = follow_helper->updateFollowing(path_coord); // Append the temporary object to the preview object at follow_start_index // 1. Delete everything appended, except for the point where following started // (thus avoiding deletion of the whole part). for (auto i = preview_path->getCoordinateCount() - 1; i > follow_start_index + 1; i = preview_path->getCoordinateCount() - 1) { preview_path->deleteCoordinate(i, false); } // 2. Merge segments at the point where following started. if (followed_path) { preview_path->connectPathParts(preview_path->findPartIndexForIndex(follow_start_index), followed_path.get(), 0, false, true); } updatePreviewPath(); hidePreviewPoints(); updateDirtyRect(); }
void DrawPathTool::updateDrawHover() { if (!shift_pressed) angle_helper->getConstrainedCursorPosMap(cur_pos_map, constrained_pos_map); if (!previous_point_is_curve_point && !left_mouse_down && editingInProgress()) { // Show a line to the cursor position as preview hidePreviewPoints(); if (!path_has_preview_point) { preview_path->addCoordinate(MapCoord(constrained_pos_map)); path_has_preview_point = true; } preview_path->setCoordinate(preview_path->getCoordinateCount() - 1, MapCoord(constrained_pos_map)); updatePreviewPath(); updateDirtyRect(); // TODO: Possible optimization: mark only the last segment as dirty } else if (previous_point_is_curve_point && !left_mouse_down && editingInProgress()) { setPreviewPointsPosition(constrained_pos_map, 1); updateDirtyRect(); } }
void DrawRectangleTool::updateHover(bool mouse_down) { if (shift_pressed) constrained_pos_map = MapCoordF(snap_helper->snapToObject(cur_pos_map, cur_map_widget)); else constrained_pos_map = cur_pos_map; if (!editingInProgress()) { setPreviewPointsPosition(constrained_pos_map); updateDirtyRect(); if (mouse_down && ctrl_pressed) pickDirection(constrained_pos_map, cur_map_widget); else if (!mouse_down) angle_helper->setCenter(constrained_pos_map); } else { hidePreviewPoints(); if (mouse_down && !dragging && (cur_pos - click_pos).manhattanLength() >= Settings::getInstance().getStartDragDistancePx()) { // Start dragging dragging = true; } if (!mouse_down || dragging) updateRectangle(); } }
void DrawPathTool::abortDrawing() { dragging = false; following = false; setEditingInProgress(false); if (!ctrl_pressed) angle_helper->setActive(false); updateSnapHelper(); updateStatusText(); hidePreviewPoints(); DrawLineAndAreaTool::abortDrawing(); }
bool DrawPathTool::pickAngle(MapCoordF coord, MapWidget* widget) { MapCoord snap_position; bool picked = snap_helper->snapToDirection(coord, widget, angle_helper.data(), &snap_position); if (picked) angle_helper->setCenter(MapCoordF(snap_position)); else { updateAngleHelper(); angle_helper->setCenter(constrained_pos_map); } hidePreviewPoints(); updateDirtyRect(); return picked; }
bool DrawFreehandTool::mousePressEvent(QMouseEvent* event, MapCoordF map_coord, MapWidget* widget) { Q_UNUSED(widget); if (event->button() == Qt::LeftButton && !editingInProgress()) { cur_pos = event->pos(); cur_pos_map = map_coord; click_pos = event->pos(); dragging = false; startDrawing(); updatePath(); hidePreviewPoints(); return true; } return false; }
bool DrawCircleTool::mousePressEvent(QMouseEvent* event, MapCoordF map_coord, MapWidget* widget) { Q_UNUSED(widget); if (isDrawingButton(event->button())) { cur_pos = event->pos(); cur_pos_map = map_coord; if (!first_point_set && event->buttons() & Qt::LeftButton) { click_pos = event->pos(); circle_start_pos_map = map_coord; opposite_pos_map = map_coord; dragging = false; first_point_set = true; start_from_center = (event->modifiers() | (key_button_bar ? key_button_bar->activeModifiers() : 0)) & Qt::ControlModifier; if (!editingInProgress()) startDrawing(); } else if (first_point_set && !second_point_set) { click_pos = event->pos(); opposite_pos_map = map_coord; dragging = false; second_point_set = true; } else return false; hidePreviewPoints(); return true; } else if (event->button() == Qt::RightButton && editingInProgress()) { abortDrawing(); return true; } return false; }
bool DrawPathTool::mouseMoveEvent(QMouseEvent* event, MapCoordF map_coord, MapWidget* widget) { cur_pos = event->pos(); cur_pos_map = map_coord; if (!containsDrawingButtons(event->buttons())) { updateHover(); } else if (!editingInProgress()) { left_mouse_down = true; if (picking_angle) pickAngle(map_coord, widget); else return false; } else if (following) { updateFollowing(); } else { bool drag_distance_reached = (event->pos() - click_pos).manhattanLength() >= Settings::getInstance().getStartDragDistancePx(); if (dragging && !drag_distance_reached) { if (create_spline_corner) { create_spline_corner = false; } else if (path_has_preview_point) { undoLastPoint(); } } else if (drag_distance_reached) { // Giving a direction by dragging dragging = true; create_spline_corner = false; create_segment = true; if (previous_point_is_curve_point) angle_helper->setCenter(click_pos_map); QPointF constrained_pos; angle_helper->getConstrainedCursorPositions(map_coord, constrained_pos_map, constrained_pos, widget); if (previous_point_is_curve_point) { hidePreviewPoints(); float drag_direction = calculateRotation(constrained_pos.toPoint(), constrained_pos_map); // Add a new node or convert the last node into a corner? if ((widget->mapToViewport(previous_pos_map) - click_pos).manhattanLength() >= Settings::getInstance().getStartDragDistancePx()) createPreviewCurve(MapCoord(click_pos_map), drag_direction); else { create_spline_corner = true; // This hides the old direction indicator previous_drag_map = previous_pos_map; } } updateDirtyRect(); } } return true; }