Make map tile cursor more responsive according to metatile selection
This commit is contained in:
parent
a04db82c2b
commit
16bbfcb654
8 changed files with 253 additions and 8 deletions
|
@ -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*);
|
||||
|
|
77
include/ui/cursortilerect.h
Normal file
77
include/ui/cursortilerect.h
Normal 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
|
|
@ -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();
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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()),
|
||||
|
|
|
@ -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
100
src/ui/cursortilerect.cpp
Normal 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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue