redesign layout dimension change window
This commit is contained in:
parent
c9695521c7
commit
c83474b6bc
13 changed files with 854 additions and 107 deletions
276
forms/resizelayoutpopup.ui
Normal file
276
forms/resizelayoutpopup.ui
Normal file
|
@ -0,0 +1,276 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>ResizeLayoutPopup</class>
|
||||||
|
<widget class="QDialog" name="ResizeLayoutPopup">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>598</width>
|
||||||
|
<height>378</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Dialog</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Resize Layout</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
<property name="margin">
|
||||||
|
<number>8</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::Reset</set>
|
||||||
|
</property>
|
||||||
|
<property name="centerButtons">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0">
|
||||||
|
<widget class="QGraphicsView" name="graphicsView"/>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QFrame" name="frame">
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Raised</enum>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="text">
|
||||||
|
<string>Width</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="NoScrollSpinBox" name="spinBox_width">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>64</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Height</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="NoScrollSpinBox" name="spinBox_height">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>64</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_3">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QFrame" name="frame_border">
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Raised</enum>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="text">
|
||||||
|
<string>Border Width</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="NoScrollSpinBox" name="spinBox_borderWidth">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>64</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_5">
|
||||||
|
<property name="text">
|
||||||
|
<string>Border Height</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="NoScrollSpinBox" name="spinBox_borderHeight">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>64</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_4">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>NoScrollSpinBox</class>
|
||||||
|
<extends>QSpinBox</extends>
|
||||||
|
<header>noscrollspinbox.h</header>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>ResizeLayoutPopup</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>248</x>
|
||||||
|
<y>254</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>157</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>ResizeLayoutPopup</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>316</x>
|
||||||
|
<y>260</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>286</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
|
@ -8,6 +8,7 @@
|
||||||
#include <QUndoCommand>
|
#include <QUndoCommand>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
|
#include <QMargins>
|
||||||
|
|
||||||
class Map;
|
class Map;
|
||||||
class Layout;
|
class Layout;
|
||||||
|
@ -203,7 +204,12 @@ private:
|
||||||
/// Implements a command to commit a map or border resize action.
|
/// Implements a command to commit a map or border resize action.
|
||||||
class ResizeLayout : public QUndoCommand {
|
class ResizeLayout : public QUndoCommand {
|
||||||
public:
|
public:
|
||||||
ResizeLayout(Layout *layout, QSize oldLayoutDimensions, QSize newLayoutDimensions,
|
// ResizeLayout(Layout *layout, QSize oldLayoutDimensions, QSize newLayoutDimensions,
|
||||||
|
// const Blockdata &oldMetatiles, const Blockdata &newMetatiles,
|
||||||
|
// QSize oldBorderDimensions, QSize newBorderDimensions,
|
||||||
|
// const Blockdata &oldBorder, const Blockdata &newBorder,
|
||||||
|
// QUndoCommand *parent = nullptr);
|
||||||
|
ResizeLayout(Layout *layout, QSize oldLayoutDimensions, QMargins newLayoutMargins,
|
||||||
const Blockdata &oldMetatiles, const Blockdata &newMetatiles,
|
const Blockdata &oldMetatiles, const Blockdata &newMetatiles,
|
||||||
QSize oldBorderDimensions, QSize newBorderDimensions,
|
QSize oldBorderDimensions, QSize newBorderDimensions,
|
||||||
const Blockdata &oldBorder, const Blockdata &newBorder,
|
const Blockdata &oldBorder, const Blockdata &newBorder,
|
||||||
|
@ -220,8 +226,7 @@ private:
|
||||||
|
|
||||||
int oldLayoutWidth;
|
int oldLayoutWidth;
|
||||||
int oldLayoutHeight;
|
int oldLayoutHeight;
|
||||||
int newLayoutWidth;
|
QMargins newLayoutMargins;
|
||||||
int newLayoutHeight;
|
|
||||||
|
|
||||||
int oldBorderWidth;
|
int oldBorderWidth;
|
||||||
int oldBorderHeight;
|
int oldBorderHeight;
|
||||||
|
|
|
@ -96,6 +96,7 @@ public:
|
||||||
void setBlock(int x, int y, Block block, bool enableScriptCallback = false);
|
void setBlock(int x, int y, Block block, bool enableScriptCallback = false);
|
||||||
void setBlockdata(Blockdata blockdata, bool enableScriptCallback = false);
|
void setBlockdata(Blockdata blockdata, bool enableScriptCallback = false);
|
||||||
|
|
||||||
|
void adjustDimensions(QMargins margins, bool setNewBlockdata = true, bool enableScriptCallback = false);
|
||||||
void setDimensions(int newWidth, int newHeight, bool setNewBlockdata = true, bool enableScriptCallback = false);
|
void setDimensions(int newWidth, int newHeight, bool setNewBlockdata = true, bool enableScriptCallback = false);
|
||||||
void setBorderDimensions(int newWidth, int newHeight, bool setNewBlockdata = true, bool enableScriptCallback = false);
|
void setBorderDimensions(int newWidth, int newHeight, bool setNewBlockdata = true, bool enableScriptCallback = false);
|
||||||
|
|
||||||
|
|
|
@ -5,12 +5,13 @@
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QRgb>
|
#include <QRgb>
|
||||||
|
|
||||||
class MovableRect : public QGraphicsItem
|
|
||||||
|
|
||||||
|
class MovableRect : public QGraphicsRectItem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MovableRect(bool *enabled, int width, int height, QRgb color);
|
MovableRect(bool *enabled, int width, int height, QRgb color);
|
||||||
QRectF boundingRect() const override
|
QRectF boundingRect() const override {
|
||||||
{
|
|
||||||
qreal penWidth = 4;
|
qreal penWidth = 4;
|
||||||
return QRectF(-penWidth,
|
return QRectF(-penWidth,
|
||||||
-penWidth,
|
-penWidth,
|
||||||
|
@ -18,21 +19,62 @@ public:
|
||||||
20 * 8 + penWidth * 2);
|
20 * 8 + penWidth * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) override
|
void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) override {
|
||||||
{
|
|
||||||
if (!(*enabled)) return;
|
if (!(*enabled)) return;
|
||||||
painter->setPen(this->color);
|
painter->setPen(this->color);
|
||||||
painter->drawRect(x() - 2, y() - 2, this->width + 3, this->height + 3);
|
painter->drawRect(this->rect().x() - 2, this->rect().y() - 2, this->rect().width() + 3, this->rect().height() + 3);
|
||||||
painter->setPen(QColor(0, 0, 0));
|
painter->setPen(QColor(0, 0, 0));
|
||||||
painter->drawRect(x() - 3, y() - 3, this->width + 5, this->height + 5);
|
painter->drawRect(this->rect().x() - 3, this->rect().y() - 3, this->rect().width() + 5, this->rect().height() + 5);
|
||||||
painter->drawRect(x() - 1, y() - 1, this->width + 1, this->height + 1);
|
painter->drawRect(this->rect().x() - 1, this->rect().y() - 1, this->rect().width() + 1, this->rect().height() + 1);
|
||||||
}
|
}
|
||||||
void updateLocation(int x, int y);
|
void updateLocation(int x, int y);
|
||||||
bool *enabled;
|
bool *enabled;
|
||||||
private:
|
|
||||||
int width;
|
protected:
|
||||||
int height;
|
|
||||||
QRgb color;
|
QRgb color;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// A MovableRect with the addition of being resizable.
|
||||||
|
class ResizableRect : public QObject, public MovableRect
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
ResizableRect(QObject *parent, bool *enabled, int width, int height, QRgb color);
|
||||||
|
|
||||||
|
QRectF boundingRect() const override {
|
||||||
|
return QRectF(this->rect() + QMargins(lineWidth, lineWidth, lineWidth, lineWidth));
|
||||||
|
}
|
||||||
|
|
||||||
|
QPainterPath shape() const override {
|
||||||
|
QPainterPath path;
|
||||||
|
path.addRect(this->rect() + QMargins(lineWidth, lineWidth, lineWidth, lineWidth));
|
||||||
|
path.addRect(this->rect() - QMargins(lineWidth, lineWidth, lineWidth, lineWidth));
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
void updatePosFromRect(QRect newPos);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void hoverMoveEvent(QGraphicsSceneHoverEvent *event) override;
|
||||||
|
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override;
|
||||||
|
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
|
||||||
|
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum class Edge { None, Left, Right, Top, Bottom, TopLeft, BottomLeft, TopRight, BottomRight };
|
||||||
|
ResizableRect::Edge detectEdge(int x, int y);
|
||||||
|
|
||||||
|
// Variables for keeping state of original rect while resizing
|
||||||
|
ResizableRect::Edge clickedEdge = ResizableRect::Edge::None;
|
||||||
|
QPointF clickedPos = QPointF();
|
||||||
|
QRect clickedRect;
|
||||||
|
|
||||||
|
int lineWidth = 8;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void rectUpdated(QRect rect);
|
||||||
|
};
|
||||||
|
|
||||||
#endif // MOVABLERECT_H
|
#endif // MOVABLERECT_H
|
||||||
|
|
|
@ -12,6 +12,8 @@ public:
|
||||||
void wheelEvent(QWheelEvent *event) override;
|
void wheelEvent(QWheelEvent *event) override;
|
||||||
void focusOutEvent(QFocusEvent *event) override;
|
void focusOutEvent(QFocusEvent *event) override;
|
||||||
|
|
||||||
|
void setLineEditEnabled(bool enabled);
|
||||||
|
|
||||||
unsigned getActionId();
|
unsigned getActionId();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
106
include/ui/resizelayoutpopup.h
Normal file
106
include/ui/resizelayoutpopup.h
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
#ifndef RESIZELAYOUTPOPUP_H
|
||||||
|
#define RESIZELAYOUTPOPUP_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QPointer>
|
||||||
|
#include <QGraphicsScene>
|
||||||
|
#include <QGraphicsLineItem>
|
||||||
|
#include <QGraphicsRectItem>
|
||||||
|
|
||||||
|
class ResizableRect;
|
||||||
|
class Editor;
|
||||||
|
namespace Ui {
|
||||||
|
class ResizeLayoutPopup;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// Custom scene that paints its background a gray checkered pattern.
|
||||||
|
/// Additionally there is a definable "valid" area which will paint the checkerboard green inside.
|
||||||
|
class CheckeredBgScene : public QGraphicsScene {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
CheckeredBgScene(QObject *parent = nullptr);
|
||||||
|
void setValidRect(int x, int y, int width, int height) {
|
||||||
|
this->validRect = QRect(x * this->gridSize, y * this->gridSize, width * this->gridSize, height * this->gridSize);
|
||||||
|
}
|
||||||
|
void setValidRect(QRect rect) {
|
||||||
|
this->validRect = rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void drawBackground(QPainter *painter, const QRectF &rect) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int gridSize = 16; // virtual pixels
|
||||||
|
QRect validRect = QRect();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// PixmapItem subclass which allows for creating a boundary which determine whether
|
||||||
|
/// the pixmap paints normally or with a black tint.
|
||||||
|
/// This item is movable and snaps on a 16x16 grid.
|
||||||
|
class BoundedPixmapItem : public QGraphicsPixmapItem {
|
||||||
|
public:
|
||||||
|
BoundedPixmapItem(const QPixmap &pixmap, QGraphicsItem *parent = nullptr);
|
||||||
|
void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) override;
|
||||||
|
|
||||||
|
void setBoundary(ResizableRect *rect) { this->boundary = rect; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QVariant itemChange(GraphicsItemChange change, const QVariant &value) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ResizableRect *boundary = nullptr;
|
||||||
|
QPointF clickedPos = QPointF();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// The main (modal) dialog window for resizing layout and border dimensions.
|
||||||
|
/// The dialog itself is minimal, and is connected to the parent widget's geometry.
|
||||||
|
class ResizeLayoutPopup : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
ResizeLayoutPopup(QWidget *parent, Editor *editor);
|
||||||
|
~ResizeLayoutPopup();
|
||||||
|
|
||||||
|
void setupLayoutView();
|
||||||
|
|
||||||
|
void resetPosition();
|
||||||
|
|
||||||
|
QMargins getResult();
|
||||||
|
QSize getBorderResult();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void moveEvent(QMoveEvent *) override {
|
||||||
|
// Prevent the dialog from being moved
|
||||||
|
this->resetPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
void resizeEvent(QResizeEvent *) override {
|
||||||
|
// Prevent the dialog from being resized
|
||||||
|
this->resetPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void on_spinBox_width_valueChanged(int value);
|
||||||
|
void on_spinBox_height_valueChanged(int value);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QWidget *parent = nullptr;
|
||||||
|
Editor *editor = nullptr;
|
||||||
|
|
||||||
|
Ui::ResizeLayoutPopup *ui;
|
||||||
|
|
||||||
|
ResizableRect *outline = nullptr;
|
||||||
|
BoundedPixmapItem *layoutPixmap = nullptr;
|
||||||
|
|
||||||
|
QPointer<CheckeredBgScene> scene = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // RESIZELAYOUTPOPUP_H
|
|
@ -22,6 +22,7 @@ VERSION = 5.4.1
|
||||||
DEFINES += PORYMAP_VERSION=\\\"$$VERSION\\\"
|
DEFINES += PORYMAP_VERSION=\\\"$$VERSION\\\"
|
||||||
|
|
||||||
SOURCES += src/core/block.cpp \
|
SOURCES += src/core/block.cpp \
|
||||||
|
src/ui/resizelayoutpopup.cpp \
|
||||||
src/core/bitpacker.cpp \
|
src/core/bitpacker.cpp \
|
||||||
src/core/blockdata.cpp \
|
src/core/blockdata.cpp \
|
||||||
src/core/events.cpp \
|
src/core/events.cpp \
|
||||||
|
@ -225,7 +226,8 @@ HEADERS += include/core/block.h \
|
||||||
include/log.h \
|
include/log.h \
|
||||||
include/ui/uintspinbox.h \
|
include/ui/uintspinbox.h \
|
||||||
include/ui/updatepromoter.h \
|
include/ui/updatepromoter.h \
|
||||||
include/ui/wildmonchart.h
|
include/ui/wildmonchart.h \
|
||||||
|
include/ui/resizelayoutpopup.h
|
||||||
|
|
||||||
FORMS += forms/mainwindow.ui \
|
FORMS += forms/mainwindow.ui \
|
||||||
forms/colorinputwidget.ui \
|
forms/colorinputwidget.ui \
|
||||||
|
@ -250,7 +252,8 @@ FORMS += forms/mainwindow.ui \
|
||||||
forms/customscriptseditor.ui \
|
forms/customscriptseditor.ui \
|
||||||
forms/customscriptslistitem.ui \
|
forms/customscriptslistitem.ui \
|
||||||
forms/updatepromoter.ui \
|
forms/updatepromoter.ui \
|
||||||
forms/wildmonchart.ui
|
forms/wildmonchart.ui \
|
||||||
|
forms/resizelayoutpopup.ui
|
||||||
|
|
||||||
RESOURCES += \
|
RESOURCES += \
|
||||||
resources/images.qrc \
|
resources/images.qrc \
|
||||||
|
|
|
@ -177,7 +177,7 @@ bool ShiftMetatiles::mergeWith(const QUndoCommand *command) {
|
||||||
************************************************************************
|
************************************************************************
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
ResizeLayout::ResizeLayout(Layout *layout, QSize oldLayoutDimensions, QSize newLayoutDimensions,
|
ResizeLayout::ResizeLayout(Layout *layout, QSize oldLayoutDimensions, QMargins newLayoutMargins,
|
||||||
const Blockdata &oldMetatiles, const Blockdata &newMetatiles,
|
const Blockdata &oldMetatiles, const Blockdata &newMetatiles,
|
||||||
QSize oldBorderDimensions, QSize newBorderDimensions,
|
QSize oldBorderDimensions, QSize newBorderDimensions,
|
||||||
const Blockdata &oldBorder, const Blockdata &newBorder,
|
const Blockdata &oldBorder, const Blockdata &newBorder,
|
||||||
|
@ -189,8 +189,7 @@ ResizeLayout::ResizeLayout(Layout *layout, QSize oldLayoutDimensions, QSize newL
|
||||||
this->oldLayoutWidth = oldLayoutDimensions.width();
|
this->oldLayoutWidth = oldLayoutDimensions.width();
|
||||||
this->oldLayoutHeight = oldLayoutDimensions.height();
|
this->oldLayoutHeight = oldLayoutDimensions.height();
|
||||||
|
|
||||||
this->newLayoutWidth = newLayoutDimensions.width();
|
this->newLayoutMargins = newLayoutMargins;
|
||||||
this->newLayoutHeight = newLayoutDimensions.height();
|
|
||||||
|
|
||||||
this->oldMetatiles = oldMetatiles;
|
this->oldMetatiles = oldMetatiles;
|
||||||
this->newMetatiles = newMetatiles;
|
this->newMetatiles = newMetatiles;
|
||||||
|
@ -210,12 +209,14 @@ void ResizeLayout::redo() {
|
||||||
|
|
||||||
if (!layout) return;
|
if (!layout) return;
|
||||||
|
|
||||||
layout->blockdata = newMetatiles;
|
|
||||||
layout->setDimensions(newLayoutWidth, newLayoutHeight, false, true);
|
|
||||||
|
|
||||||
layout->border = newBorder;
|
layout->border = newBorder;
|
||||||
layout->setBorderDimensions(newBorderWidth, newBorderHeight, false, true);
|
layout->setBorderDimensions(newBorderWidth, newBorderHeight, false, true);
|
||||||
|
|
||||||
|
layout->width = oldLayoutWidth;
|
||||||
|
layout->height = oldLayoutHeight;
|
||||||
|
layout->adjustDimensions(this->newLayoutMargins, false, true);
|
||||||
|
layout->blockdata = newMetatiles;
|
||||||
|
|
||||||
layout->lastCommitBlocks.layoutDimensions = QSize(layout->getWidth(), layout->getHeight());
|
layout->lastCommitBlocks.layoutDimensions = QSize(layout->getWidth(), layout->getHeight());
|
||||||
layout->lastCommitBlocks.borderDimensions = QSize(layout->getBorderWidth(), layout->getBorderHeight());
|
layout->lastCommitBlocks.borderDimensions = QSize(layout->getBorderWidth(), layout->getBorderHeight());
|
||||||
|
|
||||||
|
@ -225,12 +226,14 @@ void ResizeLayout::redo() {
|
||||||
void ResizeLayout::undo() {
|
void ResizeLayout::undo() {
|
||||||
if (!layout) return;
|
if (!layout) return;
|
||||||
|
|
||||||
layout->blockdata = oldMetatiles;
|
|
||||||
layout->setDimensions(oldLayoutWidth, oldLayoutHeight, false, true);
|
|
||||||
|
|
||||||
layout->border = oldBorder;
|
layout->border = oldBorder;
|
||||||
layout->setBorderDimensions(oldBorderWidth, oldBorderHeight, false, true);
|
layout->setBorderDimensions(oldBorderWidth, oldBorderHeight, false, true);
|
||||||
|
|
||||||
|
layout->width = oldLayoutWidth + newLayoutMargins.left() + newLayoutMargins.right();
|
||||||
|
layout->height = oldLayoutHeight + newLayoutMargins.top() + newLayoutMargins.bottom();
|
||||||
|
layout->adjustDimensions(-this->newLayoutMargins, false, true);
|
||||||
|
layout->blockdata = oldMetatiles;
|
||||||
|
|
||||||
layout->lastCommitBlocks.layoutDimensions = QSize(layout->getWidth(), layout->getHeight());
|
layout->lastCommitBlocks.layoutDimensions = QSize(layout->getWidth(), layout->getHeight());
|
||||||
layout->lastCommitBlocks.borderDimensions = QSize(layout->getBorderWidth(), layout->getBorderHeight());
|
layout->lastCommitBlocks.borderDimensions = QSize(layout->getBorderWidth(), layout->getBorderHeight());
|
||||||
|
|
||||||
|
|
|
@ -183,6 +183,34 @@ void Layout::setDimensions(int newWidth, int newHeight, bool setNewBlockdata, bo
|
||||||
emit layoutDimensionsChanged(QSize(getWidth(), getHeight()));
|
emit layoutDimensionsChanged(QSize(getWidth(), getHeight()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Layout::adjustDimensions(QMargins margins, bool setNewBlockdata, bool enableScriptCallback) {
|
||||||
|
int oldWidth = this->width;
|
||||||
|
int oldHeight = this->height;
|
||||||
|
int newWidth = this->width + margins.left() + margins.right();
|
||||||
|
int newHeight = this->height + margins.top() + margins.bottom();
|
||||||
|
|
||||||
|
if (setNewBlockdata) {
|
||||||
|
// Fill new blockdata TODO: replace old functions, scripting support, undo etc
|
||||||
|
Blockdata newBlockdata;
|
||||||
|
for (int y = 0; y < newHeight; y++)
|
||||||
|
for (int x = 0; x < newWidth; x++) {
|
||||||
|
if ((x < margins.left()) || (x >= newWidth - margins.right()) || (y < margins.top()) || (y >= newHeight - margins.bottom())) {
|
||||||
|
newBlockdata.append(0);
|
||||||
|
} else {
|
||||||
|
int index = (y - margins.top()) * oldWidth + (x - margins.left());
|
||||||
|
newBlockdata.append(this->blockdata.value(index));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this->blockdata = newBlockdata;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->width = newWidth;
|
||||||
|
this->height = newHeight;
|
||||||
|
|
||||||
|
emit layoutChanged(this);
|
||||||
|
emit layoutDimensionsChanged(QSize(getWidth(), getHeight()));
|
||||||
|
}
|
||||||
|
|
||||||
void Layout::setBorderDimensions(int newWidth, int newHeight, bool setNewBlockdata, bool enableScriptCallback) {
|
void Layout::setBorderDimensions(int newWidth, int newHeight, bool setNewBlockdata, bool enableScriptCallback) {
|
||||||
if (setNewBlockdata) {
|
if (setNewBlockdata) {
|
||||||
setNewBorderDimensionsBlockdata(newWidth, newHeight);
|
setNewBorderDimensionsBlockdata(newWidth, newHeight);
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "newmapconnectiondialog.h"
|
#include "newmapconnectiondialog.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "filedialog.h"
|
#include "filedialog.h"
|
||||||
|
#include "resizelayoutpopup.h"
|
||||||
|
|
||||||
#include <QClipboard>
|
#include <QClipboard>
|
||||||
#include <QDirIterator>
|
#include <QDirIterator>
|
||||||
|
@ -2961,88 +2962,31 @@ void MainWindow::on_comboBox_SecondaryTileset_currentTextChanged(const QString &
|
||||||
void MainWindow::on_pushButton_ChangeDimensions_clicked() {
|
void MainWindow::on_pushButton_ChangeDimensions_clicked() {
|
||||||
if (!editor || !editor->layout) return;
|
if (!editor || !editor->layout) return;
|
||||||
|
|
||||||
QDialog dialog(this, Qt::WindowTitleHint | Qt::WindowCloseButtonHint);
|
ResizeLayoutPopup popup(this->ui->graphicsView_Map, this->editor);
|
||||||
dialog.setWindowTitle("Change Map Dimensions");
|
popup.show();
|
||||||
dialog.setWindowModality(Qt::NonModal);
|
popup.setupLayoutView();
|
||||||
|
if (popup.exec() == QDialog::Accepted) {
|
||||||
QFormLayout form(&dialog);
|
Layout *layout = this->editor->layout;
|
||||||
|
QMargins result = popup.getResult();
|
||||||
QSpinBox *widthSpinBox = new QSpinBox();
|
QSize borderResult = popup.getBorderResult();
|
||||||
QSpinBox *heightSpinBox = new QSpinBox();
|
QSize oldLayoutDimensions(layout->getWidth(), layout->getHeight());
|
||||||
QSpinBox *bwidthSpinBox = new QSpinBox();
|
|
||||||
QSpinBox *bheightSpinBox = new QSpinBox();
|
|
||||||
widthSpinBox->setMinimum(1);
|
|
||||||
heightSpinBox->setMinimum(1);
|
|
||||||
bwidthSpinBox->setMinimum(1);
|
|
||||||
bheightSpinBox->setMinimum(1);
|
|
||||||
widthSpinBox->setMaximum(editor->project->getMaxMapWidth());
|
|
||||||
heightSpinBox->setMaximum(editor->project->getMaxMapHeight());
|
|
||||||
bwidthSpinBox->setMaximum(MAX_BORDER_WIDTH);
|
|
||||||
bheightSpinBox->setMaximum(MAX_BORDER_HEIGHT);
|
|
||||||
widthSpinBox->setValue(editor->layout->getWidth());
|
|
||||||
heightSpinBox->setValue(editor->layout->getHeight());
|
|
||||||
bwidthSpinBox->setValue(editor->layout->getBorderWidth());
|
|
||||||
bheightSpinBox->setValue(editor->layout->getBorderHeight());
|
|
||||||
if (projectConfig.useCustomBorderSize) {
|
|
||||||
form.addRow(new QLabel("Map Width"), widthSpinBox);
|
|
||||||
form.addRow(new QLabel("Map Height"), heightSpinBox);
|
|
||||||
form.addRow(new QLabel("Border Width"), bwidthSpinBox);
|
|
||||||
form.addRow(new QLabel("Border Height"), bheightSpinBox);
|
|
||||||
} else {
|
|
||||||
form.addRow(new QLabel("Width"), widthSpinBox);
|
|
||||||
form.addRow(new QLabel("Height"), heightSpinBox);
|
|
||||||
}
|
|
||||||
|
|
||||||
QLabel *errorLabel = new QLabel();
|
|
||||||
errorLabel->setStyleSheet("QLabel { color: red }");
|
|
||||||
errorLabel->setVisible(false);
|
|
||||||
|
|
||||||
QDialogButtonBox buttonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, &dialog);
|
|
||||||
form.addRow(&buttonBox);
|
|
||||||
connect(&buttonBox, &QDialogButtonBox::accepted, [&dialog, &widthSpinBox, &heightSpinBox, &errorLabel, this](){
|
|
||||||
// Ensure width and height are an acceptable size.
|
|
||||||
// The maximum number of metatiles in a map is the following:
|
|
||||||
// max = (width + 15) * (height + 14)
|
|
||||||
// This limit can be found in fieldmap.c in pokeruby/pokeemerald/pokefirered.
|
|
||||||
int numMetatiles = editor->project->getMapDataSize(widthSpinBox->value(), heightSpinBox->value());
|
|
||||||
int maxMetatiles = editor->project->getMaxMapDataSize();
|
|
||||||
if (numMetatiles <= maxMetatiles) {
|
|
||||||
dialog.accept();
|
|
||||||
} else {
|
|
||||||
QString errorText = QString("Error: The specified width and height are too large.\n"
|
|
||||||
"The maximum layout width and height is the following: (width + 15) * (height + 14) <= %1\n"
|
|
||||||
"The specified layout width and height was: (%2 + 15) * (%3 + 14) = %4")
|
|
||||||
.arg(maxMetatiles)
|
|
||||||
.arg(widthSpinBox->value())
|
|
||||||
.arg(heightSpinBox->value())
|
|
||||||
.arg(numMetatiles);
|
|
||||||
errorLabel->setText(errorText);
|
|
||||||
errorLabel->setVisible(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
connect(&buttonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);
|
|
||||||
|
|
||||||
form.addRow(errorLabel);
|
|
||||||
|
|
||||||
if (dialog.exec() == QDialog::Accepted) {
|
|
||||||
Layout *layout = editor->layout;
|
|
||||||
Blockdata oldMetatiles = layout->blockdata;
|
|
||||||
Blockdata oldBorder = layout->border;
|
|
||||||
QSize oldMapDimensions(layout->getWidth(), layout->getHeight());
|
|
||||||
QSize oldBorderDimensions(layout->getBorderWidth(), layout->getBorderHeight());
|
QSize oldBorderDimensions(layout->getBorderWidth(), layout->getBorderHeight());
|
||||||
QSize newMapDimensions(widthSpinBox->value(), heightSpinBox->value());
|
if (!result.isNull() || (borderResult != oldBorderDimensions)) {
|
||||||
QSize newBorderDimensions(bwidthSpinBox->value(), bheightSpinBox->value());
|
Blockdata oldMetatiles = layout->blockdata;
|
||||||
if (oldMapDimensions != newMapDimensions || oldBorderDimensions != newBorderDimensions) {
|
Blockdata oldBorder = layout->border;
|
||||||
layout->setDimensions(newMapDimensions.width(), newMapDimensions.height(), true, true);
|
|
||||||
layout->setBorderDimensions(newBorderDimensions.width(), newBorderDimensions.height(), true, true);
|
layout->adjustDimensions(result);
|
||||||
editor->layout->editHistory.push(new ResizeLayout(layout,
|
layout->setBorderDimensions(borderResult.width(), borderResult.height(), true, true);
|
||||||
oldMapDimensions, newMapDimensions,
|
layout->editHistory.push(new ResizeLayout(layout,
|
||||||
|
oldLayoutDimensions, result,
|
||||||
oldMetatiles, layout->blockdata,
|
oldMetatiles, layout->blockdata,
|
||||||
oldBorderDimensions, newBorderDimensions,
|
oldBorderDimensions, borderResult,
|
||||||
oldBorder, layout->border
|
oldBorder, layout->border
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_checkBox_smartPaths_stateChanged(int selected)
|
void MainWindow::on_checkBox_smartPaths_stateChanged(int selected)
|
||||||
|
|
|
@ -1,17 +1,163 @@
|
||||||
|
#include <QCursor>
|
||||||
|
#include <QGraphicsSceneHoverEvent>
|
||||||
|
|
||||||
#include "movablerect.h"
|
#include "movablerect.h"
|
||||||
|
|
||||||
MovableRect::MovableRect(bool *enabled, int width, int height, QRgb color)
|
MovableRect::MovableRect(bool *enabled, int width, int height, QRgb color)
|
||||||
|
: QGraphicsRectItem(0, 0, width, height)
|
||||||
{
|
{
|
||||||
this->enabled = enabled;
|
this->enabled = enabled;
|
||||||
this->width = width;
|
|
||||||
this->height = height;
|
|
||||||
this->color = color;
|
this->color = color;
|
||||||
this->setVisible(*enabled);
|
this->setVisible(*enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MovableRect::updateLocation(int x, int y)
|
/// Center rect on grid position (x, y)
|
||||||
{
|
void MovableRect::updateLocation(int x, int y) {
|
||||||
this->setX((x * 16) - this->width / 2 + 8);
|
this->setRect((x * 16) - this->rect().width() / 2 + 8, (y * 16) - this->rect().height() / 2 + 8, this->rect().width(), this->rect().height());
|
||||||
this->setY((y * 16) - this->height / 2 + 8);
|
|
||||||
this->setVisible(*this->enabled);
|
this->setVisible(*this->enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
************************************************************************
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
int roundUp(int numToRound, int multiple) {
|
||||||
|
return (numToRound + multiple - 1) & -multiple;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResizableRect::ResizableRect(QObject *parent, bool *enabled, int width, int height, QRgb color)
|
||||||
|
: QObject(parent),
|
||||||
|
MovableRect(enabled, width * 16, height * 16, color)
|
||||||
|
{
|
||||||
|
setZValue(0xFFFFFFFF); // ensure on top of view
|
||||||
|
setAcceptHoverEvents(true);
|
||||||
|
setFlags(this->flags() | QGraphicsItem::ItemIsMovable);
|
||||||
|
}
|
||||||
|
|
||||||
|
ResizableRect::Edge ResizableRect::detectEdge(int x, int y) {
|
||||||
|
QRectF edge = this->boundingRect();
|
||||||
|
if (x <= edge.left() + this->lineWidth) {
|
||||||
|
if (y >= edge.top() + 2 * this->lineWidth) {
|
||||||
|
if (y <= edge.bottom() - 2 * this->lineWidth) {
|
||||||
|
return ResizableRect::Edge::Left;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return ResizableRect::Edge::BottomLeft;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return ResizableRect::Edge::TopLeft;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (x >= edge.right() - this->lineWidth) {
|
||||||
|
if (y >= edge.top() + 2 * this->lineWidth) {
|
||||||
|
if (y <= edge.bottom() - 2 * this->lineWidth) {
|
||||||
|
return ResizableRect::Edge::Right;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return ResizableRect::Edge::BottomRight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return ResizableRect::Edge::TopRight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (y <= edge.top() + this->lineWidth) {
|
||||||
|
return ResizableRect::Edge::Top;
|
||||||
|
}
|
||||||
|
else if (y >= edge.bottom() - this->lineWidth) {
|
||||||
|
return ResizableRect::Edge::Bottom;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ResizableRect::Edge::None;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResizableRect::updatePosFromRect(QRect newRect) {
|
||||||
|
prepareGeometryChange();
|
||||||
|
this->setRect(newRect);
|
||||||
|
emit this->rectUpdated(newRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResizableRect::hoverMoveEvent(QGraphicsSceneHoverEvent *event) {
|
||||||
|
switch (this->detectEdge(event->pos().x(), event->pos().y())) {
|
||||||
|
case ResizableRect::Edge::None:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
case ResizableRect::Edge::Left:
|
||||||
|
case ResizableRect::Edge::Right:
|
||||||
|
this->setCursor(Qt::SizeHorCursor);
|
||||||
|
break;
|
||||||
|
case ResizableRect::Edge::Top:
|
||||||
|
case ResizableRect::Edge::Bottom:
|
||||||
|
this->setCursor(Qt::SizeVerCursor);
|
||||||
|
break;
|
||||||
|
case ResizableRect::Edge::TopRight:
|
||||||
|
case ResizableRect::Edge::BottomLeft:
|
||||||
|
this->setCursor(Qt::SizeBDiagCursor);
|
||||||
|
break;
|
||||||
|
case ResizableRect::Edge::TopLeft:
|
||||||
|
case ResizableRect::Edge::BottomRight:
|
||||||
|
this->setCursor(Qt::SizeFDiagCursor);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResizableRect::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) {
|
||||||
|
this->unsetCursor();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResizableRect::mousePressEvent(QGraphicsSceneMouseEvent *event) {
|
||||||
|
int x = event->pos().x();
|
||||||
|
int y = event->pos().y();
|
||||||
|
this->clickedPos = event->scenePos();
|
||||||
|
this->clickedRect = this->rect().toAlignedRect();
|
||||||
|
this->clickedEdge = this->detectEdge(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResizableRect::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
|
||||||
|
int dx = roundUp(event->scenePos().x() - this->clickedPos.x(), 16);
|
||||||
|
int dy = roundUp(event->scenePos().y() - this->clickedPos.y(), 16);
|
||||||
|
|
||||||
|
QRect resizedRect = this->clickedRect;
|
||||||
|
|
||||||
|
switch (this->clickedEdge) {
|
||||||
|
case ResizableRect::Edge::None:
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
case ResizableRect::Edge::Left:
|
||||||
|
resizedRect.adjust(dx, 0, 0, 0);
|
||||||
|
break;
|
||||||
|
case ResizableRect::Edge::Right:
|
||||||
|
resizedRect.adjust(0, 0, dx, 0);
|
||||||
|
break;
|
||||||
|
case ResizableRect::Edge::Top:
|
||||||
|
resizedRect.adjust(0, dy, 0, 0);
|
||||||
|
break;
|
||||||
|
case ResizableRect::Edge::Bottom:
|
||||||
|
resizedRect.adjust(0, 0, 0, dy);
|
||||||
|
break;
|
||||||
|
case ResizableRect::Edge::TopRight:
|
||||||
|
resizedRect.adjust(0, dy, dx, 0);
|
||||||
|
break;
|
||||||
|
case ResizableRect::Edge::BottomLeft:
|
||||||
|
resizedRect.adjust(dx, 0, 0, dy);
|
||||||
|
break;
|
||||||
|
case ResizableRect::Edge::TopLeft:
|
||||||
|
resizedRect.adjust(dx, dy, 0, 0);
|
||||||
|
break;
|
||||||
|
case ResizableRect::Edge::BottomRight:
|
||||||
|
resizedRect.adjust(0, 0, dx, dy);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// lower bounds limits
|
||||||
|
if (resizedRect.width() < 16)
|
||||||
|
resizedRect.setWidth(16);
|
||||||
|
if (resizedRect.height() < 16)
|
||||||
|
resizedRect.setHeight(16);
|
||||||
|
|
||||||
|
// TODO: upper bound limits
|
||||||
|
|
||||||
|
this->updatePosFromRect(resizedRect);
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "noscrollspinbox.h"
|
#include "noscrollspinbox.h"
|
||||||
#include <QWheelEvent>
|
#include <QWheelEvent>
|
||||||
|
#include <QLineEdit>
|
||||||
|
|
||||||
unsigned actionId = 0xffff;
|
unsigned actionId = 0xffff;
|
||||||
|
|
||||||
|
@ -25,6 +26,10 @@ void NoScrollSpinBox::focusOutEvent(QFocusEvent *event) {
|
||||||
QSpinBox::focusOutEvent(event);
|
QSpinBox::focusOutEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NoScrollSpinBox::setLineEditEnabled(bool enabled) {
|
||||||
|
this->lineEdit()->setReadOnly(!enabled);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned NoScrollSpinBox::getActionId() {
|
unsigned NoScrollSpinBox::getActionId() {
|
||||||
return actionId;
|
return actionId;
|
||||||
}
|
}
|
||||||
|
|
186
src/ui/resizelayoutpopup.cpp
Normal file
186
src/ui/resizelayoutpopup.cpp
Normal file
|
@ -0,0 +1,186 @@
|
||||||
|
#include "resizelayoutpopup.h"
|
||||||
|
#include "editor.h"
|
||||||
|
#include "movablerect.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "ui_resizelayoutpopup.h"
|
||||||
|
|
||||||
|
// TODO: put this in a util file or something
|
||||||
|
extern int roundUp(int, int);
|
||||||
|
|
||||||
|
CheckeredBgScene::CheckeredBgScene(QObject *parent) : QGraphicsScene(parent) { }
|
||||||
|
|
||||||
|
void CheckeredBgScene::drawBackground(QPainter *painter, const QRectF &rect) {
|
||||||
|
QRect r = rect.toRect();
|
||||||
|
int xMin = r.left() - r.left() % this->gridSize - this->gridSize;
|
||||||
|
int yMin = r.top() - r.top() % this->gridSize - this->gridSize;
|
||||||
|
int xMax = r.right() - r.right() % this->gridSize + this->gridSize;
|
||||||
|
int yMax = r.bottom() - r.bottom() % this->gridSize + this->gridSize;
|
||||||
|
|
||||||
|
// draw grid 16x16 from top to bottom of scene
|
||||||
|
QColor paintColor(0x00ff00);
|
||||||
|
for (int x = xMin, xTile = 0; x <= xMax; x += this->gridSize, xTile++) {
|
||||||
|
for (int y = yMin, yTile = 0; y <= yMax; y += this->gridSize, yTile++) {
|
||||||
|
if (!((xTile ^ yTile) & 1)) { // tile numbers have same parity (evenness)
|
||||||
|
if (this->validRect.contains(x, y)) // check if inside validRect
|
||||||
|
paintColor = QColor(132, 217, 165); // green light color
|
||||||
|
else
|
||||||
|
paintColor = 0xbcbcbc; // normal light color
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (this->validRect.contains(x, y)) // check if inside validRect
|
||||||
|
paintColor = QColor(76, 178, 121); // green dark color
|
||||||
|
else
|
||||||
|
paintColor = 0x969696; // normal dark color
|
||||||
|
}
|
||||||
|
painter->fillRect(QRect(x, y, this->gridSize, this->gridSize), paintColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
************************************************************************
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
BoundedPixmapItem::BoundedPixmapItem(const QPixmap &pixmap, QGraphicsItem *parent) : QGraphicsPixmapItem(pixmap, parent) {
|
||||||
|
setFlags(this->flags() | QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemSendsGeometryChanges | QGraphicsItem::ItemIsSelectable);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BoundedPixmapItem::paint(QPainter *painter, const QStyleOptionGraphicsItem * item, QWidget *widget) {
|
||||||
|
// Draw the pixmap darkened in the background
|
||||||
|
painter->fillRect(this->boundingRect().toAlignedRect(), QColor(0x444444));
|
||||||
|
painter->setCompositionMode(QPainter::CompositionMode_Multiply);
|
||||||
|
painter->drawPixmap(this->boundingRect().toAlignedRect(), this->pixmap());
|
||||||
|
|
||||||
|
// draw the normal pixmap on top, cropping to validRect as needed
|
||||||
|
painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
|
||||||
|
QRect intersection = this->mapRectFromScene(this->boundary->rect()).toAlignedRect() & this->boundingRect().toAlignedRect();
|
||||||
|
QPixmap cropped = this->pixmap().copy(intersection);
|
||||||
|
painter->drawPixmap(intersection, cropped);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant BoundedPixmapItem::itemChange(GraphicsItemChange change, const QVariant &value) {
|
||||||
|
if (change == ItemPositionChange && scene()) {
|
||||||
|
QPointF newPos = value.toPointF();
|
||||||
|
return QPointF(roundUp(newPos.x(), 16), roundUp(newPos.y(), 16));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return QGraphicsItem::itemChange(change, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
************************************************************************
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
ResizeLayoutPopup::ResizeLayoutPopup(QWidget *parent, Editor *editor) :
|
||||||
|
QDialog(parent),
|
||||||
|
parent(parent),
|
||||||
|
editor(editor),
|
||||||
|
ui(new Ui::ResizeLayoutPopup)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
this->resetPosition();
|
||||||
|
this->setWindowFlags(this->windowFlags() | Qt::FramelessWindowHint);
|
||||||
|
this->setWindowModality(Qt::ApplicationModal);
|
||||||
|
|
||||||
|
this->scene = new CheckeredBgScene(this);
|
||||||
|
//this->ui->graphicsView->setAlignment(Qt::AlignTop|Qt::AlignLeft);
|
||||||
|
this->ui->graphicsView->setScene(this->scene);
|
||||||
|
this->ui->graphicsView->setRenderHints(QPainter::Antialiasing);
|
||||||
|
this->ui->graphicsView->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
|
||||||
|
}
|
||||||
|
|
||||||
|
ResizeLayoutPopup::~ResizeLayoutPopup()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reset position of the dialog to cover the MainWindow's layout metatile scene
|
||||||
|
void ResizeLayoutPopup::resetPosition() {
|
||||||
|
this->setGeometry(QRect(parent->mapToGlobal(QPoint(0, 0)), parent->size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Custom scene contains
|
||||||
|
/// (1) pixmap representing the current layout / not resizable / drag-movable
|
||||||
|
/// (1) layout outline / resizable / not movable
|
||||||
|
void ResizeLayoutPopup::setupLayoutView() {
|
||||||
|
if (!this->editor || !this->editor->layout) return;
|
||||||
|
// TODO: this should be a more robust check probably
|
||||||
|
|
||||||
|
// Border stuff
|
||||||
|
bool bordersEnabled = projectConfig.useCustomBorderSize;
|
||||||
|
if (bordersEnabled) {
|
||||||
|
this->ui->spinBox_borderWidth->setMinimum(1);
|
||||||
|
this->ui->spinBox_borderHeight->setMinimum(1);
|
||||||
|
this->ui->spinBox_borderWidth->setMaximum(MAX_BORDER_WIDTH);
|
||||||
|
this->ui->spinBox_borderHeight->setMaximum(MAX_BORDER_HEIGHT);
|
||||||
|
this->ui->spinBox_borderWidth->setLineEditEnabled(false);
|
||||||
|
this->ui->spinBox_borderHeight->setLineEditEnabled(false);
|
||||||
|
} else {
|
||||||
|
this->ui->frame_border->setVisible(false);
|
||||||
|
}
|
||||||
|
this->ui->spinBox_borderWidth->setValue(this->editor->layout->getBorderWidth());
|
||||||
|
this->ui->spinBox_borderHeight->setValue(this->editor->layout->getBorderHeight());
|
||||||
|
|
||||||
|
// Layout stuff
|
||||||
|
QPixmap pixmap = this->editor->layout->pixmap;
|
||||||
|
this->layoutPixmap = new BoundedPixmapItem(pixmap);
|
||||||
|
this->scene->addItem(layoutPixmap);
|
||||||
|
int maxWidth = this->editor->project->getMaxMapWidth();
|
||||||
|
int maxHeight = this->editor->project->getMaxMapHeight();
|
||||||
|
QGraphicsRectItem *cover = new QGraphicsRectItem(-maxWidth * 8, -maxHeight * 8, maxWidth * 16, maxHeight * 16);
|
||||||
|
this->scene->addItem(cover);
|
||||||
|
|
||||||
|
this->ui->spinBox_width->setMinimum(1);
|
||||||
|
this->ui->spinBox_width->setMaximum(maxWidth);
|
||||||
|
this->ui->spinBox_height->setMinimum(1);
|
||||||
|
this->ui->spinBox_height->setMaximum(maxHeight);
|
||||||
|
|
||||||
|
this->ui->spinBox_width->setLineEditEnabled(false);
|
||||||
|
this->ui->spinBox_height->setLineEditEnabled(false);
|
||||||
|
|
||||||
|
static bool layoutSizeRectVisible = true;
|
||||||
|
|
||||||
|
this->outline = new ResizableRect(this, &layoutSizeRectVisible, this->editor->layout->getWidth(), this->editor->layout->getHeight(), qRgb(255, 0, 255));
|
||||||
|
connect(outline, &ResizableRect::rectUpdated, [=](QRect rect){
|
||||||
|
this->scene->setValidRect(rect);
|
||||||
|
this->ui->spinBox_width->setValue(rect.width() / 16);
|
||||||
|
this->ui->spinBox_height->setValue(rect.height() / 16);
|
||||||
|
});
|
||||||
|
scene->addItem(outline);
|
||||||
|
|
||||||
|
layoutPixmap->setBoundary(outline);
|
||||||
|
this->outline->rectUpdated(outline->rect().toAlignedRect());
|
||||||
|
|
||||||
|
this->ui->graphicsView->scale(0.5, 0.5);
|
||||||
|
this->ui->graphicsView->centerOn(layoutPixmap);
|
||||||
|
// this->ui->graphicsView->fitInView(cover->rect(), Qt::KeepAspectRatio);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResizeLayoutPopup::on_spinBox_width_valueChanged(int value) {
|
||||||
|
if (!this->outline) return;
|
||||||
|
QRectF rect = this->outline->rect();
|
||||||
|
this->outline->updatePosFromRect(QRect(rect.x(), rect.y(), value * 16, rect.height()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResizeLayoutPopup::on_spinBox_height_valueChanged(int value) {
|
||||||
|
if (!this->outline) return;
|
||||||
|
QRectF rect = this->outline->rect();
|
||||||
|
this->outline->updatePosFromRect(QRect(rect.x(), rect.y(), rect.width(), value * 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Result is the number of metatiles to add (or subtract) to each side of the map after dimension changes
|
||||||
|
QMargins ResizeLayoutPopup::getResult() {
|
||||||
|
QMargins result = QMargins();
|
||||||
|
|
||||||
|
result.setLeft(this->layoutPixmap->x() - this->outline->rect().left());
|
||||||
|
result.setTop(this->layoutPixmap->y() - this->outline->rect().top());
|
||||||
|
result.setRight(this->outline->rect().right() - (this->layoutPixmap->x() + this->layoutPixmap->pixmap().width()));
|
||||||
|
result.setBottom(this->outline->rect().bottom() - (this->layoutPixmap->y() + this->layoutPixmap->pixmap().height()));
|
||||||
|
|
||||||
|
return result / 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize ResizeLayoutPopup::getBorderResult() {
|
||||||
|
return QSize(this->ui->spinBox_borderWidth->value(), this->ui->spinBox_borderHeight->value());
|
||||||
|
}
|
Loading…
Reference in a new issue