Allow editing border dimensions

This commit is contained in:
GriffinR
2020-03-14 03:44:55 -04:00
parent 629abd3c06
commit c0a512803e
12 changed files with 645 additions and 398 deletions

View File

@@ -1,13 +1,17 @@
#include "historyitem.h"
HistoryItem::HistoryItem(Blockdata *metatiles, int layoutWidth, int layoutHeight) {
HistoryItem::HistoryItem(Blockdata *metatiles, Blockdata *border, int layoutWidth, int layoutHeight, int borderWidth, int borderHeight) {
this->metatiles = metatiles;
this->border = border;
this->layoutWidth = layoutWidth;
this->layoutHeight = layoutHeight;
this->borderWidth = borderWidth;
this->borderHeight = borderHeight;
}
HistoryItem::~HistoryItem() {
if (this->metatiles) delete this->metatiles;
if (this->border) delete this->border;
}
RegionMapHistoryItem::RegionMapHistoryItem(int which, QVector<uint8_t> tiles, QString cityMap) {

View File

@@ -67,7 +67,7 @@ int Map::getBorderHeight() {
return layout->border_height.toInt(nullptr, 0);
}
bool Map::blockChanged(int i, Blockdata *cache) {
bool Map::mapBlockChanged(int i, Blockdata *cache) {
if (!cache)
return true;
if (!layout->blockdata)
@@ -84,6 +84,23 @@ bool Map::blockChanged(int i, Blockdata *cache) {
return layout->blockdata->blocks->value(i) != cache->blocks->value(i);
}
bool Map::borderBlockChanged(int i, Blockdata *cache) {
if (!cache)
return true;
if (!layout->border)
return true;
if (!cache->blocks)
return true;
if (!layout->border->blocks)
return true;
if (cache->blocks->length() <= i)
return true;
if (layout->border->blocks->length() <= i)
return true;
return layout->border->blocks->value(i) != cache->blocks->value(i);
}
void Map::cacheBorder() {
if (layout->cached_border) delete layout->cached_border;
layout->cached_border = new Blockdata;
@@ -135,7 +152,7 @@ QPixmap Map::renderCollision(qreal opacity, bool ignoreCache) {
}
QPainter painter(&collision_image);
for (int i = 0; i < layout->blockdata->blocks->length(); i++) {
if (!ignoreCache && layout->cached_collision && !blockChanged(i, layout->cached_collision)) {
if (!ignoreCache && layout->cached_collision && !mapBlockChanged(i, layout->cached_collision)) {
continue;
}
changed_any = true;
@@ -179,7 +196,7 @@ QPixmap Map::render(bool ignoreCache = false, MapLayout * fromLayout) {
QPainter painter(&image);
for (int i = 0; i < layout->blockdata->blocks->length(); i++) {
if (!ignoreCache && !blockChanged(i, layout->cached_blockdata)) {
if (!ignoreCache && !mapBlockChanged(i, layout->cached_blockdata)) {
continue;
}
changed_any = true;
@@ -204,27 +221,33 @@ QPixmap Map::render(bool ignoreCache = false, MapLayout * fromLayout) {
}
QPixmap Map::renderBorder() {
bool changed_any = false;
bool changed_any = false, border_resized = false;
int width_ = getBorderWidth();
int height_ = getBorderHeight();
if (layout->border_image.isNull()) {
layout->border_image = QImage(width_ * 16, height_ * 16, QImage::Format_RGBA8888);
changed_any = true;
}
if (layout->border_image.width() != width_ * 16 || layout->border_image.height() != height_ * 16) {
layout->border_image = QImage(width_ * 16, height_ * 16, QImage::Format_RGBA8888);
border_resized = true;
}
if (!(layout->border && layout->border->blocks)) {
layout->border_pixmap = layout->border_pixmap.fromImage(layout->border_image);
return layout->border_pixmap;
}
QPainter painter(&layout->border_image);
for (int i = 0; i < layout->border->blocks->length(); i++) {
if (!blockChanged(i, layout->cached_border)) {
if (!border_resized && !borderBlockChanged(i, layout->cached_border)) {
continue;
}
changed_any = true;
Block block = layout->border->blocks->value(i);
QImage metatile_image = getMetatileImage(block.tile, layout->tileset_primary, layout->tileset_secondary);
int map_y = i / width_;
int map_x = i % width_;
uint16_t tile = block.tile;
QImage metatile_image = getMetatileImage(tile, layout->tileset_primary, layout->tileset_secondary);
int map_y = width_ ? i / width_ : 0;
int map_x = width_ ? i % width_ : 0;
painter.drawImage(QPoint(map_x * 16, map_y * 16), metatile_image);
}
painter.end();
@@ -240,23 +263,23 @@ QPixmap Map::renderConnection(MapConnection connection, MapLayout * fromLayout)
int x, y, w, h;
if (connection.direction == "up") {
x = 0;
y = getHeight() - 6;
y = getHeight() - BORDER_DISTANCE;
w = getWidth();
h = 6;
h = BORDER_DISTANCE;
} else if (connection.direction == "down") {
x = 0;
y = 0;
w = getWidth();
h = 6;
h = BORDER_DISTANCE;
} else if (connection.direction == "left") {
x = getWidth() - 6;
x = getWidth() - BORDER_DISTANCE;
y = 0;
w = 6;
w = BORDER_DISTANCE;
h = getHeight();
} else if (connection.direction == "right") {
x = 0;
y = 0;
w = 6;
w = BORDER_DISTANCE;
h = getHeight();
} else {
// this should not happen
@@ -289,6 +312,25 @@ void Map::setNewDimensionsBlockdata(int newWidth, int newHeight) {
layout->blockdata->copyFrom(newBlockData);
}
void Map::setNewBorderDimensionsBlockdata(int newWidth, int newHeight) {
int oldWidth = getBorderWidth();
int oldHeight = getBorderHeight();
Blockdata* newBlockData = new Blockdata;
for (int y = 0; y < newHeight; y++)
for (int x = 0; x < newWidth; x++) {
if (x < oldWidth && y < oldHeight) {
int index = y * oldWidth + x;
newBlockData->addBlock(layout->border->blocks->value(index));
} else {
newBlockData->addBlock(0);
}
}
layout->border->copyFrom(newBlockData);
}
void Map::setDimensions(int newWidth, int newHeight, bool setNewBlockdata) {
if (setNewBlockdata) {
setNewDimensionsBlockdata(newWidth, newHeight);
@@ -300,6 +342,17 @@ void Map::setDimensions(int newWidth, int newHeight, bool setNewBlockdata) {
emit mapChanged(this);
}
void Map::setBorderDimensions(int newWidth, int newHeight, bool setNewBlockdata) {
if (setNewBlockdata) {
setNewBorderDimensionsBlockdata(newWidth, newHeight);
}
layout->border_width = QString::number(newWidth);
layout->border_height = QString::number(newHeight);
emit mapChanged(this);
}
Block* Map::getBlock(int x, int y) {
if (layout->blockdata && layout->blockdata->blocks) {
if (x >= 0 && x < getWidth() && y >= 0 && y < getHeight()) {
@@ -354,35 +407,64 @@ void Map::_floodFillCollisionElevation(int x, int y, uint16_t collision, uint16_
}
void Map::undo() {
bool redraw = false, changed = false;
HistoryItem *commit = metatileHistory.back();
if (!commit)
return;
if (layout->blockdata) {
layout->blockdata->copyFrom(commit->metatiles);
if (commit->layoutWidth != this->getWidth() || commit->layoutHeight != this->getHeight())
{
if (commit->layoutWidth != this->getWidth() || commit->layoutHeight != this->getHeight()) {
this->setDimensions(commit->layoutWidth, commit->layoutHeight, false);
emit mapNeedsRedrawing();
redraw = true;
}
changed = true;
}
if (layout->border) {
layout->border->copyFrom(commit->border);
if (commit->borderWidth != this->getBorderWidth() || commit->borderHeight != this->getBorderHeight()) {
this->setBorderDimensions(commit->borderWidth, commit->borderHeight, false);
redraw = true;
}
changed = true;
}
if (redraw) {
emit mapNeedsRedrawing();
}
if (changed) {
emit mapChanged(this);
}
}
void Map::redo() {
bool redraw = false, changed = false;
HistoryItem *commit = metatileHistory.next();
if (!commit)
return;
if (layout->blockdata) {
layout->blockdata->copyFrom(commit->metatiles);
if (commit->layoutWidth != this->getWidth() || commit->layoutHeight != this->getHeight())
{
if (commit->layoutWidth != this->getWidth() || commit->layoutHeight != this->getHeight()) {
this->setDimensions(commit->layoutWidth, commit->layoutHeight, false);
emit mapNeedsRedrawing();
redraw = true;
}
changed = true;
}
if (layout->border) {
layout->border->copyFrom(commit->border);
if (commit->borderWidth != this->getBorderWidth() || commit->borderHeight != this->getBorderHeight()) {
this->setBorderDimensions(commit->borderWidth, commit->borderHeight, false);
redraw = true;
}
changed = true;
}
if (redraw) {
emit mapNeedsRedrawing();
}
if (changed) {
emit mapChanged(this);
}
}
@@ -392,14 +474,22 @@ void Map::commit() {
return;
}
int layoutWidth = this->getWidth();
int layoutHeight = this->getHeight();
int borderWidth = this->getBorderWidth();
int borderHeight = this->getBorderHeight();
if (layout->blockdata) {
HistoryItem *item = metatileHistory.current();
bool atCurrentHistory = item
&& layout->blockdata->equals(item->metatiles)
&& this->getWidth() == item->layoutWidth
&& this->getHeight() == item->layoutHeight;
&& layout->border->equals(item->border)
&& layoutWidth == item->layoutWidth
&& layoutHeight == item->layoutHeight
&& borderWidth == item->borderWidth
&& borderHeight == item->borderHeight;
if (!atCurrentHistory) {
HistoryItem *commit = new HistoryItem(layout->blockdata->copy(), this->getWidth(), this->getHeight());
HistoryItem *commit = new HistoryItem(layout->blockdata->copy(), layout->border->copy(), layoutWidth, layoutHeight, borderWidth, borderHeight);
metatileHistory.push(commit);
emit mapChanged(this);
}