Update to v106r41 release.

byuu says:

Changelog:

  - hiro: added Label::set(Background,Foreground)Color (not implemented
    on Cocoa backend)
  - hiro: added (Horizontal,Vertical)Layout::setPadding()
      - setMargin(m) is now an alias to setPadding({m, m, m, m})
  - hiro/Windows: update Label rendering to draw to an offscreen canvas
    to prevent flickering
  - sfc: reverted back to 224/240-line height (from 223/239-line height
    in earlier v106 WIPs)
  - bsnes: new multi-segment status bar added
  - bsnes: exiting fullscreen mode will resize and recenter window
      - this is required; the window geometry gets all scrambled when
        toggling fullscreen mode
  - bsnes: updated to a new logo [Ange Albertini]

Errata:

  - hiro/Windows: try to paint Label backgroundColor quicker to avoid
    startup flicker
      - `WM_ERASEBKGND` fallthrough to `WM_PAINT` seems to work
  - hiro/Qt: use Window backgroundColor for Label when no Label
    backgroundColor set
  - bsnes: update size multipliers in presentation.cpp to 224/240 (main
    window size is off in this WIP)
This commit is contained in:
Tim Allen
2018-06-24 14:53:44 +10:00
parent 470e27323d
commit f70a20bc42
29 changed files with 1473 additions and 1579 deletions

View File

@@ -48,6 +48,14 @@ auto pLabel::setAlignment(Alignment alignment) -> void {
}
}
auto pLabel::setBackgroundColor(Color color) -> void {
//todo
}
auto pLabel::setForegroundColor(Color color) -> void {
//todo
}
auto pLabel::setGeometry(Geometry geometry) -> void {
//NSTextView does not support vertical text centering:
//simulate this by adjusting the geometry placement (reduce height, move view down)

View File

@@ -14,6 +14,8 @@ struct pLabel : pWidget {
auto minimumSize() const -> Size override;
auto setAlignment(Alignment alignment) -> void;
auto setBackgroundColor(Color color) -> void;
auto setForegroundColor(Color color) -> void;
auto setGeometry(Geometry geometry) -> void override;
auto setText(const string& text) -> void;

View File

@@ -1395,13 +1395,19 @@ struct mLabel : mWidget {
Declare(Label)
auto alignment() const -> Alignment;
auto backgroundColor() const -> Color;
auto foregroundColor() const -> Color;
auto setAlignment(Alignment alignment = {}) -> type&;
auto setBackgroundColor(Color color = {}) -> type&;
auto setForegroundColor(Color color = {}) -> type&;
auto setText(const string& text = "") -> type&;
auto text() const -> string;
//private:
struct State {
Alignment alignment;
Color backgroundColor;
Color foregroundColor;
string text;
} state;
};

View File

@@ -497,7 +497,11 @@ struct Label : sLabel {
using internalType = mLabel;
auto alignment() const { return self().alignment(); }
auto backgroundColor() const { return self().backgroundColor(); }
auto foregroundColor() const { return self().foregroundColor(); }
auto setAlignment(Alignment alignment = {}) { return self().setAlignment(alignment), *this; }
auto setBackgroundColor(Color color = {}) { return self().setBackgroundColor(color), *this; }
auto setForegroundColor(Color color = {}) { return self().setForegroundColor(color), *this; }
auto setText(const string& text = "") { return self().setText(text), *this; }
auto text() const { return self().text(); }
};

View File

@@ -10,12 +10,32 @@ auto mLabel::alignment() const -> Alignment {
return state.alignment;
}
auto mLabel::backgroundColor() const -> Color {
return state.backgroundColor;
}
auto mLabel::foregroundColor() const -> Color {
return state.foregroundColor;
}
auto mLabel::setAlignment(Alignment alignment) -> type& {
state.alignment = alignment;
signal(setAlignment, alignment);
return *this;
}
auto mLabel::setBackgroundColor(Color color) -> type& {
state.backgroundColor = color;
signal(setBackgroundColor, color);
return *this;
}
auto mLabel::setForegroundColor(Color color) -> type& {
state.foregroundColor = color;
signal(setForegroundColor, color);
return *this;
}
auto mLabel::setText(const string& text) -> type& {
state.text = text;
signal(setText, text);

View File

@@ -38,7 +38,10 @@ auto mHorizontalLayout::minimumSize() const -> Size {
height = max(height, child.height());
}
return {settings.margin * 2 + width, settings.margin * 2 + height};
return {
settings.padding.x() + width + settings.padding.width(),
settings.padding.y() + height + settings.padding.height()
};
}
auto mHorizontalLayout::remove(sSizable sizable) -> type& {
@@ -85,10 +88,10 @@ auto mHorizontalLayout::setGeometry(Geometry containerGeometry) -> type& {
}
Geometry geometry = containerGeometry;
geometry.setX (geometry.x() + settings.margin );
geometry.setY (geometry.y() + settings.margin );
geometry.setWidth (geometry.width() - settings.margin * 2);
geometry.setHeight(geometry.height() - settings.margin * 2);
geometry.setX (geometry.x() + settings.padding.x());
geometry.setY (geometry.y() + settings.padding.y());
geometry.setWidth (geometry.width() - settings.padding.x() - settings.padding.width());
geometry.setHeight(geometry.height() - settings.padding.y() - settings.padding.height());
float minimumWidth = 0, maximumWidthCounter = 0;
for(auto& child : properties) {
@@ -121,12 +124,19 @@ auto mHorizontalLayout::setGeometry(Geometry containerGeometry) -> type& {
}
auto mHorizontalLayout::setMargin(float margin) -> type& {
settings.margin = margin;
setPadding({margin, margin, margin, margin});
return *this;
}
auto mHorizontalLayout::setPadding(Geometry padding) -> type& {
settings.padding = padding;
setGeometry(geometry());
return *this;
}
auto mHorizontalLayout::setSpacing(float spacing) -> type& {
settings.spacing = spacing;
setGeometry(geometry());
return *this;
}

View File

@@ -15,12 +15,13 @@ struct mHorizontalLayout : mLayout {
auto setFont(const Font& font = {}) -> type& override;
auto setGeometry(Geometry geometry) -> type& override;
auto setMargin(float margin = 0) -> type&;
auto setPadding(Geometry padding = {}) -> type&;
auto setSpacing(float spacing = 5) -> type&;
auto setVisible(bool visible = true) -> type&;
struct Settings {
float alignment = 0.5;
float margin = 0;
Geometry padding;
float spacing = 5;
} settings;

View File

@@ -13,11 +13,12 @@ using sHorizontalLayout = shared_pointer<mHorizontalLayout>;
struct HorizontalLayout : sHorizontalLayout {
DeclareSharedLayout(HorizontalLayout)
auto append(sSizable sizable, Size size, signed spacing = 5) { return self().append(sizable, size, spacing), *this; }
auto modify(sSizable sizable, Size size, signed spacing = 5) { return self().modify(sizable, size, spacing), *this; }
auto setAlignment(double alignment = 0.5) { return self().setAlignment(alignment), *this; }
auto setMargin(signed margin = 0) { return self().setMargin(margin), *this; }
auto setSpacing(signed spacing = 5) { return self().setSpacing(spacing), *this; }
auto append(sSizable sizable, Size size, float spacing = 5) { return self().append(sizable, size, spacing), *this; }
auto modify(sSizable sizable, Size size, float spacing = 5) { return self().modify(sizable, size, spacing), *this; }
auto setAlignment(float alignment = 0.5) { return self().setAlignment(alignment), *this; }
auto setMargin(float margin = 0) { return self().setMargin(margin), *this; }
auto setPadding(Geometry padding = {}) { return self().setPadding(padding), *this; }
auto setSpacing(float spacing = 5) { return self().setSpacing(spacing), *this; }
};
#endif
@@ -26,11 +27,12 @@ using sVerticalLayout = shared_pointer<mVerticalLayout>;
struct VerticalLayout : sVerticalLayout {
DeclareSharedLayout(VerticalLayout)
auto append(sSizable sizable, Size size, signed spacing = 5) { return self().append(sizable, size, spacing), *this; }
auto modify(sSizable sizable, Size size, signed spacing = 5) { return self().modify(sizable, size, spacing), *this; }
auto setAlignment(double alignment = 0.0) { return self().setAlignment(alignment), *this; }
auto setMargin(signed margin = 0) { return self().setMargin(margin), *this; }
auto setSpacing(signed spacing = 5) { return self().setSpacing(spacing), *this; }
auto append(sSizable sizable, Size size, float spacing = 5) { return self().append(sizable, size, spacing), *this; }
auto modify(sSizable sizable, Size size, float spacing = 5) { return self().modify(sizable, size, spacing), *this; }
auto setAlignment(float alignment = 0.0) { return self().setAlignment(alignment), *this; }
auto setMargin(float margin = 0) { return self().setMargin(margin), *this; }
auto setPadding(Geometry padding = {}) { return self().setPadding(padding), *this; }
auto setSpacing(float spacing = 5) { return self().setSpacing(spacing), *this; }
};
#endif

View File

@@ -38,7 +38,10 @@ auto mVerticalLayout::minimumSize() const -> Size {
if(&child != &properties.right()) height += child.spacing();
}
return {settings.margin * 2 + width, settings.margin * 2 + height};
return {
settings.padding.x() + width + settings.padding.width(),
settings.padding.y() + height + settings.padding.height()
};
}
auto mVerticalLayout::remove(sSizable sizable) -> type& {
@@ -85,10 +88,10 @@ auto mVerticalLayout::setGeometry(Geometry containerGeometry) -> type& {
}
Geometry geometry = containerGeometry;
geometry.setX (geometry.x() + settings.margin );
geometry.setY (geometry.y() + settings.margin );
geometry.setWidth (geometry.width() - settings.margin * 2);
geometry.setHeight(geometry.height() - settings.margin * 2);
geometry.setX (geometry.x() + settings.padding.x());
geometry.setY (geometry.y() + settings.padding.y());
geometry.setWidth (geometry.width() - settings.padding.x() - settings.padding.width());
geometry.setHeight(geometry.height() - settings.padding.y() - settings.padding.height());
float minimumHeight = 0, maximumHeightCounter = 0;
for(auto& child : properties) {
@@ -121,12 +124,19 @@ auto mVerticalLayout::setGeometry(Geometry containerGeometry) -> type& {
}
auto mVerticalLayout::setMargin(float margin) -> type& {
settings.margin = margin;
setPadding({margin, margin, margin, margin});
return *this;
}
auto mVerticalLayout::setPadding(Geometry padding) -> type& {
settings.padding = padding;
setGeometry(geometry());
return *this;
}
auto mVerticalLayout::setSpacing(float spacing) -> type& {
settings.spacing = spacing;
setGeometry(geometry());
return *this;
}

View File

@@ -15,12 +15,13 @@ struct mVerticalLayout : mLayout {
auto setFont(const Font& font = {}) -> type& override;
auto setGeometry(Geometry geometry) -> type& override;
auto setMargin(float margin = 0) -> type&;
auto setPadding(Geometry padding = {}) -> type&;
auto setSpacing(float spacing = 5) -> type&;
auto setVisible(bool visible = true) -> type& override;
struct Settings {
float alignment = 0.0;
float margin = 0;
Geometry padding;
float spacing = 5;
} settings;

View File

@@ -3,15 +3,21 @@
namespace hiro {
auto pLabel::construct() -> void {
gtkWidget = gtk_label_new("");
gtkWidget = gtk_event_box_new();
subWidget = gtk_label_new("");
gtk_widget_show(subWidget);
gtk_container_add(GTK_CONTAINER(gtkWidget), subWidget);
setAlignment(state().alignment);
setBackgroundColor(state().backgroundColor);
setForegroundColor(state().foregroundColor);
setText(state().text);
pWidget::construct();
}
auto pLabel::destruct() -> void {
gtk_widget_destroy(subWidget);
gtk_widget_destroy(gtkWidget);
}
@@ -22,15 +28,31 @@ auto pLabel::minimumSize() const -> Size {
auto pLabel::setAlignment(Alignment alignment) -> void {
if(!alignment) alignment = {0.0, 0.5};
gtk_misc_set_alignment(GTK_MISC(gtkWidget), alignment.horizontal(), alignment.vertical());
gtk_misc_set_alignment(GTK_MISC(subWidget), alignment.horizontal(), alignment.vertical());
auto justify = GTK_JUSTIFY_CENTER;
if(alignment.horizontal() < 0.333) justify = GTK_JUSTIFY_LEFT;
if(alignment.horizontal() > 0.666) justify = GTK_JUSTIFY_RIGHT;
gtk_label_set_justify(GTK_LABEL(gtkWidget), justify);
gtk_label_set_justify(GTK_LABEL(subWidget), justify);
}
auto pLabel::setBackgroundColor(Color color) -> void {
if(!color) color = self().parentWindow(true)->backgroundColor();
auto gdkColor = CreateColor(color);
gtk_widget_modify_bg(gtkWidget, GTK_STATE_NORMAL, color ? &gdkColor : nullptr);
}
auto pLabel::setForegroundColor(Color color) -> void {
auto gdkColor = CreateColor(color);
gtk_widget_modify_fg(subWidget, GTK_STATE_NORMAL, color ? &gdkColor : nullptr);
}
auto pLabel::setText(const string& text) -> void {
gtk_label_set_text(GTK_LABEL(gtkWidget), text);
gtk_label_set_text(GTK_LABEL(subWidget), text);
}
auto pLabel::setVisible(bool visible) -> void {
setBackgroundColor(state().backgroundColor);
return pWidget::setVisible(visible);
}
}

View File

@@ -7,7 +7,12 @@ struct pLabel : pWidget {
auto minimumSize() const -> Size override;
auto setAlignment(Alignment alignment) -> void;
auto setBackgroundColor(Color color) -> void;
auto setForegroundColor(Color color) -> void;
auto setText(const string& text) -> void;
auto setVisible(bool visible) -> void override;
GtkWidget* subWidget = nullptr;
};
}

File diff suppressed because it is too large Load Diff

View File

@@ -5,10 +5,11 @@ namespace hiro {
auto pLabel::construct() -> void {
qtWidget = qtLabel = new QLabel;
setAlignment(state().alignment);
setText(state().text);
pWidget::construct();
setAlignment(state().alignment);
setBackgroundColor(state().backgroundColor);
setForegroundColor(state().foregroundColor);
setText(state().text);
}
auto pLabel::destruct() -> void {
@@ -26,6 +27,29 @@ auto pLabel::setAlignment(Alignment alignment) -> void {
qtLabel->setAlignment((Qt::Alignment)CalculateAlignment(alignment));
}
auto pLabel::setBackgroundColor(Color color) -> void {
if(color) {
QPalette palette = qtLabel->palette();
palette.setColor(QPalette::Base, QColor(color.red(), color.green(), color.blue()));
qtLabel->setBackgroundRole(QPalette::Base);
qtLabel->setPalette(palette);
qtLabel->setAutoFillBackground(true);
} else {
//todo
}
}
auto pLabel::setForegroundColor(Color color) -> void {
if(color) {
QPalette palette = qtLabel->palette();
palette.setColor(QPalette::Text, QColor(color.red(), color.green(), color.blue()));
qtLabel->setForegroundRole(QPalette::Text);
qtLabel->setPalette(palette);
} else {
//todo
}
}
auto pLabel::setText(const string& text) -> void {
qtLabel->setText(QString::fromUtf8(text));
}

View File

@@ -7,6 +7,8 @@ struct pLabel : pWidget {
auto minimumSize() const -> Size override;
auto setAlignment(Alignment alignment) -> void;
auto setBackgroundColor(Color color) -> void;
auto setForegroundColor(Color color) -> void;
auto setText(const string& text) -> void;
QLabel* qtLabel = nullptr;

View File

@@ -8,7 +8,6 @@ auto pLabel::construct() -> void {
0, 0, 0, 0, _parentHandle(), nullptr, GetModuleHandle(0), 0);
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)&reference);
pWidget::_setState();
setAlignment(state().alignment);
setText(state().text);
}
@@ -25,6 +24,14 @@ auto pLabel::setAlignment(Alignment alignment) -> void {
InvalidateRect(hwnd, 0, false);
}
auto pLabel::setBackgroundColor(Color color) -> void {
InvalidateRect(hwnd, 0, false);
}
auto pLabel::setForegroundColor(Color color) -> void {
InvalidateRect(hwnd, 0, false);
}
auto pLabel::setText(const string& text) -> void {
SetWindowText(hwnd, utf16_t(text));
InvalidateRect(hwnd, 0, false);
@@ -44,20 +51,32 @@ static auto CALLBACK Label_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM
BeginPaint(hwnd, &ps);
RECT rc;
GetClientRect(hwnd, &rc);
//todo: use DrawThemeParentBackground if Label is inside TabFrame
if(auto brush = window->self()->hbrush) {
FillRect(ps.hdc, &rc, brush);
} else {
DrawThemeParentBackground(hwnd, ps.hdc, &rc);
}
SetBkMode(ps.hdc, TRANSPARENT);
SelectObject(ps.hdc, label->self()->hfont);
auto hdcMemory = CreateCompatibleDC(ps.hdc);
auto hbmMemory = CreateCompatibleBitmap(ps.hdc, rc.right - rc.left, rc.bottom - rc.top);
SelectObject(hdcMemory, hbmMemory);
uint length = GetWindowTextLength(hwnd);
wchar_t text[length + 1];
GetWindowText(hwnd, text, length + 1);
text[length] = 0;
DrawText(ps.hdc, text, -1, &rc, DT_CALCRECT | DT_END_ELLIPSIS);
//todo: use DrawThemeParentBackground if Label is inside TabFrame
if(auto color = label->backgroundColor()) {
auto brush = CreateSolidBrush(CreateRGB(color));
FillRect(hdcMemory, &rc, brush);
DeleteObject(brush);
} else if(auto brush = window->self()->hbrush) {
FillRect(hdcMemory, &rc, brush);
} else {
DrawThemeParentBackground(hwnd, hdcMemory, &rc);
}
SetBkMode(hdcMemory, TRANSPARENT);
SelectObject(hdcMemory, label->self()->hfont);
DrawText(hdcMemory, text, -1, &rc, DT_CALCRECT | DT_END_ELLIPSIS);
uint height = rc.bottom;
GetClientRect(hwnd, &rc);
rc.top = (rc.bottom - height) / 2;
rc.bottom = rc.top + height;
@@ -67,7 +86,15 @@ static auto CALLBACK Label_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM
uint verticalAlignment = DT_VCENTER;
if(label->alignment().vertical() < 0.333) verticalAlignment = DT_TOP;
if(label->alignment().vertical() > 0.666) verticalAlignment = DT_BOTTOM;
DrawText(ps.hdc, text, -1, &rc, DT_END_ELLIPSIS | horizontalAlignment | verticalAlignment);
if(auto color = label->foregroundColor()) {
SetTextColor(hdcMemory, CreateRGB(color));
}
DrawText(hdcMemory, text, -1, &rc, DT_END_ELLIPSIS | horizontalAlignment | verticalAlignment);
GetClientRect(hwnd, &rc);
BitBlt(ps.hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, hdcMemory, 0, 0, SRCCOPY);
DeleteObject(hbmMemory);
DeleteObject(hdcMemory);
EndPaint(hwnd, &ps);
return false;
}

View File

@@ -7,6 +7,8 @@ struct pLabel : pWidget {
auto minimumSize() const -> Size override;
auto setAlignment(Alignment alignment) -> void;
auto setBackgroundColor(Color color) -> void;
auto setForegroundColor(Color color) -> void;
auto setText(const string& text) -> void;
};