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:
Tim Allen
2018-08-05 19:00:15 +10:00
parent 552d385031
commit 5da4532771
117 changed files with 1316 additions and 2383 deletions

View File

@@ -8,8 +8,8 @@ static auto CALLBACK Application_windowProc(HWND, UINT, WPARAM, LPARAM) -> LRESU
auto pApplication::run() -> void {
MSG msg;
if(Application::state.onMain) {
while(!Application::state.quit) {
if(Application::state().onMain) {
while(!Application::state().quit) {
Application::doMain();
processEvents();
}
@@ -243,7 +243,7 @@ case WM_GETMINMAXINFO: {
*/
static auto CALLBACK Application_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) -> LRESULT {
if(Application::state.quit) return DefWindowProc(hwnd, msg, wparam, lparam);
if(Application::state().quit) return DefWindowProc(hwnd, msg, wparam, lparam);
auto object = (mObject*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
if(!object) return DefWindowProc(hwnd, msg, wparam, lparam);

View File

@@ -2,7 +2,7 @@
namespace hiro {
struct pObject : mLock {
struct pObject : Lock {
pObject(mObject& reference) : reference(reference) {}
virtual ~pObject() = default;
virtual auto construct() -> void;

View File

@@ -41,7 +41,6 @@
#include "widget/label.cpp"
#include "widget/line-edit.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"

View File

@@ -68,7 +68,6 @@ static vector<wObject> windows;
#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"

View File

@@ -148,7 +148,7 @@ static auto CALLBACK Menu_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM
}
static auto CALLBACK Shared_windowProc(WindowProc windowProc, HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) -> LRESULT {
if(Application::state.quit) return DefWindowProc(hwnd, msg, wparam, lparam);
if(Application::state().quit) return DefWindowProc(hwnd, msg, wparam, lparam);
auto object = (mObject*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
if(!object) return DefWindowProc(hwnd, msg, wparam, lparam);

View File

@@ -36,12 +36,12 @@ auto pLineEdit::setEditable(bool editable) -> void {
}
auto pLineEdit::setForegroundColor(Color color) -> void {
InvalidateRect(hwnd, 0, true);
}
auto pLineEdit::setText(const string& text) -> void {
lock();
auto lock = acquire();
SetWindowText(hwnd, utf16_t(text));
unlock();
}
auto pLineEdit::onChange() -> void {

View File

@@ -3,25 +3,23 @@
namespace hiro {
auto pTableViewColumn::construct() -> void {
if(auto grandparent = _grandparent()) {
grandparent->lock();
if(auto parent = _parent()) {
auto lock = parent->acquire();
wchar_t text[] = L"";
LVCOLUMN lvColumn{0};
lvColumn.mask = LVCF_FMT | LVCF_TEXT | LVCF_SUBITEM;
lvColumn.fmt = LVCFMT_LEFT;
lvColumn.iSubItem = self().offset();
lvColumn.pszText = text;
ListView_InsertColumn(grandparent->hwnd, self().offset(), &lvColumn);
ListView_InsertColumn(parent->hwnd, self().offset(), &lvColumn);
_setState();
grandparent->unlock();
}
}
auto pTableViewColumn::destruct() -> void {
if(auto grandparent = _grandparent()) {
grandparent->lock();
ListView_DeleteColumn(grandparent->hwnd, self().offset());
grandparent->unlock();
if(auto parent = _parent()) {
auto lock = parent->acquire();
ListView_DeleteColumn(parent->hwnd, self().offset());
}
}
@@ -57,7 +55,8 @@ auto pTableViewColumn::setResizable(bool resizable) -> void {
_setState();
}
auto pTableViewColumn::setSortable(bool sortable) -> void {
auto pTableViewColumn::setSorting(Sort sorting) -> void {
_setState();
}
auto pTableViewColumn::setText(const string& text) -> void {
@@ -71,36 +70,33 @@ auto pTableViewColumn::setWidth(signed width) -> void {
_setState();
}
auto pTableViewColumn::_grandparent() -> maybe<pTableView&> {
if(auto parent = _parent()) return parent->_parent();
return nothing;
}
auto pTableViewColumn::_parent() -> maybe<pTableViewHeader&> {
if(auto parent = self().parentTableViewHeader()) {
auto pTableViewColumn::_parent() -> maybe<pTableView&> {
if(auto parent = self().parentTableView()) {
if(auto self = parent->self()) return *self;
}
return nothing;
return {};
}
auto pTableViewColumn::_setState() -> void {
if(auto grandparent = _grandparent()) {
grandparent->lock();
grandparent->_setIcons();
utf16_t text(state().text);
if(auto parent = _parent()) {
auto lock = parent->acquire();
parent->_setIcons();
string text = state().text;
if(state().sorting == Sort::Ascending ) text.append(" ^");
if(state().sorting == Sort::Descending) text.append(" v");
utf16_t wtext(text);
LVCOLUMN lvColumn;
lvColumn.mask = LVCF_FMT | LVCF_SUBITEM | LVCF_TEXT | LVCF_WIDTH;
lvColumn.fmt = LVCFMT_CENTER;
lvColumn.iSubItem = self().offset();
lvColumn.iImage = self().offset();
lvColumn.pszText = text;
lvColumn.pszText = wtext;
lvColumn.cx = _width;
if(state().horizontalAlignment < 0.333) lvColumn.fmt = LVCFMT_LEFT;
if(state().horizontalAlignment > 0.666) lvColumn.fmt = LVCFMT_RIGHT;
if(state().icon) lvColumn.mask |= LVCF_IMAGE;
if(!state().resizable) lvColumn.fmt |= LVCFMT_FIXED_WIDTH;
ListView_SetColumn(grandparent->hwnd, self().offset(), &lvColumn);
grandparent->unlock();
ListView_SetColumn(parent->hwnd, self().offset(), &lvColumn);
}
}

View File

@@ -14,13 +14,12 @@ 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 setWidth(signed width) -> void;
auto _grandparent() -> maybe<pTableView&>;
auto _parent() -> maybe<pTableViewHeader&>;
auto _parent() -> maybe<pTableView&>;
auto _setState() -> void;
signed _width = 128; //computed width (via TableView::resizeColumns)

View File

@@ -1,42 +0,0 @@
#if defined(Hiro_TableView)
namespace hiro {
auto pTableViewHeader::construct() -> void {
_setState();
}
auto pTableViewHeader::destruct() -> void {
}
auto pTableViewHeader::append(sTableViewColumn column) -> void {
}
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 self = parent->self()) return *self;
}
return nothing;
}
auto pTableViewHeader::_setState() -> void {
if(auto parent = _parent()) {
auto style = GetWindowLong(parent->hwnd, GWL_STYLE);
self().visible() ? style &=~ LVS_NOCOLUMNHEADER : style |= LVS_NOCOLUMNHEADER;
SetWindowLong(parent->hwnd, GWL_STYLE, style);
for(auto& column : state().columns) {
if(auto self = column->self()) self->_setState();
}
}
}
}
#endif

View File

@@ -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

View File

@@ -35,8 +35,9 @@ auto pTableView::construct() -> void {
setBackgroundColor(state().backgroundColor);
setBatchable(state().batchable);
setBordered(state().bordered);
setHeadered(state().headered);
setSortable(state().sortable);
_setIcons();
_setSortable();
resizeColumns();
}
@@ -45,61 +46,53 @@ auto pTableView::destruct() -> void {
DestroyWindow(hwnd);
}
auto pTableView::append(sTableViewHeader header) -> void {
auto pTableView::append(sTableViewColumn column) -> void {
resizeColumns();
}
auto pTableView::append(sTableViewItem item) -> void {
}
auto pTableView::remove(sTableViewHeader header) -> void {
LVCOLUMN lvColumn{LVCF_WIDTH};
while(ListView_GetColumn(hwnd, 0, &lvColumn)) {
ListView_DeleteColumn(hwnd, 0);
}
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++;
}
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(state().columns[column]->expandable()) expandable++;
}
signed maximumWidth = self().geometry().width() - 4;
SCROLLBARINFO sbInfo{sizeof(SCROLLBARINFO)};
if(GetScrollBarInfo(hwnd, OBJID_VSCROLL, &sbInfo)) {
if(!(sbInfo.rgstate[0] & STATE_SYSTEM_INVISIBLE)) {
maximumWidth -= sbInfo.rcScrollBar.right - sbInfo.rcScrollBar.left;
}
}
signed expandWidth = 0;
if(expandable && maximumWidth > minimumWidth) {
expandWidth = (maximumWidth - minimumWidth) / expandable;
}
for(auto column : range(header->columnCount())) {
if(auto self = header->state.columns[column]->self()) {
signed width = widths[column];
if(self->state().expandable) width += expandWidth;
self->_width = width;
self->_setState();
}
signed maximumWidth = self().geometry().width() - 4;
SCROLLBARINFO sbInfo{sizeof(SCROLLBARINFO)};
if(GetScrollBarInfo(hwnd, OBJID_VSCROLL, &sbInfo)) {
if(!(sbInfo.rgstate[0] & STATE_SYSTEM_INVISIBLE)) {
maximumWidth -= sbInfo.rcScrollBar.right - sbInfo.rcScrollBar.left;
}
}
unlock();
signed expandWidth = 0;
if(expandable && maximumWidth > minimumWidth) {
expandWidth = (maximumWidth - minimumWidth) / expandable;
}
for(auto column : range(self().columnCount())) {
if(auto self = state().columns[column]->self()) {
signed width = widths[column];
if(self->state().expandable) width += expandWidth;
self->_width = width;
self->_setState();
}
}
}
auto pTableView::setAlignment(Alignment alignment) -> void {
@@ -125,10 +118,8 @@ auto pTableView::setForegroundColor(Color color) -> void {
auto pTableView::setGeometry(Geometry geometry) -> void {
pWidget::setGeometry(geometry);
if(auto& header = state().header) {
for(auto& column : header->state.columns) {
if(column->state.expandable) return resizeColumns();
}
for(auto& column : state().columns) {
if(column->state.expandable) return resizeColumns();
}
}
@@ -179,9 +170,7 @@ auto pTableView::onCustomDraw(LPARAM lparam) -> LRESULT {
HDC hdc = lvcd->nmcd.hdc;
HDC hdcSource = CreateCompatibleDC(hdc);
unsigned row = lvcd->nmcd.dwItemSpec;
auto& header = state().header;
if(!header) break;
for(auto column : range(header->columnCount())) {
for(auto column : range(self().columnCount())) {
RECT rc, rcLabel;
ListView_GetSubItemRect(hwnd, row, column, LVIR_BOUNDS, &rc);
ListView_GetSubItemRect(hwnd, row, column, LVIR_LABEL, &rcLabel);
@@ -278,10 +267,8 @@ auto pTableView::onCustomDraw(LPARAM lparam) -> LRESULT {
auto pTableView::onSort(LPARAM lparam) -> void {
auto nmlistview = (LPNMLISTVIEW)lparam;
if(auto& header = state().header) {
if(auto column = header->column(nmlistview->iSubItem)) {
if(column->sortable()) self().doSort(column);
}
if(auto column = self().column(nmlistview->iSubItem)) {
if(state().sortable) self().doSort(column);
}
}
@@ -301,6 +288,19 @@ auto pTableView::onToggle(LPARAM lparam) -> void {
}
}
auto pTableView::setHeadered(bool headered) -> void {
auto style = GetWindowLong(hwnd, GWL_STYLE);
headered ? style &=~ LVS_NOCOLUMNHEADER : style |= LVS_NOCOLUMNHEADER;
SetWindowLong(hwnd, GWL_STYLE, style);
}
auto pTableView::setSortable(bool sortable) -> void {
//note: this won't change the visual style: WC_LISTVIEW caches this in CreateWindow
auto style = GetWindowLong(hwnd, GWL_STYLE);
sortable ? style &=~ LVS_NOSORTHEADER : style |= LVS_NOSORTHEADER;
SetWindowLong(hwnd, GWL_STYLE, style);
}
auto pTableView::_backgroundColor(unsigned _row, unsigned _column) -> Color {
if(auto item = self().item(_row)) {
if(auto cell = item->cell(_column)) {
@@ -308,11 +308,11 @@ auto pTableView::_backgroundColor(unsigned _row, unsigned _column) -> Color {
}
if(auto color = item->backgroundColor()) return color;
}
// if(auto column = self().column(_column)) {
// if(auto color = column->backgroundColor()) return color;
// }
//if(auto column = self().column(_column)) {
// if(auto color = column->backgroundColor()) return color;
//}
if(auto color = self().backgroundColor()) return color;
// if(state().columns.size() >= 2 && _row % 2) return {240, 240, 240};
//if(state().columns.size() >= 2 && _row % 2) return {240, 240, 240};
return {255, 255, 255};
}
@@ -336,14 +336,15 @@ auto pTableView::_cellWidth(unsigned _row, unsigned _column) -> unsigned {
auto pTableView::_columnWidth(unsigned _column) -> unsigned {
unsigned width = 12;
if(auto header = state().header) {
if(auto column = header->column(_column)) {
if(auto& icon = column->state.icon) {
width += 16 + 12; //yes; icon spacing in column headers is excessive
}
if(auto& text = column->state.text) {
width += pFont::size(self().font(true), text).width();
}
if(auto column = self().column(_column)) {
if(auto& icon = column->state.icon) {
width += 16 + 12; //yes; icon spacing in column headers is excessive
}
if(auto& text = column->state.text) {
width += pFont::size(self().font(true), text).width();
}
if(column->state.sorting != Sort::None) {
width += 12;
}
}
return width;
@@ -356,9 +357,9 @@ auto pTableView::_font(unsigned _row, unsigned _column) -> Font {
}
if(auto font = item->font()) return font;
}
// if(auto column = self().column(_column)) {
// if(auto font = column->font()) return font;
// }
//if(auto column = self().column(_column)) {
// if(auto font = column->font()) return font;
//}
if(auto font = self().font(true)) return font;
return {};
}
@@ -370,9 +371,9 @@ auto pTableView::_foregroundColor(unsigned _row, unsigned _column) -> Color {
}
if(auto color = item->foregroundColor()) return color;
}
// if(auto column = self().column(_column)) {
// if(auto color = column->foregroundColor()) return color;
// }
//if(auto column = self().column(_column)) {
// if(auto color = column->foregroundColor()) return color;
//}
if(auto color = self().foregroundColor()) return color;
return {0, 0, 0};
}
@@ -383,21 +384,19 @@ auto pTableView::_setIcons() -> void {
imageList = ImageList_Create(16, 16, ILC_COLOR32, 1, 0);
ListView_SetImageList(hwnd, imageList, LVSIL_SMALL);
if(auto& header = state().header) {
for(auto column : range(header->columnCount())) {
image icon;
if(auto& sourceIcon = header->state.columns[column]->state.icon) {
icon.allocate(sourceIcon.width(), sourceIcon.height());
memory::copy(icon.data(), sourceIcon.data(), icon.size());
icon.scale(16, 16);
} else {
icon.allocate(16, 16);
icon.fill(0x00ffffff);
}
auto bitmap = CreateBitmap(icon);
ImageList_Add(imageList, bitmap, nullptr);
DeleteObject(bitmap);
for(auto column : range(self().columnCount())) {
image icon;
if(auto& sourceIcon = state().columns[column]->state.icon) {
icon.allocate(sourceIcon.width(), sourceIcon.height());
memory::copy(icon.data(), sourceIcon.data(), icon.size());
icon.scale(16, 16);
} else {
icon.allocate(16, 16);
icon.fill(0x00ffffff);
}
auto bitmap = CreateBitmap(icon);
ImageList_Add(imageList, bitmap, nullptr);
DeleteObject(bitmap);
}
//empty icon used for ListViewItems (drawn manually via onCustomDraw)
@@ -409,31 +408,14 @@ auto pTableView::_setIcons() -> void {
DeleteObject(bitmap);
}
auto pTableView::_setSortable() -> void {
bool sortable = false;
if(auto& header = state().header) {
for(auto& column : header->state.columns) {
if(column->sortable()) sortable = true;
}
}
//note: this won't change the visual style: WC_LISTVIEW caches this in CreateWindow
auto style = GetWindowLong(hwnd, GWL_STYLE);
!sortable ? style |= LVS_NOSORTHEADER : style &=~ LVS_NOSORTHEADER;
SetWindowLong(hwnd, GWL_STYLE, style);
}
auto pTableView::_width(unsigned column) -> unsigned {
if(auto& header = state().header) {
if(auto width = header->state.columns[column]->width()) return width;
unsigned width = 1;
if(header->visible()) width = max(width, _columnWidth(column));
for(auto row : range(state().items.size())) {
width = max(width, _cellWidth(row, column));
}
return width;
if(auto width = self().column(column).width()) return width;
unsigned width = 1;
if(state().headered) width = max(width, _columnWidth(column));
for(auto row : range(state().items.size())) {
width = max(width, _cellWidth(row, column));
}
return 1;
return width;
}
}

View File

@@ -5,9 +5,9 @@ namespace hiro {
struct pTableView : pWidget {
Declare(TableView, Widget)
auto append(sTableViewHeader header) -> void;
auto append(sTableViewColumn column) -> void;
auto append(sTableViewItem item) -> void;
auto remove(sTableViewHeader header) -> void;
auto remove(sTableViewColumn column) -> void;
auto remove(sTableViewItem item) -> void;
auto resizeColumns() -> void;
auto setAlignment(Alignment alignment) -> void;
@@ -16,6 +16,8 @@ struct pTableView : pWidget {
auto setBordered(bool bordered) -> void;
auto setForegroundColor(Color color) -> void;
auto setGeometry(Geometry geometry) -> void override;
auto setHeadered(bool headered) -> void;
auto setSortable(bool sortable) -> void;
auto onActivate(LPARAM lparam) -> void;
auto onChange(LPARAM lparam) -> void;
@@ -30,7 +32,6 @@ struct pTableView : pWidget {
auto _font(unsigned row, unsigned column) -> Font;
auto _foregroundColor(unsigned row, unsigned column) -> Color;
auto _setIcons() -> void;
auto _setSortable() -> void;
auto _width(unsigned column) -> unsigned;
WindowProc windowProc = nullptr;

View File

@@ -25,6 +25,7 @@ auto pTextEdit::destruct() -> void {
auto pTextEdit::setBackgroundColor(Color color) -> void {
if(backgroundBrush) { DeleteObject(backgroundBrush); backgroundBrush = 0; }
backgroundBrush = CreateSolidBrush(color ? CreateRGB(color) : GetSysColor(COLOR_WINDOW));
InvalidateRect(hwnd, 0, true);
}
auto pTextEdit::setCursor(Cursor cursor) -> void {
@@ -40,14 +41,14 @@ auto pTextEdit::setEditable(bool editable) -> void {
}
auto pTextEdit::setForegroundColor(Color color) -> void {
InvalidateRect(hwnd, 0, true);
}
auto pTextEdit::setText(string text) -> void {
lock();
auto lock = acquire();
text.replace("\r", "");
text.replace("\n", "\r\n");
SetWindowText(hwnd, utf16_t(text));
unlock();
}
auto pTextEdit::setWordWrap(bool wordWrap) -> void {

View File

@@ -170,7 +170,7 @@ auto pWindow::setModal(bool modality) -> void {
_modalityUpdate();
while(state().modal) {
Application::processEvents();
if(Application::state.onMain) {
if(Application::state().onMain) {
Application::doMain();
} else {
usleep(20 * 1000);
@@ -193,6 +193,9 @@ auto pWindow::setTitle(string text) -> void {
auto pWindow::setVisible(bool visible) -> void {
auto lock = acquire();
ShowWindow(hwnd, visible ? SW_SHOWNORMAL : SW_HIDE);
if(auto& sizable = state().sizable) {
sizable->setGeometry(self().geometry().setPosition());
}
if(!visible) setModal(false);
}