Make map tile cursor more responsive according to metatile selection

This commit is contained in:
Marcus Huderle 2019-01-11 08:52:35 -06:00
parent a04db82c2b
commit 16bbfcb654
8 changed files with 253 additions and 8 deletions

View file

@ -21,6 +21,7 @@
#include "mappixmapitem.h"
#include "settings.h"
#include "movablerect.h"
#include "cursortilerect.h"
class DraggablePixmapItem;
class MetatilesPixmapItem;
@ -96,7 +97,7 @@ public:
QList<QGraphicsPixmapItem*> borderItems;
QList<QGraphicsLineItem*> gridLines;
MovableRect *playerViewRect = nullptr;
MovableRect *cursorMapTileRect = nullptr;
CursorTileRect *cursorMapTileRect = nullptr;
QGraphicsScene *scene_metatiles = nullptr;
QGraphicsScene *scene_current_metatile_selection = nullptr;
@ -149,6 +150,9 @@ private:
QString getMovementPermissionText(uint16_t collision, uint16_t elevation);
private slots:
void onMapStartPaint(QGraphicsSceneMouseEvent *event, MapPixmapItem *item);
void onMapEndPaint(QGraphicsSceneMouseEvent *event, MapPixmapItem *item);
void setSmartPathCursorMode(QGraphicsSceneMouseEvent *event);
void mouseEvent_map(QGraphicsSceneMouseEvent *event, MapPixmapItem *item);
void mouseEvent_collision(QGraphicsSceneMouseEvent *event, CollisionPixmapItem *item);
void onConnectionMoved(MapConnection*);

View file

@ -0,0 +1,77 @@
#ifndef CURSORTILERECT_H
#define CURSORTILERECT_H
#include <QGraphicsItem>
#include <QPainter>
#include <QRgb>
class CursorTileRect : public QGraphicsItem
{
public:
CursorTileRect(bool *enabled, QRgb color);
QRectF boundingRect() const override
{
int width = this->width;
int height = this->height;
if (this->singleTileMode) {
width = 16;
height = 16;
} else if (!this->rightClickSelectionAnchored && this->smartPathMode && this->selectionHeight == 3 && this->selectionWidth == 3) {
width = 32;
height = 32;
}
qreal penWidth = 4;
return QRectF(-penWidth,
-penWidth,
width + penWidth * 2,
height + penWidth * 2);
}
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget) override
{
int width = this->width;
int height = this->height;
if (this->singleTileMode) {
width = 16;
height = 16;
} else if (this->smartPathInEffect()) {
width = 32;
height = 32;
}
painter->setPen(this->color);
painter->drawRect(-1, -1, width + 2, height + 2);
painter->setPen(QColor(0, 0, 0));
painter->drawRect(-2, -2, width + 4, height + 4);
painter->drawRect(0, 0, width, height);
}
void initAnchor(int coordX, int coordY);
void stopAnchor();
void initRightClickSelectionAnchor(int coordX, int coordY);
void stopRightClickSelectionAnchor();
void setSmartPathMode();
bool getSmartPathMode() { return this->smartPathMode; }
void setSingleTileMode();
void stopSingleTileMode();
void setNormalPathMode();
void updateLocation(int x, int y);
void updateSelectionSize(int width, int height);
bool *enabled;
private:
int width;
int height;
bool anchored;
bool rightClickSelectionAnchored;
bool smartPathMode;
bool singleTileMode;
int anchorCoordX;
int anchorCoordY;
int selectionWidth;
int selectionHeight;
QRgb color;
bool smartPathInEffect();
};
#endif // CURSORTILERECT_H

View file

@ -43,6 +43,8 @@ private:
static QList<int> smartPathTable;
signals:
void startPaint(QGraphicsSceneMouseEvent *, MapPixmapItem *);
void endPaint(QGraphicsSceneMouseEvent *, MapPixmapItem *);
void mouseEvent(QGraphicsSceneMouseEvent *, MapPixmapItem *);
void hoveredMapMetatileChanged(int x, int y);
void hoveredMapMetatileCleared();

View file

@ -32,6 +32,7 @@ SOURCES += src/core/block.cpp \
src/ui/collisionpixmapitem.cpp \
src/ui/connectionpixmapitem.cpp \
src/ui/currentselectedmetatilespixmapitem.cpp \
src/ui/cursortilerect.cpp \
src/ui/eventpropertiesframe.cpp \
src/ui/filterchildrenproxymodel.cpp \
src/ui/graphicsview.cpp \
@ -79,6 +80,7 @@ HEADERS += include/core/block.h \
include/ui/collisionpixmapitem.h \
include/ui/connectionpixmapitem.h \
include/ui/currentselectedmetatilespixmapitem.h \
include/ui/cursortilerect.h \
include/ui/eventpropertiesframe.h \
include/ui/filterchildrenproxymodel.h \
include/ui/graphicsview.h \

View file

@ -18,7 +18,7 @@ Editor::Editor(Ui::MainWindow* ui)
this->selected_events = new QList<DraggablePixmapItem*>;
this->settings = new Settings();
this->playerViewRect = new MovableRect(&this->settings->playerViewRectEnabled, 30 * 8, 20 * 8, qRgb(255, 255, 255));
this->cursorMapTileRect = new MovableRect(&this->settings->cursorTileRectEnabled, 16, 16, qRgb(255, 255, 255));
this->cursorMapTileRect = new CursorTileRect(&this->settings->cursorTileRectEnabled, qRgb(255, 255, 255));
}
void Editor::saveProject() {
@ -36,7 +36,7 @@ void Editor::save() {
}
void Editor::undo() {
if (current_view) {
if (current_view && map_item->paintingEnabled) {
map->undo();
map_item->draw();
collision_item->draw();
@ -44,7 +44,7 @@ void Editor::undo() {
}
void Editor::redo() {
if (current_view) {
if (current_view && map_item->paintingEnabled) {
map->redo();
map_item->draw();
collision_item->draw();
@ -75,6 +75,7 @@ void Editor::setEditingMap() {
}
setBorderItemsVisible(ui->checkBox_ToggleBorder->isChecked());
setConnectionItemsVisible(false);
this->cursorMapTileRect->stopSingleTileMode();
}
void Editor::setEditingCollision() {
@ -94,6 +95,7 @@ void Editor::setEditingCollision() {
}
setBorderItemsVisible(ui->checkBox_ToggleBorder->isChecked());
setConnectionItemsVisible(false);
this->cursorMapTileRect->setSingleTileMode();
}
void Editor::setEditingObjects() {
@ -111,6 +113,7 @@ void Editor::setEditingObjects() {
}
setBorderItemsVisible(ui->checkBox_ToggleBorder->isChecked());
setConnectionItemsVisible(false);
this->cursorMapTileRect->setSingleTileMode();
}
void Editor::setEditingConnections() {
@ -139,6 +142,7 @@ void Editor::setEditingConnections() {
}
setBorderItemsVisible(true, 0.4);
setConnectionItemsVisible(true);
this->cursorMapTileRect->setSingleTileMode();
}
void Editor::setDiveEmergeControls() {
@ -350,6 +354,8 @@ void Editor::onHoveredMetatileSelectionCleared() {
}
void Editor::onSelectedMetatilesChanged() {
QPoint size = this->metatile_selector_item->getSelectionDimensions();
this->cursorMapTileRect->updateSelectionSize(size.x(), size.y());
this->redrawCurrentMetatilesSelection();
}
@ -441,7 +447,7 @@ bool Editor::setMap(QString map_name) {
return true;
}
void Editor::mouseEvent_map(QGraphicsSceneMouseEvent *event, MapPixmapItem *item) {
void Editor::onMapStartPaint(QGraphicsSceneMouseEvent *event, MapPixmapItem *item) {
if (!item->paintingEnabled) {
return;
}
@ -449,8 +455,36 @@ void Editor::mouseEvent_map(QGraphicsSceneMouseEvent *event, MapPixmapItem *item
QPointF pos = event->pos();
int x = static_cast<int>(pos.x()) / 16;
int y = static_cast<int>(pos.y()) / 16;
this->playerViewRect->updateLocation(x, y);
this->cursorMapTileRect->updateLocation(x, y);
if (event->buttons() & Qt::RightButton && (map_edit_mode == "paint" || map_edit_mode == "fill")) {
this->cursorMapTileRect->initRightClickSelectionAnchor(x, y);
} else {
this->cursorMapTileRect->initAnchor(x, y);
}
}
void Editor::onMapEndPaint(QGraphicsSceneMouseEvent *event, MapPixmapItem *item) {
if (!item->paintingEnabled) {
return;
}
this->cursorMapTileRect->stopRightClickSelectionAnchor();
this->cursorMapTileRect->stopAnchor();
}
void Editor::setSmartPathCursorMode(QGraphicsSceneMouseEvent *event)
{
bool smartPathsEnabled = event->modifiers() & Qt::ShiftModifier;
if (smartPathsEnabled || settings->smartPathsEnabled) {
this->cursorMapTileRect->setSmartPathMode();
} else {
this->cursorMapTileRect->setNormalPathMode();
}
}
void Editor::mouseEvent_map(QGraphicsSceneMouseEvent *event, MapPixmapItem *item) {
if (!item->paintingEnabled) {
return;
}
if (map_edit_mode == "paint") {
if (event->buttons() & Qt::RightButton) {
item->updateMetatileSelection(event);
@ -461,6 +495,7 @@ void Editor::mouseEvent_map(QGraphicsSceneMouseEvent *event, MapPixmapItem *item
item->floodFill(event);
}
} else {
this->setSmartPathCursorMode(event);
item->paint(event);
}
} else if (map_edit_mode == "select") {
@ -483,7 +518,14 @@ void Editor::mouseEvent_map(QGraphicsSceneMouseEvent *event, MapPixmapItem *item
} else if (map_edit_mode == "shift") {
item->shift(event);
}
QPointF pos = event->pos();
int x = static_cast<int>(pos.x()) / 16;
int y = static_cast<int>(pos.y()) / 16;
this->playerViewRect->updateLocation(x, y);
this->cursorMapTileRect->updateLocation(x, y);
}
void Editor::mouseEvent_collision(QGraphicsSceneMouseEvent *event, CollisionPixmapItem *item) {
if (!item->paintingEnabled) {
return;
@ -592,6 +634,10 @@ void Editor::displayMapMetatiles() {
map_item = new MapPixmapItem(map, this->metatile_selector_item, this->settings);
connect(map_item, SIGNAL(mouseEvent(QGraphicsSceneMouseEvent*,MapPixmapItem*)),
this, SLOT(mouseEvent_map(QGraphicsSceneMouseEvent*,MapPixmapItem*)));
connect(map_item, SIGNAL(startPaint(QGraphicsSceneMouseEvent*,MapPixmapItem*)),
this, SLOT(onMapStartPaint(QGraphicsSceneMouseEvent*,MapPixmapItem*)));
connect(map_item, SIGNAL(endPaint(QGraphicsSceneMouseEvent*,MapPixmapItem*)),
this, SLOT(onMapEndPaint(QGraphicsSceneMouseEvent*,MapPixmapItem*)));
connect(map_item, SIGNAL(hoveredMapMetatileChanged(int, int)),
this, SLOT(onHoveredMapMetatileChanged(int, int)));
connect(map_item, SIGNAL(hoveredMapMetatileCleared()),

View file

@ -1623,6 +1623,7 @@ void MainWindow::on_toolButton_Paint_clicked()
{
editor->map_edit_mode = "paint";
editor->settings->mapCursor = QCursor(QPixmap(":/icons/pencil_cursor.ico"), 10, 10);
editor->cursorMapTileRect->stopSingleTileMode();
ui->scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
@ -1635,6 +1636,7 @@ void MainWindow::on_toolButton_Select_clicked()
{
editor->map_edit_mode = "select";
editor->settings->mapCursor = QCursor(QPixmap(":/icons/cursor.ico"), 0, 0);
editor->cursorMapTileRect->setSingleTileMode();
ui->scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
@ -1647,6 +1649,7 @@ void MainWindow::on_toolButton_Fill_clicked()
{
editor->map_edit_mode = "fill";
editor->settings->mapCursor = QCursor(QPixmap(":/icons/fill_color_cursor.ico"), 10, 10);
editor->cursorMapTileRect->setSingleTileMode();
ui->scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
@ -1659,6 +1662,7 @@ void MainWindow::on_toolButton_Dropper_clicked()
{
editor->map_edit_mode = "pick";
editor->settings->mapCursor = QCursor(QPixmap(":/icons/pipette_cursor.ico"), 10, 10);
editor->cursorMapTileRect->setSingleTileMode();
ui->scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
@ -1671,6 +1675,7 @@ void MainWindow::on_toolButton_Move_clicked()
{
editor->map_edit_mode = "move";
editor->settings->mapCursor = QCursor(QPixmap(":/icons/move.ico"), 7, 7);
editor->cursorMapTileRect->setSingleTileMode();
ui->scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
@ -1683,6 +1688,7 @@ void MainWindow::on_toolButton_Shift_clicked()
{
editor->map_edit_mode = "shift";
editor->settings->mapCursor = QCursor(QPixmap(":/icons/shift_cursor.ico"), 10, 10);
editor->cursorMapTileRect->setSingleTileMode();
ui->scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
@ -1837,7 +1843,13 @@ void MainWindow::on_pushButton_clicked()
void MainWindow::on_checkBox_smartPaths_stateChanged(int selected)
{
editor->settings->smartPathsEnabled = selected == Qt::Checked;
bool enabled = selected == Qt::Checked;
editor->settings->smartPathsEnabled = enabled;
if (enabled) {
editor->cursorMapTileRect->setSmartPathMode();
} else {
editor->cursorMapTileRect->setNormalPathMode();
}
}
void MainWindow::on_checkBox_ToggleBorder_stateChanged(int selected)

100
src/ui/cursortilerect.cpp Normal file
View file

@ -0,0 +1,100 @@
#include "cursortilerect.h"
#include "log.h"
CursorTileRect::CursorTileRect(bool *enabled, QRgb color)
{
this->enabled = enabled;
this->color = color;
this->width = 16;
this->height = 16;
this->smartPathMode = false;
this->singleTileMode = false;
this->anchored = false;
this->rightClickSelectionAnchored = false;
this->anchorCoordX = 0;
this->anchorCoordY = 0;
this->selectionWidth = 1;
this->selectionHeight = 1;
}
void CursorTileRect::initAnchor(int coordX, int coordY)
{
this->anchorCoordX = coordX;
this->anchorCoordY = coordY;
this->anchored = true;
}
void CursorTileRect::stopAnchor()
{
this->anchored = false;
}
void CursorTileRect::initRightClickSelectionAnchor(int coordX, int coordY)
{
this->anchorCoordX = coordX;
this->anchorCoordY = coordY;
this->rightClickSelectionAnchored = true;
}
void CursorTileRect::stopRightClickSelectionAnchor()
{
this->rightClickSelectionAnchored = false;
}
void CursorTileRect::updateSelectionSize(int width, int height)
{
this->selectionWidth = width;
this->selectionHeight = height;
this->width = width * 16;
this->height = height * 16;
this->prepareGeometryChange();
this->update();
}
void CursorTileRect::setSmartPathMode()
{
this->smartPathMode = true;
}
void CursorTileRect::setSingleTileMode()
{
this->singleTileMode = true;
}
void CursorTileRect::stopSingleTileMode()
{
this->singleTileMode = false;
}
void CursorTileRect::setNormalPathMode()
{
this->smartPathMode = false;
}
bool CursorTileRect::smartPathInEffect()
{
return !this->rightClickSelectionAnchored && this->smartPathMode && this->selectionHeight == 3 && this->selectionWidth == 3;
}
void CursorTileRect::updateLocation(int coordX, int coordY)
{
if (!this->singleTileMode) {
if (this->rightClickSelectionAnchored) {
coordX = qMin(coordX, this->anchorCoordX);
coordY = qMin(coordY, this->anchorCoordY);
}
else if (this->anchored && !this->smartPathInEffect()) {
int xDiff = coordX - this->anchorCoordX;
int yDiff = coordY - this->anchorCoordY;
if (xDiff < 0 && xDiff % this->selectionWidth != 0) xDiff -= this->selectionWidth;
if (yDiff < 0 && yDiff % this->selectionHeight != 0) yDiff -= this->selectionHeight;
coordX = this->anchorCoordX + (xDiff / this->selectionWidth) * this->selectionWidth;
coordY = this->anchorCoordY + (yDiff / this->selectionHeight) * this->selectionHeight;
}
}
this->setX(coordX * 16);
this->setY(coordY * 16);
this->setVisible(*this->enabled);
}

View file

@ -515,6 +515,7 @@ void MapPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
int y = static_cast<int>(pos.y()) / 16;
this->paint_tile_initial_x = x;
this->paint_tile_initial_y = y;
emit startPaint(event, this);
emit mouseEvent(event, this);
}
void MapPixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
@ -524,5 +525,6 @@ void MapPixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
emit mouseEvent(event, this);
}
void MapPixmapItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
emit endPaint(event, this);
emit mouseEvent(event, this);
}