Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds specific tools for selection tool #1620

Merged
merged 6 commits into from
Jul 10, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 148 additions & 0 deletions src/tiled/abstracttileselectiontool.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
/*
* abstracttileselectiontool.cpp
* Copyright 2017, Ketan Gupta <ketan19972010@gmail.com>
*
* This file is part of Tiled.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "abstracttileselectiontool.h"

#include "mapdocument.h"
#include "changeselectedarea.h"

#include <QAction>
#include <QActionGroup>
#include <QApplication>
#include <QToolBar>

using namespace Tiled;
using namespace Tiled::Internal;

AbstractTileSelectionTool::AbstractTileSelectionTool(const QString &name,
const QIcon &icon,
const QKeySequence &shortcut,
QObject *parent)
: AbstractTileTool(name, icon, shortcut, parent)
, mSelectionMode(Replace)
, mDefaultMode(Replace)
{
QIcon replaceIcon(QLatin1String(":images/16x16/selection-replace.png"));
QIcon addIcon(QLatin1String(":images/16x16/selection-add.png"));
QIcon subtractIcon(QLatin1String(":images/16x16/selection-subtract.png"));
QIcon intersectIcon(QLatin1String(":images/16x16/selection-intersect.png"));

mReplace = new QAction(this);
mReplace->setIcon(replaceIcon);
mReplace->setCheckable(true);
mReplace->setChecked(true);

mAdd = new QAction(this);
mAdd->setIcon(addIcon);
mAdd->setCheckable(true);

mSubtract = new QAction(this);
mSubtract->setIcon(subtractIcon);
mSubtract->setCheckable(true);

mIntersect = new QAction(this);
mIntersect->setIcon(intersectIcon);
mIntersect->setCheckable(true);

mActionGroup = new QActionGroup(this);
mActionGroup->addAction(mReplace);
mActionGroup->addAction(mAdd);
mActionGroup->addAction(mSubtract);
mActionGroup->addAction(mIntersect);

connect(mReplace, &QAction::triggered,
[this]() { mSelectionMode = mDefaultMode = Replace; });
connect(mAdd, &QAction::triggered,
[this]() { mSelectionMode = mDefaultMode = Add; });
connect(mSubtract, &QAction::triggered,
[this]() { mSelectionMode = mDefaultMode = Subtract; });
connect(mIntersect, &QAction::triggered,
[this]() { mSelectionMode = mDefaultMode = Intersect; });

languageChanged();
}

void AbstractTileSelectionTool::mousePressed(QGraphicsSceneMouseEvent *event)
{
const Qt::MouseButton button = event->button();

if (button != Qt::LeftButton && button != Qt::RightButton)
return;

MapDocument *document = mapDocument();

QRegion selection;

// Left button modifies selection, right button clears selection
if (button == Qt::LeftButton) {
selection = document->selectedArea();

switch (mSelectionMode) {
case Replace: selection = mSelectedRegion; break;
case Add: selection += mSelectedRegion; break;
case Subtract: selection -= mSelectedRegion; break;
case Intersect: selection &= mSelectedRegion; break;
}
}

if (selection != document->selectedArea()) {
QUndoCommand *cmd = new ChangeSelectedArea(document, selection);
document->undoStack()->push(cmd);
}
}

void AbstractTileSelectionTool::mouseReleased(QGraphicsSceneMouseEvent *)
{
}

void AbstractTileSelectionTool::modifiersChanged(Qt::KeyboardModifiers modifiers)
{
if (modifiers == Qt::ControlModifier)
mSelectionMode = Subtract;
else if (modifiers == Qt::ShiftModifier)
mSelectionMode = Add;
else if (modifiers == (Qt::ControlModifier | Qt::ShiftModifier))
mSelectionMode = Intersect;
else
mSelectionMode = mDefaultMode;

switch (mSelectionMode) {
case Replace: mReplace->setChecked(true); break;
case Add: mAdd->setChecked(true); break;
case Subtract: mSubtract->setChecked(true); break;
case Intersect: mIntersect->setChecked(true); break;
}
}

void AbstractTileSelectionTool::languageChanged()
{
mReplace->setToolTip(tr("Replace Selection"));
mAdd->setToolTip(tr("Add Selection"));
mSubtract->setToolTip(tr("Subtract Selection"));
mIntersect->setToolTip(tr("Intersect Selection"));
}

void AbstractTileSelectionTool::populateToolBar(QToolBar *toolBar)
{
toolBar->addAction(mReplace);
toolBar->addAction(mAdd);
toolBar->addAction(mSubtract);
toolBar->addAction(mIntersect);
}
81 changes: 81 additions & 0 deletions src/tiled/abstracttileselectiontool.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* abstracttileselectiontool.h
* Copyright 2017, Ketan Gupta <ketan19972010@gmail.com>
*
* This file is part of Tiled.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once


#include "abstracttiletool.h"

class QAction;
class QActionGroup;

namespace Tiled {
namespace Internal {

class MapDocument;

class AbstractTileSelectionTool : public AbstractTileTool
{
Q_OBJECT

public:
AbstractTileSelectionTool(const QString &name,
const QIcon &icon,
const QKeySequence &shortcut,
QObject *parent = nullptr);

void mousePressed(QGraphicsSceneMouseEvent *event) override;
void mouseReleased(QGraphicsSceneMouseEvent *event) override;

void modifiersChanged(Qt::KeyboardModifiers modifiers) override;

void languageChanged() override;

void populateToolBar(QToolBar *toolBar) override;

protected:
enum SelectionMode {
Replace,
Add,
Subtract,
Intersect
};

SelectionMode selectionMode() { return mSelectionMode; }

QRegion selectedRegion() { return mSelectedRegion; }
void setSelectedRegion(QRegion region) { mSelectedRegion = region; }

private:

SelectionMode mSelectionMode;
SelectionMode mDefaultMode;

QRegion mSelectedRegion;

QAction *mReplace;
QAction *mAdd;
QAction *mSubtract;
QAction *mIntersect;
QActionGroup *mActionGroup;
};

} // namespace Internal
} // namespace Tiled
Binary file added src/tiled/images/16x16/selection-add.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/tiled/images/16x16/selection-intersect.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/tiled/images/16x16/selection-replace.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/tiled/images/16x16/selection-subtract.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
58 changes: 9 additions & 49 deletions src/tiled/magicwandtool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,16 @@

#include "brushitem.h"
#include "tilepainter.h"
#include "tile.h"
#include "mapscene.h"
#include "mapdocument.h"
#include "changeselectedarea.h"

#include <QApplication>

using namespace Tiled;
using namespace Tiled::Internal;

MagicWandTool::MagicWandTool(QObject *parent)
: AbstractTileTool(tr("Magic Wand"),
QIcon(QLatin1String(
":images/22x22/stock-tool-fuzzy-select-22.png")),
QKeySequence(tr("W")),
parent)
: AbstractTileSelectionTool(tr("Magic Wand"),
QIcon(QLatin1String(
":images/22x22/stock-tool-fuzzy-select-22.png")),
QKeySequence(tr("W")),
parent)
{
}

Expand All @@ -52,48 +46,14 @@ void MagicWandTool::tilePositionChanged(const QPoint &tilePos)
return;

TilePainter regionComputer(mapDocument(), tileLayer);
mSelectedRegion = regionComputer.computeFillRegion(tilePos);
brushItem()->setTileRegion(mSelectedRegion);
}

void MagicWandTool::mousePressed(QGraphicsSceneMouseEvent *event)
{
const Qt::MouseButton button = event->button();
const Qt::KeyboardModifiers modifiers = event->modifiers();

if (button != Qt::LeftButton && button != Qt::RightButton)
return;

MapDocument *document = mapDocument();

QRegion selection;

// Left button modifies selection, right button clears selection
if (button == Qt::LeftButton) {
selection = document->selectedArea();

if (modifiers == Qt::ShiftModifier)
selection += mSelectedRegion;
else if (modifiers == Qt::ControlModifier)
selection -= mSelectedRegion;
else if (modifiers == (Qt::ControlModifier | Qt::ShiftModifier))
selection &= mSelectedRegion;
else
selection = mSelectedRegion;
}

if (selection != document->selectedArea()) {
QUndoCommand *cmd = new ChangeSelectedArea(document, selection);
document->undoStack()->push(cmd);
}
}

void MagicWandTool::mouseReleased(QGraphicsSceneMouseEvent *)
{
setSelectedRegion(regionComputer.computeFillRegion(tilePos));
brushItem()->setTileRegion(selectedRegion());
}

void MagicWandTool::languageChanged()
{
setName(tr("Magic Wand"));
setShortcut(QKeySequence(tr("W")));

AbstractTileSelectionTool::languageChanged();
}
11 changes: 2 additions & 9 deletions src/tiled/magicwandtool.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
#pragma once


#include "abstracttiletool.h"
#include "abstracttileselectiontool.h"

#include "tilelayer.h"

Expand All @@ -36,24 +36,17 @@ class MapDocument;
/**
* Implements a tool that selects a region of connected similar tiles on the layer.
*/
class MagicWandTool : public AbstractTileTool
class MagicWandTool : public AbstractTileSelectionTool
{
Q_OBJECT

public:
MagicWandTool(QObject *parent = nullptr);

void mousePressed(QGraphicsSceneMouseEvent *event) override;
void mouseReleased(QGraphicsSceneMouseEvent *event) override;

void languageChanged() override;

protected:
void tilePositionChanged(const QPoint &tilePos) override;

private:

QRegion mSelectedRegion;
};

} // namespace Internal
Expand Down
1 change: 1 addition & 0 deletions src/tiled/mapeditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -851,6 +851,7 @@ void MapEditor::setupQuickStamps()
void MapEditor::retranslateUi()
{
mToolsToolBar->setWindowTitle(tr("Tools"));
mToolSpecificToolBar->setWindowTitle(tr("Tool Options"));
}

} // namespace Internal
Expand Down
Loading