From b94412cb8376a07aeb034e152bcb443f4e996183 Mon Sep 17 00:00:00 2001 From: tetektoza <tetektoza@gmail.com> Date: Thu, 1 Aug 2024 01:21:42 +0200 Subject: [PATCH] Everywhere: Add coordinates of current cursor position to QStatusBar This patch adds coordinates of current cursor position to QStatusBar while displaying them in two different colors either cursor is on an image or it is not. --- source/mainwindow.cpp | 10 ++++-- source/mainwindow.h | 1 + source/views/celview.cpp | 45 +++++++++++++++++++++------ source/views/celview.h | 2 ++ source/views/levelcelview.cpp | 57 +++++++++++++++++++++++++++-------- source/views/levelcelview.h | 9 ++++++ source/views/view.cpp | 7 +++++ source/views/view.h | 1 + 8 files changed, 107 insertions(+), 25 deletions(-) diff --git a/source/mainwindow.cpp b/source/mainwindow.cpp index 30a25ea8..81620bac 100644 --- a/source/mainwindow.cpp +++ b/source/mainwindow.cpp @@ -625,7 +625,7 @@ void MainWindow::openFile(const OpenAsParam ¶ms) QObject::connect(this->trnUniqueWidget, &PaletteWidget::clearRootBorder, this->trnWidget, &PaletteWidget::clearBorder); if (isTileset) { - this->levelCelView = new LevelCelView(this->undoStack); + this->levelCelView = new LevelCelView(this->undoStack, this); this->levelCelView->initialize(this->gfx, this->min, this->til, this->sol, this->amp); // Refresh CEL view if a PAL or TRN is modified @@ -651,7 +651,7 @@ void MainWindow::openFile(const OpenAsParam ¶ms) } // Otherwise build a CelView else { - this->celView = new CelView(this->undoStack); + this->celView = new CelView(this->undoStack, this); this->celView->initialize(this->gfx); // Refresh CEL view if a PAL or TRN is modified @@ -778,6 +778,12 @@ void MainWindow::openPalFiles(QStringList filePaths, PaletteWidget *widget) this->ui->statusBar->clearMessage(); } +void MainWindow::updateStatusBar(const QString &status, const QString &styleSheet) +{ + this->ui->statusBar->setStyleSheet(styleSheet); + this->ui->statusBar->showMessage(status); +} + void MainWindow::saveFile(const QString &gfxPath) { this->ui->statusBar->showMessage("Saving..."); diff --git a/source/mainwindow.h b/source/mainwindow.h index 0711caf1..570358f0 100644 --- a/source/mainwindow.h +++ b/source/mainwindow.h @@ -63,6 +63,7 @@ class MainWindow : public QMainWindow { void nextPaletteCycle(D1PAL_CYCLE_TYPE type); void resetPaletteCycle(); + void updateStatusBar(const QString &status, const QString &styleSheet); QString getLastFilePath(); QString fileDialog(FILE_DIALOG_MODE mode, const char *title, const char *filter); diff --git a/source/views/celview.cpp b/source/views/celview.cpp index 92e4eba8..67b9a4a7 100644 --- a/source/views/celview.cpp +++ b/source/views/celview.cpp @@ -11,6 +11,7 @@ #include <QMenu> #include <QMessageBox> #include <QMimeData> +#include <utility> #include "ui_celview.h" #include "undostack/framecmds.h" @@ -40,6 +41,25 @@ void CelScene::mousePressEvent(QGraphicsSceneMouseEvent *event) emit this->framePixelClicked(x, y); } +void CelScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + bool isInImage = false; + auto *levelcelview = dynamic_cast<LevelCelView *>(view); + if (levelcelview != nullptr) { + if (levelcelview->checkImageType(event->scenePos().x(), event->scenePos().y()) != IMAGE_TYPE::NONE) + isInImage = true; + } else { + isInImage = dynamic_cast<CelView *>(view)->isInImage(event->scenePos().x(), event->scenePos().y()); + } + + if (isInImage) { + dynamic_cast<MainWindow *>(view->window())->updateStatusBar(QString::fromStdString(std::to_string(static_cast<int>(event->scenePos().x())) + ", " + std::to_string(static_cast<int>(event->scenePos().y()))), "color: rgb(0, 0, 0);"); + return; + } + + dynamic_cast<MainWindow *>(view->window())->updateStatusBar(QString::fromStdString(std::to_string(static_cast<int>(event->scenePos().x())) + ", " + std::to_string(static_cast<int>(event->scenePos().y()))), "color: rgb(160, 160, 160);"); +} + void CelScene::dragEnterEvent(QGraphicsSceneDragDropEvent *event) { this->dragMoveEvent(event); @@ -73,7 +93,7 @@ void CelScene::contextMenuEvent(QContextMenuEvent *event) CelView::CelView(std::shared_ptr<UndoStack> us, QWidget *parent) : QWidget(parent) - , undoStack(us) + , undoStack(std::move(us)) , ui(new Ui::CelView()) , celScene(new CelScene(this)) { @@ -121,18 +141,23 @@ int CelView::getCurrentFrameIndex() return this->currentFrameIndex; } -void CelView::framePixelClicked(unsigned x, unsigned y) +bool CelView::isInImage(unsigned int x, unsigned int y) const { - int frameIndex = this->currentFrameIndex; + const int frameIndex = this->currentFrameIndex; + + const int tx = x - CEL_SCENE_SPACING; + const int ty = y - CEL_SCENE_SPACING; + + return ((ty > 0 && ty < this->gfx->getFrameHeight(frameIndex)) /* Coordinates are above/below image */ + && (tx > 0 && tx < this->gfx->getFrameWidth(frameIndex) /* Coordinates are to the left/right of the image */)); +} - int tx = x - CEL_SCENE_SPACING; - if (tx < 0 || tx >= this->gfx->getFrameWidth(frameIndex)) - return; // click is left or right from the frame -> ignore - int ty = y - CEL_SCENE_SPACING; - if (ty < 0 || ty >= this->gfx->getFrameHeight(frameIndex)) - return; // click is up or down from the frame -> ignore +void CelView::framePixelClicked(unsigned x, unsigned y) +{ + if (!isInImage(x, y)) + return; - int colorIndex = this->gfx->getFrame(frameIndex)->getPixel(tx, ty).getPaletteIndex(); + int colorIndex = this->gfx->getFrame(this->currentFrameIndex)->getPixel(x - CEL_SCENE_SPACING, y - CEL_SCENE_SPACING).getPaletteIndex(); emit this->colorIndexClicked(colorIndex); } diff --git a/source/views/celview.h b/source/views/celview.h index cec78e7b..9cd1b4c0 100644 --- a/source/views/celview.h +++ b/source/views/celview.h @@ -33,6 +33,7 @@ class CelScene : public QGraphicsScene { private slots: void mousePressEvent(QGraphicsSceneMouseEvent *event); + void mouseMoveEvent(QGraphicsSceneMouseEvent *event); void dragEnterEvent(QGraphicsSceneDragDropEvent *event); void dragMoveEvent(QGraphicsSceneDragDropEvent *event); void dropEvent(QGraphicsSceneDragDropEvent *event); @@ -66,6 +67,7 @@ class CelView : public QWidget { void updateGroupIndex(); void displayFrame(); + [[nodiscard]] bool isInImage(unsigned int x, unsigned int y) const; signals: void frameRefreshed(); diff --git a/source/views/levelcelview.cpp b/source/views/levelcelview.cpp index b3cdba61..4244cf72 100644 --- a/source/views/levelcelview.cpp +++ b/source/views/levelcelview.cpp @@ -184,6 +184,38 @@ void LevelCelView::update() this->tabFrameWidget->initialize(this, this->gfx); } +IMAGE_TYPE LevelCelView::checkImageType(unsigned x, unsigned y) +{ + unsigned celFrameWidth = MICRO_WIDTH; // this->gfx->getFrameWidth(this->currentFrameIndex); + unsigned subtileWidth = this->min->getSubtileWidth() * MICRO_WIDTH; + unsigned tileWidth = subtileWidth * TILE_WIDTH; + + unsigned celFrameHeight = MICRO_HEIGHT; // this->gfx->getFrameHeight(this->currentFrameIndex); + unsigned subtileHeight = this->min->getSubtileHeight() * MICRO_HEIGHT; + unsigned subtileShiftY = subtileWidth / 4; + unsigned tileHeight = subtileHeight + 2 * subtileShiftY; + + if (x >= CEL_SCENE_SPACING && x < (celFrameWidth + CEL_SCENE_SPACING) + && y >= CEL_SCENE_SPACING && y < (celFrameHeight + CEL_SCENE_SPACING) + && this->gfx->getFrameCount() != 0) { + return IMAGE_TYPE::FRAME; + } else if (x >= (celFrameWidth + CEL_SCENE_SPACING * 2) + && x < (celFrameWidth + subtileWidth + CEL_SCENE_SPACING * 2) + && y >= CEL_SCENE_SPACING + && y < (subtileHeight + CEL_SCENE_SPACING) + && this->min->getSubtileCount() != 0) { + return IMAGE_TYPE::SUBTILE; + } else if (x >= (celFrameWidth + subtileWidth + CEL_SCENE_SPACING * 3) + && x < (celFrameWidth + subtileWidth + tileWidth + CEL_SCENE_SPACING * 3) + && y >= CEL_SCENE_SPACING + && y < (tileHeight + CEL_SCENE_SPACING) + && this->til->getTileCount() != 0) { + return IMAGE_TYPE::TILE; + } + + return IMAGE_TYPE::NONE; +} + void LevelCelView::framePixelClicked(unsigned x, unsigned y) { quint8 index = 0; @@ -199,19 +231,16 @@ void LevelCelView::framePixelClicked(unsigned x, unsigned y) this->mode = TILESET_MODE::FREE; - if (x >= CEL_SCENE_SPACING && x < (celFrameWidth + CEL_SCENE_SPACING) - && y >= CEL_SCENE_SPACING && y < (celFrameHeight + CEL_SCENE_SPACING) - && this->gfx->getFrameCount() != 0) { + switch (this->checkImageType(x, y)) { + case IMAGE_TYPE::FRAME: { // If CEL frame color is clicked, select it in the palette widgets D1GfxFrame *frame = this->gfx->getFrame(this->currentFrameIndex); index = frame->getPixel(x - CEL_SCENE_SPACING, y - CEL_SCENE_SPACING).getPaletteIndex(); emit this->colorIndexClicked(index); - } else if (x >= (celFrameWidth + CEL_SCENE_SPACING * 2) - && x < (celFrameWidth + subtileWidth + CEL_SCENE_SPACING * 2) - && y >= CEL_SCENE_SPACING - && y < (subtileHeight + CEL_SCENE_SPACING) - && this->min->getSubtileCount() != 0) { + break; + } + case IMAGE_TYPE::SUBTILE: { this->mode = TILESET_MODE::SUBTILE; // When a CEL frame is clicked in the subtile, display the corresponding CEL frame @@ -230,11 +259,9 @@ void LevelCelView::framePixelClicked(unsigned x, unsigned y) this->currentFrameIndex = frameIndex - 1; this->displayFrame(); } - } else if (x >= (celFrameWidth + subtileWidth + CEL_SCENE_SPACING * 3) - && x < (celFrameWidth + subtileWidth + tileWidth + CEL_SCENE_SPACING * 3) - && y >= CEL_SCENE_SPACING - && y < (tileHeight + CEL_SCENE_SPACING) - && this->til->getTileCount() != 0) { + break; + } + case IMAGE_TYPE::TILE: { this->mode = TILESET_MODE::TILE; // When a subtile is clicked in the tile, display the corresponding subtile @@ -249,6 +276,10 @@ void LevelCelView::framePixelClicked(unsigned x, unsigned y) this->currentSubtileIndex = tilSubtiles.at(this->editIndex); this->displayFrame(); } + break; + } + default: + break; } this->update(); diff --git a/source/views/levelcelview.h b/source/views/levelcelview.h index 6f98e691..6a76af3a 100644 --- a/source/views/levelcelview.h +++ b/source/views/levelcelview.h @@ -39,6 +39,13 @@ enum class TILESET_MODE { TILE, // Edit tile }; +enum class IMAGE_TYPE { + NONE, + FRAME, + SUBTILE, + TILE +}; + class LevelCelView : public QWidget { Q_OBJECT @@ -94,6 +101,8 @@ class LevelCelView : public QWidget { void displayFrame(); + IMAGE_TYPE checkImageType(unsigned int x, unsigned int y); + private: void update(); void collectFrameUsers(int frameIndex, QList<int> &users) const; diff --git a/source/views/view.cpp b/source/views/view.cpp index 54f38f7e..01de0d0c 100644 --- a/source/views/view.cpp +++ b/source/views/view.cpp @@ -1,8 +1,10 @@ #include "view.h" +#include "mainwindow.h" View::View(QWidget *parent) : QGraphicsView(parent) { + this->setMouseTracking(true); } void View::mousePressEvent(QMouseEvent *event) @@ -50,3 +52,8 @@ void View::mouseReleaseEvent(QMouseEvent *event) } } } + +void View::leaveEvent(QEvent *event) +{ + dynamic_cast<MainWindow *>(this->window())->updateStatusBar("", "color: rgb(0, 0, 0);"); +} diff --git a/source/views/view.h b/source/views/view.h index 62de97dd..235f93cd 100644 --- a/source/views/view.h +++ b/source/views/view.h @@ -13,4 +13,5 @@ class View : public QGraphicsView { private slots: void mouseReleaseEvent(QMouseEvent *event); void mousePressEvent(QMouseEvent *event); + void leaveEvent(QEvent *event) override; };