Add custom dash patterns to grid settings
This commit is contained in:
parent
a277e19334
commit
44642c347f
12 changed files with 394 additions and 245 deletions
|
@ -114,7 +114,10 @@
|
||||||
<item row="1" column="2">
|
<item row="1" column="2">
|
||||||
<widget class="NoScrollSpinBox" name="spinBox_Height">
|
<widget class="NoScrollSpinBox" name="spinBox_Height">
|
||||||
<property name="minimum">
|
<property name="minimum">
|
||||||
<number>1</number>
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>999</number>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -141,7 +144,10 @@
|
||||||
<item row="0" column="2">
|
<item row="0" column="2">
|
||||||
<widget class="NoScrollSpinBox" name="spinBox_Width">
|
<widget class="NoScrollSpinBox" name="spinBox_Width">
|
||||||
<property name="minimum">
|
<property name="minimum">
|
||||||
<number>1</number>
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>999</number>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -175,10 +181,24 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="2">
|
<item row="1" column="2">
|
||||||
<widget class="NoScrollSpinBox" name="spinBox_Y"/>
|
<widget class="NoScrollSpinBox" name="spinBox_Y">
|
||||||
|
<property name="minimum">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>999</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="2">
|
<item row="0" column="2">
|
||||||
<widget class="NoScrollSpinBox" name="spinBox_X"/>
|
<widget class="NoScrollSpinBox" name="spinBox_X">
|
||||||
|
<property name="minimum">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>999</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="0" rowspan="2">
|
<item row="0" column="0" rowspan="2">
|
||||||
<widget class="QToolButton" name="button_LinkOffsets">
|
<widget class="QToolButton" name="button_LinkOffsets">
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "collisionpixmapitem.h"
|
#include "collisionpixmapitem.h"
|
||||||
#include "mappixmapitem.h"
|
#include "mappixmapitem.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
#include "gridsettings.h"
|
||||||
#include "movablerect.h"
|
#include "movablerect.h"
|
||||||
#include "cursortilerect.h"
|
#include "cursortilerect.h"
|
||||||
#include "mapruler.h"
|
#include "mapruler.h"
|
||||||
|
@ -68,6 +69,7 @@ public:
|
||||||
void displayMapConnections();
|
void displayMapConnections();
|
||||||
void displayMapBorder();
|
void displayMapBorder();
|
||||||
void displayMapGrid();
|
void displayMapGrid();
|
||||||
|
void updateMapGrid();
|
||||||
void displayWildMonTables();
|
void displayWildMonTables();
|
||||||
|
|
||||||
void updateMapBorder();
|
void updateMapBorder();
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
#include "shortcutseditor.h"
|
#include "shortcutseditor.h"
|
||||||
#include "preferenceeditor.h"
|
#include "preferenceeditor.h"
|
||||||
#include "projectsettingseditor.h"
|
#include "projectsettingseditor.h"
|
||||||
#include "gridsettingsdialog.h"
|
#include "gridsettings.h"
|
||||||
#include "customscriptseditor.h"
|
#include "customscriptseditor.h"
|
||||||
#include "wildmonchart.h"
|
#include "wildmonchart.h"
|
||||||
#include "updatepromoter.h"
|
#include "updatepromoter.h"
|
||||||
|
|
|
@ -4,15 +4,6 @@
|
||||||
|
|
||||||
#include <QCursor>
|
#include <QCursor>
|
||||||
|
|
||||||
struct GridSettings {
|
|
||||||
uint width = 16;
|
|
||||||
uint height = 16;
|
|
||||||
int offsetX = 0;
|
|
||||||
int offsetY = 0;
|
|
||||||
Qt::PenStyle style = Qt::SolidLine;
|
|
||||||
QColor color = Qt::black;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Settings
|
class Settings
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
99
include/ui/gridsettings.h
Normal file
99
include/ui/gridsettings.h
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
#ifndef GRIDSETTINGS_H
|
||||||
|
#define GRIDSETTINGS_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QAbstractButton>
|
||||||
|
|
||||||
|
class GridSettings {
|
||||||
|
public:
|
||||||
|
explicit GridSettings() {};
|
||||||
|
~GridSettings() {};
|
||||||
|
|
||||||
|
enum Style {
|
||||||
|
Solid,
|
||||||
|
LargeDashes,
|
||||||
|
SmallDashes,
|
||||||
|
Crosshairs,
|
||||||
|
Dots,
|
||||||
|
};
|
||||||
|
|
||||||
|
uint width = 16;
|
||||||
|
uint height = 16;
|
||||||
|
int offsetX = 0;
|
||||||
|
int offsetY = 0;
|
||||||
|
Style style = Style::Solid;
|
||||||
|
QColor color = Qt::black;
|
||||||
|
QList<qreal> getHorizontalDashPattern() const { return this->getDashPattern(this->width); }
|
||||||
|
QList<qreal> getVerticalDashPattern() const { return this->getDashPattern(this->height); }
|
||||||
|
|
||||||
|
static QString getStyleName(Style style);
|
||||||
|
static GridSettings::Style getStyleFromName(const QString &name);
|
||||||
|
private:
|
||||||
|
static const QMap<Style, QString> styleToName;
|
||||||
|
|
||||||
|
QList<qreal> getCenteredDashPattern(uint length, qreal dashLength, qreal gapLength) const;
|
||||||
|
QList<qreal> getDashPattern(uint length) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bool operator==(const GridSettings &a, const GridSettings &b) {
|
||||||
|
return a.width == b.width
|
||||||
|
&& a.height == b.height
|
||||||
|
&& a.offsetX == b.offsetX
|
||||||
|
&& a.offsetY == b.offsetY
|
||||||
|
&& a.style == b.style
|
||||||
|
&& a.color == b.color;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator!=(const GridSettings &a, const GridSettings &b) {
|
||||||
|
return !(operator==(a, b));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class GridSettingsDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
class GridSettingsDialog : public QDialog {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit GridSettingsDialog(QWidget *parent = nullptr);
|
||||||
|
explicit GridSettingsDialog(GridSettings *settings, QWidget *parent = nullptr);
|
||||||
|
~GridSettingsDialog();
|
||||||
|
|
||||||
|
void setSettings(const GridSettings &settings);
|
||||||
|
GridSettings settings() const { return *m_settings; }
|
||||||
|
|
||||||
|
void setDefaultSettings(const GridSettings &settings);
|
||||||
|
GridSettings defaultSettings() const { return m_defaultSettings; }
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void changedGridSettings();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::GridSettingsDialog *ui;
|
||||||
|
GridSettings *const m_settings;
|
||||||
|
const GridSettings m_originalSettings;
|
||||||
|
GridSettings m_defaultSettings;
|
||||||
|
bool m_dimensionsLinked = true;
|
||||||
|
bool m_offsetsLinked = true;
|
||||||
|
bool m_ownedSettings = false;
|
||||||
|
|
||||||
|
void init();
|
||||||
|
void updateInput();
|
||||||
|
void setWidth(int value);
|
||||||
|
void setHeight(int value);
|
||||||
|
void setOffsetX(int value);
|
||||||
|
void setOffsetY(int value);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void dialogButtonClicked(QAbstractButton *button);
|
||||||
|
void on_spinBox_Width_valueChanged(int value);
|
||||||
|
void on_spinBox_Height_valueChanged(int value);
|
||||||
|
void on_spinBox_X_valueChanged(int value);
|
||||||
|
void on_spinBox_Y_valueChanged(int value);
|
||||||
|
void on_comboBox_Style_currentTextChanged(const QString &text);
|
||||||
|
void onColorChanged(QRgb color);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // GRIDSETTINGS_H
|
|
@ -1,59 +0,0 @@
|
||||||
#ifndef GRIDSETTINGSDIALOG_H
|
|
||||||
#define GRIDSETTINGSDIALOG_H
|
|
||||||
|
|
||||||
#include <QDialog>
|
|
||||||
#include <QAbstractButton>
|
|
||||||
|
|
||||||
#include "settings.h"
|
|
||||||
|
|
||||||
namespace Ui {
|
|
||||||
class GridSettingsDialog;
|
|
||||||
}
|
|
||||||
|
|
||||||
class GridSettingsDialog : public QDialog
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit GridSettingsDialog(GridSettings *settings = nullptr, QWidget *parent = nullptr);
|
|
||||||
~GridSettingsDialog();
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void changedGridSettings();
|
|
||||||
|
|
||||||
private:
|
|
||||||
Ui::GridSettingsDialog *ui;
|
|
||||||
GridSettings *settings;
|
|
||||||
GridSettings originalSettings;
|
|
||||||
bool dimensionsLinked = true;
|
|
||||||
bool offsetsLinked = true;
|
|
||||||
|
|
||||||
void reset(bool force = false);
|
|
||||||
void setWidth(int value);
|
|
||||||
void setHeight(int value);
|
|
||||||
void setOffsetX(int value);
|
|
||||||
void setOffsetY(int value);
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void dialogButtonClicked(QAbstractButton *button);
|
|
||||||
void on_spinBox_Width_valueChanged(int value);
|
|
||||||
void on_spinBox_Height_valueChanged(int value);
|
|
||||||
void on_spinBox_X_valueChanged(int value);
|
|
||||||
void on_spinBox_Y_valueChanged(int value);
|
|
||||||
void on_comboBox_Style_currentIndexChanged(int index);
|
|
||||||
void onColorChanged(QRgb color);
|
|
||||||
};
|
|
||||||
|
|
||||||
inline bool operator==(const struct GridSettings &a, const struct GridSettings &b) {
|
|
||||||
return a.width == b.width
|
|
||||||
&& a.height == b.height
|
|
||||||
&& a.offsetX == b.offsetX
|
|
||||||
&& a.offsetY == b.offsetY
|
|
||||||
&& a.style == b.style
|
|
||||||
&& a.color == b.color;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator!=(const struct GridSettings &a, const struct GridSettings &b) {
|
|
||||||
return !(operator==(a, b));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // GRIDSETTINGSDIALOG_H
|
|
|
@ -61,7 +61,7 @@ SOURCES += src/core/block.cpp \
|
||||||
src/ui/collisionpixmapitem.cpp \
|
src/ui/collisionpixmapitem.cpp \
|
||||||
src/ui/connectionpixmapitem.cpp \
|
src/ui/connectionpixmapitem.cpp \
|
||||||
src/ui/currentselectedmetatilespixmapitem.cpp \
|
src/ui/currentselectedmetatilespixmapitem.cpp \
|
||||||
src/ui/gridsettingsdialog.cpp \
|
src/ui/gridsettings.cpp \
|
||||||
src/ui/newmapconnectiondialog.cpp \
|
src/ui/newmapconnectiondialog.cpp \
|
||||||
src/ui/overlay.cpp \
|
src/ui/overlay.cpp \
|
||||||
src/ui/prefab.cpp \
|
src/ui/prefab.cpp \
|
||||||
|
@ -159,7 +159,7 @@ HEADERS += include/core/block.h \
|
||||||
include/ui/collisionpixmapitem.h \
|
include/ui/collisionpixmapitem.h \
|
||||||
include/ui/connectionpixmapitem.h \
|
include/ui/connectionpixmapitem.h \
|
||||||
include/ui/currentselectedmetatilespixmapitem.h \
|
include/ui/currentselectedmetatilespixmapitem.h \
|
||||||
include/ui/gridsettingsdialog.h \
|
include/ui/gridsettings.h \
|
||||||
include/ui/newmapconnectiondialog.h \
|
include/ui/newmapconnectiondialog.h \
|
||||||
include/ui/prefabframe.h \
|
include/ui/prefabframe.h \
|
||||||
include/ui/projectsettingseditor.h \
|
include/ui/projectsettingseditor.h \
|
||||||
|
|
|
@ -1875,25 +1875,29 @@ void Editor::displayMapGrid() {
|
||||||
// elements of the scripting API, so they're painted manually in MapView::drawForeground.
|
// elements of the scripting API, so they're painted manually in MapView::drawForeground.
|
||||||
this->mapGrid = new QGraphicsItemGroup();
|
this->mapGrid = new QGraphicsItemGroup();
|
||||||
|
|
||||||
const uint pixelMapWidth = map->getWidth() * 16;
|
const int pixelMapWidth = map->getWidth() * 16;
|
||||||
const uint pixelMapHeight = map->getHeight() * 16;
|
const int pixelMapHeight = map->getHeight() * 16;
|
||||||
|
|
||||||
|
// The grid can be moved with a user-specified x/y offset. The grid's dash patterns will only wrap in full pattern increments,
|
||||||
|
// so we draw an additional row/column outside the map that can be revealed as the offset changes.
|
||||||
|
const int offsetX = (this->gridSettings.offsetX % this->gridSettings.width) - this->gridSettings.width;
|
||||||
|
const int offsetY = (this->gridSettings.offsetY % this->gridSettings.height) - this->gridSettings.height;
|
||||||
|
|
||||||
QPen pen;
|
QPen pen;
|
||||||
pen.setStyle(this->gridSettings.style);
|
|
||||||
pen.setColor(this->gridSettings.color);
|
pen.setColor(this->gridSettings.color);
|
||||||
|
|
||||||
// Create vertical lines
|
// Create vertical lines
|
||||||
int offset = this->gridSettings.offsetX % this->gridSettings.width;
|
pen.setDashPattern(this->gridSettings.getVerticalDashPattern());
|
||||||
for (uint i = offset; i <= pixelMapWidth; i += this->gridSettings.width) {
|
for (int i = offsetX; i <= pixelMapWidth; i += this->gridSettings.width) {
|
||||||
auto line = new QGraphicsLineItem(i, 0, i, pixelMapHeight);
|
auto line = new QGraphicsLineItem(i, offsetY, i, pixelMapHeight);
|
||||||
line->setPen(pen);
|
line->setPen(pen);
|
||||||
this->mapGrid->addToGroup(line);
|
this->mapGrid->addToGroup(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create horizontal lines
|
// Create horizontal lines
|
||||||
offset = this->gridSettings.offsetY % this->gridSettings.height;
|
pen.setDashPattern(this->gridSettings.getHorizontalDashPattern());
|
||||||
for (uint i = offset; i <= pixelMapHeight; i += this->gridSettings.height) {
|
for (int i = offsetY; i <= pixelMapHeight; i += this->gridSettings.height) {
|
||||||
auto line = new QGraphicsLineItem(0, i, pixelMapWidth, i);
|
auto line = new QGraphicsLineItem(offsetX, i, pixelMapWidth, i);
|
||||||
line->setPen(pen);
|
line->setPen(pen);
|
||||||
this->mapGrid->addToGroup(line);
|
this->mapGrid->addToGroup(line);
|
||||||
}
|
}
|
||||||
|
@ -1901,6 +1905,12 @@ void Editor::displayMapGrid() {
|
||||||
this->mapGrid->setVisible(porymapConfig.showGrid);
|
this->mapGrid->setVisible(porymapConfig.showGrid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Editor::updateMapGrid() {
|
||||||
|
displayMapGrid();
|
||||||
|
if (ui->graphicsView_Map->scene())
|
||||||
|
ui->graphicsView_Map->scene()->update();
|
||||||
|
}
|
||||||
|
|
||||||
void Editor::updatePrimaryTileset(QString tilesetLabel, bool forceLoad)
|
void Editor::updatePrimaryTileset(QString tilesetLabel, bool forceLoad)
|
||||||
{
|
{
|
||||||
if (map->layout->tileset_primary_label != tilesetLabel || forceLoad)
|
if (map->layout->tileset_primary_label != tilesetLabel || forceLoad)
|
||||||
|
|
|
@ -1929,7 +1929,7 @@ void MainWindow::on_actionShow_Grid_triggered() {
|
||||||
void MainWindow::on_actionGrid_Settings_triggered() {
|
void MainWindow::on_actionGrid_Settings_triggered() {
|
||||||
if (!this->gridSettingsDialog) {
|
if (!this->gridSettingsDialog) {
|
||||||
this->gridSettingsDialog = new GridSettingsDialog(&this->editor->gridSettings, this);
|
this->gridSettingsDialog = new GridSettingsDialog(&this->editor->gridSettings, this);
|
||||||
connect(this->gridSettingsDialog, &GridSettingsDialog::changedGridSettings, this->editor, &Editor::displayMapGrid);
|
connect(this->gridSettingsDialog, &GridSettingsDialog::changedGridSettings, this->editor, &Editor::updateMapGrid);
|
||||||
}
|
}
|
||||||
openSubWindow(this->gridSettingsDialog);
|
openSubWindow(this->gridSettingsDialog);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,12 +31,24 @@ void MapView::drawForeground(QPainter *painter, const QRectF&) {
|
||||||
if (!editor) return;
|
if (!editor) return;
|
||||||
|
|
||||||
QStyleOptionGraphicsItem option;
|
QStyleOptionGraphicsItem option;
|
||||||
if (editor->mapGrid) {
|
|
||||||
for (auto item : editor->mapGrid->childItems()) {
|
// Draw elements of the map view that should always render on top of anything added by the user with the scripting API.
|
||||||
if (item->isVisible())
|
|
||||||
item->paint(painter, &option, this);
|
// Draw map grid
|
||||||
|
if (editor->mapGrid && editor->mapGrid->isVisible()) {
|
||||||
|
painter->save();
|
||||||
|
if (editor->map) {
|
||||||
|
// We're clipping here to hide parts of the grid that are outside the map.
|
||||||
|
const QRectF mapRect(-0.5, -0.5, editor->map->getWidth() * 16 + 1.5, editor->map->getHeight() * 16 + 1.5);
|
||||||
|
painter->setClipping(true);
|
||||||
|
painter->setClipRect(mapRect);
|
||||||
}
|
}
|
||||||
|
for (auto item : editor->mapGrid->childItems())
|
||||||
|
item->paint(painter, &option, this);
|
||||||
|
painter->restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Draw cursor rectangles
|
||||||
if (editor->playerViewRect && editor->playerViewRect->isVisible())
|
if (editor->playerViewRect && editor->playerViewRect->isVisible())
|
||||||
editor->playerViewRect->paint(painter, &option, this);
|
editor->playerViewRect->paint(painter, &option, this);
|
||||||
if (editor->cursorMapTileRect && editor->cursorMapTileRect->isVisible())
|
if (editor->cursorMapTileRect && editor->cursorMapTileRect->isVisible())
|
||||||
|
|
230
src/ui/gridsettings.cpp
Normal file
230
src/ui/gridsettings.cpp
Normal file
|
@ -0,0 +1,230 @@
|
||||||
|
#include "ui_gridsettingsdialog.h"
|
||||||
|
#include "gridsettings.h"
|
||||||
|
|
||||||
|
// TODO: Save settings in config
|
||||||
|
|
||||||
|
const QMap<GridSettings::Style, QString> GridSettings::styleToName = {
|
||||||
|
{Style::Solid, "Solid"},
|
||||||
|
{Style::LargeDashes, "Large Dashes"},
|
||||||
|
{Style::SmallDashes, "Small Dashes"},
|
||||||
|
{Style::Crosshairs, "Crosshairs"},
|
||||||
|
{Style::Dots, "Dots"},
|
||||||
|
};
|
||||||
|
|
||||||
|
QString GridSettings::getStyleName(GridSettings::Style style) {
|
||||||
|
return styleToName.value(style);
|
||||||
|
}
|
||||||
|
|
||||||
|
GridSettings::Style GridSettings::getStyleFromName(const QString &name) {
|
||||||
|
return styleToName.key(name, GridSettings::Style::Solid);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We do some extra work here to A: try and center the dashes away from the intersections, and B: keep the dash pattern's total
|
||||||
|
// length equal to the length of a grid square. This keeps the patterns looking reasonable regardless of the grid size.
|
||||||
|
// Otherwise, the dashes can start to intersect in weird ways and create grid patterns that don't look like a rectangular grid.
|
||||||
|
QList<qreal> GridSettings::getCenteredDashPattern(uint length, qreal dashLength, qreal gapLength) const {
|
||||||
|
const qreal minEdgesLength = 0.6*2;
|
||||||
|
if (length <= dashLength + minEdgesLength)
|
||||||
|
return {dashLength};
|
||||||
|
|
||||||
|
// Every dash after the first one needs to have room for a 'gapLength' segment.
|
||||||
|
const int numDashes = 1 + ((length - minEdgesLength) - dashLength) / (dashLength + gapLength);
|
||||||
|
|
||||||
|
// Total length of the pattern excluding the centering edges. There are always 1 fewer gap segments than dashes.
|
||||||
|
const qreal mainLength = (dashLength * numDashes) + (gapLength * (numDashes-1));
|
||||||
|
|
||||||
|
const qreal edgeLength = (length - mainLength) / 2;
|
||||||
|
|
||||||
|
// Fill the pattern
|
||||||
|
QList<qreal> pattern = {0, edgeLength};
|
||||||
|
for (int i = 0; i < numDashes-1; i++) {
|
||||||
|
pattern.append(dashLength);
|
||||||
|
pattern.append(gapLength);
|
||||||
|
}
|
||||||
|
pattern.append(dashLength);
|
||||||
|
pattern.append(edgeLength);
|
||||||
|
|
||||||
|
return pattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<qreal> GridSettings::getDashPattern(uint length) const {
|
||||||
|
switch (this->style) {
|
||||||
|
|
||||||
|
// Equivalent to setting Qt::PenStyle::Solid with no dash pattern.
|
||||||
|
case Style::Solid: return {1, 0};
|
||||||
|
|
||||||
|
// Roughly equivalent to Qt::PenStyle::DashLine but with centering.
|
||||||
|
case Style::LargeDashes: return getCenteredDashPattern(length, 3.0, 2.0);
|
||||||
|
|
||||||
|
// Roughly equivalent to Qt::PenStyle::DotLine but with centering.
|
||||||
|
case Style::SmallDashes: return getCenteredDashPattern(length, 1.0, 2.5);
|
||||||
|
|
||||||
|
// Dashes only at intersections, in the shape of a crosshair.
|
||||||
|
case Style::Crosshairs: {
|
||||||
|
const qreal crosshairLength = 2.0;
|
||||||
|
return {crosshairLength / 2, length - crosshairLength, crosshairLength / 2, 0};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dots only at intersections.
|
||||||
|
case Style::Dots: {
|
||||||
|
const qreal dotLength = 0.1;
|
||||||
|
return {dotLength, length - dotLength};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invalid
|
||||||
|
default: return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GridSettingsDialog::GridSettingsDialog(QWidget *parent) :
|
||||||
|
QDialog(parent),
|
||||||
|
ui(new Ui::GridSettingsDialog),
|
||||||
|
m_settings(new GridSettings),
|
||||||
|
m_originalSettings(*m_settings)
|
||||||
|
{
|
||||||
|
m_ownedSettings = true;
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
GridSettingsDialog::GridSettingsDialog(GridSettings *settings, QWidget *parent) :
|
||||||
|
QDialog(parent),
|
||||||
|
ui(new Ui::GridSettingsDialog),
|
||||||
|
m_settings(settings),
|
||||||
|
m_originalSettings(*settings)
|
||||||
|
{
|
||||||
|
m_ownedSettings = false;
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GridSettingsDialog::init() {
|
||||||
|
ui->setupUi(this);
|
||||||
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
|
||||||
|
// Populate the styles combo box
|
||||||
|
const QSignalBlocker b_Style(ui->comboBox_Style);
|
||||||
|
ui->comboBox_Style->addItem(GridSettings::getStyleName(GridSettings::Style::Solid));
|
||||||
|
ui->comboBox_Style->addItem(GridSettings::getStyleName(GridSettings::Style::LargeDashes));
|
||||||
|
ui->comboBox_Style->addItem(GridSettings::getStyleName(GridSettings::Style::SmallDashes));
|
||||||
|
ui->comboBox_Style->addItem(GridSettings::getStyleName(GridSettings::Style::Crosshairs));
|
||||||
|
ui->comboBox_Style->addItem(GridSettings::getStyleName(GridSettings::Style::Dots));
|
||||||
|
|
||||||
|
ui->button_LinkDimensions->setChecked(m_dimensionsLinked);
|
||||||
|
ui->button_LinkOffsets->setChecked(m_offsetsLinked);
|
||||||
|
|
||||||
|
connect(ui->buttonBox, &QDialogButtonBox::clicked, this, &GridSettingsDialog::dialogButtonClicked);
|
||||||
|
connect(ui->button_LinkDimensions, &QAbstractButton::toggled, [this](bool on) { m_dimensionsLinked = on; });
|
||||||
|
connect(ui->button_LinkOffsets, &QAbstractButton::toggled, [this](bool on) { m_offsetsLinked = on; });
|
||||||
|
connect(ui->colorInput, &ColorInputWidget::colorChanged, this, &GridSettingsDialog::onColorChanged);
|
||||||
|
|
||||||
|
updateInput();
|
||||||
|
}
|
||||||
|
|
||||||
|
GridSettingsDialog::~GridSettingsDialog() {
|
||||||
|
delete ui;
|
||||||
|
if (m_ownedSettings)
|
||||||
|
delete m_settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GridSettingsDialog::setSettings(const GridSettings &settings) {
|
||||||
|
if (*m_settings == settings)
|
||||||
|
return;
|
||||||
|
*m_settings = settings;
|
||||||
|
updateInput();
|
||||||
|
emit changedGridSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GridSettingsDialog::updateInput() {
|
||||||
|
setWidth(m_settings->width);
|
||||||
|
setHeight(m_settings->height);
|
||||||
|
setOffsetX(m_settings->offsetX);
|
||||||
|
setOffsetY(m_settings->offsetY);
|
||||||
|
|
||||||
|
const QSignalBlocker b_Color(ui->colorInput);
|
||||||
|
ui->colorInput->setColor(m_settings->color.rgb());
|
||||||
|
|
||||||
|
const QSignalBlocker b_Style(ui->comboBox_Style);
|
||||||
|
ui->comboBox_Style->setCurrentText(GridSettings::getStyleName(m_settings->style));
|
||||||
|
}
|
||||||
|
|
||||||
|
void GridSettingsDialog::setWidth(int value) {
|
||||||
|
const QSignalBlocker b(ui->spinBox_Width);
|
||||||
|
ui->spinBox_Width->setValue(value);
|
||||||
|
m_settings->width = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GridSettingsDialog::setHeight(int value) {
|
||||||
|
const QSignalBlocker b(ui->spinBox_Height);
|
||||||
|
ui->spinBox_Height->setValue(value);
|
||||||
|
m_settings->height = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GridSettingsDialog::setOffsetX(int value) {
|
||||||
|
const QSignalBlocker b(ui->spinBox_X);
|
||||||
|
ui->spinBox_X->setValue(value);
|
||||||
|
m_settings->offsetX = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GridSettingsDialog::setOffsetY(int value) {
|
||||||
|
const QSignalBlocker b(ui->spinBox_Y);
|
||||||
|
ui->spinBox_Y->setValue(value);
|
||||||
|
m_settings->offsetY = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GridSettingsDialog::on_spinBox_Width_valueChanged(int value) {
|
||||||
|
setWidth(value);
|
||||||
|
if (m_dimensionsLinked)
|
||||||
|
setHeight(value);
|
||||||
|
|
||||||
|
emit changedGridSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GridSettingsDialog::on_spinBox_Height_valueChanged(int value) {
|
||||||
|
setHeight(value);
|
||||||
|
if (m_dimensionsLinked)
|
||||||
|
setWidth(value);
|
||||||
|
|
||||||
|
emit changedGridSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GridSettingsDialog::on_spinBox_X_valueChanged(int value) {
|
||||||
|
setOffsetX(value);
|
||||||
|
if (m_offsetsLinked)
|
||||||
|
setOffsetY(value);
|
||||||
|
|
||||||
|
emit changedGridSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GridSettingsDialog::on_spinBox_Y_valueChanged(int value) {
|
||||||
|
setOffsetY(value);
|
||||||
|
if (m_offsetsLinked)
|
||||||
|
setOffsetX(value);
|
||||||
|
|
||||||
|
emit changedGridSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GridSettingsDialog::on_comboBox_Style_currentTextChanged(const QString &text) {
|
||||||
|
m_settings->style = GridSettings::getStyleFromName(text);
|
||||||
|
emit changedGridSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GridSettingsDialog::onColorChanged(QRgb color) {
|
||||||
|
m_settings->color = QColor::fromRgb(color);
|
||||||
|
emit changedGridSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GridSettingsDialog::dialogButtonClicked(QAbstractButton *button) {
|
||||||
|
auto role = ui->buttonBox->buttonRole(button);
|
||||||
|
if (role == QDialogButtonBox::AcceptRole) {
|
||||||
|
// "OK"
|
||||||
|
close();
|
||||||
|
} else if (role == QDialogButtonBox::RejectRole) {
|
||||||
|
// "Cancel"
|
||||||
|
setSettings(m_originalSettings);
|
||||||
|
close();
|
||||||
|
} else if (role == QDialogButtonBox::ResetRole) {
|
||||||
|
// "Restore Defaults"
|
||||||
|
setSettings(m_defaultSettings);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,156 +0,0 @@
|
||||||
#include "ui_gridsettingsdialog.h"
|
|
||||||
#include "gridsettingsdialog.h"
|
|
||||||
|
|
||||||
// TODO: Save settings in config
|
|
||||||
// TODO: Look into custom painting to improve performance
|
|
||||||
// TODO: Add tooltips
|
|
||||||
|
|
||||||
const QList<QPair<QString, Qt::PenStyle>> penStyleMap = {
|
|
||||||
{"Solid", Qt::SolidLine},
|
|
||||||
{"Large Dashes", Qt::DashLine},
|
|
||||||
{"Small Dashes", Qt::DotLine},
|
|
||||||
{"Dots", Qt::CustomDashLine}, // TODO: Implement a custom pattern for this
|
|
||||||
};
|
|
||||||
|
|
||||||
GridSettingsDialog::GridSettingsDialog(GridSettings *settings, QWidget *parent) :
|
|
||||||
QDialog(parent),
|
|
||||||
ui(new Ui::GridSettingsDialog),
|
|
||||||
settings(settings)
|
|
||||||
{
|
|
||||||
ui->setupUi(this);
|
|
||||||
setAttribute(Qt::WA_DeleteOnClose);
|
|
||||||
|
|
||||||
// Populate the styles combo box
|
|
||||||
for (const auto &pair : penStyleMap)
|
|
||||||
ui->comboBox_Style->addItem(pair.first, static_cast<int>(pair.second));
|
|
||||||
|
|
||||||
ui->spinBox_Width->setMaximum(INT_MAX);
|
|
||||||
ui->spinBox_Height->setMaximum(INT_MAX);
|
|
||||||
ui->spinBox_X->setMaximum(INT_MAX);
|
|
||||||
ui->spinBox_Y->setMaximum(INT_MAX);
|
|
||||||
|
|
||||||
ui->button_LinkDimensions->setChecked(this->dimensionsLinked);
|
|
||||||
ui->button_LinkOffsets->setChecked(this->offsetsLinked);
|
|
||||||
|
|
||||||
// Initialize the settings
|
|
||||||
if (!this->settings)
|
|
||||||
this->settings = new GridSettings; // TODO: Don't leak this
|
|
||||||
this->originalSettings = *this->settings;
|
|
||||||
reset(true);
|
|
||||||
|
|
||||||
connect(ui->buttonBox, &QDialogButtonBox::clicked, this, &GridSettingsDialog::dialogButtonClicked);
|
|
||||||
connect(ui->button_LinkDimensions, &QAbstractButton::toggled, [this](bool on) { this->dimensionsLinked = on; });
|
|
||||||
connect(ui->button_LinkOffsets, &QAbstractButton::toggled, [this](bool on) { this->offsetsLinked = on; });
|
|
||||||
connect(ui->colorInput, &ColorInputWidget::colorChanged, this, &GridSettingsDialog::onColorChanged);
|
|
||||||
}
|
|
||||||
|
|
||||||
GridSettingsDialog::~GridSettingsDialog() {
|
|
||||||
delete ui;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GridSettingsDialog::reset(bool force) {
|
|
||||||
if (!force && *this->settings == this->originalSettings)
|
|
||||||
return;
|
|
||||||
*this->settings = this->originalSettings;
|
|
||||||
|
|
||||||
setWidth(this->settings->width);
|
|
||||||
setHeight(this->settings->height);
|
|
||||||
setOffsetX(this->settings->offsetX);
|
|
||||||
setOffsetY(this->settings->offsetY);
|
|
||||||
|
|
||||||
const QSignalBlocker b_Color(ui->colorInput);
|
|
||||||
ui->colorInput->setColor(this->settings->color.rgb());
|
|
||||||
|
|
||||||
const QSignalBlocker b_Style(ui->comboBox_Style);
|
|
||||||
// TODO: Debug
|
|
||||||
//ui->comboBox_Style->setCurrentIndex(ui->comboBox_Style->findData(static_cast<int>(this->settings->style)));
|
|
||||||
for (const auto &pair : penStyleMap) {
|
|
||||||
if (pair.second == this->settings->style) {
|
|
||||||
ui->comboBox_Style->setCurrentText(pair.first);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
emit changedGridSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GridSettingsDialog::setWidth(int value) {
|
|
||||||
const QSignalBlocker b(ui->spinBox_Width);
|
|
||||||
ui->spinBox_Width->setValue(value);
|
|
||||||
this->settings->width = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GridSettingsDialog::setHeight(int value) {
|
|
||||||
const QSignalBlocker b(ui->spinBox_Height);
|
|
||||||
ui->spinBox_Height->setValue(value);
|
|
||||||
this->settings->height = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GridSettingsDialog::setOffsetX(int value) {
|
|
||||||
const QSignalBlocker b(ui->spinBox_X);
|
|
||||||
ui->spinBox_X->setValue(value);
|
|
||||||
this->settings->offsetX = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GridSettingsDialog::setOffsetY(int value) {
|
|
||||||
const QSignalBlocker b(ui->spinBox_Y);
|
|
||||||
ui->spinBox_Y->setValue(value);
|
|
||||||
this->settings->offsetY = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GridSettingsDialog::on_spinBox_Width_valueChanged(int value) {
|
|
||||||
setWidth(value);
|
|
||||||
if (this->dimensionsLinked)
|
|
||||||
setHeight(value);
|
|
||||||
|
|
||||||
emit changedGridSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GridSettingsDialog::on_spinBox_Height_valueChanged(int value) {
|
|
||||||
setHeight(value);
|
|
||||||
if (this->dimensionsLinked)
|
|
||||||
setWidth(value);
|
|
||||||
|
|
||||||
emit changedGridSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GridSettingsDialog::on_spinBox_X_valueChanged(int value) {
|
|
||||||
setOffsetX(value);
|
|
||||||
if (this->offsetsLinked)
|
|
||||||
setOffsetY(value);
|
|
||||||
|
|
||||||
emit changedGridSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GridSettingsDialog::on_spinBox_Y_valueChanged(int value) {
|
|
||||||
setOffsetY(value);
|
|
||||||
if (this->offsetsLinked)
|
|
||||||
setOffsetX(value);
|
|
||||||
|
|
||||||
emit changedGridSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GridSettingsDialog::on_comboBox_Style_currentIndexChanged(int index) {
|
|
||||||
if (index < 0 || index >= penStyleMap.length())
|
|
||||||
return;
|
|
||||||
|
|
||||||
this->settings->style = penStyleMap.at(index).second;
|
|
||||||
emit changedGridSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GridSettingsDialog::onColorChanged(QRgb color) {
|
|
||||||
this->settings->color = QColor::fromRgb(color);
|
|
||||||
emit changedGridSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GridSettingsDialog::dialogButtonClicked(QAbstractButton *button) {
|
|
||||||
auto role = ui->buttonBox->buttonRole(button);
|
|
||||||
if (role == QDialogButtonBox::AcceptRole) {
|
|
||||||
close();
|
|
||||||
} else if (role == QDialogButtonBox::RejectRole) {
|
|
||||||
reset();
|
|
||||||
close();
|
|
||||||
} else if (role == QDialogButtonBox::ResetRole) {
|
|
||||||
reset(); // TODO: We should restore to original defaults, not to the values when the window was opened.
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in a new issue