Qt: Add copy and QoL improvements to graphic views (closes #1541)

This commit is contained in:
Vicki Pfau 2019-10-01 18:37:00 -07:00
parent 28151ee65c
commit 038d21debd
13 changed files with 412 additions and 285 deletions

View File

@ -78,6 +78,7 @@ Misc:
- Qt: Remove What's This icon from dialogs
- CMake: Don't use libzip on embedded platforms (fixes mgba.io/i/1527)
- Qt: Printer quality of life improvements (fixes mgba.io/i/1540)
- Qt: Add copy and QoL improvements to graphic views (closes mgba.io/i/1541)
0.7.3: (2019-09-15)
Emulation fixes:

View File

@ -116,6 +116,9 @@ void AssetTile::selectIndex(int index) {
m_ui.preview->setColor(i ^ flip, data[i]);
}
m_ui.preview->update();
QImage tile(reinterpret_cast<const uchar*>(data), 8, 8, QImage::Format_ARGB32);
m_activeTile = tile.rgbSwapped();
}
void AssetTile::setFlip(bool h, bool v) {

View File

@ -21,6 +21,7 @@ Q_OBJECT
public:
AssetTile(QWidget* parent = nullptr);
void setController(std::shared_ptr<CoreController>);
QImage activeTile() const { return m_activeTile; }
public slots:
void setPalette(int);
@ -48,6 +49,7 @@ private:
bool m_flipV = false;
QMap<QString, QLabel*> m_customProperties;
QImage m_activeTile;
};
}

View File

@ -22,7 +22,9 @@
#include <mgba/internal/gb/memory.h>
#endif
#include <QAction>
#include <QButtonGroup>
#include <QClipboard>
#include <QFontDatabase>
#include <QMouseEvent>
#include <QRadioButton>
@ -88,11 +90,19 @@ MapView::MapView(std::shared_ptr<CoreController> controller, QWidget* parent)
});
group->addButton(button);
}
#ifdef USE_PNG
connect(m_ui.exportButton, &QAbstractButton::clicked, this, &MapView::exportMap);
#else
m_ui.exportButton->setVisible(false);
#endif
connect(m_ui.copyButton, &QAbstractButton::clicked, this, &MapView::copyMap);
QAction* exportAction = new QAction(this);
exportAction->setShortcut(QKeySequence::Save);
connect(exportAction, &QAction::triggered, this, &MapView::exportMap);
addAction(exportAction);
QAction* copyAction = new QAction(this);
copyAction->setShortcut(QKeySequence::Copy);
connect(copyAction, &QAction::triggered, this, &MapView::copyMap);
addAction(copyAction);
m_ui.map->installEventFilter(this);
m_ui.tile->addCustomProperty("mapAddr", tr("Map Addr."));
m_ui.tile->addCustomProperty("flip", tr("Mirror"));
@ -211,7 +221,7 @@ void MapView::updateTilesGBA(bool force) {
mBitmapCacheCleanRow(bitmapCache, m_bitmapStatus, j);
memcpy(static_cast<void*>(&bgBits[width * j * 4]), mBitmapCacheGetRow(bitmapCache, j), width * 4);
}
m_rawMap = m_rawMap.rgbSwapped();
m_rawMap = m_rawMap.convertToFormat(QImage::Format_RGB32).rgbSwapped();
} else {
mMapCache* mapCache = mMapCacheSetGetPointer(&m_cacheSet->maps, m_map);
int tilesW = 1 << mMapCacheSystemInfoGetTilesWide(mapCache->sysConfig);
@ -242,23 +252,18 @@ void MapView::updateTilesGB(bool force) {
}
#endif
#ifdef USE_PNG
void MapView::exportMap() {
QString filename = GBAApp::app()->getSaveFileName(this, tr("Export map"),
tr("Portable Network Graphics (*.png)"));
VFile* vf = VFileDevice::open(filename, O_WRONLY | O_CREAT | O_TRUNC);
if (!vf) {
LOG(QT, ERROR) << tr("Failed to open output PNG file: %1").arg(filename);
if (filename.isNull()) {
return;
}
CoreController::Interrupter interrupter(m_controller);
png_structp png = PNGWriteOpen(vf);
png_infop info = PNGWriteHeaderA(png, m_rawMap.width(), m_rawMap.height());
QImage map = m_rawMap.rgbSwapped();
PNGWritePixelsA(png, map.width(), map.height(), map.bytesPerLine() / 4, static_cast<const void*>(map.constBits()));
PNGWriteClose(png, info);
vf->close(vf);
m_rawMap.save(filename, "PNG");
}
#endif
void MapView::copyMap() {
CoreController::Interrupter interrupter(m_controller);
GBAApp::app()->clipboard()->setImage(m_rawMap);
}

View File

@ -21,10 +21,9 @@ Q_OBJECT
public:
MapView(std::shared_ptr<CoreController> controller, QWidget* parent = nullptr);
#ifdef USE_PNG
public slots:
void exportMap();
#endif
void copyMap();
private slots:
void selectMap(int);

View File

@ -13,38 +13,7 @@
<property name="windowTitle">
<string>Maps</string>
</property>
<layout class="QGridLayout" name="gridLayout" rowstretch="0,0,0,0,0,0">
<item row="3" column="0">
<widget class="QGBA::AssetTile" name="tile"/>
</item>
<item row="2" column="0">
<widget class="QGBA::AssetInfo" name="bgInfo">
<property name="title">
<string/>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2"/>
</widget>
</item>
<item row="5" column="0">
<widget class="QPushButton" name="exportButton">
<property name="text">
<string>Export</string>
</property>
</widget>
</item>
<item row="4" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<layout class="QGridLayout" name="gridLayout" rowstretch="0,0,0,0,0,0,0">
<item row="1" column="0">
<layout class="QVBoxLayout" name="bgLayout">
<item>
@ -79,7 +48,7 @@
</item>
</layout>
</item>
<item row="1" column="1" rowspan="5" colspan="2">
<item row="1" column="1" rowspan="6" colspan="2">
<widget class="QScrollArea" name="scrollArea">
<property name="widgetResizable">
<bool>true</bool>
@ -133,21 +102,59 @@
</widget>
</widget>
</item>
<item row="3" column="0">
<widget class="QGBA::AssetTile" name="tile"/>
</item>
<item row="4" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item row="6" column="0">
<widget class="QPushButton" name="exportButton">
<property name="text">
<string>Export</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QGBA::AssetInfo" name="bgInfo">
<property name="title">
<string/>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2"/>
</widget>
</item>
<item row="5" column="0">
<widget class="QPushButton" name="copyButton">
<property name="text">
<string>Copy</string>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>QGBA::AssetInfo</class>
<extends>QGroupBox</extends>
<header>AssetInfo.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QGBA::AssetTile</class>
<extends>QGroupBox</extends>
<header>AssetTile.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QGBA::AssetInfo</class>
<extends>QGroupBox</extends>
<header>AssetInfo.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>

View File

@ -8,6 +8,8 @@
#include "CoreController.h"
#include "GBAApp.h"
#include <QAction>
#include <QClipboard>
#include <QFontDatabase>
#include <QTimer>
@ -52,6 +54,17 @@ ObjView::ObjView(std::shared_ptr<CoreController> controller, QWidget* parent)
updateTiles(true);
});
connect(m_ui.exportButton, &QAbstractButton::clicked, this, &ObjView::exportObj);
connect(m_ui.copyButton, &QAbstractButton::clicked, this, &ObjView::copyObj);
QAction* exportAction = new QAction(this);
exportAction->setShortcut(QKeySequence::Save);
connect(exportAction, &QAction::triggered, this, &ObjView::exportObj);
addAction(exportAction);
QAction* copyAction = new QAction(this);
copyAction->setShortcut(QKeySequence::Copy);
connect(copyAction, &QAction::triggered, this, &ObjView::copyObj);
addAction(copyAction);
}
void ObjView::selectObj(int obj) {
@ -203,7 +216,15 @@ void ObjView::updateTilesGB(bool force) {
void ObjView::exportObj() {
QString filename = GBAApp::app()->getSaveFileName(this, tr("Export sprite"),
tr("Portable Network Graphics (*.png)"));
if (filename.isNull()) {
return;
}
CoreController::Interrupter interrupter(m_controller);
QImage obj = compositeObj(m_objInfo);
obj.save(filename, "PNG");
}
void ObjView::copyObj() {
CoreController::Interrupter interrupter(m_controller);
GBAApp::app()->clipboard()->setImage(compositeObj(m_objInfo));
}

View File

@ -23,6 +23,7 @@ public:
public slots:
void exportObj();
void copyObj();
private slots:
void selectObj(int);

View File

@ -6,80 +6,170 @@
<rect>
<x>0</x>
<y>0</y>
<width>454</width>
<height>385</height>
<width>641</width>
<height>470</height>
</rect>
</property>
<property name="windowTitle">
<string>Sprites</string>
</property>
<layout class="QGridLayout" name="gridLayout" columnstretch="0,0,1">
<item row="0" column="2" rowspan="4">
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
<layout class="QGridLayout" name="gridLayout" columnstretch="0,0,1,1">
<item row="2" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Geometry</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<property name="margin">
<number>0</number>
</property>
<item row="0" column="0" alignment="Qt::AlignHCenter|Qt::AlignVCenter">
<widget class="QGBA::TilePainter" name="tiles" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>8</width>
<height>8</height>
</size>
</property>
</widget>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Position</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="x">
<property name="minimumSize">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>0</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="tileId_3">
<property name="text">
<string>, </string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="y">
<property name="minimumSize">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>0</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Dimensions</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="w">
<property name="minimumSize">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>8</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="tileId_5">
<property name="text">
<string>×</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="h">
<property name="minimumSize">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>8</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QSpinBox" name="magnification">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="suffix">
<string>×</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>8</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Magnification</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="exportButton">
<property name="text">
<string>Export</string>
</property>
</widget>
</item>
</layout>
<item row="0" column="1" rowspan="5">
<widget class="QGBA::AssetTile" name="tile">
<property name="title">
<string>Tile</string>
</property>
</widget>
</item>
<item row="3" column="0">
<item row="4" column="2">
<widget class="QPushButton" name="exportButton">
<property name="text">
<string>Export</string>
</property>
</widget>
</item>
<item row="3" column="0" rowspan="2">
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Attributes</string>
@ -383,154 +473,6 @@
</layout>
</widget>
</item>
<item row="0" column="1" rowspan="4">
<widget class="QGBA::AssetTile" name="tile">
<property name="title">
<string>Tile</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Geometry</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Position</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="x">
<property name="minimumSize">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>0</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="tileId_3">
<property name="text">
<string>, </string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="y">
<property name="minimumSize">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>0</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Dimensions</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="w">
<property name="minimumSize">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>8</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="tileId_5">
<property name="text">
<string>×</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="h">
<property name="minimumSize">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>8</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
@ -568,6 +510,80 @@
</item>
</layout>
</item>
<item row="1" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QSpinBox" name="magnification">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="suffix">
<string>×</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>8</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Magnification</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="4" column="3">
<widget class="QPushButton" name="copyButton">
<property name="text">
<string>Copy</string>
</property>
</widget>
</item>
<item row="0" column="2" rowspan="4" colspan="2">
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0" alignment="Qt::AlignHCenter|Qt::AlignVCenter">
<widget class="QGBA::TilePainter" name="tiles" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>8</width>
<height>8</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>

View File

@ -36,6 +36,11 @@ PrinterView::PrinterView(std::shared_ptr<CoreController> controller, QWidget* pa
m_ui.image->setFixedHeight(m_ui.image->size().height() / oldMag * mag);
});
QAction* save = new QAction(this);
save->setShortcut(QKeySequence::Save);
connect(save, &QAction::triggered, this, &MapView::save);
addAction(save);
clear();
}

View File

@ -8,6 +8,8 @@
#include "CoreController.h"
#include "GBAApp.h"
#include <QAction>
#include <QClipboard>
#include <QFontDatabase>
#include <QTimer>
@ -87,7 +89,20 @@ TileView::TileView(std::shared_ptr<CoreController> controller, QWidget* parent)
updateTiles(true);
});
connect(m_ui.exportButton, &QAbstractButton::clicked, this, &TileView::exportTiles);
connect(m_ui.exportAll, &QAbstractButton::clicked, this, &TileView::exportTiles);
connect(m_ui.exportOne, &QAbstractButton::clicked, this, &TileView::exportTile);
connect(m_ui.copyAll, &QAbstractButton::clicked, this, &TileView::copyTiles);
connect(m_ui.copyOne, &QAbstractButton::clicked, this, &TileView::copyTile);
QAction* exportAll = new QAction(this);
exportAll->setShortcut(QKeySequence::Save);
connect(exportAll, &QAction::triggered, this, &TileView::exportTiles);
addAction(exportAll);
QAction* copyOne = new QAction(this);
copyOne->setShortcut(QKeySequence::Copy);
connect(copyOne, &QAction::triggered, this, &TileView::copyTile);
addAction(copyOne);
}
#ifdef M_CORE_GBA
@ -162,8 +177,36 @@ void TileView::updatePalette(int palette) {
void TileView::exportTiles() {
QString filename = GBAApp::app()->getSaveFileName(this, tr("Export tiles"),
tr("Portable Network Graphics (*.png)"));
if (filename.isNull()) {
return;
}
CoreController::Interrupter interrupter(m_controller);
updateTiles(false);
QPixmap pixmap(m_ui.tiles->backing());
pixmap.save(filename, "PNG");
}
void TileView::exportTile() {
QString filename = GBAApp::app()->getSaveFileName(this, tr("Export tile"),
tr("Portable Network Graphics (*.png)"));
if (filename.isNull()) {
return;
}
CoreController::Interrupter interrupter(m_controller);
updateTiles(false);
QImage image(m_ui.tile->activeTile());
image.save(filename, "PNG");
}
void TileView::copyTiles() {
CoreController::Interrupter interrupter(m_controller);
updateTiles(false);
QPixmap pixmap();
GBAApp::app()->clipboard()->setPixmap(m_ui.tiles->backing());
}
void TileView::copyTile() {
CoreController::Interrupter interrupter(m_controller);
updateTiles(false);
GBAApp::app()->clipboard()->setImage(m_ui.tile->activeTile());
}

View File

@ -24,6 +24,9 @@ public:
public slots:
void updatePalette(int);
void exportTiles();
void exportTile();
void copyTiles();
void copyTile();
private:
#ifdef M_CORE_GBA

View File

@ -6,14 +6,28 @@
<rect>
<x>0</x>
<y>0</y>
<width>693</width>
<height>467</height>
<width>748</width>
<height>823</height>
</rect>
</property>
<property name="windowTitle">
<string>Tiles</string>
</property>
<layout class="QGridLayout" name="gridLayout" columnstretch="0,1">
<layout class="QGridLayout" name="gridLayout" rowstretch="0,0,0,1,0,0,0,0" columnstretch="0,1">
<item row="5" column="0">
<widget class="QPushButton" name="exportOne">
<property name="text">
<string>Export Selected</string>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QPushButton" name="exportAll">
<property name="text">
<string>Export All</string>
</property>
</widget>
</item>
<item row="0" column="0">
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
@ -104,17 +118,7 @@
</property>
</spacer>
</item>
<item row="1" column="0">
<widget class="QGBA::AssetTile" name="tile"/>
</item>
<item row="4" column="0">
<widget class="QPushButton" name="exportButton">
<property name="text">
<string>Export</string>
</property>
</widget>
</item>
<item row="0" column="1" rowspan="5">
<item row="0" column="1" rowspan="8">
<widget class="QScrollArea" name="scrollArea">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
@ -133,7 +137,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>405</width>
<width>480</width>
<height>768</height>
</rect>
</property>
@ -179,6 +183,23 @@
</widget>
</widget>
</item>
<item row="1" column="0">
<widget class="QGBA::AssetTile" name="tile"/>
</item>
<item row="4" column="0">
<widget class="QPushButton" name="copyOne">
<property name="text">
<string>Copy Selected</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QPushButton" name="copyAll">
<property name="text">
<string>Copy All</string>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>