mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-09-02 02:42:51 +02:00
Update to v106r55 release.
byuu says: Everything *should* be working again, but of course that won't actually be the case. Here's where things stand: - bsnes, higan, icarus, and genius compile and run fine on FreeBSD with GTK - ruby video and audio drivers are untested on Windows, macOS, and Linux - hiro is untested on macOS - bsnes' status bar is not showing up properly with hiro/qt - bsnes and higan's about screen is not showing up properly with hiro/qt (1x1 window size) - bsnes on Windows crashes often when saving states, and I'm not sure why ... it happens inside Encode::RLE - bsnes on Windows crashes with ruby.input.windows (unsure why) - bsnes on Windows fails to show the verified emblem on the status bar properly - hiro on Windows flickers when changing tabs To build the Windows bsnes and higan ports, use ruby="video.gdi audio.directsound" Compilation error logs for Linux will help me fix the inevitable list of typos there. I can fix the typos on other platforms, I just haven't gotten to it yet.
This commit is contained in:
@@ -23,7 +23,7 @@ auto pMenuRadioItem::construct() -> void {
|
||||
}
|
||||
|
||||
auto pMenuRadioItem::destruct() -> void {
|
||||
if(Application::state.quit) return; //TODO: hack
|
||||
if(Application::state().quit) return; //TODO: hack
|
||||
delete qtMenuRadioItem;
|
||||
delete qtActionGroup;
|
||||
qtMenuRadioItem = nullptr;
|
||||
|
@@ -23,7 +23,7 @@ auto pMenu::construct() -> void {
|
||||
}
|
||||
|
||||
auto pMenu::destruct() -> void {
|
||||
if(Application::state.quit) return; //TODO: hack
|
||||
if(Application::state().quit) return; //TODO: hack
|
||||
delete qtMenu;
|
||||
qtMenu = nullptr;
|
||||
}
|
||||
|
@@ -5,8 +5,8 @@ namespace hiro {
|
||||
XlibDisplay* pApplication::display = nullptr;
|
||||
|
||||
auto pApplication::run() -> void {
|
||||
if(Application::state.onMain) {
|
||||
while(!Application::state.quit) {
|
||||
if(Application::state().onMain) {
|
||||
while(!Application::state().quit) {
|
||||
Application::doMain();
|
||||
processEvents();
|
||||
}
|
||||
@@ -53,7 +53,7 @@ auto pApplication::initialize() -> void {
|
||||
|
||||
display = XOpenDisplay(0);
|
||||
|
||||
auto name = Application::state.name ? Application::state.name : string{"hiro"};
|
||||
static auto name = Application::state().name ? Application::state().name : string{"hiro"};
|
||||
|
||||
//QApplication stores references to argc;
|
||||
//and will access them after pApplication::initialize() returns
|
||||
|
@@ -3,6 +3,8 @@
|
||||
#if HIRO_QT==5
|
||||
#include <QtWidgets>
|
||||
#endif
|
||||
#undef foreach
|
||||
|
||||
#include <nall/xorg/guard.hpp>
|
||||
#define XK_MISCELLANY
|
||||
#define XK_LATIN1
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace hiro {
|
||||
|
||||
struct pObject : mLock {
|
||||
struct pObject : Lock {
|
||||
pObject(mObject& reference) : reference(reference) {}
|
||||
virtual ~pObject() {}
|
||||
auto self() const -> mObject& { return (mObject&)reference; }
|
||||
|
@@ -50,7 +50,6 @@
|
||||
#include "widget/tab-frame.cpp"
|
||||
#include "widget/tab-frame-item.cpp"
|
||||
#include "widget/table-view.cpp"
|
||||
#include "widget/table-view-header.cpp"
|
||||
#include "widget/table-view-column.cpp"
|
||||
#include "widget/table-view-item.cpp"
|
||||
#include "widget/table-view-cell.cpp"
|
||||
|
@@ -52,7 +52,6 @@
|
||||
#include "widget/tab-frame.hpp"
|
||||
#include "widget/tab-frame-item.hpp"
|
||||
#include "widget/table-view.hpp"
|
||||
#include "widget/table-view-header.hpp"
|
||||
#include "widget/table-view-column.hpp"
|
||||
#include "widget/table-view-item.hpp"
|
||||
#include "widget/table-view-cell.hpp"
|
||||
|
@@ -10,7 +10,7 @@ auto pComboButton::construct() -> void {
|
||||
}
|
||||
|
||||
auto pComboButton::destruct() -> void {
|
||||
if(Application::state.quit) return; //TODO: hack
|
||||
if(Application::state().quit) return; //TODO: hack
|
||||
delete qtComboButton;
|
||||
qtWidget = qtComboButton = nullptr;
|
||||
}
|
||||
|
@@ -11,7 +11,7 @@ auto pTabFrame::construct() -> void {
|
||||
}
|
||||
|
||||
auto pTabFrame::destruct() -> void {
|
||||
if(Application::state.quit) return; //TODO: hack
|
||||
if(Application::state().quit) return; //TODO: hack
|
||||
delete qtTabFrame;
|
||||
qtWidget = qtTabFrame = nullptr;
|
||||
}
|
||||
|
@@ -3,7 +3,18 @@
|
||||
namespace hiro {
|
||||
|
||||
auto pTableViewColumn::construct() -> void {
|
||||
if(auto header = _parent()) header->_setState();
|
||||
if(auto parent = _parent()) {
|
||||
auto lock = parent->acquire();
|
||||
//parent->qtTableView->setAlternatingRowColors(parent->self().columnCount() >= 2);
|
||||
parent->qtTableView->setColumnCount(parent->self().columnCount());
|
||||
for(auto& column : parent->state().columns) {
|
||||
if(auto delegate = column->self()) {
|
||||
delegate->setIcon(delegate->state().icon);
|
||||
delegate->setText(delegate->state().text); //also handles setSorting();
|
||||
delegate->_setState();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto pTableViewColumn::destruct() -> void {
|
||||
@@ -42,19 +53,31 @@ auto pTableViewColumn::setHorizontalAlignment(double alignment) -> void {
|
||||
}
|
||||
|
||||
auto pTableViewColumn::setIcon(const image& icon) -> void {
|
||||
//unsupported
|
||||
if(auto parent = _parent()) {
|
||||
parent->qtTableView->headerItem()->setIcon(self().offset(), CreateIcon(icon));
|
||||
}
|
||||
}
|
||||
|
||||
auto pTableViewColumn::setResizable(bool resizable) -> void {
|
||||
_setState();
|
||||
}
|
||||
|
||||
auto pTableViewColumn::setSortable(bool sortable) -> void {
|
||||
_setState();
|
||||
auto pTableViewColumn::setSorting(Sort) -> void {
|
||||
if(auto parent = _parent()) {
|
||||
string label = state().text;
|
||||
if(state().sorting == Sort::Ascending ) label.append(" \u25b4");
|
||||
if(state().sorting == Sort::Descending) label.append(" \u25be");
|
||||
parent->qtTableView->headerItem()->setText(self().offset(), QString::fromUtf8(label));
|
||||
}
|
||||
}
|
||||
|
||||
auto pTableViewColumn::setText(const string& text) -> void {
|
||||
_setState();
|
||||
auto pTableViewColumn::setText(const string&) -> void {
|
||||
if(auto parent = _parent()) {
|
||||
string label = state().text;
|
||||
if(state().sorting == Sort::Ascending ) label.append(" \u25b4");
|
||||
if(state().sorting == Sort::Descending) label.append(" \u25be");
|
||||
parent->qtTableView->headerItem()->setText(self().offset(), QString::fromUtf8(label));
|
||||
}
|
||||
}
|
||||
|
||||
auto pTableViewColumn::setVerticalAlignment(double alignment) -> void {
|
||||
@@ -69,36 +92,26 @@ auto pTableViewColumn::setWidth(signed width) -> void {
|
||||
_setState();
|
||||
}
|
||||
|
||||
auto pTableViewColumn::_parent() -> maybe<pTableViewHeader&> {
|
||||
if(auto parent = self().parentTableViewHeader()) {
|
||||
auto pTableViewColumn::_parent() -> maybe<pTableView&> {
|
||||
if(auto parent = self().parentTableView()) {
|
||||
if(auto delegate = parent->self()) return *delegate;
|
||||
}
|
||||
return nothing;
|
||||
return {};
|
||||
}
|
||||
|
||||
auto pTableViewColumn::_setState() -> void {
|
||||
if(auto header = _parent()) {
|
||||
if(auto parent = header->_parent()) {
|
||||
auto lock = parent->acquire();
|
||||
#if HIRO_QT==4
|
||||
parent->qtTableView->header()->setResizeMode(self().offset(), state().resizable ? QHeaderView::Interactive : QHeaderView::Fixed);
|
||||
#elif HIRO_QT==5
|
||||
parent->qtTableView->header()->setSectionResizeMode(self().offset(), state().resizable ? QHeaderView::Interactive : QHeaderView::Fixed);
|
||||
#endif
|
||||
bool clickable = false;
|
||||
for(auto& column : header->state().columns) clickable |= column->state.sortable;
|
||||
#if HIRO_QT==4
|
||||
parent->qtTableView->header()->setClickable(clickable);
|
||||
#elif HIRO_QT==5
|
||||
parent->qtTableView->header()->setSectionsClickable(clickable);
|
||||
#endif
|
||||
parent->qtTableView->headerItem()->setText(self().offset(), QString::fromUtf8(state().text));
|
||||
parent->qtTableView->setColumnHidden(self().offset(), !self().visible());
|
||||
if(auto parent = _parent()) {
|
||||
auto lock = parent->acquire();
|
||||
#if HIRO_QT==4
|
||||
parent->qtTableView->header()->setResizeMode(self().offset(), state().resizable ? QHeaderView::Interactive : QHeaderView::Fixed);
|
||||
#elif HIRO_QT==5
|
||||
parent->qtTableView->header()->setSectionResizeMode(self().offset(), state().resizable ? QHeaderView::Interactive : QHeaderView::Fixed);
|
||||
#endif
|
||||
parent->qtTableView->setColumnHidden(self().offset(), !self().visible());
|
||||
|
||||
for(auto& item : parent->state().items) {
|
||||
if(auto cell = item->cell(self().offset())) {
|
||||
if(auto self = cell->self()) self->_setState();
|
||||
}
|
||||
for(auto& item : parent->state().items) {
|
||||
if(auto cell = item->cell(self().offset())) {
|
||||
if(auto self = cell->self()) self->_setState();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -15,13 +15,13 @@ struct pTableViewColumn : pObject {
|
||||
auto setHorizontalAlignment(double alignment) -> void;
|
||||
auto setIcon(const image& icon) -> void;
|
||||
auto setResizable(bool resizable) -> void;
|
||||
auto setSortable(bool sortable) -> void;
|
||||
auto setSorting(Sort sorting) -> void;
|
||||
auto setText(const string& text) -> void;
|
||||
auto setVerticalAlignment(double alignment) -> void;
|
||||
auto setVisible(bool visible) -> void;
|
||||
auto setWidth(signed width) -> void;
|
||||
|
||||
auto _parent() -> maybe<pTableViewHeader&>;
|
||||
auto _parent() -> maybe<pTableView&>;
|
||||
auto _setState() -> void;
|
||||
};
|
||||
|
||||
|
@@ -1,43 +0,0 @@
|
||||
#if defined(Hiro_TableView)
|
||||
|
||||
namespace hiro {
|
||||
|
||||
auto pTableViewHeader::construct() -> void {
|
||||
}
|
||||
|
||||
auto pTableViewHeader::destruct() -> void {
|
||||
}
|
||||
|
||||
auto pTableViewHeader::append(sTableViewColumn column) -> void {
|
||||
_setState();
|
||||
}
|
||||
|
||||
auto pTableViewHeader::remove(sTableViewColumn column) -> void {
|
||||
}
|
||||
|
||||
auto pTableViewHeader::setVisible(bool visible) -> void {
|
||||
_setState();
|
||||
}
|
||||
|
||||
auto pTableViewHeader::_parent() -> maybe<pTableView&> {
|
||||
if(auto parent = self().parentTableView()) {
|
||||
if(auto delegate = parent->self()) return *delegate;
|
||||
}
|
||||
return nothing;
|
||||
}
|
||||
|
||||
auto pTableViewHeader::_setState() -> void {
|
||||
if(auto parent = _parent()) {
|
||||
auto lock = parent->acquire();
|
||||
//parent->qtTableView->setAlternatingRowColors(self().columnCount() >= 2);
|
||||
parent->qtTableView->setColumnCount(self().columnCount());
|
||||
parent->qtTableView->setHeaderHidden(!self().visible());
|
||||
for(auto& column : state().columns) {
|
||||
if(auto self = column->self()) self->_setState();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,18 +0,0 @@
|
||||
#if defined(Hiro_TableView)
|
||||
|
||||
namespace hiro {
|
||||
|
||||
struct pTableViewHeader : pObject {
|
||||
Declare(TableViewHeader, Object)
|
||||
|
||||
auto append(sTableViewColumn column) -> void;
|
||||
auto remove(sTableViewColumn column) -> void;
|
||||
auto setVisible(bool visible) -> void override;
|
||||
|
||||
auto _parent() -> maybe<pTableView&>;
|
||||
auto _setState() -> void;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@@ -27,24 +27,21 @@ auto pTableView::construct() -> void {
|
||||
setBatchable(state().batchable);
|
||||
setBordered(state().bordered);
|
||||
setForegroundColor(state().foregroundColor);
|
||||
setHeadered(state().headered);
|
||||
setSortable(state().sortable);
|
||||
|
||||
pWidget::construct();
|
||||
}
|
||||
|
||||
auto pTableView::destruct() -> void {
|
||||
if(Application::state.quit) return; //TODO: hack
|
||||
if(Application::state().quit) return; //TODO: hack
|
||||
delete qtTableViewDelegate;
|
||||
delete qtTableView;
|
||||
qtWidget = qtTableView = nullptr;
|
||||
qtTableViewDelegate = nullptr;
|
||||
}
|
||||
|
||||
auto pTableView::append(sTableViewHeader header) -> void {
|
||||
lock();
|
||||
if(auto self = header->self()) {
|
||||
self->_setState();
|
||||
}
|
||||
unlock();
|
||||
auto pTableView::append(sTableViewColumn column) -> void {
|
||||
}
|
||||
|
||||
auto pTableView::append(sTableViewItem item) -> void {
|
||||
@@ -56,44 +53,40 @@ auto pTableView::append(sTableViewItem item) -> void {
|
||||
unlock();
|
||||
}
|
||||
|
||||
auto pTableView::remove(sTableViewHeader header) -> void {
|
||||
auto pTableView::remove(sTableViewColumn column) -> void {
|
||||
}
|
||||
|
||||
auto pTableView::remove(sTableViewItem item) -> void {
|
||||
}
|
||||
|
||||
auto pTableView::resizeColumns() -> void {
|
||||
lock();
|
||||
auto lock = acquire();
|
||||
|
||||
if(auto& header = state().header) {
|
||||
vector<signed> widths;
|
||||
signed minimumWidth = 0;
|
||||
signed expandable = 0;
|
||||
for(auto column : range(header->columnCount())) {
|
||||
signed width = _width(column);
|
||||
widths.append(width);
|
||||
minimumWidth += width;
|
||||
if(header->column(column).expandable()) expandable++;
|
||||
}
|
||||
|
||||
signed maximumWidth = self().geometry().width() - 6;
|
||||
if(auto scrollBar = qtTableView->verticalScrollBar()) {
|
||||
if(scrollBar->isVisible()) maximumWidth -= scrollBar->geometry().width();
|
||||
}
|
||||
|
||||
signed expandWidth = 0;
|
||||
if(expandable && maximumWidth > minimumWidth) {
|
||||
expandWidth = (maximumWidth - minimumWidth) / expandable;
|
||||
}
|
||||
|
||||
for(auto column : range(header->columnCount())) {
|
||||
signed width = widths[column];
|
||||
if(header->column(column).expandable()) width += expandWidth;
|
||||
qtTableView->setColumnWidth(column, width);
|
||||
}
|
||||
vector<signed> widths;
|
||||
signed minimumWidth = 0;
|
||||
signed expandable = 0;
|
||||
for(auto column : range(self().columnCount())) {
|
||||
signed width = _width(column);
|
||||
widths.append(width);
|
||||
minimumWidth += width;
|
||||
if(self().column(column).expandable()) expandable++;
|
||||
}
|
||||
|
||||
unlock();
|
||||
signed maximumWidth = self().geometry().width() - 6;
|
||||
if(auto scrollBar = qtTableView->verticalScrollBar()) {
|
||||
if(scrollBar->isVisible()) maximumWidth -= scrollBar->geometry().width();
|
||||
}
|
||||
|
||||
signed expandWidth = 0;
|
||||
if(expandable && maximumWidth > minimumWidth) {
|
||||
expandWidth = (maximumWidth - minimumWidth) / expandable;
|
||||
}
|
||||
|
||||
for(auto column : range(self().columnCount())) {
|
||||
signed width = widths[column];
|
||||
if(self().column(column).expandable()) width += expandWidth;
|
||||
qtTableView->setColumnWidth(column, width);
|
||||
}
|
||||
}
|
||||
|
||||
auto pTableView::setAlignment(Alignment alignment) -> void {
|
||||
@@ -128,40 +121,48 @@ auto pTableView::setForegroundColor(Color color) -> void {
|
||||
qtTableView->setAutoFillBackground((bool)color);
|
||||
}
|
||||
|
||||
auto pTableView::setHeadered(bool headered) -> void {
|
||||
qtTableView->setHeaderHidden(!headered);
|
||||
}
|
||||
|
||||
auto pTableView::setSortable(bool sortable) -> void {
|
||||
#if HIRO_QT==4
|
||||
qtTableView->header()->setClickable(sortable);
|
||||
#elif HIRO_QT==5
|
||||
qtTableView->header()->setSectionsClickable(sortable);
|
||||
#endif
|
||||
}
|
||||
|
||||
//called on resize/show events
|
||||
auto pTableView::_onSize() -> void {
|
||||
//resize columns only if at least one column is expandable
|
||||
if(auto& header = state().header) {
|
||||
for(auto& column : header->state.columns) {
|
||||
if(column->expandable()) return resizeColumns();
|
||||
}
|
||||
for(auto& column : state().columns) {
|
||||
if(column->expandable()) return resizeColumns();
|
||||
}
|
||||
}
|
||||
|
||||
auto pTableView::_width(unsigned column) -> unsigned {
|
||||
if(auto& header = state().header) {
|
||||
if(auto width = header->column(column).width()) return width;
|
||||
unsigned width = 1;
|
||||
if(!header->column(column).visible()) return width;
|
||||
if(header->visible()) width = max(width, _widthOfColumn(column));
|
||||
for(auto row : range(state().items.size())) {
|
||||
width = max(width, _widthOfCell(row, column));
|
||||
}
|
||||
return width;
|
||||
if(auto width = self().column(column).width()) return width;
|
||||
unsigned width = 1;
|
||||
if(!self().column(column).visible()) return width;
|
||||
if(state().headered) width = max(width, _widthOfColumn(column));
|
||||
for(auto row : range(state().items.size())) {
|
||||
width = max(width, _widthOfCell(row, column));
|
||||
}
|
||||
return 1;
|
||||
return width;
|
||||
}
|
||||
|
||||
auto pTableView::_widthOfColumn(unsigned _column) -> unsigned {
|
||||
unsigned width = 8;
|
||||
if(auto& header = state().header) {
|
||||
if(auto column = header->column(_column)) {
|
||||
if(auto& icon = column->state.icon) {
|
||||
width += icon.width() + 4;
|
||||
}
|
||||
if(auto& text = column->state.text) {
|
||||
width += pFont::size(column->font(true), text).width();
|
||||
}
|
||||
if(auto column = self().column(_column)) {
|
||||
if(auto& icon = column->state.icon) {
|
||||
width += icon.width() + 4;
|
||||
}
|
||||
if(auto& text = column->state.text) {
|
||||
width += pFont::size(column->font(true), text).width();
|
||||
}
|
||||
if(column->state.sorting != Sort::None) {
|
||||
width += 12;
|
||||
}
|
||||
}
|
||||
return width;
|
||||
@@ -204,10 +205,8 @@ auto QtTableView::onContext() -> void {
|
||||
}
|
||||
|
||||
auto QtTableView::onSort(int columnNumber) -> void {
|
||||
if(auto& header = p.state().header) {
|
||||
if(auto column = header->column(columnNumber)) {
|
||||
if(!p.locked() && column.sortable()) p.self().doSort(column);
|
||||
}
|
||||
if(auto column = p.self().column(columnNumber)) {
|
||||
if(!p.locked() && p.state().sortable) p.self().doSort(column);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -5,9 +5,9 @@ namespace hiro {
|
||||
struct pTableView : pWidget {
|
||||
Declare(TableView, Widget)
|
||||
|
||||
auto append(sTableViewHeader header) -> void;
|
||||
auto append(sTableViewColumn header) -> void;
|
||||
auto append(sTableViewItem item) -> void;
|
||||
auto remove(sTableViewHeader header) -> void;
|
||||
auto remove(sTableViewColumn header) -> void;
|
||||
auto remove(sTableViewItem item) -> void;
|
||||
auto resizeColumns() -> void;
|
||||
auto setAlignment(Alignment alignment) -> void;
|
||||
@@ -15,6 +15,8 @@ struct pTableView : pWidget {
|
||||
auto setBatchable(bool batchable) -> void;
|
||||
auto setBordered(bool bordered) -> void;
|
||||
auto setForegroundColor(Color color) -> void;
|
||||
auto setHeadered(bool headered) -> void;
|
||||
auto setSortable(bool sortable) -> void;
|
||||
|
||||
auto _onSize() -> void;
|
||||
auto _width(unsigned column) -> unsigned;
|
||||
|
@@ -13,7 +13,7 @@ auto pTextEdit::construct() -> void {
|
||||
}
|
||||
|
||||
auto pTextEdit::destruct() -> void {
|
||||
if(Application::state.quit) return; //TODO: hack
|
||||
if(Application::state().quit) return; //TODO: hack
|
||||
delete qtTextEdit;
|
||||
qtWidget = qtTextEdit = nullptr;
|
||||
}
|
||||
|
@@ -7,7 +7,7 @@ auto pWindow::construct() -> void {
|
||||
qtWindow->setWindowTitle(" ");
|
||||
|
||||
//if program was given a name, try and set the window taskbar icon to a matching pixmap image
|
||||
if(auto name = Application::state.name) {
|
||||
if(auto name = Application::state().name) {
|
||||
if(file::exists({Path::user(), ".local/share/icons/", name, ".png"})) {
|
||||
qtWindow->setWindowIcon(QIcon(QString::fromUtf8(string{Path::user(), ".local/share/icons/", name, ".png"})));
|
||||
} else if(file::exists({"/usr/local/share/pixmaps/", name, ".png"})) {
|
||||
@@ -44,7 +44,7 @@ auto pWindow::construct() -> void {
|
||||
}
|
||||
|
||||
auto pWindow::destruct() -> void {
|
||||
if(Application::state.quit) return; //TODO: hack
|
||||
if(Application::state().quit) return; //TODO: hack
|
||||
delete qtStatusBar;
|
||||
delete qtContainer;
|
||||
delete qtMenuBar;
|
||||
@@ -189,8 +189,8 @@ auto pWindow::setModal(bool modal) -> void {
|
||||
setVisible(false);
|
||||
qtWindow->setWindowModality(Qt::ApplicationModal);
|
||||
setVisible(true);
|
||||
while(!Application::state.quit && state().modal) {
|
||||
if(Application::state.onMain) {
|
||||
while(!Application::state().quit && state().modal) {
|
||||
if(Application::state().onMain) {
|
||||
Application::doMain();
|
||||
} else {
|
||||
usleep(20 * 1000);
|
||||
@@ -217,13 +217,12 @@ auto pWindow::setTitle(const string& text) -> void {
|
||||
}
|
||||
|
||||
auto pWindow::setVisible(bool visible) -> void {
|
||||
lock();
|
||||
auto lock = acquire();
|
||||
qtWindow->setVisible(visible);
|
||||
if(visible) {
|
||||
_updateFrameGeometry();
|
||||
setGeometry(state().geometry);
|
||||
}
|
||||
unlock();
|
||||
}
|
||||
|
||||
auto pWindow::_append(mWidget& widget) -> void {
|
||||
|
Reference in New Issue
Block a user