mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-08-26 08:24:57 +02:00
Update to v104r13 release.
byuu says: Changelog: - nall/GNUmakefile: build=release changed to -O2, build=optimize is now -O3 - hiro: added Monitor::dpi(uint index) → Position [returns logical DPI for x, y] - Position is a bad name, but dpi(monitor).(x,y)() make more sense than .(width,height)() - hiro: Position, Size, Geometry, Font changed from using signed int to float - hiro: Alignment changed from using double to float - hiro: added skeleton (unused) Application::scale(), setScale() functions Errata: - hiro/cocoa's Monitor::dpi() is untested. Probably will cause issues with macOS' automatic scaling. - hiro/gtk lacks a way to get both per-monitor and per-axis (x,y) DPI scaling - hiro/qt lacks a way to get per-monitor DPI scaling (Qt 5.x has this, but I still use Qt 4.x) - and just to get global DPI, hiro/qt's DPI retrieval has to use undocumented functions ... fun The goal with this WIP was basically to prepare hiro for potential automatic scaling. It'll be extremely difficult, but I'm convinced that it must be possible if macOS can do it. By moving from signed integers to floats for coordinates, we can now scale and unscale without losing precision. That of course isn't the hard part, though. The hard part is where and how to do the scaling. In the ideal application, hiro/core and hiro/extension will handle 100% of this, and the per-platform hiro/(cocoa,gtk,qt,windows) will not be aware of what's going on, but ... to even make that possible, things will need to change in every per-platform core, eg the per-platform code will have to call a core function to change geometry, which will know about the scaling and unscale the values back down again. Gonna be a lot of work, but ... it's a start.
This commit is contained in:
@@ -16,7 +16,7 @@ auto mFixedLayout::modify(sSizable sizable, Geometry geometry) -> type& {
|
||||
}
|
||||
|
||||
auto mFixedLayout::minimumSize() const -> Size {
|
||||
signed width = Size::Minimum, height = Size::Minimum;
|
||||
float width = Size::Minimum, height = Size::Minimum;
|
||||
for(auto n : range(sizableCount())) {
|
||||
width = max(width, sizable(n)->minimumSize().width());
|
||||
height = max(height, sizable(n)->minimumSize().height());
|
||||
|
@@ -14,10 +14,10 @@ struct mFixedLayout : mLayout {
|
||||
auto setFont(const Font& font = {}) -> type& override;
|
||||
auto setVisible(bool visible = true) ->type& override;
|
||||
|
||||
struct Properties {
|
||||
struct Property {
|
||||
Geometry geometry;
|
||||
};
|
||||
vector<Properties> properties;
|
||||
vector<Property> properties;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -1,41 +1,41 @@
|
||||
#if defined(Hiro_HorizontalLayout)
|
||||
|
||||
auto mHorizontalLayout::append(sSizable sizable, Size size, signed spacing) -> type& {
|
||||
auto mHorizontalLayout::append(sSizable sizable, Size size, float spacing) -> type& {
|
||||
properties.append({size.width(), size.height(), spacing < 0 ? settings.spacing : spacing});
|
||||
mLayout::append(sizable);
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto mHorizontalLayout::modify(sSizable sizable, Size size, signed spacing) -> type& {
|
||||
auto mHorizontalLayout::modify(sSizable sizable, Size size, float spacing) -> type& {
|
||||
if(sizable && this->sizable(sizable->offset()) == sizable) {
|
||||
auto& properties = this->properties[sizable->offset()];
|
||||
properties.width = size.width();
|
||||
properties.height = size.height();
|
||||
properties.spacing = spacing;
|
||||
properties.setWidth(size.width());
|
||||
properties.setHeight(size.height());
|
||||
properties.setSpacing(spacing);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto mHorizontalLayout::minimumSize() const -> Size {
|
||||
signed width = 0, height = 0;
|
||||
float width = 0, height = 0;
|
||||
|
||||
for(auto n : range(sizableCount())) {
|
||||
auto& child = properties[sizable(n)->offset()];
|
||||
if(child.width == Size::Minimum || child.width == Size::Maximum) {
|
||||
if(child.width() == Size::Minimum || child.width() == Size::Maximum) {
|
||||
width += sizable(n)->minimumSize().width();
|
||||
} else {
|
||||
width += child.width;
|
||||
width += child.width();
|
||||
}
|
||||
if(&child != &properties.right()) width += child.spacing;
|
||||
if(&child != &properties.right()) width += child.spacing();
|
||||
}
|
||||
|
||||
for(auto n : range(sizableCount())) {
|
||||
auto& child = properties[sizable(n)->offset()];
|
||||
if(child.height == Size::Minimum || child.height == Size::Maximum) {
|
||||
if(child.height() == Size::Minimum || child.height() == Size::Maximum) {
|
||||
height = max(height, sizable(n)->minimumSize().height());
|
||||
continue;
|
||||
}
|
||||
height = max(height, child.height);
|
||||
height = max(height, child.height());
|
||||
}
|
||||
|
||||
return {settings.margin * 2 + width, settings.margin * 2 + height};
|
||||
@@ -53,7 +53,7 @@ auto mHorizontalLayout::reset() -> type& {
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto mHorizontalLayout::setAlignment(double alignment) -> type& {
|
||||
auto mHorizontalLayout::setAlignment(float alignment) -> type& {
|
||||
settings.alignment = max(0.0, min(1.0, alignment));
|
||||
return *this;
|
||||
}
|
||||
@@ -80,8 +80,8 @@ auto mHorizontalLayout::setGeometry(Geometry containerGeometry) -> type& {
|
||||
auto properties = this->properties;
|
||||
for(auto n : range(sizableCount())) {
|
||||
auto& child = properties[sizable(n)->offset()];
|
||||
if(child.width == Size::Minimum) child.width = sizable(n)->minimumSize().width();
|
||||
if(child.height == Size::Minimum) child.height = sizable(n)->minimumSize().height();
|
||||
if(child.width() == Size::Minimum) child.setWidth(sizable(n)->minimumSize().width());
|
||||
if(child.height() == Size::Minimum) child.setHeight(sizable(n)->minimumSize().height());
|
||||
}
|
||||
|
||||
Geometry geometry = containerGeometry;
|
||||
@@ -90,42 +90,42 @@ auto mHorizontalLayout::setGeometry(Geometry containerGeometry) -> type& {
|
||||
geometry.setWidth (geometry.width() - settings.margin * 2);
|
||||
geometry.setHeight(geometry.height() - settings.margin * 2);
|
||||
|
||||
signed minimumWidth = 0, maximumWidthCounter = 0;
|
||||
float minimumWidth = 0, maximumWidthCounter = 0;
|
||||
for(auto& child : properties) {
|
||||
if(child.width == Size::Maximum) maximumWidthCounter++;
|
||||
if(child.width != Size::Maximum) minimumWidth += child.width;
|
||||
if(&child != &properties.right()) minimumWidth += child.spacing;
|
||||
if(child.width() == Size::Maximum) maximumWidthCounter++;
|
||||
if(child.width() != Size::Maximum) minimumWidth += child.width();
|
||||
if(&child != &properties.right()) minimumWidth += child.spacing();
|
||||
}
|
||||
|
||||
for(auto& child : properties) {
|
||||
if(child.width == Size::Maximum) child.width = (geometry.width() - minimumWidth) / maximumWidthCounter;
|
||||
if(child.height == Size::Maximum) child.height = geometry.height();
|
||||
if(child.width() == Size::Maximum) child.setWidth((geometry.width() - minimumWidth) / maximumWidthCounter);
|
||||
if(child.height() == Size::Maximum) child.setHeight(geometry.height());
|
||||
}
|
||||
|
||||
signed maximumHeight = 0;
|
||||
for(auto& child : properties) maximumHeight = max(maximumHeight, child.height);
|
||||
float maximumHeight = 0;
|
||||
for(auto& child : properties) maximumHeight = max(maximumHeight, child.height());
|
||||
|
||||
for(auto n : range(sizableCount())) {
|
||||
auto& child = properties[sizable(n)->offset()];
|
||||
signed pivot = (maximumHeight - child.height) * settings.alignment;
|
||||
Geometry childGeometry = {geometry.x(), geometry.y() + pivot, child.width, child.height};
|
||||
float pivot = (maximumHeight - child.height()) * settings.alignment;
|
||||
Geometry childGeometry = {geometry.x(), geometry.y() + pivot, child.width(), child.height()};
|
||||
if(childGeometry.width() < 1) childGeometry.setWidth (1);
|
||||
if(childGeometry.height() < 1) childGeometry.setHeight(1);
|
||||
sizable(n)->setGeometry(childGeometry);
|
||||
|
||||
geometry.setX (geometry.x() + child.width + child.spacing);
|
||||
geometry.setWidth(geometry.width() - child.width + child.spacing);
|
||||
geometry.setX (geometry.x() + child.width() + child.spacing());
|
||||
geometry.setWidth(geometry.width() - child.width() + child.spacing());
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto mHorizontalLayout::setMargin(signed margin) -> type& {
|
||||
auto mHorizontalLayout::setMargin(float margin) -> type& {
|
||||
settings.margin = margin;
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto mHorizontalLayout::setSpacing(signed spacing) -> type& {
|
||||
auto mHorizontalLayout::setSpacing(float spacing) -> type& {
|
||||
settings.spacing = spacing;
|
||||
return *this;
|
||||
}
|
||||
|
@@ -5,29 +5,31 @@ struct mHorizontalLayout : mLayout {
|
||||
using mLayout::append;
|
||||
using mLayout::remove;
|
||||
|
||||
auto append(sSizable sizable, Size size, signed spacing = 5) -> type&;
|
||||
auto append(sSizable sizable, Size size, float spacing = 5) -> type&;
|
||||
auto minimumSize() const -> Size override;
|
||||
auto modify(sSizable sizable, Size size, signed spacing = 5) -> type&;
|
||||
auto modify(sSizable sizable, Size size, float spacing = 5) -> type&;
|
||||
auto remove(sSizable sizable) -> type& override;
|
||||
auto reset() -> type& override;
|
||||
auto setAlignment(double alignment = 0.5) -> type&;
|
||||
auto setAlignment(float alignment = 0.5) -> type&;
|
||||
auto setEnabled(bool enabled = true) -> type& override;
|
||||
auto setFont(const Font& font = {}) -> type& override;
|
||||
auto setGeometry(Geometry geometry) -> type& override;
|
||||
auto setMargin(signed margin = 0) -> type&;
|
||||
auto setSpacing(signed spacing = 5) -> type&;
|
||||
auto setMargin(float margin = 0) -> type&;
|
||||
auto setSpacing(float spacing = 5) -> type&;
|
||||
auto setVisible(bool visible = true) -> type&;
|
||||
|
||||
struct Settings {
|
||||
double alignment = 0.5;
|
||||
signed margin = 0;
|
||||
signed spacing = 5;
|
||||
float alignment = 0.5;
|
||||
float margin = 0;
|
||||
float spacing = 5;
|
||||
} settings;
|
||||
|
||||
struct Property {
|
||||
signed width;
|
||||
signed height;
|
||||
signed spacing;
|
||||
struct Property : Size {
|
||||
Property() = default;
|
||||
Property(float width, float height, float spacing) : Size(width, height), _spacing(spacing) {}
|
||||
auto setSpacing(float spacing) -> Property& { return _spacing = spacing, *this; }
|
||||
auto spacing() const -> float { return _spacing; }
|
||||
float _spacing = 0;
|
||||
};
|
||||
vector<Property> properties;
|
||||
};
|
||||
|
@@ -1,41 +1,41 @@
|
||||
#if defined(Hiro_VerticalLayout)
|
||||
|
||||
auto mVerticalLayout::append(sSizable sizable, Size size, signed spacing) -> type& {
|
||||
auto mVerticalLayout::append(sSizable sizable, Size size, float spacing) -> type& {
|
||||
properties.append({size.width(), size.height(), spacing < 0 ? settings.spacing : spacing});
|
||||
mLayout::append(sizable);
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto mVerticalLayout::modify(sSizable sizable, Size size, signed spacing) -> type& {
|
||||
auto mVerticalLayout::modify(sSizable sizable, Size size, float spacing) -> type& {
|
||||
if(sizable && this->sizable(sizable->offset()) == sizable) {
|
||||
auto& properties = this->properties[sizable->offset()];
|
||||
properties.width = size.width();
|
||||
properties.height = size.height();
|
||||
properties.spacing = spacing;
|
||||
properties.setWidth(size.width());
|
||||
properties.setHeight(size.height());
|
||||
properties.setSpacing(spacing);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto mVerticalLayout::minimumSize() const -> Size {
|
||||
signed width = 0, height = 0;
|
||||
float width = 0, height = 0;
|
||||
|
||||
for(auto n : range(sizableCount())) {
|
||||
auto& child = properties[sizable(n)->offset()];
|
||||
if(child.width == Size::Minimum || child.width == Size::Maximum) {
|
||||
if(child.width() == Size::Minimum || child.width() == Size::Maximum) {
|
||||
width = max(width, sizable(n)->minimumSize().width());
|
||||
continue;
|
||||
}
|
||||
width = max(width, child.width);
|
||||
width = max(width, child.width());
|
||||
}
|
||||
|
||||
for(auto n : range(sizableCount())) {
|
||||
auto& child = properties[sizable(n)->offset()];
|
||||
if(child.height == Size::Minimum || child.height == Size::Maximum) {
|
||||
if(child.height() == Size::Minimum || child.height() == Size::Maximum) {
|
||||
height += sizable(n)->minimumSize().height();
|
||||
} else {
|
||||
height += child.height;
|
||||
height += child.height();
|
||||
}
|
||||
if(&child != &properties.right()) height += child.spacing;
|
||||
if(&child != &properties.right()) height += child.spacing();
|
||||
}
|
||||
|
||||
return {settings.margin * 2 + width, settings.margin * 2 + height};
|
||||
@@ -53,7 +53,7 @@ auto mVerticalLayout::reset() -> type& {
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto mVerticalLayout::setAlignment(double alignment) -> type& {
|
||||
auto mVerticalLayout::setAlignment(float alignment) -> type& {
|
||||
settings.alignment = max(0.0, min(1.0, alignment));
|
||||
return *this;
|
||||
}
|
||||
@@ -80,8 +80,8 @@ auto mVerticalLayout::setGeometry(Geometry containerGeometry) -> type& {
|
||||
auto properties = this->properties;
|
||||
for(auto n : range(sizableCount())) {
|
||||
auto& child = properties[sizable(n)->offset()];
|
||||
if(child.width == Size::Minimum) child.width = sizable(n)->minimumSize().width();
|
||||
if(child.height == Size::Minimum) child.height = sizable(n)->minimumSize().height();
|
||||
if(child.width() == Size::Minimum) child.setWidth(sizable(n)->minimumSize().width());
|
||||
if(child.height() == Size::Minimum) child.setHeight(sizable(n)->minimumSize().height());
|
||||
}
|
||||
|
||||
Geometry geometry = containerGeometry;
|
||||
@@ -90,42 +90,42 @@ auto mVerticalLayout::setGeometry(Geometry containerGeometry) -> type& {
|
||||
geometry.setWidth (geometry.width() - settings.margin * 2);
|
||||
geometry.setHeight(geometry.height() - settings.margin * 2);
|
||||
|
||||
signed minimumHeight = 0, maximumHeightCounter = 0;
|
||||
float minimumHeight = 0, maximumHeightCounter = 0;
|
||||
for(auto& child : properties) {
|
||||
if(child.height == Size::Maximum) maximumHeightCounter++;
|
||||
if(child.height != Size::Maximum) minimumHeight += child.height;
|
||||
if(&child != &properties.right()) minimumHeight += child.spacing;
|
||||
if(child.height() == Size::Maximum) maximumHeightCounter++;
|
||||
if(child.height() != Size::Maximum) minimumHeight += child.height();
|
||||
if(&child != &properties.right()) minimumHeight += child.spacing();
|
||||
}
|
||||
|
||||
for(auto& child : properties) {
|
||||
if(child.width == Size::Maximum) child.width = geometry.width();
|
||||
if(child.height == Size::Maximum) child.height = (geometry.height() - minimumHeight) / maximumHeightCounter;
|
||||
if(child.width() == Size::Maximum) child.setWidth(geometry.width());
|
||||
if(child.height() == Size::Maximum) child.setHeight((geometry.height() - minimumHeight) / maximumHeightCounter);
|
||||
}
|
||||
|
||||
signed maximumWidth = 0;
|
||||
for(auto& child : properties) maximumWidth = max(maximumWidth, child.width);
|
||||
float maximumWidth = 0;
|
||||
for(auto& child : properties) maximumWidth = max(maximumWidth, child.width());
|
||||
|
||||
for(auto n : range(sizableCount())) {
|
||||
auto& child = properties[sizable(n)->offset()];
|
||||
signed pivot = (maximumWidth - child.width) * settings.alignment;
|
||||
Geometry childGeometry = {geometry.x() + pivot, geometry.y(), child.width, child.height};
|
||||
float pivot = (maximumWidth - child.width()) * settings.alignment;
|
||||
Geometry childGeometry = {geometry.x() + pivot, geometry.y(), child.width(), child.height()};
|
||||
if(childGeometry.width() < 1) childGeometry.setWidth (1);
|
||||
if(childGeometry.height() < 1) childGeometry.setHeight(1);
|
||||
sizable(n)->setGeometry(childGeometry);
|
||||
|
||||
geometry.setY (geometry.y() + child.height + child.spacing);
|
||||
geometry.setHeight(geometry.height() - child.height + child.spacing);
|
||||
geometry.setY (geometry.y() + child.height() + child.spacing());
|
||||
geometry.setHeight(geometry.height() - child.height() + child.spacing());
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto mVerticalLayout::setMargin(signed margin) -> type& {
|
||||
auto mVerticalLayout::setMargin(float margin) -> type& {
|
||||
settings.margin = margin;
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto mVerticalLayout::setSpacing(signed spacing) -> type& {
|
||||
auto mVerticalLayout::setSpacing(float spacing) -> type& {
|
||||
settings.spacing = spacing;
|
||||
return *this;
|
||||
}
|
||||
|
@@ -5,31 +5,33 @@ struct mVerticalLayout : mLayout {
|
||||
using mLayout::append;
|
||||
using mLayout::remove;
|
||||
|
||||
auto append(sSizable sizable, Size size, signed spacing = 5) -> type&;
|
||||
auto modify(sSizable sizable, Size size, signed spacing = 5) -> type&;
|
||||
auto append(sSizable sizable, Size size, float spacing = 5) -> type&;
|
||||
auto modify(sSizable sizable, Size size, float spacing = 5) -> type&;
|
||||
auto minimumSize() const -> Size override;
|
||||
auto remove(sSizable sizable) -> type& override;
|
||||
auto reset() -> type& override;
|
||||
auto setAlignment(double alignment = 0.0) -> type&;
|
||||
auto setAlignment(float alignment = 0.0) -> type&;
|
||||
auto setEnabled(bool enabled = true) -> type& override;
|
||||
auto setFont(const Font& font = {}) -> type& override;
|
||||
auto setGeometry(Geometry geometry) -> type& override;
|
||||
auto setMargin(signed margin = 0) -> type&;
|
||||
auto setSpacing(signed spacing = 5) -> type&;
|
||||
auto setMargin(float margin = 0) -> type&;
|
||||
auto setSpacing(float spacing = 5) -> type&;
|
||||
auto setVisible(bool visible = true) -> type& override;
|
||||
|
||||
struct Settings {
|
||||
double alignment = 0.0;
|
||||
signed margin = 0;
|
||||
signed spacing = 5;
|
||||
float alignment = 0.0;
|
||||
float margin = 0;
|
||||
float spacing = 5;
|
||||
} settings;
|
||||
|
||||
struct Properties {
|
||||
signed width;
|
||||
signed height;
|
||||
signed spacing;
|
||||
struct Property : Size {
|
||||
Property() = default;
|
||||
Property(float width, float height, float spacing) : Size(width, height), _spacing(spacing) {}
|
||||
auto setSpacing(float spacing) -> Property& { return _spacing = spacing, *this; }
|
||||
auto spacing() const -> float { return _spacing; }
|
||||
float _spacing = 0;
|
||||
};
|
||||
vector<Properties> properties;
|
||||
vector<Property> properties;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user