feat(macos): integrate approved layered app icon (#399)

This commit is contained in:
Nathan Dane authored and GitHub committed 2026-10-12 16:39:45 -04:00
1 parent d381d2b7f3
commit 55f2f29fff
24 files changed
+3123 -14

No files matched your search

+19
View File
@@ -17,6 +17,25 @@ Generated-in-code assets are original and have no file to list:
| File | Author | Source | Licence | | File | Author | Source | Licence |
|---|---|---|---| |---|---|---|---|
| assets/icon.svg | SolidCraft contributors | original macOS adaptation of the code-drawn SolidCraft mark, edited and exported with VectorCraft; Apple HIG and production templates consulted as layout references only | MIT OR Apache-2.0 |
| assets/SolidCraft.icon/icon.json | SolidCraft contributors | approved Icon Composer composition and appearance settings for the original SolidCraft artwork | MIT OR Apache-2.0 |
| assets/SolidCraft.icon/Assets/01-background.svg | SolidCraft contributors | original full-square porcelain background exported from VectorCraft for system masking | MIT OR Apache-2.0 |
| assets/SolidCraft.icon/Assets/02-grid.svg | SolidCraft contributors | original perspective grid with elliptical radial alpha, exported from VectorCraft | MIT OR Apache-2.0 |
| assets/SolidCraft.icon/Assets/03-solid.svg | SolidCraft contributors | original blue CAD solid with white edges clipped to its silhouette, exported from VectorCraft | MIT OR Apache-2.0 |
| assets/Assets.car | SolidCraft contributors | Apple actool compilation of assets/SolidCraft.icon for macOS; contains original artwork only | MIT OR Apache-2.0 |
| assets/icon.vectorcraft | SolidCraft contributors | editable VectorCraft source for assets/icon.svg, with named face and background layers | MIT OR Apache-2.0 |
| assets/icon.png | SolidCraft contributors | 1024 × 1024 transparent sRGB export of assets/icon.svg from VectorCraft | MIT OR Apache-2.0 |
| assets/icon.icns | SolidCraft contributors | traditional macOS fallback packaged from assets/icon.png by Apple's iconutil | MIT OR Apache-2.0 |
| assets/icon.iconset/icon_16x16.png | SolidCraft contributors | native sips export from assets/icon.png | MIT OR Apache-2.0 |
| assets/icon.iconset/icon_16x16@2x.png | SolidCraft contributors | native sips export from assets/icon.png | MIT OR Apache-2.0 |
| assets/icon.iconset/icon_32x32.png | SolidCraft contributors | native sips export from assets/icon.png | MIT OR Apache-2.0 |
| assets/icon.iconset/icon_32x32@2x.png | SolidCraft contributors | native sips export from assets/icon.png | MIT OR Apache-2.0 |
| assets/icon.iconset/icon_128x128.png | SolidCraft contributors | native sips export from assets/icon.png | MIT OR Apache-2.0 |
| assets/icon.iconset/icon_128x128@2x.png | SolidCraft contributors | native sips export from assets/icon.png | MIT OR Apache-2.0 |
| assets/icon.iconset/icon_256x256.png | SolidCraft contributors | native sips export from assets/icon.png | MIT OR Apache-2.0 |
| assets/icon.iconset/icon_256x256@2x.png | SolidCraft contributors | native sips export from assets/icon.png | MIT OR Apache-2.0 |
| assets/icon.iconset/icon_512x512.png | SolidCraft contributors | native sips export from assets/icon.png | MIT OR Apache-2.0 |
| assets/icon.iconset/icon_512x512@2x.png | SolidCraft contributors | native sips export from assets/icon.png | MIT OR Apache-2.0 |
| docs/screenshots/sample-plate.png | SolveCraft contributors | screenshot of SolveCraft itself (`solvecraft --sample`) | MIT OR Apache-2.0 | | docs/screenshots/sample-plate.png | SolveCraft contributors | screenshot of SolveCraft itself (`solvecraft --sample`) | MIT OR Apache-2.0 |
| docs/screenshots/enclosure-demo-0.2.1.gif | SolveCraft contributors | original electronics enclosure screen recording of the actual SolveCraft 0.2.1 English desktop UI, generated with examples/demo/record_ui.sh and its original animated pointer overlay (4× playback) | MIT OR Apache-2.0 | | docs/screenshots/enclosure-demo-0.2.1.gif | SolveCraft contributors | original electronics enclosure screen recording of the actual SolveCraft 0.2.1 English desktop UI, generated with examples/demo/record_ui.sh and its original animated pointer overlay (4× playback) | MIT OR Apache-2.0 |
| docs/screenshots/enclosure-demo-0.2.1.mp4 | SolveCraft contributors | original electronics enclosure screen recording of the actual SolveCraft 0.2.1 English desktop UI, generated with examples/demo/record_ui.sh and its original animated pointer overlay (4× playback) | MIT OR Apache-2.0 | | docs/screenshots/enclosure-demo-0.2.1.mp4 | SolveCraft contributors | original electronics enclosure screen recording of the actual SolveCraft 0.2.1 English desktop UI, generated with examples/demo/record_ui.sh and its original animated pointer overlay (4× playback) | MIT OR Apache-2.0 |
+17 -5
View File
@@ -12,6 +12,7 @@
#![deny(clippy::unwrap_used, clippy::expect_used, clippy::panic, clippy::unimplemented, clippy::todo, clippy::unreachable)] #![deny(clippy::unwrap_used, clippy::expect_used, clippy::panic, clippy::unimplemented, clippy::todo, clippy::unreachable)]
#![forbid(unsafe_code)] #![forbid(unsafe_code)]
#[cfg(not(target_os = "macos"))]
#[path = "../../app_icon.rs"] #[path = "../../app_icon.rs"]
mod app_icon; mod app_icon;
mod control_server; mod control_server;
@@ -127,13 +128,15 @@ const STENCIL_BITS: u8 = 8;
const MSAA: u16 = 4; const MSAA: u16 = 4;
fn app_viewport() -> Result<egui::ViewportBuilder, eframe::Error> { fn app_viewport() -> Result<egui::ViewportBuilder, eframe::Error> {
// Let macOS use the bundle's layered icon; eframe's default bitmap would replace it.
#[cfg(target_os = "macos")]
let icon = egui::IconData::default();
#[cfg(not(target_os = "macos"))]
let icon =
egui::IconData { rgba: app_icon::rgba(64).map_err(|e| eframe::Error::AppCreation(std::io::Error::other(e).into()))?, width: 64, height: 64 };
Ok(egui::ViewportBuilder::default() Ok(egui::ViewportBuilder::default()
.with_title("SolidCraft") .with_title("SolidCraft")
.with_icon(egui::IconData { .with_icon(icon)
rgba: app_icon::rgba(64).map_err(|e| eframe::Error::AppCreation(std::io::Error::other(e).into()))?,
width: 64,
height: 64,
})
.with_inner_size([1600.0, 1000.0]) .with_inner_size([1600.0, 1000.0])
.with_min_inner_size([960.0, 600.0]) .with_min_inner_size([960.0, 600.0])
.with_drag_and_drop(true) .with_drag_and_drop(true)
@@ -281,6 +284,15 @@ mod backend_tests {
#[cfg(test)] #[cfg(test)]
mod icon_tests { mod icon_tests {
#[cfg(target_os = "macos")]
#[test]
fn macos_preserves_the_bundle_icon_instead_of_setting_a_runtime_bitmap() {
let viewport = super::app_viewport().expect("viewport");
assert_eq!(viewport.icon.as_deref(), Some(&eframe::egui::IconData::default()));
assert_eq!(viewport.app_id.as_deref(), Some("ai.storyteller.solvecraft"));
}
#[cfg(not(target_os = "macos"))]
#[test] #[test]
fn desktop_viewport_supplies_the_original_mark_to_the_window() { fn desktop_viewport_supplies_the_original_mark_to_the_window() {
let viewport = super::app_viewport().expect("viewport"); let viewport = super::app_viewport().expect("viewport");
BIN
View File
Binary file not shown.
+48
View File
@@ -0,0 +1,48 @@
# SolidCraft macOS icon
`SolidCraft.icon/` is the approved Icon Composer source, containing separate
background, grid and solid SVG layers and the owner's appearance settings.
The white edges are clipped to the solid silhouette. Artwork is original and
attributed in `ATTRIBUTION.md`.
`Assets.car` is compiled by Apple's `actool` and supplies the layered icon on
macOS 26 and later. It is checked in so the existing release workflow can still
package on older Xcode runners. After editing and saving `SolidCraft.icon`,
regenerate the catalog with Xcode 26 or later from the repository root:
```sh
mkdir -p target/macos-icon
xcrun actool assets/SolidCraft.icon \
--compile target/macos-icon --platform macosx \
--minimum-deployment-target 11.0 --app-icon SolidCraft \
--output-partial-info-plist target/macos-icon/icon-info.plist \
--output-format human-readable-text
cp target/macos-icon/Assets.car assets/Assets.car
```
`icon.vectorcraft` and `icon.svg` preserve the traditional artwork before
Icon Composer's system material effects. `icon.png` is its transparent 1024 px
VectorCraft export with native rounded corners and optical padding. The
`icon.iconset/` variants and `icon.icns` provide the older-macOS fallback.
After re-exporting the traditional PNG, regenerate them with Apple's tools:
```sh
for s in 16 32 128 256 512; do
sips -z "$s" "$s" assets/icon.png \
--out "assets/icon.iconset/icon_${s}x${s}.png" >/dev/null
sips -z "$((s * 2))" "$((s * 2))" assets/icon.png \
--out "assets/icon.iconset/icon_${s}x${s}@2x.png" >/dev/null
done
iconutil -c icns -o assets/icon.icns assets/icon.iconset
```
Only `packaging/macos/package.sh` consumes these resources. Its existing signed
app/DMG workflow copies the catalog and ICNS into `Contents/Resources`, and
`Info.plist` references `SolidCraft` through `CFBundleIconName` and
`CFBundleIconFile`. The macOS viewport opts out of eframe's runtime bitmap so
Finder, the Dock and the application switcher use the bundle icon. Other
platforms retain the existing code-drawn icon and packaging.
Design references: [Apple app-icon HIG](https://developer.apple.com/design/human-interface-guidelines/app-icons)
and [Icon Composer documentation](https://developer.apple.com/documentation/xcode/creating-your-app-icon-using-icon-composer).
No Apple artwork is shipped.
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1024" height="1024" viewBox="0 0 1024 1024">
<defs>
<linearGradient id="linear-gradient-1" x1="512" y1="0" x2="512" y2="1024" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#fcfdfe"/>
<stop offset="1" stop-color="#dce3ed"/>
</linearGradient>
</defs>
<title>Untitled-2</title>
<g id="_01_Background" data-name="01 Background">
<path id="Porcelain___legacy_macOS_silhouette" data-name="Porcelain • legacy macOS silhouette" d="M0 0 L1024 0 L1024 1024 L0 1024 Z" fill="url(#linear-gradient-1)"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 683 B

+16
View File
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1024" height="1024" viewBox="0 0 1024 1024">
<defs>
<radialGradient id="radial-gradient-1" cx="0" cy="0" r="699.707" gradientTransform="matrix(1 0 0 0.5 512 740.159)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#507eaa"/>
<stop offset="0.3" stop-color="#507eaa" stop-opacity="0.9"/>
<stop offset="0.65" stop-color="#507eaa" stop-opacity="0.35"/>
<stop offset="1" stop-color="#507eaa" stop-opacity="0"/>
</radialGradient>
</defs>
<title>Untitled-2</title>
<g id="_02_Grid" data-name="02 Grid">
<path id="Grid___elliptical_radial_alpha_beneath_solid" data-name="Grid • elliptical radial alpha beneath solid" d="M-19.692 -364.359 L1043.692 248.564 M-19.692 248.564 L1043.692 -364.359 M-19.692 -250.351 L1043.692 362.572 M-19.692 362.572 L1043.692 -250.351 M-19.692 -136.343 L1043.692 476.58 M-19.692 476.58 L1043.692 -136.343 M-19.692 -22.335 L1043.692 590.588 M-19.692 590.588 L1043.692 -22.335 M-19.692 91.673 L1043.692 704.596 M-19.692 704.596 L1043.692 91.673 M-19.692 205.681 L1043.692 818.604 M-19.692 818.604 L1043.692 205.681 M-19.692 319.689 L1043.692 932.612 M-19.692 932.612 L1043.692 319.689 M-19.692 547.705 L1043.692 1160.628 M-19.692 1160.628 L1043.692 547.705 M-19.692 661.713 L1043.692 1274.636 M-19.692 1274.636 L1043.692 661.713 M-19.692 775.721 L1043.692 1388.644 M-19.692 1388.644 L1043.692 775.721 M-19.692 889.729 L1043.692 1502.652 M-19.692 1502.652 L1043.692 889.729 M-19.692 1003.737 L1043.692 1616.66 M-19.692 1616.66 L1043.692 1003.737 M-19.692 1117.745 L1043.692 1730.668 M-19.692 1730.668 L1043.692 1117.745" fill="none" stroke="url(#radial-gradient-1)" stroke-width="3.938" stroke-miterlimit="10" opacity="0.28"/>
<path id="Origin_axes___shared_elliptical_radial_alpha" data-name="Origin axes • shared elliptical radial alpha" d="M-19.692 433.697 L1043.692 1046.62 M-19.692 1046.62 L1043.692 433.697" fill="none" stroke="url(#radial-gradient-1)" stroke-width="4.431" stroke-miterlimit="10" opacity="0.28"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1024" height="1024" viewBox="0 0 1024 1024">
<defs>
<linearGradient id="linear-gradient-1" x1="385.63" y1="53.364" x2="522.989" y2="510.769" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#8dc4fc"/>
<stop offset="1" stop-color="#5d9feb"/>
</linearGradient>
<linearGradient id="linear-gradient-2" x1="207.063" y1="303.357" x2="426.837" y2="968.175" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#438feb"/>
<stop offset="1" stop-color="#2b72cf"/>
</linearGradient>
<linearGradient id="linear-gradient-3" x1="632.876" y1="399.508" x2="783.971" y2="968.175" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#2869bd"/>
<stop offset="1" stop-color="#1e4d98"/>
</linearGradient>
<linearGradient id="linear-gradient-4" x1="619.14" y1="413.244" x2="790.839" y2="605.547" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#83baf6"/>
<stop offset="1" stop-color="#5597e6"/>
</linearGradient>
<linearGradient id="linear-gradient-5" x1="619.14" y1="179.734" x2="694.687" y2="396.761" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#306cbc"/>
<stop offset="1" stop-color="#22529c"/>
</linearGradient>
<clipPath id="clip-path-1">
<path d="M512 53.364 L709.797 167.372 L709.797 367.848 L736.547 382.716 L735.255 411.435 L907.594 510.769 L907.594 740.159 L512 968.175 L314.203 854.167 L314.203 624.777 L116.406 510.769 L116.406 282.753 Z"/>
</clipPath>
</defs>
<title>Untitled-2</title>
<g id="_03_Solid" data-name="03 Solid">
<path id="Solid_silhouette" data-name="Solid silhouette" d="M512 53.364 L709.797 167.372 L709.797 396.761 L907.594 510.769 L907.594 740.159 L512 968.175 L314.203 854.167 L314.203 624.777 L116.406 510.769 L116.406 282.753 Z" fill="#2864b8"/>
<path id="Top___extruded_profile" data-name="Top • extruded profile" d="M116.406 282.753 L512 53.364 L709.797 167.372 L512 282.753 L709.797 396.761 L512 510.769 Z" fill="url(#linear-gradient-1)"/>
<path id="Left___stepped_face" data-name="Left • stepped face" d="M116.406 282.753 L512 510.769 L512 968.175 L314.203 854.167 L314.203 624.777 L116.406 510.769 Z" fill="url(#linear-gradient-2)"/>
<path id="Right___milled_recess" data-name="Right • milled recess" d="M512 510.769 L709.797 396.761 L709.797 624.777 L907.594 510.769 L907.594 740.159 L512 968.175 Z" fill="url(#linear-gradient-3)"/>
<path id="Top___lower_step" data-name="Top • lower step" d="M709.797 396.761 L907.594 510.769 L709.797 624.777 Z" fill="url(#linear-gradient-4)"/>
<path id="Inner___upper_step" data-name="Inner • upper step" d="M709.797 167.372 L709.797 396.761 L512 282.753 Z" fill="url(#linear-gradient-5)"/>
<g clip-path="url(#clip-path-1)">
<path id="Cut_edges___original_SolidCraft_topology" data-name="Cut edges • original SolidCraft topology" d="M702.665 155.146 L716.929 179.597 L540.216 282.68 L723.951 388.583 L723.951 600.282 L900.526 498.507 L914.662 523.032 L695.643 649.272 L695.643 421.256 L526.154 518.948 L526.154 968.175 L497.846 968.175 L497.846 518.948 L109.338 295.016 L123.474 270.491 L512 494.433 L681.454 396.761 L483.784 282.827 Z" fill="#edf5ff" opacity="0.88"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

+115
View File
@@ -0,0 +1,115 @@
{
"fill" : "system-light",
"groups" : [
{
"layers" : [
{
"glass-specializations" : [
{
"appearance" : "tinted",
"value" : false
}
],
"image-name" : "03-solid.svg",
"name" : "03-solid"
}
],
"name" : "03 Solid",
"shadow" : {
"kind" : "none",
"opacity" : 0
},
"specular" : true,
"translucency" : {
"enabled" : false,
"value" : 0.3
}
},
{
"layers" : [
{
"fill" : "none",
"glass-specializations" : [
{
"value" : true
},
{
"appearance" : "tinted",
"value" : false
}
],
"hidden" : false,
"image-name" : "02-grid.svg",
"name" : "02-grid",
"opacity-specializations" : [
{
"value" : 1
},
{
"appearance" : "tinted",
"value" : 1
}
]
}
],
"name" : "02 Grid",
"shadow" : {
"kind" : "none",
"opacity" : 0
},
"specular" : false,
"translucency" : {
"enabled" : false,
"value" : 0.3
}
},
{
"layers" : [
{
"fill" : "none",
"glass" : false,
"hidden" : false,
"image-name" : "01-background.svg",
"name" : "01-background",
"position-specializations" : [
{
"value" : {
"scale" : 1,
"translation-in-points" : [
0,
0
]
}
},
{
"idiom" : "watchOS",
"value" : {
"scale" : 1.09,
"translation-in-points" : [
0,
0
]
}
}
]
}
],
"name" : "01 Background",
"shadow" : {
"kind" : "none",
"opacity" : 0
},
"specular" : false,
"translucency" : {
"enabled" : false,
"value" : 0.3
}
}
],
"supported-platforms" : {
"circles" : [
"watchOS"
],
"squares" : "shared"
}
}
BIN
View File
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

+63
View File
@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1024" height="1024" viewBox="0 0 1024 1024">
<defs>
<filter id="filter-1" filterUnits="userSpaceOnUse" x="64.5" y="64.5" width="895" height="895" data-vc-blend="multiply" color-interpolation-filters="sRGB"><feGaussianBlur in="SourceAlpha" stdDeviation="6.5"/><feOffset dx="0" dy="10" result="shadow"/><feFlood flood-color="#243047" flood-opacity="0.16"/><feComposite in2="shadow" operator="in" result="paint"/><feMerge><feMergeNode in="paint"/><feMergeNode in="SourceGraphic"/></feMerge></filter>
<linearGradient id="linear-gradient-1" x1="512" y1="96" x2="512" y2="928" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#fcfdfe"/>
<stop offset="1" stop-color="#dce3ed"/>
</linearGradient>
<clipPath id="clip-path-1">
<path d="M320 96 L704 96 C858 96 928 166 928 320 L928 704 C928 858 858 928 704 928 L320 928 C166 928 96 858 96 704 L96 320 C96 166 166 96 320 96 Z"/>
</clipPath>
<radialGradient id="radial-gradient-1" cx="0" cy="0" r="568.512" gradientTransform="matrix(1 0 0 0.5 512 697.379)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#507eaa"/>
<stop offset="0.3" stop-color="#507eaa" stop-opacity="0.9"/>
<stop offset="0.65" stop-color="#507eaa" stop-opacity="0.35"/>
<stop offset="1" stop-color="#507eaa" stop-opacity="0"/>
</radialGradient>
<linearGradient id="linear-gradient-2" x1="409.324" y1="139.358" x2="520.928" y2="511" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#8dc4fc"/>
<stop offset="1" stop-color="#5d9feb"/>
</linearGradient>
<linearGradient id="linear-gradient-3" x1="264.239" y1="342.478" x2="442.805" y2="882.642" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#438feb"/>
<stop offset="1" stop-color="#2b72cf"/>
</linearGradient>
<linearGradient id="linear-gradient-4" x1="610.212" y1="420.601" x2="732.976" y2="882.642" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#2869bd"/>
<stop offset="1" stop-color="#1e4d98"/>
</linearGradient>
<linearGradient id="linear-gradient-5" x1="599.051" y1="431.761" x2="738.557" y2="588.007" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#83baf6"/>
<stop offset="1" stop-color="#5597e6"/>
</linearGradient>
<linearGradient id="linear-gradient-6" x1="599.051" y1="242.034" x2="660.434" y2="418.369" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#306cbc"/>
<stop offset="1" stop-color="#22529c"/>
</linearGradient>
<clipPath id="clip-path-2">
<path d="M512 139.358 L672.71 231.99 L672.71 394.877 L694.445 406.957 L693.395 430.291 L833.42 511 L833.42 697.379 L512 882.642 L351.29 790.01 L351.29 603.631 L190.58 511 L190.58 325.737 Z"/>
</clipPath>
</defs>
<title>SolidCraft macOS application icon</title>
<g id="Layer_1" data-name="Layer 1">
<g filter="url(#filter-1)">
<path id="Porcelain___legacy_macOS_silhouette" data-name="Porcelain • legacy macOS silhouette" d="M320 96 L704 96 C858 96 928 166 928 320 L928 704 C928 858 858 928 704 928 L320 928 C166 928 96 858 96 704 L96 320 C96 166 166 96 320 96 Z" fill="url(#linear-gradient-1)"/>
</g>
</g>
<g id="Experiment___faint_origin_grid" data-name="Experiment • faint origin grid" clip-path="url(#clip-path-1)">
<path id="Grid___elliptical_radial_alpha_beneath_solid" data-name="Grid • elliptical radial alpha beneath solid" d="M80 -200.041 L944 297.959 M80 297.959 L944 -200.041 M80 -107.41 L944 390.59 M80 390.59 L944 -107.41 M80 -14.778 L944 483.222 M80 483.222 L944 -14.778 M80 77.853 L944 575.853 M80 575.853 L944 77.853 M80 170.485 L944 668.485 M80 668.485 L944 170.485 M80 263.116 L944 761.116 M80 761.116 L944 263.116 M80 355.748 L944 853.748 M80 853.748 L944 355.748 M80 541.01 L944 1039.01 M80 1039.01 L944 541.01 M80 633.642 L944 1131.642 M80 1131.642 L944 633.642 M80 726.273 L944 1224.273 M80 1224.273 L944 726.273 M80 818.905 L944 1316.905 M80 1316.905 L944 818.905 M80 911.536 L944 1409.536 M80 1409.536 L944 911.536 M80 1004.168 L944 1502.168 M80 1502.168 L944 1004.168" fill="none" stroke="url(#radial-gradient-1)" stroke-width="3.2" stroke-miterlimit="10" opacity="0.28"/>
<path id="Origin_axes___shared_elliptical_radial_alpha" data-name="Origin axes • shared elliptical radial alpha" d="M80 448.379 L944 946.379 M80 946.379 L944 448.379" fill="none" stroke="url(#radial-gradient-1)" stroke-width="3.6" stroke-miterlimit="10" opacity="0.28"/>
</g>
<g id="SolidCraft___machined_solid" data-name="SolidCraft • machined solid">
<path id="Solid_silhouette" data-name="Solid silhouette" d="M512 139.358 L672.71 231.99 L672.71 418.369 L833.42 511 L833.42 697.379 L512 882.642 L351.29 790.01 L351.29 603.631 L190.58 511 L190.58 325.737 Z" fill="#2864b8"/>
<path id="Top___extruded_profile" data-name="Top • extruded profile" d="M190.58 325.737 L512 139.358 L672.71 231.99 L512 325.737 L672.71 418.369 L512 511 Z" fill="url(#linear-gradient-2)"/>
<path id="Left___stepped_face" data-name="Left • stepped face" d="M190.58 325.737 L512 511 L512 882.642 L351.29 790.01 L351.29 603.631 L190.58 511 Z" fill="url(#linear-gradient-3)"/>
<path id="Right___milled_recess" data-name="Right • milled recess" d="M512 511 L672.71 418.369 L672.71 603.631 L833.42 511 L833.42 697.379 L512 882.642 Z" fill="url(#linear-gradient-4)"/>
<path id="Top___lower_step" data-name="Top • lower step" d="M672.71 418.369 L833.42 511 L672.71 603.631 Z" fill="url(#linear-gradient-5)"/>
<path id="Inner___upper_step" data-name="Inner • upper step" d="M672.71 231.99 L672.71 418.369 L512 325.737 Z" fill="url(#linear-gradient-6)"/>
<g clip-path="url(#clip-path-2)">
<path id="Cut_edges___original_SolidCraft_topology" data-name="Cut edges • original SolidCraft topology" d="M190.58 325.737 L512 511 L512 882.642 M512 511 L672.71 418.369 M672.71 231.99 L512 325.737 L672.71 418.369 L672.71 603.631 L833.42 511" fill="none" stroke="#edf5ff" stroke-width="23" stroke-miterlimit="10" opacity="0.88"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.1 KiB

File diff suppressed because it is too large. Load diff
+2
View File
@@ -28,6 +28,8 @@
<string>@VERSION@</string> <string>@VERSION@</string>
<key>CFBundleIconFile</key> <key>CFBundleIconFile</key>
<string>SolidCraft</string> <string>SolidCraft</string>
<key>CFBundleIconName</key>
<string>SolidCraft</string>
<key>LSApplicationCategoryType</key> <key>LSApplicationCategoryType</key>
<string>public.app-category.graphics-design</string> <string>public.app-category.graphics-design</string>
<!-- Must match MACOSX_DEPLOYMENT_TARGET in package.sh. --> <!-- Must match MACOSX_DEPLOYMENT_TARGET in package.sh. -->
+7 -9
View File
@@ -62,14 +62,10 @@ done
echo "==> assembling $APP" echo "==> assembling $APP"
mkdir -p "$APP/Contents/MacOS" "$APP/Contents/Resources" mkdir -p "$APP/Contents/MacOS" "$APP/Contents/Resources"
cp "$WORK/bin/solidcraft" "$APP/Contents/MacOS/SolidCraft" cp "$WORK/bin/solidcraft" "$APP/Contents/MacOS/SolidCraft"
# The icon, drawn by the CLI (no image files are committed). # Apple-compiled layered icon and older-macOS fallback (regeneration: assets/README.md).
SET="$WORK/SolidCraft.iconset" # Keep compiled resources so packaging also works on runners with older Xcode versions.
mkdir -p "$SET" cp "$ROOT/assets/Assets.car" "$APP/Contents/Resources/Assets.car"
for s in 16 32 128 256 512; do cp "$ROOT/assets/icon.icns" "$APP/Contents/Resources/SolidCraft.icns"
"$WORK/bin/solidcraft-cli" icon --size "$s" --out "$SET/icon_${s}x${s}.png" >/dev/null
"$WORK/bin/solidcraft-cli" icon --size $((s * 2)) --out "$SET/icon_${s}x${s}@2x.png" >/dev/null
done
iconutil -c icns -o "$APP/Contents/Resources/SolidCraft.icns" "$SET"
mkdir -p "$APP/Contents/Resources/Licenses" mkdir -p "$APP/Contents/Resources/Licenses"
copy_docs "$APP/Contents/Resources/Licenses" copy_docs "$APP/Contents/Resources/Licenses"
sed -e "s/@VERSION@/$VERSION/g" -e "s/@SHORT_VERSION@/$SHORT_VERSION/g" "$HERE/Info.plist.in" >"$APP/Contents/Info.plist" sed -e "s/@VERSION@/$VERSION/g" -e "s/@SHORT_VERSION@/$SHORT_VERSION/g" "$HERE/Info.plist.in" >"$APP/Contents/Info.plist"
@@ -100,11 +96,13 @@ ls -la "$MNT" "$MNT/SolidCraft.app/Contents" "$MNT/SolidCraft.app/Contents/MacOS
test -L "$MNT/Applications" && test "$(readlink "$MNT/Applications")" = /Applications test -L "$MNT/Applications" && test "$(readlink "$MNT/Applications")" = /Applications
plutil -lint "$MNT/SolidCraft.app/Contents/Info.plist" plutil -lint "$MNT/SolidCraft.app/Contents/Info.plist"
# Check the names Finder/LaunchServices actually use, and the bundle identity. # Check the names Finder/LaunchServices actually use, and the bundle identity.
for key in CFBundleName CFBundleDisplayName CFBundleExecutable CFBundleIconFile; do for key in CFBundleName CFBundleDisplayName CFBundleExecutable CFBundleIconFile CFBundleIconName; do
test "$(/usr/libexec/PlistBuddy -c "Print :$key" "$MNT/SolidCraft.app/Contents/Info.plist")" = SolidCraft test "$(/usr/libexec/PlistBuddy -c "Print :$key" "$MNT/SolidCraft.app/Contents/Info.plist")" = SolidCraft
done done
test "$(/usr/libexec/PlistBuddy -c 'Print :CFBundleIdentifier' "$MNT/SolidCraft.app/Contents/Info.plist")" = "$MACOS_BUNDLE_ID" test "$(/usr/libexec/PlistBuddy -c 'Print :CFBundleIdentifier' "$MNT/SolidCraft.app/Contents/Info.plist")" = "$MACOS_BUNDLE_ID"
test -s "$MNT/SolidCraft.app/Contents/Resources/SolidCraft.icns" test -s "$MNT/SolidCraft.app/Contents/Resources/SolidCraft.icns"
cmp "$ROOT/assets/icon.icns" "$MNT/SolidCraft.app/Contents/Resources/SolidCraft.icns"
cmp "$ROOT/assets/Assets.car" "$MNT/SolidCraft.app/Contents/Resources/Assets.car"
cmp "$HERE/README.txt" "$MNT/README.txt" cmp "$HERE/README.txt" "$MNT/README.txt"
case "$ARCH" in universal) WANT=(arm64 x86_64) ;; aarch64) WANT=(arm64) ;; *) WANT=(x86_64) ;; esac case "$ARCH" in universal) WANT=(arm64 x86_64) ;; aarch64) WANT=(arm64) ;; *) WANT=(x86_64) ;; esac
for arch in "${WANT[@]}"; do for arch in "${WANT[@]}"; do