UIGChooser::UIGChooser(QWidget *pParent) : QWidget(pParent) , m_pMainLayout(0) , m_pChooserModel(0) , m_pChooserView(0) , m_pStatusBar(0) { /* Prepare palette: */ preparePalette(); /* Prepare layout: */ prepareLayout(); /* Prepare model: */ prepareModel(); /* Prepare view: */ prepareView(); /* Prepare connections: */ prepareConnections(); /* Load: */ load(); }
UIGDetailsView::UIGDetailsView(QWidget *pParent) : QGraphicsView(pParent) , m_iMinimumWidthHint(0) , m_iMinimumHeightHint(0) { /* Prepare palette: */ preparePalette(); /* Setup frame: */ setFrameShape(QFrame::NoFrame); setFrameShadow(QFrame::Plain); setAlignment(Qt::AlignLeft | Qt::AlignTop); /* Setup scroll-bars policy: */ setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); /* Update scene-rect: */ updateSceneRect(); }
UIGRuntimeInformation::UIGRuntimeInformation(QWidget *pParent) : QWidget(pParent) , m_pMainLayout(0) , m_pDetailsModel(0) , m_pDetailsView(0) { /* Prepare palette: */ preparePalette(); /* Prepare layout: */ prepareLayout(); /* Prepare model: */ prepareModel(); /* Prepare view: */ prepareView(); /* Prepare connections: */ prepareConnections(); }
void UIToolsView::prepare() { /* Install Tools-view accessibility interface factory: */ QAccessible::installFactory(UIAccessibilityInterfaceForUIToolsView::pFactory); /* Prepare palette: */ preparePalette(); /* Setup frame: */ setFrameShape(QFrame::NoFrame); setFrameShadow(QFrame::Plain); setAlignment(Qt::AlignLeft | Qt::AlignTop); /* Setup scroll-bars policy: */ setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); /* Update scene-rect: */ updateSceneRect(); /* Apply language settings: */ retranslateUi(); }
/** * Convert the given map into a PNG file on disk, by rendering the map as it * would appear in the game. * * @param map * Map file to export. * * @param allTilesets * Collection of tilesets to use when rendering the map. * * @param destFile * Filename of destination (including ".png") * * @throw stream::error on error */ void map2dToPng(const gm::Map2D& map, const gm::TilesetCollection& allTilesets, const std::string& destFile) { gg::Point outSize = map.mapSize(); // in pixels gg::Point globalTileSize = map.tileSize(); outSize.x *= globalTileSize.x; outSize.y *= globalTileSize.y; png::image<png::index_pixel> png(outSize.x, outSize.y); std::shared_ptr<const gg::Palette> srcPal; gg::ColourDepth depth = gg::ColourDepth::VGA; // default, should never be used for (auto& i : allTilesets) { depth = i.second->colourDepth(); if (i.second->caps() & gg::Tileset::Caps::HasPalette) { srcPal = i.second->palette(); break; } } int forceXP = -1; png::palette pngPal; png::tRNS pngTNS; int palOffset; auto transparentIndex = preparePalette(depth, srcPal.get(), &pngPal, &pngTNS, &palOffset, forceXP); png.set_palette(pngPal); if (pngTNS.size() > 0) png.set_tRNS(pngTNS); // Get the map background auto bg = map.background(allTilesets); switch (bg.att) { case gm::Map2D::Background::Attachment::NoBackground: { for (unsigned int y = 0; y < outSize.y; y++) { for (unsigned int x = 0; x < outSize.x; x++) { png[y][x] = transparentIndex; } } break; } case gm::Map2D::Background::Attachment::SingleColour: { // Find the background colour in the palette. This won't find transparent // colours, but that's what NoBackground is for. png::index_pixel clr(0); unsigned int palIndex = 0; for (auto& i : pngPal) { if ( (bg.clr.red == i.red) && (bg.clr.green == i.green) && (bg.clr.blue == i.blue) ) { clr = palIndex; break; } palIndex++; } for (unsigned int y = 0; y < outSize.y; y++) { for (unsigned int x = 0; x < outSize.x; x++) { png[y][x] = clr; } } break; } // TODO - case gm::Map2D::Background::Attachment::SingleImageCentred: case gm::Map2D::Background::Attachment::SingleImageTiled: { auto tilePixels = bg.img->convert(); auto tileMask = bg.img->convert_mask(); auto tileSize = bg.img->dimensions(); for (unsigned int y = 0; y < outSize.y; y++) { for (unsigned int x = 0; x < outSize.x; x++) { auto pos = (y % tileSize.y) * tileSize.x + (x % tileSize.x); png[y][x] = png::index_pixel( (tileMask[pos] & (int)gg::Image::Mask::Transparent) ? transparentIndex : (tilePixels[pos] + palOffset) ); } } break; } } for (auto& layer : map.layers()) { // Figure out the layer size (in tiles) and the tile size gg::Point layerSize, tileSize; getLayerDims(map, *layer, &layerSize, &tileSize); // Prepare tileset std::vector<CachedTile> cache; // Run through all items in the layer and render them one by one for (auto& t : layer->items()) { CachedTile thisTile; unsigned int tileCode = t.code; // Find the cached tile bool found = false; for (auto& ct : cache) { if (ct.code == tileCode) { thisTile = ct; found = true; break; } } if (!found) { // Tile hasn't been cached yet, load it from the tileset gm::Map2D::Layer::ImageFromCodeInfo imgType; try { imgType = layer->imageFromCode(t, allTilesets); } catch (const std::exception& e) { std::cerr << "Error loading image: " << e.what() << std::endl; imgType.type = gm::Map2D::Layer::ImageFromCodeInfo::ImageType::Unknown; } switch (imgType.type) { case gm::Map2D::Layer::ImageFromCodeInfo::ImageType::Supplied: assert(imgType.img); thisTile.data = imgType.img->convert(); thisTile.mask = imgType.img->convert_mask(); thisTile.dims = imgType.img->dimensions(); thisTile.code = tileCode; break; case gm::Map2D::Layer::ImageFromCodeInfo::ImageType::Blank: thisTile.dims = {0, 0}; break; case gm::Map2D::Layer::ImageFromCodeInfo::ImageType::NumImageTypes: // Avoid compiler warning about unhandled enum assert(false); // fall through case gm::Map2D::Layer::ImageFromCodeInfo::ImageType::Unknown: case gm::Map2D::Layer::ImageFromCodeInfo::ImageType::HexDigit: case gm::Map2D::Layer::ImageFromCodeInfo::ImageType::Interactive: // Display nothing, but could be changed to a question mark thisTile.dims = {0, 0}; break; } cache.push_back(thisTile); } if ((thisTile.dims.x == 0) || (thisTile.dims.y == 0)) continue; // no image // Draw tile onto png unsigned int tnsSize = pngTNS.size(); unsigned int offX = t.pos.x * tileSize.x; unsigned int offY = t.pos.y * tileSize.y; for (unsigned int tY = 0; tY < thisTile.dims.y; tY++) { unsigned int pngY = offY+tY; if (pngY >= outSize.y) break; // don't write past image edge for (unsigned int tX = 0; tX < thisTile.dims.x; tX++) { unsigned int pngX = offX+tX; if (pngX >= outSize.x) break; // don't write past image edge auto pos = tY * thisTile.dims.x + tX; // Only write opaque pixels if ((thisTile.mask[pos] & (int)gg::Image::Mask::Transparent) == 0) { unsigned int pix = thisTile.data[pos] + palOffset; // Also skip pixels if they are using palette transparency if ((pix >= tnsSize) || (pngTNS[pix] > 0)) { png[pngY][pngX] = png::index_pixel(pix); } } // else let higher layers see through to lower ones } } } // else layer is empty } png.write(destFile); return; }