mirror of
https://github.com/geode-sdk/geode.git
synced 2024-11-23 16:07:52 -05:00
Merge branch 'better-layouts' of https://github.com/geode-sdk/geode into better-layouts
This commit is contained in:
commit
8fb118fb12
9 changed files with 218 additions and 102 deletions
|
@ -15,14 +15,32 @@ string(STRIP "${GEODE_VERSION}" GEODE_VERSION)
|
||||||
|
|
||||||
# Check if version has a tag like v1.0.0-alpha
|
# Check if version has a tag like v1.0.0-alpha
|
||||||
string(FIND ${GEODE_VERSION} "-" GEODE_VERSION_HAS_TAG)
|
string(FIND ${GEODE_VERSION} "-" GEODE_VERSION_HAS_TAG)
|
||||||
if (GEODE_VERSION_HAS_TAG)
|
if (NOT ${GEODE_VERSION_HAS_TAG} EQUAL "-1")
|
||||||
string(REGEX MATCH "[a-z]+[0-9]?$" GEODE_VERSION_TAG ${GEODE_VERSION})
|
string(REGEX MATCH "[a-z]+(\.[0-9]+)?$" GEODE_VERSION_TAG ${GEODE_VERSION})
|
||||||
string(SUBSTRING "${GEODE_VERSION}" 0 ${GEODE_VERSION_HAS_TAG} GEODE_VERSION)
|
string(SUBSTRING "${GEODE_VERSION}" 0 ${GEODE_VERSION_HAS_TAG} GEODE_VERSION)
|
||||||
|
string(FIND ${GEODE_VERSION_TAG} "." GEODE_VERSION_TAG_HAS_NUMBER)
|
||||||
|
|
||||||
|
# Extract tag type and number from tag
|
||||||
|
if (NOT ${GEODE_VERSION_TAG_HAS_NUMBER} EQUAL "-1")
|
||||||
|
string(SUBSTRING "${GEODE_VERSION_TAG}" 0 ${GEODE_VERSION_TAG_HAS_NUMBER} GEODE_VERSION_TAG_TYPE)
|
||||||
|
math(EXPR GEODE_VERSION_TAG_HAS_NUMBER "${GEODE_VERSION_TAG_HAS_NUMBER} + 1")
|
||||||
|
string(SUBSTRING "${GEODE_VERSION_TAG}" ${GEODE_VERSION_TAG_HAS_NUMBER} -1 GEODE_VERSION_TAG_NUMBER)
|
||||||
else()
|
else()
|
||||||
set(GEODE_VERSION_TAG "")
|
set(GEODE_VERSION_TAG_TYPE "${GEODE_VERSION_TAG}")
|
||||||
|
set(GEODE_VERSION_TAG_NUMBER "")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
message(STATUS "Version: ${GEODE_VERSION}, tag: ${GEODE_VERSION_TAG}")
|
# Capitalize first letter of tag type
|
||||||
|
string(SUBSTRING ${GEODE_VERSION_TAG_TYPE} 0 1 FIRST_LETTER)
|
||||||
|
string(TOUPPER ${FIRST_LETTER} FIRST_LETTER)
|
||||||
|
string(REGEX REPLACE "^.(.*)" "${FIRST_LETTER}\\1" GEODE_VERSION_TAG_TYPE "${GEODE_VERSION_TAG_TYPE}")
|
||||||
|
else()
|
||||||
|
set(GEODE_VERSION_TAG "")
|
||||||
|
set(GEODE_VERSION_TAG_TYPE "")
|
||||||
|
set(GEODE_VERSION_TAG_NUMBER "")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
message(STATUS "Version: ${GEODE_VERSION}, tag: ${GEODE_VERSION_TAG} (type: ${GEODE_VERSION_TAG_TYPE}, number: ${GEODE_VERSION_TAG_NUMBER})")
|
||||||
|
|
||||||
project(geode-sdk VERSION ${GEODE_VERSION} LANGUAGES CXX C)
|
project(geode-sdk VERSION ${GEODE_VERSION} LANGUAGES CXX C)
|
||||||
|
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
1.0.0-beta
|
1.0.0-beta.6
|
|
@ -1,8 +1,21 @@
|
||||||
cmake_minimum_required(VERSION 3.21 FATAL_ERROR)
|
cmake_minimum_required(VERSION 3.21 FATAL_ERROR)
|
||||||
|
|
||||||
project(geode-loader VERSION ${GEODE_VERSION} LANGUAGES C CXX)
|
project(geode-loader VERSION ${GEODE_VERSION} LANGUAGES C CXX)
|
||||||
set(PROJECT_VERSION_TYPE geode::VersionTag::Beta)
|
if (GEODE_VERSION_TAG_TYPE)
|
||||||
set(PROJECT_VERSION_SUFFIX -beta)
|
if (GEODE_VERSION_TAG_NUMBER)
|
||||||
|
set(PROJECT_VERSION_TAG_CONSTR "geode::VersionTag(geode::VersionTag::${GEODE_VERSION_TAG_TYPE}, ${GEODE_VERSION_TAG_NUMBER})")
|
||||||
|
else()
|
||||||
|
set(PROJECT_VERSION_TAG_CONSTR "geode::VersionTag::${GEODE_VERSION_TAG_TYPE}")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
set(PROJECT_VERSION_TAG_CONSTR "std::nullopt")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (GEODE_VERSION_TAG)
|
||||||
|
set(PROJECT_VERSION_SUFFIX "-${GEODE_VERSION_TAG}")
|
||||||
|
else()
|
||||||
|
set(PROJECT_VERSION_SUFFIX "")
|
||||||
|
endif()
|
||||||
|
|
||||||
# Package info file for internal representation
|
# Package info file for internal representation
|
||||||
configure_file(resources/mod.json.in ${CMAKE_CURRENT_SOURCE_DIR}/resources/mod.json)
|
configure_file(resources/mod.json.in ${CMAKE_CURRENT_SOURCE_DIR}/resources/mod.json)
|
||||||
|
|
|
@ -14,24 +14,73 @@ namespace geode {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A version label, like v1.0.0-alpha or v2.3.4-prerelease. Purely semantic,
|
* A version label, like v1.0.0-alpha or v2.3.4-prerelease. Limited to these
|
||||||
* and not used in comparisons; so for example v1.0.0-alpha == v1.0.0.
|
* options; arbitary identifiers are not supported. Additional numbering
|
||||||
|
* may be added after the identifier, such as v1.0.0-beta.1
|
||||||
*/
|
*/
|
||||||
enum class VersionTag {
|
struct VersionTag {
|
||||||
|
enum {
|
||||||
Alpha,
|
Alpha,
|
||||||
Beta,
|
Beta,
|
||||||
Prerelease,
|
Prerelease,
|
||||||
|
} value;
|
||||||
|
std::optional<size_t> number;
|
||||||
|
|
||||||
|
using Type = decltype(value);
|
||||||
|
|
||||||
|
constexpr VersionTag(Type const& value) : value(value) {}
|
||||||
|
constexpr VersionTag(Type const& value, std::optional<size_t> number)
|
||||||
|
: value(value), number(number) {}
|
||||||
|
|
||||||
|
constexpr bool operator==(VersionTag const& other) const {
|
||||||
|
return value == other.value && number == other.number;
|
||||||
|
}
|
||||||
|
constexpr bool operator<(VersionTag const& other) const {
|
||||||
|
if (value == other.value) {
|
||||||
|
if (number && other.number) return number < other.number;
|
||||||
|
if (number) return true;
|
||||||
|
if (other.number) return false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return value < other.value;
|
||||||
|
}
|
||||||
|
constexpr bool operator<=(VersionTag const& other) const {
|
||||||
|
if (value == other.value) {
|
||||||
|
if (number && other.number) return number <= other.number;
|
||||||
|
if (number) return true;
|
||||||
|
if (other.number) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return value <= other.value;
|
||||||
|
}
|
||||||
|
constexpr bool operator>(VersionTag const& other) const {
|
||||||
|
if (value == other.value) {
|
||||||
|
if (number && other.number) return number > other.number;
|
||||||
|
if (number) return true;
|
||||||
|
if (other.number) return false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return value > other.value;
|
||||||
|
}
|
||||||
|
constexpr bool operator>=(VersionTag const& other) const {
|
||||||
|
if (value == other.value) {
|
||||||
|
if (number && other.number) return number >= other.number;
|
||||||
|
if (number) return true;
|
||||||
|
if (other.number) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return value >= other.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Result<VersionTag> parse(std::stringstream& str);
|
||||||
|
std::string toSuffixString() const;
|
||||||
|
std::string toString() const;
|
||||||
};
|
};
|
||||||
GEODE_DLL std::optional<VersionTag> versionTagFromString(std::string const& str);
|
|
||||||
GEODE_DLL std::string versionTagToSuffixString(VersionTag tag);
|
|
||||||
GEODE_DLL std::string versionTagToString(VersionTag tag);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class representing version information. Not strictly semver, notably in
|
* Class representing version information. Uses a limited subset of SemVer;
|
||||||
* regard to identifiers; identifiers are restricted to a few common ones,
|
* identifiers are restricted to a few predefined ones, and only one
|
||||||
* and are purely semantic, i.e. not used in comparisons. See VersionTag
|
* identifier is allowed. See VersionTag for details
|
||||||
* for details
|
|
||||||
* @class VersionInfo
|
|
||||||
*/
|
*/
|
||||||
class GEODE_DLL VersionInfo final {
|
class GEODE_DLL VersionInfo final {
|
||||||
protected:
|
protected:
|
||||||
|
@ -78,24 +127,24 @@ namespace geode {
|
||||||
// Apple clang does not support operator<=>! Yippee!
|
// Apple clang does not support operator<=>! Yippee!
|
||||||
|
|
||||||
constexpr bool operator==(VersionInfo const& other) const {
|
constexpr bool operator==(VersionInfo const& other) const {
|
||||||
return std::tie(m_major, m_minor, m_patch) ==
|
return std::tie(m_major, m_minor, m_patch, m_tag) ==
|
||||||
std::tie(other.m_major, other.m_minor, other.m_patch);
|
std::tie(other.m_major, other.m_minor, other.m_patch, other.m_tag);
|
||||||
}
|
}
|
||||||
constexpr bool operator<(VersionInfo const& other) const {
|
constexpr bool operator<(VersionInfo const& other) const {
|
||||||
return std::tie(m_major, m_minor, m_patch) <
|
return std::tie(m_major, m_minor, m_patch, m_tag) <
|
||||||
std::tie(other.m_major, other.m_minor, other.m_patch);
|
std::tie(other.m_major, other.m_minor, other.m_patch, other.m_tag);
|
||||||
}
|
}
|
||||||
constexpr bool operator<=(VersionInfo const& other) const {
|
constexpr bool operator<=(VersionInfo const& other) const {
|
||||||
return std::tie(m_major, m_minor, m_patch) <=
|
return std::tie(m_major, m_minor, m_patch, m_tag) <=
|
||||||
std::tie(other.m_major, other.m_minor, other.m_patch);
|
std::tie(other.m_major, other.m_minor, other.m_patch, other.m_tag);
|
||||||
}
|
}
|
||||||
constexpr bool operator>(VersionInfo const& other) const {
|
constexpr bool operator>(VersionInfo const& other) const {
|
||||||
return std::tie(m_major, m_minor, m_patch) >
|
return std::tie(m_major, m_minor, m_patch, m_tag) >
|
||||||
std::tie(other.m_major, other.m_minor, other.m_patch);
|
std::tie(other.m_major, other.m_minor, other.m_patch, other.m_tag);
|
||||||
}
|
}
|
||||||
constexpr bool operator>=(VersionInfo const& other) const {
|
constexpr bool operator>=(VersionInfo const& other) const {
|
||||||
return std::tie(m_major, m_minor, m_patch) >=
|
return std::tie(m_major, m_minor, m_patch, m_tag) >=
|
||||||
std::tie(other.m_major, other.m_minor, other.m_patch);
|
std::tie(other.m_major, other.m_minor, other.m_patch, other.m_tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string toString(bool includeTag = true) const;
|
std::string toString(bool includeTag = true) const;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"geode": "@PROJECT_VERSION@",
|
"geode": "@PROJECT_VERSION@@PROJECT_VERSION_SUFFIX@",
|
||||||
"id": "geode.loader",
|
"id": "geode.loader",
|
||||||
"version": "@PROJECT_VERSION@@PROJECT_VERSION_SUFFIX@",
|
"version": "@PROJECT_VERSION@@PROJECT_VERSION_SUFFIX@",
|
||||||
"name": "Geode",
|
"name": "Geode",
|
||||||
|
|
|
@ -269,8 +269,9 @@ AxisLayout::Row* AxisLayout::fitInRow(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
axisLength += pos.axisLength;
|
axisLength += pos.axisLength;
|
||||||
if (pos.crossLength > crossLength) {
|
// squishing doesn't affect cross length, that's done separately
|
||||||
crossLength = pos.crossLength;
|
if (pos.crossLength / squish > crossLength) {
|
||||||
|
crossLength = pos.crossLength / squish;
|
||||||
}
|
}
|
||||||
prev = opts;
|
prev = opts;
|
||||||
ix++;
|
ix++;
|
||||||
|
@ -303,7 +304,7 @@ AxisLayout::Row* AxisLayout::fitInRow(
|
||||||
available.axisLength / nextAxisLength * scale * squish,
|
available.axisLength / nextAxisLength * scale * squish,
|
||||||
// how much should the nodes be squished to fit the next item in this
|
// how much should the nodes be squished to fit the next item in this
|
||||||
// row
|
// row
|
||||||
available.axisLength / nextAxisLength * scale * squish,
|
available.axisLength / nextAxisLength,
|
||||||
axisLength,
|
axisLength,
|
||||||
crossLength,
|
crossLength,
|
||||||
axisEndsLength,
|
axisEndsLength,
|
||||||
|
@ -322,6 +323,8 @@ void AxisLayout::tryFitLayout(
|
||||||
// like i genuinely have no clue fr why some of these work tho,
|
// like i genuinely have no clue fr why some of these work tho,
|
||||||
// i just threw in random equations and numbers until it worked
|
// i just threw in random equations and numbers until it worked
|
||||||
|
|
||||||
|
log::debug("tryFitLayout -> scale: {}, squish: {}, prio: {}", scale, squish, prio);
|
||||||
|
|
||||||
auto rows = CCArray::create();
|
auto rows = CCArray::create();
|
||||||
float totalRowCrossLength = 0.f;
|
float totalRowCrossLength = 0.f;
|
||||||
float crossScaleDownFactor = 0.f;
|
float crossScaleDownFactor = 0.f;
|
||||||
|
@ -358,16 +361,32 @@ void AxisLayout::tryFitLayout(
|
||||||
}
|
}
|
||||||
newNodes->release();
|
newNodes->release();
|
||||||
|
|
||||||
|
if (!rows->count()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
log::debug("crossScaleDownFactor: {}, crossSquishFactor: {}", crossScaleDownFactor, crossSquishFactor);
|
||||||
|
|
||||||
auto available = nodeAxis(on, m_axis, 1.f);
|
auto available = nodeAxis(on, m_axis, 1.f);
|
||||||
|
|
||||||
|
if (available.axisLength <= 0.f || available.crossLength <= 0.f) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// if cross axis overflow not allowed and it's overflowing, try to scale
|
// if cross axis overflow not allowed and it's overflowing, try to scale
|
||||||
// down layout if there are any nodes with auto-scale enabled (or
|
// down layout if there are any nodes with auto-scale enabled (or
|
||||||
// auto-scale is enabled by default)
|
// auto-scale is enabled by default)
|
||||||
if (
|
if (
|
||||||
|
(
|
||||||
!m_allowCrossAxisOverflow &&
|
!m_allowCrossAxisOverflow &&
|
||||||
doAutoScale &&
|
doAutoScale &&
|
||||||
totalRowCrossLength > available.crossLength
|
totalRowCrossLength > available.crossLength
|
||||||
|
) || (
|
||||||
|
!m_growCrossAxis &&
|
||||||
|
static_cast<Row*>(rows->firstObject())->axisLength > available.axisLength
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
|
log::debug("scaling");
|
||||||
bool attemptRescale = false;
|
bool attemptRescale = false;
|
||||||
auto minScaleForPrio = this->minScaleForPrio(nodes, prio);
|
auto minScaleForPrio = this->minScaleForPrio(nodes, prio);
|
||||||
if (
|
if (
|
||||||
|
@ -379,7 +398,9 @@ void AxisLayout::tryFitLayout(
|
||||||
crossScaleDownFactor == scale
|
crossScaleDownFactor == scale
|
||||||
) {
|
) {
|
||||||
// is there still some lower priority nodes we could try scaling?
|
// is there still some lower priority nodes we could try scaling?
|
||||||
|
log::debug("prio: {} :: scale: {}", prio, scale);
|
||||||
if (prio > minMaxPrios.first) {
|
if (prio > minMaxPrios.first) {
|
||||||
|
log::debug("scale to max");
|
||||||
while (true) {
|
while (true) {
|
||||||
prio -= 1;
|
prio -= 1;
|
||||||
auto scale = this->maxScaleForPrio(nodes, prio);
|
auto scale = this->maxScaleForPrio(nodes, prio);
|
||||||
|
@ -391,13 +412,17 @@ void AxisLayout::tryFitLayout(
|
||||||
}
|
}
|
||||||
attemptRescale = true;
|
attemptRescale = true;
|
||||||
}
|
}
|
||||||
// otherwise we're just gonna squish
|
// otherwise set scale to min and squish
|
||||||
|
else {
|
||||||
|
scale = minScaleForPrio;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// otherwise scale as usual
|
// otherwise scale as usual
|
||||||
else {
|
else {
|
||||||
attemptRescale = true;
|
attemptRescale = true;
|
||||||
}
|
}
|
||||||
if (attemptRescale) {
|
if (attemptRescale) {
|
||||||
|
log::debug("gonna try with scale {} from {}", crossScaleDownFactor, scale);
|
||||||
rows->release();
|
rows->release();
|
||||||
return this->tryFitLayout(
|
return this->tryFitLayout(
|
||||||
on, nodes,
|
on, nodes,
|
||||||
|
@ -408,10 +433,21 @@ void AxisLayout::tryFitLayout(
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we're still overflowing, squeeze nodes closer together
|
// if we're still overflowing, squeeze nodes closer together
|
||||||
if (!m_allowCrossAxisOverflow && totalRowCrossLength > available.crossLength) {
|
if (
|
||||||
|
(
|
||||||
|
!m_allowCrossAxisOverflow &&
|
||||||
|
totalRowCrossLength > available.crossLength
|
||||||
|
) || (
|
||||||
|
!m_growCrossAxis &&
|
||||||
|
static_cast<Row*>(rows->firstObject())->axisLength > available.axisLength
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
log::debug("gonna try with squish {} from {}", crossSquishFactor, squish);
|
||||||
// if squishing rows would take less squishing that squishing columns,
|
// if squishing rows would take less squishing that squishing columns,
|
||||||
// then squish rows
|
// then squish rows
|
||||||
if (totalRowCrossLength / available.crossLength < crossSquishFactor) {
|
if (
|
||||||
|
!m_growCrossAxis || totalRowCrossLength / available.crossLength < crossSquishFactor
|
||||||
|
) {
|
||||||
rows->release();
|
rows->release();
|
||||||
return this->tryFitLayout(
|
return this->tryFitLayout(
|
||||||
on, nodes,
|
on, nodes,
|
||||||
|
@ -489,25 +525,6 @@ void AxisLayout::tryFitLayout(
|
||||||
rowCrossPos -= row->crossLength * columnSquish;
|
rowCrossPos -= row->crossLength * columnSquish;
|
||||||
}
|
}
|
||||||
|
|
||||||
// scale down & squish row if it overflows main axis
|
|
||||||
float rowScale = scale;
|
|
||||||
float rowSquish = squish;
|
|
||||||
if (row->axisLength > available.axisLength) {
|
|
||||||
row->axisLength /= scale * squish;
|
|
||||||
if (m_autoScale) {
|
|
||||||
rowScale = available.axisLength / row->axisLength;
|
|
||||||
if (rowScale < AXISLAYOUT_DEFAULT_MIN_SCALE) {
|
|
||||||
rowScale = AXISLAYOUT_DEFAULT_MIN_SCALE;
|
|
||||||
}
|
|
||||||
row->axisLength *= rowScale;
|
|
||||||
}
|
|
||||||
// squishing needs to take into account the row ends
|
|
||||||
if (row->axisLength > available.axisLength) {
|
|
||||||
rowSquish = available.axisLength / row->axisLength;
|
|
||||||
}
|
|
||||||
row->axisLength *= rowSquish;
|
|
||||||
}
|
|
||||||
|
|
||||||
float rowAxisPos;
|
float rowAxisPos;
|
||||||
switch (m_axisAlignment) {
|
switch (m_axisAlignment) {
|
||||||
case AxisAlignment::Start: {
|
case AxisAlignment::Start: {
|
||||||
|
@ -532,34 +549,33 @@ void AxisLayout::tryFitLayout(
|
||||||
size_t ix = 0;
|
size_t ix = 0;
|
||||||
AxisLayoutOptions const* prev = nullptr;
|
AxisLayoutOptions const* prev = nullptr;
|
||||||
for (auto& node : CCArrayExt<CCNode*>(row->nodes)) {
|
for (auto& node : CCArrayExt<CCNode*>(row->nodes)) {
|
||||||
auto scale = rowScale;
|
|
||||||
auto opts = axisOpts(node);
|
auto opts = axisOpts(node);
|
||||||
// rescale node if overflowing
|
// rescale node if overflowing
|
||||||
if (this->shouldAutoScale(opts)) {
|
if (this->shouldAutoScale(opts)) {
|
||||||
scale = scaleByOpts(opts, scale, prio);
|
auto nodeScale = scaleByOpts(opts, scale, prio);
|
||||||
// CCMenuItemSpriteExtra is quirky af
|
// CCMenuItemSpriteExtra is quirky af
|
||||||
if (auto btn = typeinfo_cast<CCMenuItemSpriteExtra*>(node)) {
|
if (auto btn = typeinfo_cast<CCMenuItemSpriteExtra*>(node)) {
|
||||||
btn->m_baseScale = scale;
|
btn->m_baseScale = nodeScale;
|
||||||
}
|
}
|
||||||
node->setScale(scale);
|
node->setScale(nodeScale);
|
||||||
}
|
}
|
||||||
if (!ix) {
|
if (!ix) {
|
||||||
rowAxisPos += row->axisEndsLength * scale / 2 * (1.f - rowSquish);
|
rowAxisPos += row->axisEndsLength * scale / 2 * (1.f - squish);
|
||||||
}
|
}
|
||||||
auto pos = nodeAxis(node, m_axis, rowSquish);
|
auto pos = nodeAxis(node, m_axis, squish);
|
||||||
float axisPos;
|
float axisPos;
|
||||||
if (m_axisAlignment == AxisAlignment::Even) {
|
if (m_axisAlignment == AxisAlignment::Even) {
|
||||||
axisPos = rowAxisPos + evenSpace / 2 - pos.axisLength * (.5f - pos.axisAnchor);
|
axisPos = rowAxisPos + evenSpace / 2 - pos.axisLength * (.5f - pos.axisAnchor);
|
||||||
rowAxisPos += evenSpace -
|
rowAxisPos += evenSpace -
|
||||||
row->axisEndsLength * scale * (1.f - rowSquish) * 1.f / nodes->count();
|
row->axisEndsLength * scale * (1.f - squish) * 1.f / nodes->count();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (ix) {
|
if (ix) {
|
||||||
rowAxisPos += this->nextGap(prev, opts) * scale * rowSquish;
|
rowAxisPos += this->nextGap(prev, opts) * scale * squish;
|
||||||
}
|
}
|
||||||
axisPos = rowAxisPos + pos.axisLength * pos.axisAnchor;
|
axisPos = rowAxisPos + pos.axisLength * pos.axisAnchor;
|
||||||
rowAxisPos += pos.axisLength -
|
rowAxisPos += pos.axisLength -
|
||||||
row->axisEndsLength * scale * (1.f - rowSquish) * 1.f / nodes->count();
|
row->axisEndsLength * scale * (1.f - squish) * 1.f / nodes->count();
|
||||||
}
|
}
|
||||||
float crossOffset;
|
float crossOffset;
|
||||||
switch (m_crossAlignment) {
|
switch (m_crossAlignment) {
|
||||||
|
@ -634,6 +650,7 @@ void AxisLayout::apply(CCNode* on) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log::debug("applying");
|
||||||
this->tryFitLayout(
|
this->tryFitLayout(
|
||||||
on, nodes,
|
on, nodes,
|
||||||
minMaxPrio, doAutoScale,
|
minMaxPrio, doAutoScale,
|
||||||
|
|
|
@ -11,6 +11,6 @@ static constexpr geode::VersionInfo LOADER_VERSION = {
|
||||||
@PROJECT_VERSION_MAJOR@,
|
@PROJECT_VERSION_MAJOR@,
|
||||||
@PROJECT_VERSION_MINOR@,
|
@PROJECT_VERSION_MINOR@,
|
||||||
@PROJECT_VERSION_PATCH@,
|
@PROJECT_VERSION_PATCH@,
|
||||||
@PROJECT_VERSION_TYPE@,
|
@PROJECT_VERSION_TAG_CONSTR@,
|
||||||
};
|
};
|
||||||
static constexpr const char* LOADER_MOD_JSON = R"JSON_SEPARATOR(@LOADER_MOD_JSON@)JSON_SEPARATOR";
|
static constexpr const char* LOADER_MOD_JSON = R"JSON_SEPARATOR(@LOADER_MOD_JSON@)JSON_SEPARATOR";
|
||||||
|
|
|
@ -79,9 +79,7 @@ void ModListCell::setupInfo(
|
||||||
this->addChild(versionLabel);
|
this->addChild(versionLabel);
|
||||||
|
|
||||||
if (auto tag = info.version().getTag()) {
|
if (auto tag = info.version().getTag()) {
|
||||||
auto tagLabel = TagNode::create(
|
auto tagLabel = TagNode::create(tag.value().toString().c_str());
|
||||||
versionTagToString(tag.value()).c_str()
|
|
||||||
);
|
|
||||||
tagLabel->setAnchorPoint({ .0f, .5f });
|
tagLabel->setAnchorPoint({ .0f, .5f });
|
||||||
tagLabel->setScale(.3f);
|
tagLabel->setScale(.3f);
|
||||||
tagLabel->setPosition(
|
tagLabel->setPosition(
|
||||||
|
|
|
@ -10,31 +10,57 @@ USE_GEODE_NAMESPACE();
|
||||||
|
|
||||||
// VersionTag
|
// VersionTag
|
||||||
|
|
||||||
std::optional<VersionTag> geode::versionTagFromString(std::string const& str) {
|
Result<VersionTag> VersionTag::parse(std::stringstream& str) {
|
||||||
switch (hash(str.c_str())) {
|
std::string iden;
|
||||||
case hash("alpha"): return VersionTag::Alpha;
|
while ('a' <= str.peek() && str.peek() <= 'z') {
|
||||||
case hash("beta"): return VersionTag::Beta;
|
iden += str.get();
|
||||||
case hash("prerelease"): return VersionTag::Prerelease;
|
|
||||||
default: return std::nullopt;
|
|
||||||
}
|
}
|
||||||
|
if (str.fail()) {
|
||||||
|
return Err("Unable to parse tag");
|
||||||
|
}
|
||||||
|
VersionTag tag = VersionTag::Alpha;
|
||||||
|
switch (hash(iden.c_str())) {
|
||||||
|
case hash("alpha"): tag = VersionTag::Alpha; break;
|
||||||
|
case hash("beta"): tag = VersionTag::Beta; break;
|
||||||
|
case hash("prerelease"): case hash("pr"): tag = VersionTag::Prerelease; break;
|
||||||
|
default: return Err("Invalid tag \"" + iden + "\"");
|
||||||
|
}
|
||||||
|
if (str.peek() == '.') {
|
||||||
|
str.get();
|
||||||
|
size_t num;
|
||||||
|
str >> num;
|
||||||
|
if (str.fail()) {
|
||||||
|
return Err("Unable to parse tag number");
|
||||||
|
}
|
||||||
|
tag.number = num;
|
||||||
|
}
|
||||||
|
return Ok(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string geode::versionTagToSuffixString(VersionTag tag) {
|
std::string VersionTag::toSuffixString() const {
|
||||||
switch (tag) {
|
std::string res = "";
|
||||||
case VersionTag::Alpha: return "-alpha";
|
switch (value) {
|
||||||
case VersionTag::Beta: return "-beta";
|
case Alpha: res += "-alpha"; break;
|
||||||
case VersionTag::Prerelease: return "-prerelease";
|
case Beta: res += "-beta"; break;
|
||||||
|
case Prerelease: res += "-prerelease"; break;
|
||||||
}
|
}
|
||||||
return "";
|
if (number) {
|
||||||
|
res += "." + std::to_string(number.value());
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string geode::versionTagToString(VersionTag tag) {
|
std::string VersionTag::toString() const {
|
||||||
switch (tag) {
|
std::string res = "";
|
||||||
case VersionTag::Alpha: return "Alpha";
|
switch (value) {
|
||||||
case VersionTag::Beta: return "Beta";
|
case Alpha: res += "Alpha"; break;
|
||||||
case VersionTag::Prerelease: return "Prerelease";
|
case Beta: res += "Beta"; break;
|
||||||
|
case Prerelease: res += "Prerelease"; break;
|
||||||
}
|
}
|
||||||
return "";
|
if (number) {
|
||||||
|
res += " " + std::to_string(number.value());
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// VersionInfo
|
// VersionInfo
|
||||||
|
@ -77,18 +103,13 @@ Result<VersionInfo> VersionInfo::parse(std::string const& string) {
|
||||||
std::optional<VersionTag> tag;
|
std::optional<VersionTag> tag;
|
||||||
if (str.peek() == '-') {
|
if (str.peek() == '-') {
|
||||||
str.get();
|
str.get();
|
||||||
std::string iden;
|
GEODE_UNWRAP_INTO(tag, VersionTag::parse(str));
|
||||||
str >> iden;
|
|
||||||
if (str.fail()) {
|
|
||||||
return Err("Unable to parse tag");
|
|
||||||
}
|
|
||||||
if (auto t = versionTagFromString(iden)) {
|
|
||||||
tag = t;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return Err("Invalid tag \"" + iden + "\"");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!str.eof()) {
|
||||||
|
return Err("Expected end of version, found '" + std::string(1, str.get()) + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(VersionInfo(major, minor, patch, tag));
|
return Ok(VersionInfo(major, minor, patch, tag));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +118,7 @@ std::string VersionInfo::toString(bool includeTag) const {
|
||||||
return fmt::format(
|
return fmt::format(
|
||||||
"v{}.{}.{}{}",
|
"v{}.{}.{}{}",
|
||||||
m_major, m_minor, m_patch,
|
m_major, m_minor, m_patch,
|
||||||
versionTagToSuffixString(m_tag.value())
|
m_tag.value().toSuffixString()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return fmt::format("v{}.{}.{}", m_major, m_minor, m_patch);
|
return fmt::format("v{}.{}.{}", m_major, m_minor, m_patch);
|
||||||
|
|
Loading…
Reference in a new issue