timelapse replay layout edits then map edits
This commit is contained in:
parent
cd5b1f98d2
commit
99eb92c3b2
3 changed files with 121 additions and 87 deletions
|
@ -27,6 +27,7 @@ public:
|
|||
private:
|
||||
Ui::MapImageExporter *ui;
|
||||
|
||||
Layout *layout = nullptr;
|
||||
Map *map = nullptr;
|
||||
Editor *editor = nullptr;
|
||||
QGraphicsScene *scene = nullptr;
|
||||
|
|
|
@ -1208,6 +1208,7 @@ void MainWindow::scrollTreeView(QString itemName) {
|
|||
}
|
||||
}
|
||||
|
||||
// !TODO: remove this?
|
||||
void MainWindow::sortMapList() {
|
||||
}
|
||||
|
||||
|
@ -2564,6 +2565,17 @@ void MainWindow::on_action_Export_Map_Image_triggered() {
|
|||
}
|
||||
|
||||
void MainWindow::on_actionExport_Stitched_Map_Image_triggered() {
|
||||
if (!this->editor->map) {
|
||||
QMessageBox warning(this);
|
||||
warning.setText("Notice");
|
||||
warning.setInformativeText("Map stich images are not possible without a map selected.");
|
||||
warning.setStandardButtons(QMessageBox::Ok);
|
||||
warning.setDefaultButton(QMessageBox::Cancel);
|
||||
warning.setIcon(QMessageBox::Warning);
|
||||
|
||||
warning.exec();
|
||||
return;
|
||||
}
|
||||
showExportMapImageWindow(ImageExporterMode::Stitch);
|
||||
}
|
||||
|
||||
|
|
|
@ -29,15 +29,18 @@ MapImageExporter::MapImageExporter(QWidget *parent_, Editor *editor_, ImageExpor
|
|||
{
|
||||
ui->setupUi(this);
|
||||
this->map = editor_->map;
|
||||
this->layout = editor_->layout;
|
||||
this->editor = editor_;
|
||||
this->mode = mode;
|
||||
this->setWindowTitle(getTitle(this->mode));
|
||||
this->ui->groupBox_Connections->setVisible(this->mode == ImageExporterMode::Normal);
|
||||
this->ui->groupBox_Timelapse->setVisible(this->mode == ImageExporterMode::Timelapse);
|
||||
|
||||
if (this->map) {
|
||||
this->ui->comboBox_MapSelection->addItems(editor->project->mapNames);
|
||||
this->ui->comboBox_MapSelection->setCurrentText(map->name);
|
||||
this->ui->comboBox_MapSelection->setEnabled(false);// TODO: allow selecting map from drop-down
|
||||
}
|
||||
|
||||
updatePreview();
|
||||
}
|
||||
|
@ -53,13 +56,13 @@ void MapImageExporter::saveImage() {
|
|||
switch (this->mode)
|
||||
{
|
||||
case ImageExporterMode::Normal:
|
||||
defaultFilename = map->name;
|
||||
defaultFilename = this->map? this->map->name : this->layout->name;
|
||||
break;
|
||||
case ImageExporterMode::Stitch:
|
||||
defaultFilename = QString("Stitch_From_%1").arg(map->name);
|
||||
defaultFilename = QString("Stitch_From_%1").arg(this->map? this->map->name : this->layout->name);
|
||||
break;
|
||||
case ImageExporterMode::Timelapse:
|
||||
defaultFilename = QString("Timelapse_%1").arg(map->name);
|
||||
defaultFilename = QString("Timelapse_%1").arg(this->map? this->map->name : this->layout->name);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -91,29 +94,32 @@ void MapImageExporter::saveImage() {
|
|||
}
|
||||
case ImageExporterMode::Timelapse:
|
||||
// !TODO: also need layout editHistory!
|
||||
QProgressDialog progress("Building map timelapse...", "Cancel", 0, 1, this);
|
||||
QGifImage timelapseImg;
|
||||
timelapseImg.setDefaultDelay(timelapseDelayMs);
|
||||
timelapseImg.setDefaultTransparentColor(QColor(0, 0, 0));
|
||||
|
||||
auto generateTimelapseFromHistory = [=, this, &timelapseImg](QString progressText, QUndoStack &historyStack){
|
||||
//
|
||||
QProgressDialog progress(progressText, "Cancel", 0, 1, this);
|
||||
progress.setAutoClose(true);
|
||||
progress.setWindowModality(Qt::WindowModal);
|
||||
progress.setModal(true);
|
||||
progress.setMaximum(1);
|
||||
progress.setValue(0);
|
||||
|
||||
Layout *layout = this->map->layout;
|
||||
if (!layout) break;
|
||||
|
||||
int maxWidth = layout->getWidth() * 16;
|
||||
int maxHeight = layout->getHeight() * 16;
|
||||
int maxWidth = this->layout->getWidth() * 16;
|
||||
int maxHeight = this->layout->getHeight() * 16;
|
||||
if (showBorder) {
|
||||
maxWidth += 2 * STITCH_MODE_BORDER_DISTANCE * 16;
|
||||
maxHeight += 2 * STITCH_MODE_BORDER_DISTANCE * 16;
|
||||
}
|
||||
// Rewind to the specified start of the map edit history.
|
||||
int i = 0;
|
||||
while (this->map->editHistory.canUndo()) {
|
||||
while (historyStack.canUndo()) {
|
||||
progress.setValue(i);
|
||||
this->map->editHistory.undo();
|
||||
int width = this->map->getWidth() * 16;
|
||||
int height = this->map->getHeight() * 16;
|
||||
historyStack.undo();
|
||||
int width = this->layout->getWidth() * 16;
|
||||
int height = this->layout->getHeight() * 16;
|
||||
if (showBorder) {
|
||||
width += 2 * STITCH_MODE_BORDER_DISTANCE * 16;
|
||||
height += 2 * STITCH_MODE_BORDER_DISTANCE * 16;
|
||||
|
@ -126,25 +132,23 @@ void MapImageExporter::saveImage() {
|
|||
}
|
||||
i++;
|
||||
}
|
||||
QGifImage timelapseImg(QSize(maxWidth, maxHeight));
|
||||
timelapseImg.setDefaultDelay(timelapseDelayMs);
|
||||
timelapseImg.setDefaultTransparentColor(QColor(0, 0, 0));
|
||||
|
||||
// Draw each frame, skpping the specified number of map edits in
|
||||
// the undo history.
|
||||
progress.setMaximum(i);
|
||||
while (i > 0) {
|
||||
if (progress.wasCanceled()) {
|
||||
progress.close();
|
||||
while (i > 0 && this->map->editHistory.canRedo()) {
|
||||
while (i > 0 && historyStack.canRedo()) {
|
||||
i--;
|
||||
this->map->editHistory.redo();
|
||||
historyStack.redo();
|
||||
}
|
||||
return;
|
||||
}
|
||||
while (this->map->editHistory.canRedo() &&
|
||||
!historyItemAppliesToFrame(this->map->editHistory.command(this->map->editHistory.index()))) {
|
||||
while (historyStack.canRedo() &&
|
||||
!historyItemAppliesToFrame(historyStack.command(historyStack.index()))) {
|
||||
i--;
|
||||
this->map->editHistory.redo();
|
||||
historyStack.redo();
|
||||
}
|
||||
progress.setValue(progress.maximum() - i);
|
||||
QPixmap pixmap = this->getFormattedMapPixmap(this->map, !this->showBorder);
|
||||
|
@ -160,11 +164,11 @@ void MapImageExporter::saveImage() {
|
|||
for (int j = 0; j < timelapseSkipAmount; j++) {
|
||||
if (i > 0) {
|
||||
i--;
|
||||
this->map->editHistory.redo();
|
||||
while (this->map->editHistory.canRedo() &&
|
||||
!historyItemAppliesToFrame(this->map->editHistory.command(this->map->editHistory.index()))) {
|
||||
historyStack.redo();
|
||||
while (historyStack.canRedo() &&
|
||||
!historyItemAppliesToFrame(historyStack.command(historyStack.index()))) {
|
||||
i--;
|
||||
this->map->editHistory.redo();
|
||||
historyStack.redo();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -172,8 +176,16 @@ void MapImageExporter::saveImage() {
|
|||
// The latest map state is the last animated frame.
|
||||
QPixmap pixmap = this->getFormattedMapPixmap(this->map, !this->showBorder);
|
||||
timelapseImg.addFrame(pixmap.toImage());
|
||||
timelapseImg.save(filepath);
|
||||
progress.close();
|
||||
};
|
||||
|
||||
if (this->layout)
|
||||
generateTimelapseFromHistory("Building layout timelapse...", this->layout->editHistory);
|
||||
|
||||
if (this->map)
|
||||
generateTimelapseFromHistory("Building map timelapse...", this->map->editHistory);
|
||||
|
||||
timelapseImg.save(filepath);
|
||||
break;
|
||||
}
|
||||
this->close();
|
||||
|
@ -358,17 +370,22 @@ void MapImageExporter::updatePreview() {
|
|||
scene->itemsBoundingRect().height() + 2);
|
||||
}
|
||||
|
||||
// THIS
|
||||
QPixmap MapImageExporter::getFormattedMapPixmap(Map *map, bool ignoreBorder) {
|
||||
QPixmap pixmap;
|
||||
|
||||
// draw background layer / base image
|
||||
Layout *layout = map->layout;
|
||||
if (!layout) {
|
||||
return QPixmap();
|
||||
}
|
||||
Layout *layout;
|
||||
|
||||
// draw background layer / base image
|
||||
if (!this->map) {
|
||||
layout = this->layout;
|
||||
layout->render(true);
|
||||
pixmap = layout->pixmap;
|
||||
} else {
|
||||
layout = map->layout;
|
||||
map->layout->render(true);
|
||||
pixmap = map->layout->pixmap;
|
||||
}
|
||||
|
||||
if (showCollision) {
|
||||
QPainter collisionPainter(&pixmap);
|
||||
|
@ -401,6 +418,10 @@ QPixmap MapImageExporter::getFormattedMapPixmap(Map *map, bool ignoreBorder) {
|
|||
pixmap = newPixmap;
|
||||
}
|
||||
|
||||
if (!this->map) {
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
if (!this->mode) {
|
||||
// if showing connections, draw on outside of image
|
||||
QPainter connectionPainter(&pixmap);
|
||||
|
|
Loading…
Reference in a new issue