void MapScene::setMapDocument(MapDocument *mapDocument) { if (mMapDocument) { mMapDocument->disconnect(this); if (!mSelectedObjectItems.isEmpty()) { mSelectedObjectItems.clear(); emit selectedObjectItemsChanged(); } } mMapDocument = mapDocument; if (mMapDocument) { MapRenderer *renderer = mMapDocument->renderer(); renderer->setObjectLineWidth(mObjectLineWidth); renderer->setFlag(ShowTileObjectOutlines, mShowTileObjectOutlines); connect(mMapDocument, SIGNAL(mapChanged()), this, SLOT(mapChanged())); connect(mMapDocument, &MapDocument::regionChanged, this, &MapScene::repaintRegion); connect(mMapDocument, SIGNAL(tileLayerDrawMarginsChanged(TileLayer*)), this, SLOT(tileLayerDrawMarginsChanged(TileLayer*))); connect(mMapDocument, SIGNAL(layerAdded(int)), this, SLOT(layerAdded(int))); connect(mMapDocument, SIGNAL(layerRemoved(int)), this, SLOT(layerRemoved(int))); connect(mMapDocument, SIGNAL(layerChanged(int)), this, SLOT(layerChanged(int))); connect(mMapDocument, SIGNAL(objectGroupChanged(ObjectGroup*)), this, SLOT(objectGroupChanged(ObjectGroup*))); connect(mMapDocument, SIGNAL(imageLayerChanged(ImageLayer*)), this, SLOT(imageLayerChanged(ImageLayer*))); connect(mMapDocument, SIGNAL(currentLayerIndexChanged(int)), this, SLOT(currentLayerIndexChanged())); connect(mMapDocument, SIGNAL(tilesetTileOffsetChanged(Tileset*)), this, SLOT(tilesetTileOffsetChanged(Tileset*))); connect(mMapDocument, SIGNAL(objectsInserted(ObjectGroup*,int,int)), this, SLOT(objectsInserted(ObjectGroup*,int,int))); connect(mMapDocument, SIGNAL(objectsRemoved(QList<MapObject*>)), this, SLOT(objectsRemoved(QList<MapObject*>))); connect(mMapDocument, SIGNAL(objectsChanged(QList<MapObject*>)), this, SLOT(objectsChanged(QList<MapObject*>))); connect(mMapDocument, SIGNAL(objectsIndexChanged(ObjectGroup*,int,int)), this, SLOT(objectsIndexChanged(ObjectGroup*,int,int))); connect(mMapDocument, SIGNAL(selectedObjectsChanged()), this, SLOT(updateSelectedObjectItems())); } refreshScene(); }
void ExportAsImageDialog::accept() { const QString fileName = mUi->fileNameEdit->text(); if (fileName.isEmpty()) return; if (QFile::exists(fileName)) { const QMessageBox::StandardButton button = QMessageBox::warning(this, tr("Export as Image"), tr("%1 already exists.\n" "Do you want to replace it?") .arg(QFileInfo(fileName).fileName()), QMessageBox::Yes | QMessageBox::No, QMessageBox::No); if (button != QMessageBox::Yes) return; } const bool visibleLayersOnly = mUi->visibleLayersOnly->isChecked(); const bool useCurrentScale = mUi->currentZoomLevel->isChecked(); const bool drawTileGrid = mUi->drawTileGrid->isChecked(); const bool includeBackgroundColor = mUi->includeBackgroundColor->isChecked(); MapRenderer *renderer = mMapDocument->renderer(); // Remember the current render flags const Tiled::RenderFlags renderFlags = renderer->flags(); renderer->setFlag(ShowTileObjectOutlines, false); QSize mapSize = renderer->mapSize(); QMargins margins = mMapDocument->map()->computeLayerOffsetMargins(); mapSize.setWidth(mapSize.width() + margins.left() + margins.right()); mapSize.setHeight(mapSize.height() + margins.top() + margins.bottom()); if (useCurrentScale) mapSize *= mCurrentScale; QImage image; try { image = QImage(mapSize, QImage::Format_ARGB32_Premultiplied); if (includeBackgroundColor) { if (mMapDocument->map()->backgroundColor().isValid()) image.fill(mMapDocument->map()->backgroundColor()); else image.fill(Qt::gray); } else { image.fill(Qt::transparent); } } catch (const std::bad_alloc &) { QMessageBox::critical(this, tr("Out of Memory"), tr("Could not allocate sufficient memory for the image. " "Try reducing the zoom level or using a 64-bit version of Tiled.")); return; } if (image.isNull()) { const size_t gigabyte = 1073741824; const size_t memory = size_t(mapSize.width()) * size_t(mapSize.height()) * 4; const double gigabytes = (double) memory / gigabyte; QMessageBox::critical(this, tr("Image too Big"), tr("The resulting image would be %1 x %2 pixels and take %3 GB of memory. " "Tiled is unable to create such an image. Try reducing the zoom level.") .arg(mapSize.width()) .arg(mapSize.height()) .arg(gigabytes, 0, 'f', 2)); return; } QPainter painter(&image); if (useCurrentScale) { if (smoothTransform(mCurrentScale)) painter.setRenderHints(QPainter::SmoothPixmapTransform); painter.setTransform(QTransform::fromScale(mCurrentScale, mCurrentScale)); renderer->setPainterScale(mCurrentScale); } else { renderer->setPainterScale(1); } painter.translate(margins.left(), margins.top()); foreach (const Layer *layer, mMapDocument->map()->layers()) { if (visibleLayersOnly && !layer->isVisible()) continue; painter.setOpacity(layer->opacity()); painter.translate(layer->offset()); const TileLayer *tileLayer = dynamic_cast<const TileLayer*>(layer); const ObjectGroup *objGroup = dynamic_cast<const ObjectGroup*>(layer); const ImageLayer *imageLayer = dynamic_cast<const ImageLayer*>(layer); if (tileLayer) { renderer->drawTileLayer(&painter, tileLayer); } else if (objGroup) { QList<MapObject*> objects = objGroup->objects(); if (objGroup->drawOrder() == ObjectGroup::TopDownOrder) qStableSort(objects.begin(), objects.end(), objectLessThan); foreach (const MapObject *object, objects) { if (object->isVisible()) { if (object->rotation() != qreal(0)) { QPointF origin = renderer->pixelToScreenCoords(object->position()); painter.save(); painter.translate(origin); painter.rotate(object->rotation()); painter.translate(-origin); } const QColor color = MapObjectItem::objectColor(object); renderer->drawMapObject(&painter, object, color); if (object->rotation() != qreal(0)) painter.restore(); } } } else if (imageLayer) { renderer->drawImageLayer(&painter, imageLayer); } painter.translate(-layer->offset()); }
void SaveAsImageDialog::accept() { const QString fileName = ui->name->text(); if (fileName.isEmpty()) return; if (QFile::exists(fileName)) { const QMessageBox::StandardButton button = QMessageBox::warning(this, tr("Save as Image"), tr("%1 already exists.\n" "Do you want to replace it?") .arg(QFileInfo(fileName).fileName()), QMessageBox::Yes | QMessageBox::No, QMessageBox::No); if (button != QMessageBox::Yes) return; } const bool visibleLayersOnly = ui->visibleLayers->isChecked(); const bool useCurrentScale = ui->currentZoomLevel->isChecked(); const bool drawTileGrid = ui->showGrid->isChecked(); MapRenderer *renderer = mMapEditor->renderer(); //remember the current render flags const Aurora::RenderFlags renderFlags = renderer->flags(); renderer->setFlag(ShowTileObjectOutlines, false); QSize mapSize = renderer->mapSize(); if (useCurrentScale) mapSize *= mCurrentScale; QImage image(mapSize, QImage::Format_ARGB32); image.fill(Qt::transparent); QPainter painter(&image); if (useCurrentScale && mCurrentScale != qreal(1)) { painter.setRenderHints(QPainter::SmoothPixmapTransform | QPainter::HighQualityAntialiasing); painter.setTransform(QTransform::fromScale(mCurrentScale, mCurrentScale)); } foreach (const Layer *layer, mMapEditor->map()->layers()) { if (visibleLayersOnly && !layer->isVisible()) continue; painter.setOpacity(layer->opacity()); const Tilelayer *tilelayer = dynamic_cast<const Tilelayer*>(layer); if (tilelayer) { renderer->drawTilelayer(&painter, tilelayer); } } if (drawTileGrid) { renderer->drawGrid(&painter, QRectF(QPointF(), renderer->mapSize())); } //restore the previous render flags renderer->setFlags(renderFlags); image.save(fileName); mPath = QFileInfo(fileName).path(); //store settings for next time QSettings *s = Preferences::instance()->settings(); s->setValue(QLatin1String(VISIBLE_ONLY_KEY), visibleLayersOnly); s->setValue(QLatin1String(CURRENT_SCALE_KEY), useCurrentScale); s->setValue(QLatin1String(DRAW_GRID_KEY), drawTileGrid); QDialog::accept(); }