Пример #1
0
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();
	}
}
Пример #2
0
DrawPathTool::DrawPathTool(MapEditorController* editor, QAction* tool_button, bool is_helper_tool, bool allow_closing_paths)
: DrawLineAndAreaTool(editor, DrawPath, tool_button, is_helper_tool)
, allow_closing_paths(allow_closing_paths)
, finished_path_is_selected(false)
, cur_map_widget(mapWidget())
, angle_helper(new ConstrainAngleToolHelper())
, snap_helper(new SnappingToolHelper(this))
, follow_helper(new FollowPathToolHelper())
, key_button_bar(NULL)
{
	angle_helper->setActive(false);
	connect(angle_helper.data(), SIGNAL(displayChanged()), this, SLOT(updateDirtyRect()));
	
	updateSnapHelper();
	connect(snap_helper.data(), SIGNAL(displayChanged()), this, SLOT(updateDirtyRect()));
	
	dragging = false;
	appending = false;
	following = false;
	picking_angle = false;
	picked_angle = false;
	draw_dash_points = false;
	shift_pressed = false;
	ctrl_pressed = false;
	
	connect(map(), SIGNAL(objectSelectionChanged()), this, SLOT(objectSelectionChanged()));
}
Пример #3
0
void MapEditorToolBase::init()
{
	connect(map(), SIGNAL(objectSelectionChanged()), this, SLOT(objectSelectionChanged()));
	connect(map(), SIGNAL(selectedObjectEdited()), this, SLOT(updateDirtyRect()));
	initImpl();
	updateDirtyRect();
	updateStatusText();
	
	MapEditorTool::init();
}
Пример #4
0
void CutHoleTool::pathAborted()
{
	delete path_tool;
	path_tool = NULL;
	updateDirtyRect();
	updateStatusText();
}
Пример #5
0
void RotateTool::clickRelease()
{
	rotation_center = cur_pos_map;
	angle_helper->setCenter(rotation_center);
	updateDirtyRect();
	updateStatusText();
}
Пример #6
0
void ScaleTool::objectSelectionChanged()
{
	if (map()->getNumSelectedObjects() == 0)
		deactivate();
	else
		updateDirtyRect();
}
Пример #7
0
void DrawTextTool::updatePreviewText()
{
	renderables->removeRenderablesOfObject(preview_text, false);
	preview_text->update();
	renderables->insertRenderablesOfObject(preview_text);
	updateDirtyRect();
}
Пример #8
0
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();
	}
}
Пример #9
0
void RotatePatternTool::objectSelectionChangedImpl()
{
	if (map()->getNumSelectedObjects() == 0)
		deactivate();
	else
		updateDirtyRect();
}
Пример #10
0
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();
}
Пример #11
0
void CutTool::pathAborted()
{
	delete path_tool;
	path_tool = nullptr;
	cutting_area = false;
	updateDirtyRect();
}
Пример #12
0
bool DrawPathTool::keyReleaseEvent(QKeyEvent* event)
{
	if (event->key() == Qt::Key_Control)
	{
		ctrl_pressed = false;
		if (!picked_angle)
			angle_helper->setActive(false);
		if (editingInProgress() && !dragging)
			updateDrawHover();
		updateStatusText();
	}
	else if (event->key() == Qt::Key_Shift)
	{
		shift_pressed = false;
		if (!dragging && !following)
		{
			updateHover();
			updateDirtyRect();
		}
		updateStatusText();
	}
	else
		return false;
	return true;
}
Пример #13
0
void DrawPointTool::mouseMove()
{
	PointSymbol* point = reinterpret_cast<PointSymbol*>(editor->activeSymbol());
	
	if (!isDragging())
	{
		// Show preview object at this position
		renderables->removeRenderablesOfObject(preview_object, false);
		if (preview_object->getSymbol() != point)
		{
			bool success = preview_object->setSymbol(point, true);
			Q_ASSERT(success);
			Q_UNUSED(success);
		}
		
		preview_object->setPosition(constrained_pos_map);
		if (point->isRotatable())
			preview_object->setRotation(0);
		preview_object->update();
		renderables->insertRenderablesOfObject(preview_object);
		updateDirtyRect();
		
		return;
	}
}
Пример #14
0
bool DrawTextTool::mouseMoveEvent(QMouseEvent* event, MapCoordF map_coord, MapWidget* widget)
{
	bool mouse_down = event->buttons() & Qt::LeftButton;
	cur_pos = event->pos();
	cur_pos_map = map_coord;
	
	if (text_editor)
		return text_editor->mouseMoveEvent(event, map_coord, widget);
	
	if (!mouse_down)
	{
		setPreviewLetter();
	}
	else // if (mouse_down)
	{
		if (!dragging && (event->pos() - click_pos).manhattanLength() >= Settings::getInstance().getStartDragDistancePx())
		{
			// Start dragging
			dragging = true;
		}
		
		if (dragging)
			updateDirtyRect();
	}
	return true;
}
Пример #15
0
bool ScaleTool::mouseReleaseEvent(QMouseEvent* event, MapCoordF map_coord, MapWidget* widget)
{
	Q_UNUSED(widget);
	
	if (event->button() != Qt::LeftButton)
		return false;
	
	if (!scaling)
	{
		scaling_center = map_coord;
		scaling_center_set = true;
	}
	else
	{
		scaling = false;
		updateDragging(map_coord);
		finishEditingSelection(*renderables, *old_renderables, true);
		map()->setObjectsDirty();
		map()->emitSelectionEdited();
	}
	
	updateDirtyRect();
	updateStatusText();
	return true;
}
Пример #16
0
void DrawRectangleTool::pickDirection(MapCoordF coord, MapWidget* widget)
{
	MapCoord snap_position;
	snap_helper->snapToDirection(coord, widget, angle_helper.data(), &snap_position);
	angle_helper->setActive(true, MapCoordF(snap_position));
	updateDirtyRect();
	picked_direction = true;
}
Пример #17
0
void CutHoleTool::objectSelectionChanged()
{
	Map* map = this->map();
	if (map->getNumSelectedObjects() != 1 || !((*map->selectedObjectsBegin())->getSymbol()->getContainedTypes() & Symbol::Area))
		deactivate();
	else
		updateDirtyRect();
}
Пример #18
0
void CutHoleTool::init()
{
	connect(map(), SIGNAL(objectSelectionChanged()), this, SLOT(objectSelectionChanged()));
	updateDirtyRect();
	updateStatusText();
	
	MapEditorTool::init();
}
Пример #19
0
void DrawPointTool::updatePreviewObject(MapCoordF pos)
{
	renderables->removeRenderablesOfObject(preview_object.get(), false);
	preview_object->setPosition(pos);
	preview_object->update();
	renderables->insertRenderablesOfObject(preview_object.get());
	updateDirtyRect();
}
Пример #20
0
void RotateTool::clickRelease()
{
	rotation_center = cur_pos_map;
	rotation_center_set = true;
	
	updateDirtyRect();
	updateStatusText();
}
Пример #21
0
void ScaleTool::init()
{
	// Set initial scaling center to the center of the bounding box of the selected objects
	if (map()->getNumSelectedObjects() > 0)
	{
		QRectF rect;
		map()->includeSelectionRect(rect);
		scaling_center = MapCoordF(rect.center());
		scaling_center_set = true;
	}
	
	connect(map(), SIGNAL(objectSelectionChanged()), this, SLOT(objectSelectionChanged()));
	connect(map(), SIGNAL(selectedObjectEdited()), this, SLOT(updateDirtyRect()));
	updateDirtyRect();
	updateStatusText();
	
	MapEditorTool::init();
}
Пример #22
0
void MapEditorToolBase::updatePreviewObjects()
{
	if (!editingInProgress())
	{
		qWarning("MapEditorToolBase::updatePreviewObjects() called but editing == false");
		return;
	}
	updateSelectionEditPreview(*renderables);
	updateDirtyRect();
}
Пример #23
0
void RotateTool::dragFinish()
{
	if (rotating)
	{
		rotating = false;
		finishEditing();
		updateDirtyRect();
		updateStatusText();
	}
}
Пример #24
0
bool DrawPathTool::keyPressEvent(QKeyEvent* event)
{
	bool key_handled = false;
	if (editingInProgress())
	{
		key_handled = true;
		if (event->key() == Qt::Key_Escape)
			abortDrawing();
		else if (event->key() == Qt::Key_Backspace)
			undoLastPoint();
		else if (event->key() == Qt::Key_Return && allow_closing_paths)
		{
			if (! (event->modifiers() & Qt::ControlModifier))
				closeDrawing();
			finishDrawing();
		}
		else
			key_handled = false;
	}
	else if (event->key() == Qt::Key_Backspace && finished_path_is_selected)
	{
		key_handled = removeLastPointFromSelectedPath();
	}
	
	if (event->key() == Qt::Key_Tab)
		deactivate();
	else if (event->key() == Qt::Key_Space)
	{
		draw_dash_points = !draw_dash_points;
		updateStatusText();
	}
	else if (event->key() == Qt::Key_Control)
	{
		ctrl_pressed = true;
		angle_helper->setActive(true);
		if (editingInProgress() && !dragging)
			updateDrawHover();
		picked_angle = false;
		updateStatusText();
	}
	else if (event->key() == Qt::Key_Shift)
	{
		shift_pressed = true;
		if (!dragging)
		{
			updateHover();
			updateDirtyRect();
		}
		updateStatusText();
	}
	else
		return key_handled;
	return true;
}
Пример #25
0
void RotateTool::dragFinish()
{
	if (qAbs(current_rotation) > 0.0001)
	{
		for (auto object : map()->selectedObjects())
			object->rotateAround(rotation_center, -current_rotation);
	}
	original_rotation = current_rotation = 0;
	finishEditing();
	updateDirtyRect();
	updateStatusText();
}
Пример #26
0
DrawRectangleTool::DrawRectangleTool(MapEditorController* editor, QAction* tool_button, bool is_helper_tool)
: DrawLineAndAreaTool(editor, DrawRectangle, tool_button, is_helper_tool)
, angle_helper(new ConstrainAngleToolHelper())
, snap_helper(new SnappingToolHelper(this))
, key_button_bar(NULL)
{
	cur_map_widget = mapWidget();
	draw_dash_points = true;
	shift_pressed = false;
	ctrl_pressed = false;
	picked_direction = false;
	snapped_to_line = false;
	no_more_effect_on_click = false;
	
	angle_helper->addDefaultAnglesDeg(0);
	angle_helper->setActive(false);
	connect(angle_helper.data(), SIGNAL(displayChanged()), this, SLOT(updateDirtyRect()));
	
	snap_helper->setFilter(SnappingToolHelper::AllTypes);
	connect(snap_helper.data(), SIGNAL(displayChanged()), this, SLOT(updateDirtyRect()));
}
Пример #27
0
bool DrawPathTool::removeLastPointFromSelectedPath()
{
	if (editingInProgress() || map()->getNumSelectedObjects() != 1)
	{
		return false;
	}
	
	Object* object = map()->getFirstSelectedObject();
	if (object->getType() != Object::Path)
	{
		return false;
	}
	
	PathObject* path = object->asPath();
	if (path->parts().size() != 1)
	{
		return false;
	}
	
	int points_on_path = 0;
	int num_coords = path->getCoordinateCount();
	for (int i = 0; i < num_coords && points_on_path < 3; ++i)
	{
		++points_on_path;
		if (path->getCoordinate(i).isCurveStart())
		{
			i += 2; // Skip the control points.
		}
	}
	
	if (points_on_path < 3)
	{
		// Too few points after deleting the last: delete the whole object.
		map()->deleteSelectedObjects();
		return true;
	}
	
	ReplaceObjectsUndoStep* undo_step = new ReplaceObjectsUndoStep(map());
	Object* undo_duplicate = object->duplicate();
	undo_duplicate->setMap(map());
	undo_step->addObject(object, undo_duplicate);
	map()->push(undo_step);
	updateDirtyRect();
	
	path->parts().front().setClosed(false);
	path->deleteCoordinate(num_coords - 1, false);
	
	path->update();
	map()->setObjectsDirty();
	map()->emitSelectionEdited();
	return true;
}
Пример #28
0
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;
}
Пример #29
0
void CutTool::updatePreviewObjects()
{
	deletePreviewPath();
	
	preview_path = new PathObject { edit_object->parts()[drag_part_index] };
	preview_path->setSymbol(Map::getCoveringCombinedLine(), false);
	if (drag_forward)
		preview_path->changePathBounds(0, drag_start_len, drag_end_len);
	else
		preview_path->changePathBounds(0, drag_end_len, drag_start_len);
	
	preview_path->update();
	renderables->insertRenderablesOfObject(preview_path);
	
	updateDirtyRect();
}
Пример #30
0
void EditPointTool::objectSelectionChangedImpl()
{
	if (text_editor)
	{
		// This case can be reproduced by using "select all objects of symbol" for any symbol while editing a text.
		// Revert selection to text object in order to be able to finish editing. Not optimal, but better than crashing.
		map()->clearObjectSelection(false);
		map()->addObjectToSelection(text_editor->getObject(), false);
		finishEditing();
		map()->emitSelectionChanged();
		return;
	}
	
	updateHoverState(cur_pos_map);
	updateDirtyRect();
	updateStatusText();
}