mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-24 10:23:02 -07:00
Compare commits
6 commits
e2eb36f19f
...
a571a9aa04
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a571a9aa04 | ||
|
|
648b472bfb | ||
|
|
daa0dcb2ea | ||
|
|
21633eb0ec | ||
|
|
b80e6994ab | ||
|
|
03229db0bd |
8 changed files with 86 additions and 53 deletions
60
.github/workflows/desktop-build.yml
vendored
60
.github/workflows/desktop-build.yml
vendored
|
|
@ -161,14 +161,11 @@ jobs:
|
|||
uses: actions/checkout@v7
|
||||
|
||||
- name: "Restore compiler cache (ccache)"
|
||||
id: ccache_restore
|
||||
id: restore_ccache
|
||||
uses: actions/cache/restore@v6
|
||||
env:
|
||||
BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
|
||||
with:
|
||||
key: ccache-${{ matrix.distro }}${{ matrix.version }}-${{ env.BRANCH_NAME }}
|
||||
key: ccache-${{ matrix.distro }}${{ matrix.version }}
|
||||
path: ${{ env.CACHE }}
|
||||
restore-keys: ccache-${{ matrix.distro }}${{ matrix.version }}-
|
||||
|
||||
- name: "Build ${{ matrix.distro }} ${{ matrix.version }} Docker image"
|
||||
shell: bash
|
||||
|
|
@ -203,10 +200,10 @@ jobs:
|
|||
|
||||
# Delete used cache to emulate a ccache update. See https://github.com/actions/cache/issues/342
|
||||
- name: "Delete remote compiler cache (ccache)"
|
||||
if: github.ref == 'refs/heads/master' && steps.ccache_restore.outputs.cache-hit
|
||||
if: github.ref == 'refs/heads/master' && steps.restore_ccache.outputs.cache-hit
|
||||
continue-on-error: true
|
||||
env:
|
||||
CACHE_PRIMARY_KEY: ${{ steps.ccache_restore.outputs.cache-primary-key }}
|
||||
CACHE_PRIMARY_KEY: ${{ steps.restore_ccache.outputs.cache-primary-key }}
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
if gh cache delete --repo "$GITHUB_REPOSITORY" "$CACHE_PRIMARY_KEY"; then
|
||||
|
|
@ -217,7 +214,7 @@ jobs:
|
|||
if: github.ref == 'refs/heads/master'
|
||||
uses: actions/cache/save@v6
|
||||
with:
|
||||
key: ${{ steps.ccache_restore.outputs.cache-primary-key }}
|
||||
key: ${{ steps.restore_ccache.outputs.cache-primary-key }}
|
||||
path: ${{ env.CACHE }}
|
||||
|
||||
- name: "Upload artifact"
|
||||
|
|
@ -264,13 +261,14 @@ jobs:
|
|||
- os: macOS
|
||||
target: 13 # EOL 2025-09-15
|
||||
runner: macos-15-intel # https://github.com/actions/runner-images/blob/main/images/macos/macos-15-Readme.md
|
||||
# macos-26-intel is very slow and fails in CPack during DMG config if not increasing Finder timeout
|
||||
|
||||
ccache_eviction_age: 7d
|
||||
cmake_generator: Ninja
|
||||
make_package: 1
|
||||
override_target: 13
|
||||
package_suffix: "-macOS13_Intel"
|
||||
qt_version: 6.11.0
|
||||
qt_version: 6.11.1
|
||||
qt_modules: qtimageformats qtmultimedia qtwebsockets
|
||||
soc: Intel
|
||||
type: Release
|
||||
|
|
@ -279,47 +277,48 @@ jobs:
|
|||
|
||||
- os: macOS
|
||||
target: 14 # EOL 2026-??
|
||||
runner: macos-15 # https://github.com/actions/runner-images/blob/main/images/macos/macos-15-arm64-Readme.md
|
||||
runner: macos-26 # https://github.com/actions/runner-images/blob/main/images/macos/macos-26-arm64-Readme.md
|
||||
|
||||
ccache_eviction_age: 7d
|
||||
cmake_generator: Ninja
|
||||
make_package: 1
|
||||
override_target: 14
|
||||
package_suffix: "-macOS14"
|
||||
qt_version: 6.11.0
|
||||
qt_version: 6.11.1
|
||||
qt_modules: qtimageformats qtmultimedia qtwebsockets
|
||||
soc: Apple
|
||||
type: Release
|
||||
use_ccache: 1
|
||||
xcode: "26.3"
|
||||
xcode: "26.6"
|
||||
|
||||
- os: macOS
|
||||
target: 15
|
||||
runner: macos-15 # https://github.com/actions/runner-images/blob/main/images/macos/macos-15-arm64-Readme.md
|
||||
runner: macos-26 # https://github.com/actions/runner-images/blob/main/images/macos/macos-26-arm64-Readme.md
|
||||
|
||||
ccache_eviction_age: 7d
|
||||
cmake_generator: Ninja
|
||||
make_package: 1
|
||||
override_target: 15
|
||||
package_suffix: "-macOS15"
|
||||
qt_version: 6.11.0
|
||||
qt_version: 6.11.1
|
||||
qt_modules: qtimageformats qtmultimedia qtwebsockets
|
||||
soc: Apple
|
||||
type: Release
|
||||
use_ccache: 1
|
||||
xcode: "26.3"
|
||||
xcode: "26.6"
|
||||
|
||||
- os: macOS
|
||||
target: 15
|
||||
runner: macos-15 # https://github.com/actions/runner-images/blob/main/images/macos/macos-15-arm64-Readme.md
|
||||
target: 26
|
||||
runner: macos-26 # https://github.com/actions/runner-images/blob/main/images/macos/macos-26-arm64-Readme.md
|
||||
|
||||
ccache_eviction_age: 7d
|
||||
cmake_generator: Ninja
|
||||
qt_version: 6.11.0
|
||||
qt_version: 6.11.1
|
||||
qt_modules: qtimageformats qtmultimedia qtwebsockets
|
||||
soc: Apple
|
||||
type: Debug
|
||||
use_ccache: 1
|
||||
xcode: "26.3"
|
||||
xcode: "26.6"
|
||||
|
||||
- os: Windows
|
||||
target: 10
|
||||
|
|
@ -329,7 +328,7 @@ jobs:
|
|||
cmake_generator_platform: x64
|
||||
make_package: 1
|
||||
package_suffix: "-Win10"
|
||||
qt_version: 6.11.0
|
||||
qt_version: 6.11.1
|
||||
qt_modules: qtimageformats qtmultimedia qtwebsockets
|
||||
type: Release
|
||||
|
||||
|
|
@ -349,7 +348,6 @@ jobs:
|
|||
|
||||
- name: "[Windows] Add msbuild to PATH"
|
||||
if: matrix.os == 'Windows'
|
||||
id: add-msbuild
|
||||
uses: microsoft/setup-msbuild@v3
|
||||
with:
|
||||
msbuild-architecture: x64
|
||||
|
|
@ -360,14 +358,11 @@ jobs:
|
|||
|
||||
- name: "[macOS] Restore compiler cache (ccache)"
|
||||
if: matrix.os == 'macOS' && matrix.use_ccache == 1
|
||||
id: ccache_restore
|
||||
id: restore_ccache
|
||||
uses: actions/cache/restore@v6
|
||||
env:
|
||||
BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
|
||||
with:
|
||||
key: ccache-${{ matrix.runner }}-${{ matrix.soc }}-${{ matrix.type }}-${{ env.BRANCH_NAME }}
|
||||
key: ccache-${{ matrix.runner }}_${{ matrix.override_target }}-Xcode${{ matrix.xcode }}
|
||||
path: ${{ env.CCACHE_DIR }}
|
||||
restore-keys: ccache-${{ matrix.runner }}-${{ matrix.soc }}-${{ matrix.type }}-
|
||||
|
||||
- name: "Install aqtinstall"
|
||||
run: pipx install aqtinstall
|
||||
|
|
@ -385,7 +380,7 @@ jobs:
|
|||
id: restore_qt
|
||||
uses: actions/cache/restore@v6
|
||||
with:
|
||||
key: thin-qt-macos-${{ matrix.soc }}-${{ steps.resolve_qt_version.outputs.version }}
|
||||
key: Qt-${{ steps.resolve_qt_version.outputs.version }}-macOS-${{ matrix.soc }}-${{ matrix.qt_modules }}-thin
|
||||
path: ${{ github.workspace }}/Qt
|
||||
|
||||
# Using jurplel/install-qt-action to install Qt without using brew
|
||||
|
|
@ -407,7 +402,7 @@ jobs:
|
|||
if: matrix.os == 'macOS' && steps.restore_qt.outputs.cache-hit != 'true'
|
||||
uses: actions/cache/save@v6
|
||||
with:
|
||||
key: thin-qt-macos-${{ matrix.soc }}-${{ steps.resolve_qt_version.outputs.version }}
|
||||
key: ${{ steps.restore_qt.outputs.cache-primary-key }}
|
||||
path: ${{ github.workspace }}/Qt
|
||||
|
||||
- name: "[Windows] Install Qt ${{ matrix.qt_version }}"
|
||||
|
|
@ -417,6 +412,7 @@ jobs:
|
|||
# Qt 6.11.0 only works with aqtinstall directly from git until aqtinstall 3.4 is released
|
||||
aqtsource: git+https://github.com/miurahr/aqtinstall.git
|
||||
cache: true
|
||||
cache-key-prefix: Qt
|
||||
modules: ${{ matrix.qt_modules }}
|
||||
version: ${{ steps.resolve_qt_version.outputs.version }}
|
||||
|
||||
|
|
@ -457,21 +453,21 @@ jobs:
|
|||
|
||||
# Delete used cache to emulate a ccache update. See https://github.com/actions/cache/issues/342
|
||||
- name: "[macOS] Delete remote compiler cache (ccache)"
|
||||
if: matrix.os == 'macOS' && matrix.use_ccache == 1 && github.ref == 'refs/heads/master' && steps.ccache_restore.outputs.cache-hit
|
||||
if: matrix.os == 'macOS' && matrix.use_ccache == 1 && github.ref == 'refs/heads/master' && steps.restore_ccache.outputs.cache-hit
|
||||
continue-on-error: true
|
||||
env:
|
||||
CACHE_PRIMARY_KEY: ${{ steps.ccache_restore.outputs.cache-primary-key }}
|
||||
CACHE_PRIMARY_KEY: ${{ steps.restore_ccache.outputs.cache-primary-key }}
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
if gh cache delete --repo "$GITHUB_REPOSITORY" "$CACHE_PRIMARY_KEY"; then
|
||||
echo "Cache deleted successfully"
|
||||
fi
|
||||
|
||||
- name: "[macOS] Save updated compiler cache (ccache)"
|
||||
- name: "[macOS] Cache updated compiler cache (ccache)"
|
||||
if: matrix.os == 'macOS' && matrix.use_ccache == 1 && github.ref == 'refs/heads/master'
|
||||
uses: actions/cache/save@v6
|
||||
with:
|
||||
key: ${{ steps.ccache_restore.outputs.cache-primary-key }}
|
||||
key: ${{ steps.restore_ccache.outputs.cache-primary-key }}
|
||||
path: ${{ env.CCACHE_DIR }}
|
||||
|
||||
- name: "[macOS] Sign app bundle"
|
||||
|
|
|
|||
|
|
@ -52,8 +52,7 @@
|
|||
id="defs8">
|
||||
<polygon
|
||||
id="s"
|
||||
points="-301930,415571 0,-513674 301930,415571 -488533,-158734 488533,-158734 "
|
||||
transform="scale(1.94676e-6,1.94676e-6)"
|
||||
points="-0.587785,0.809017 0,-1 0.587785,0.809017 -0.951057,-0.309017 0.951057,-0.309017 "
|
||||
style="fill:#ffde00" />
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.1 KiB |
|
|
@ -16,6 +16,6 @@
|
|||
<rect id="rect10" height="2.88" width="12.8" y="4.278e-9" x="0"/>
|
||||
<rect id="rect12" height="2.88" width="12.8" y="3.36" x="0" fill="#da121a"/>
|
||||
<polygon id="polygon14" points="0 0 8.6603 5 0 10" fill="#0f47af" transform="scale(.96)"/>
|
||||
<polygon id="polygon16" points="4.1557e5 -3.0193e5 -5.1367e5 0 4.1557e5 3.0193e5 -1.5873e5 -4.8853e5 -1.5873e5 4.8853e5" fill="#fcdd09" transform="matrix(.0000029902 0 0 .0000029902 2.7713 4.8)"/>
|
||||
<polygon id="polygon16" points="4.01394 3.897169 1.23532 4.8 4.01394 5.702831 2.296666 3.3392 2.296666 6.2608" fill="#fcdd09"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.1 KiB |
|
|
@ -14,6 +14,32 @@
|
|||
#define DEFAULT_COLOR_MODERATOR_RIGHT "#000000";
|
||||
#define DEFAULT_COLOR_ADMIN "#ff2701";
|
||||
|
||||
/**
|
||||
* Clamps an svg render size so that rendering does not exceed a multiple of the requested size.
|
||||
*
|
||||
* Rendering at the full native size of an svg just to scale it down afterwards wastes memory,
|
||||
* and canvases with extreme coordinates can exceed Qt's rasterizer coordinate limit which makes
|
||||
* Qt silently drop shapes from the rendered image.
|
||||
*
|
||||
* @param renderSize The size the svg would be rendered at.
|
||||
* @param requestedSize The size that was actually requested.
|
||||
*
|
||||
* @return A size with the aspect ratio of renderSize whose longest side is at most four times
|
||||
* the longest side of requestedSize.
|
||||
*/
|
||||
static QSize capRenderSize(const QSize &renderSize, const QSize &requestedSize)
|
||||
{
|
||||
const int longestRequestedSide = qMax(requestedSize.width(), requestedSize.height());
|
||||
if (longestRequestedSide <= 0) {
|
||||
return renderSize;
|
||||
}
|
||||
|
||||
const int longestRenderSide = qMax(renderSize.width(), renderSize.height());
|
||||
const qreal scale = qMin<qreal>(1.0, static_cast<qreal>(longestRequestedSide * 4) / longestRenderSide);
|
||||
return QSize(qMax(1, static_cast<int>(renderSize.width() * scale)),
|
||||
qMax(1, static_cast<int>(renderSize.height() * scale)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads in an svg from file and scales it without affecting image quality.
|
||||
*
|
||||
|
|
@ -35,6 +61,9 @@ static QPixmap loadSvg(const QString &svgPath, const QSize &size, bool expandOnl
|
|||
// If expandOnly, make sure the pixmap is at least as large as the svg, so that we don't lose any detail.
|
||||
// QIcon.pixmap(size) will automatically scale down the image, but it won't scale it up.
|
||||
QSize pixmapSize = expandOnly ? svgRenderer.defaultSize().expandedTo(size) : size;
|
||||
if (expandOnly) {
|
||||
pixmapSize = capRenderSize(pixmapSize, size);
|
||||
}
|
||||
QPixmap pix(pixmapSize);
|
||||
pix.fill(Qt::transparent);
|
||||
|
||||
|
|
@ -247,7 +276,9 @@ static QIcon loadAndColorSvg(const QString &iconPath,
|
|||
|
||||
QSvgRenderer svgRenderer(doc.toByteArray());
|
||||
|
||||
QPixmap pix(svgRenderer.defaultSize().expandedTo(QSize(minSize, minSize)));
|
||||
const QSize pixmapSize =
|
||||
capRenderSize(svgRenderer.defaultSize().expandedTo(QSize(minSize, minSize)), QSize(minSize, minSize));
|
||||
QPixmap pix(pixmapSize);
|
||||
pix.fill(Qt::transparent);
|
||||
|
||||
QPainter pixPainter(&pix);
|
||||
|
|
|
|||
|
|
@ -39,7 +39,10 @@ void UserCardArtProvider::requestCardArt(const QString &userName, const QString
|
|||
|
||||
const QString key = makeKey(userName, cardName, providerId);
|
||||
|
||||
if (cardArtCache.contains(key) || pending.contains(key)) {
|
||||
if (pending.contains(key)) {
|
||||
return;
|
||||
}
|
||||
if (cardArtCache.contains(key) && !cardArtCache.value(key).isNull()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -63,6 +66,10 @@ QPixmap UserCardArtProvider::cropCardArt(const QPixmap &fullRes)
|
|||
|
||||
void UserCardArtProvider::insertIntoCache(const QString &key, const QPixmap &pixmap)
|
||||
{
|
||||
if (pixmap.isNull()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cardArtCache.contains(key)) {
|
||||
cacheInsertionOrder.append(key);
|
||||
while (cacheInsertionOrder.size() > MaxCacheEntries) {
|
||||
|
|
@ -129,8 +136,6 @@ void UserCardArtProvider::processQueue()
|
|||
|
||||
if (!fullRes.isNull()) {
|
||||
self->insertIntoCache(key, self->cropCardArt(fullRes));
|
||||
} else {
|
||||
self->insertIntoCache(key, QPixmap());
|
||||
}
|
||||
|
||||
self->pending.remove(key);
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ public slots:
|
|||
|
||||
private:
|
||||
bool dbReady = false;
|
||||
static constexpr int MaxCacheEntries = 300;
|
||||
static constexpr int MaxCacheEntries = 1024;
|
||||
QList<QString> cacheInsertionOrder; // FIFO eviction
|
||||
QMap<QString, QPixmap> cardArtCache;
|
||||
QSet<QString> pending;
|
||||
|
|
|
|||
|
|
@ -101,23 +101,21 @@ void UserListPainter::drawBackground(QPainter *painter,
|
|||
bg.setColorAt(0, blend(style.cardStart, accentColor, selected ? 0.75 : 0.65));
|
||||
bg.setColorAt(1, blend(style.cardEnd, accentColor, selected ? 0.18 : 0.10));
|
||||
} else {
|
||||
// Regular users are the light theme's neutral paper cards. A flat
|
||||
// warm card fill (the normal row surface, slightly deepened) keeps
|
||||
// every row clearly visible without borrowing a role color. Selection
|
||||
// shifts the fill toward a soft slate so the highlight still reads.
|
||||
const QColor paper = style.cardEnd.darker(108);
|
||||
bg.setColorAt(0, blend(paper, accentColor, selected ? 0.35 : 0.0));
|
||||
bg.setColorAt(1, blend(paper, accentColor, selected ? 0.25 : 0.0));
|
||||
// Regular users keep a scaled-down accent tint so the banner card art
|
||||
// stays legible over a colored backdrop (the pre-branch painter was
|
||||
// always dark-styled) while the role hierarchy still reads.
|
||||
bg.setColorAt(0, blend(style.cardStart, accentColor, (selected ? 0.75 : 0.65) * 0.7));
|
||||
bg.setColorAt(1, blend(style.cardEnd, accentColor, (selected ? 0.18 : 0.10) * 0.7));
|
||||
}
|
||||
|
||||
painter->setPen(Qt::NoPen);
|
||||
painter->setBrush(bg);
|
||||
painter->drawRoundedRect(cardRect, 6, 6);
|
||||
|
||||
if (style.dark || hasRole || selected) {
|
||||
painter->setBrush(accentColor);
|
||||
painter->drawRoundedRect(QRectF(cardRect.left(), cardRect.top(), 3, cardRect.height()), 2, 2);
|
||||
}
|
||||
// The 3px accent bar anchors every row so the banner card art reads as a
|
||||
// consistent strip in either scheme (pre-branch parity).
|
||||
painter->setBrush(accentColor);
|
||||
painter->drawRoundedRect(QRectF(cardRect.left(), cardRect.top(), 3, cardRect.height()), 2, 2);
|
||||
}
|
||||
|
||||
static QString makeKey(const QString &user, const QString &card, const QString &providerId)
|
||||
|
|
|
|||
|
|
@ -1372,9 +1372,13 @@ void UserListWidget::updateCardArtParams(const ServerInfo_User &user, const QStr
|
|||
params.zoom = cap.zoom();
|
||||
cardArtParamsMap.insert(userName, params);
|
||||
cardArtProvider->requestCardArt(userName, params.cardName, params.cardProviderId);
|
||||
} else {
|
||||
cardArtParamsMap.remove(userName); // clear stale params on removal
|
||||
}
|
||||
// Intentionally no removal branch: buddy/ignore list copies never carry
|
||||
// card_art_params (the server omits the column), so a params-less copy here
|
||||
// means "this snapshot doesn't include it", not "the banner was removed".
|
||||
// Removing on such copies would wipe banners that the live online list set.
|
||||
// The map is rebuilt from scratch (clear() + repopulate) on every rebuild,
|
||||
// which is what actually drops stale entries.
|
||||
}
|
||||
|
||||
void UserListWidget::processUserInfo(const ServerInfo_User &user, bool online)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue