3 Commits

Author SHA1 Message Date
Marcos Paulo 26b79dc929 chore: release 0.6.3
Release / release (push) Has been cancelled
2026-10-12 21:40:44 -03:00
Marcos Paulo 5569ce264a feat(ui): Catppuccin themes; use the masi/craft-libs fork
Adds Latte, Frappé, Macchiato and Mocha to the interface themes (Options, View >
Interface Theme, ui.theme command). craft-ui now comes from the masi/craft-libs fork.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-12 20:53:10 -03:00
Marcos Paulo efe325f178 chore: debrand ArtCraft and Discord references
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-12 20:53:10 -03:00
37 changed files with 224 additions and 227 deletions
+23
View File
@@ -0,0 +1,23 @@
# Strip upstream (ArtCraft / Discord) branding. Run: ~/.agents/skills/debrand/debrand.pl (--check in CI)
delete docs/brand
# MIT/Apache texts stay verbatim. The copyright holder line stays everywhere (legal requirement).
keep ^(LICENSE-(MIT|APACHE)|\.debrand)$
dropline ^crates/ui-egui/src/i18n/.*\.tsv$ :: \t.*(?:ArtCraft|Discord)
dropline ^ATTRIBUTION\.md$ :: \|\s*`docs/brand/
sub (?s)\nThe ArtCraft name, wordmark and logos in docs/brand/.*?LICENSE-brand\.txt\.\n =>
sub (?s)\s*The ArtCraft name, wordmark, and logos in `docs/brand/`.*?source-code license\. =>
sub \s*The ArtCraft logos in `docs/brand/` are not open source \(`docs/brand/LICENSE-brand\.txt`\)\. =>
sub drawn in ArtCraft, vectorised => drawn by hand, vectorised
sub created\s+in ArtCraft, then => created by hand, then
sub made in ArtCraft \( => drawn by hand (
sub the owner's ArtCraft drawing => the owner's drawing
sub the ArtCraft team and CADCraft contributors => the CADCraft contributors
sub ArtCraft, ArtCraftX,\s =>
sub \bArtCraft, =>
sub https://getartcraft\.com/apps/cadcraft => https://github.com/storytold/cadcraft
sub https://discord\.gg/artcraft => https://github.com/storytold/cadcraft/issues
sub \s*The only exception is the ArtCraft brand in `docs/brand/` \(trademarks, `docs/brand/LICENSE-brand\.txt`\)\. =>
sub (?s)\s*The one\nexception is the ArtCraft brand in `docs/brand/`: ArtCraft trademarks, not open source, used under\n`docs/brand/LICENSE-brand\.txt`\. =>
forbid (?i)artcraft(?! Team and the CADCraft contributors)
forbid (?i)discord
sub Discord \(Help › Discord\), then the theme toggle => the theme toggle
+3
View File
@@ -0,0 +1,3 @@
[submodule "tools/craft-skills"]
path = tools/craft-skills
url = https://git.marcospaulo.dev.br/storytold/craft-skills.git
+1 -1
View File
@@ -23,7 +23,7 @@ People trust CADCraft with their drawings; a crash loses their work. **This outr
## Non-negotiables
- **Clean-room.** AutoCAD is installed on the dev machine and may be *observed* black-box: run it, use its UI with synthetic drawings, take screenshots (by window id) stored only under `plan/autocad/screenshots/` (never committed). **Never** read, disassemble or copy anything inside the AutoCAD bundle (names/listings only); never copy Autodesk fonts (SHX), hatch patterns (`.pat`), linetypes (`.lin`), templates, CUI/PGP files, icons, artwork or help text; never commit files produced by AutoCAD. File formats come from public specifications (Autodesk's published DXF Reference, the Open Design Alliance's public DWG specification) and our own synthetic tests. Never copy or link GPL/LGPL/AGPL code (LibreDWG, LibreCAD, QCAD, FreeCAD's planegcs, SolveSpace, OpenCASCADE) — don't even read their sources.
- **Assets — absolutely essential.** CADCraft contains **no Autodesk, Adobe or Avid iconography, images, fonts, patterns or artwork — ever.** Every icon is drawn in code (`crates/ui-egui/src/icons.rs`), every hatch pattern and linetype is our own definition (`crates/doc/src/library.rs`), the drafting font is our own (`crates/fonts/src/stroke.rs`). Any file asset must be original, public domain/CC0, OSI-licensed, or redistributable Creative Commons (or licensed open source by a contributor who made it), and **must have a row in `ATTRIBUTION.md`** with author, source and licence (`cargo xtask assets` enforces it). The only exception is the ArtCraft brand in `docs/brand/` (trademarks, `docs/brand/LICENSE-brand.txt`). Screenshots of Autodesk software are never committed. Breaking this rule is the most serious mistake you can make in this repo.
- **Assets — absolutely essential.** CADCraft contains **no Autodesk, Adobe or Avid iconography, images, fonts, patterns or artwork — ever.** Every icon is drawn in code (`crates/ui-egui/src/icons.rs`), every hatch pattern and linetype is our own definition (`crates/doc/src/library.rs`), the drafting font is our own (`crates/fonts/src/stroke.rs`). Any file asset must be original, public domain/CC0, OSI-licensed, or redistributable Creative Commons (or licensed open source by a contributor who made it), and **must have a row in `ATTRIBUTION.md`** with author, source and licence (`cargo xtask assets` enforces it). Screenshots of Autodesk software are never committed. Breaking this rule is the most serious mistake you can make in this repo.
- **Fonts live in [`storytold/craft-fonts`](https://github.com/storytold/craft-fonts)**, never in this repo. It is an optional build input (`CRAFT_FONTS_DIR`, embedded by `crates/fonts/build.rs`), never a `Cargo.toml` dependency. Code and tests must work without it.
- **Shared test corpora** live in separate repos (`storytold/<app>-corpus`); never commit large binary fixtures here.
- **Everything is a command.** User-visible behaviour = a command in `crates/engine/src/cmd/*` (`CommandSpec`: id = AutoCAD's command name in lower case, label, menu path, shortcut, aliases, params doc, `enabled`, JSON `run`, optional `interactive` prompt machine) + tests. UI-only commands live in `crates/ui-egui/src/menus.rs` (`UI_COMMANDS`). The command line, menus, toolbar, Tool Sets, scripts, CLI, control channel and MCP all reach the same commands.
+1 -11
View File
@@ -9,9 +9,7 @@ artwork, fonts, hatch patterns, linetypes, templates or presets.** Every asset i
CADCraft contributors or third-party material under an open licence (OSI open source, public domain
/ CC0, or Creative Commons that allows redistribution). Screenshots of Autodesk software are never
committed. Font files are not added here: shared fonts live in
[storytold/craft-fonts](https://github.com/storytold/craft-fonts), an optional build input. The one
exception is the ArtCraft brand in `docs/brand/`: ArtCraft trademarks, not open source, used under
`docs/brand/LICENSE-brand.txt`.
[storytold/craft-fonts](https://github.com/storytold/craft-fonts), an optional build input.
Generated-in-code assets are original and have no file to list:
- the UI icon set (`crates/ui-egui/src/icons.rs`);
@@ -43,14 +41,6 @@ Generated-in-code assets are original and have no file to list:
| `docs/images/ui-apartment.png` | CADCraft contributors | screenshot of CADCraft itself (examples/apartment.dxf) | MIT OR Apache-2.0 | Original; no Autodesk UI |
| `docs/images/ui-layout.png` | CADCraft contributors | screenshot of CADCraft itself (a layout of examples/apartment.dxf) | MIT OR Apache-2.0 | Original; no Autodesk UI |
| `docs/images/ui-bracket.png` | CADCraft contributors | screenshot of CADCraft itself (sample drawing generated in code) | MIT OR Apache-2.0 | Original; no Autodesk UI |
| `docs/brand/artcraft-logo-white.png` | ArtCraft Team | storytold/craftrules `assets/brand/` | ArtCraft brand terms (`docs/brand/LICENSE-brand.txt`) | Trademark, not open source |
| `docs/brand/artcraft-logo-white.svg` | ArtCraft Team | storytold/craftrules `assets/brand/` | ArtCraft brand terms (`docs/brand/LICENSE-brand.txt`) | Trademark, not open source |
| `docs/brand/artcraft-logo.png` | ArtCraft Team | storytold/craftrules `assets/brand/` | ArtCraft brand terms (`docs/brand/LICENSE-brand.txt`) | Trademark, not open source |
| `docs/brand/artcraft-logo.svg` | ArtCraft Team | storytold/craftrules `assets/brand/` | ArtCraft brand terms (`docs/brand/LICENSE-brand.txt`) | Trademark, not open source |
| `docs/brand/artcraft-mark-black.png` | ArtCraft Team | storytold/craftrules `assets/brand/` | ArtCraft brand terms (`docs/brand/LICENSE-brand.txt`) | Trademark, not open source |
| `docs/brand/artcraft-mark-black.svg` | ArtCraft Team | storytold/craftrules `assets/brand/` | ArtCraft brand terms (`docs/brand/LICENSE-brand.txt`) | Trademark, not open source |
| `docs/brand/artcraft-mark.png` | ArtCraft Team | storytold/craftrules `assets/brand/` | ArtCraft brand terms (`docs/brand/LICENSE-brand.txt`) | Trademark, not open source |
| `docs/brand/artcraft-mark.svg` | ArtCraft Team | storytold/craftrules `assets/brand/` | ArtCraft brand terms (`docs/brand/LICENSE-brand.txt`) | Trademark, not open source |
## Interface translations
+1 -1
View File
@@ -23,7 +23,7 @@ People trust CADCraft with their drawings; a crash loses their work. **This outr
## Non-negotiables
- **Clean-room.** AutoCAD is installed on the dev machine and may be *observed* black-box: run it, use its UI with synthetic drawings, take screenshots (by window id) stored only under `plan/autocad/screenshots/` (never committed). **Never** read, disassemble or copy anything inside the AutoCAD bundle (names/listings only); never copy Autodesk fonts (SHX), hatch patterns (`.pat`), linetypes (`.lin`), templates, CUI/PGP files, icons, artwork or help text; never commit files produced by AutoCAD. File formats come from public specifications (Autodesk's published DXF Reference, the Open Design Alliance's public DWG specification) and our own synthetic tests. Never copy or link GPL/LGPL/AGPL code (LibreDWG, LibreCAD, QCAD, FreeCAD's planegcs, SolveSpace, OpenCASCADE) — don't even read their sources.
- **Assets — absolutely essential.** CADCraft contains **no Autodesk, Adobe or Avid iconography, images, fonts, patterns or artwork — ever.** Every icon is drawn in code (`crates/ui-egui/src/icons.rs`), every hatch pattern and linetype is our own definition (`crates/doc/src/library.rs`), the drafting font is our own (`crates/fonts/src/stroke.rs`). Any file asset must be original, public domain/CC0, OSI-licensed, or redistributable Creative Commons (or licensed open source by a contributor who made it), and **must have a row in `ATTRIBUTION.md`** with author, source and licence (`cargo xtask assets` enforces it). The only exception is the ArtCraft brand in `docs/brand/` (trademarks, `docs/brand/LICENSE-brand.txt`). Screenshots of Autodesk software are never committed. Breaking this rule is the most serious mistake you can make in this repo.
- **Assets — absolutely essential.** CADCraft contains **no Autodesk, Adobe or Avid iconography, images, fonts, patterns or artwork — ever.** Every icon is drawn in code (`crates/ui-egui/src/icons.rs`), every hatch pattern and linetype is our own definition (`crates/doc/src/library.rs`), the drafting font is our own (`crates/fonts/src/stroke.rs`). Any file asset must be original, public domain/CC0, OSI-licensed, or redistributable Creative Commons (or licensed open source by a contributor who made it), and **must have a row in `ATTRIBUTION.md`** with author, source and licence (`cargo xtask assets` enforces it). Screenshots of Autodesk software are never committed. Breaking this rule is the most serious mistake you can make in this repo.
- **Fonts live in [`storytold/craft-fonts`](https://github.com/storytold/craft-fonts)**, never in this repo. It is an optional build input (`CRAFT_FONTS_DIR`, embedded by `crates/fonts/build.rs`), never a `Cargo.toml` dependency. Code and tests must work without it.
- **Shared test corpora** live in separate repos (`storytold/<app>-corpus`); never commit large binary fixtures here.
- **Everything is a command.** User-visible behaviour = a command in `crates/engine/src/cmd/*` (`CommandSpec`: id = AutoCAD's command name in lower case, label, menu path, shortcut, aliases, params doc, `enabled`, JSON `run`, optional `interactive` prompt machine) + tests. UI-only commands live in `crates/ui-egui/src/menus.rs` (`UI_COMMANDS`). The command line, menus, toolbar, Tool Sets, scripts, CLI, control channel and MCP all reach the same commands.
Generated
+17 -17
View File
@@ -546,7 +546,7 @@ checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04"
[[package]]
name = "cadcraft"
version = "0.6.2"
version = "0.6.3"
dependencies = [
"cadcraft-engine",
"cadcraft-io",
@@ -566,7 +566,7 @@ dependencies = [
[[package]]
name = "cadcraft-cli"
version = "0.6.2"
version = "0.6.3"
dependencies = [
"cadcraft-engine",
"cadcraft-io",
@@ -577,14 +577,14 @@ dependencies = [
[[package]]
name = "cadcraft-color"
version = "0.6.2"
version = "0.6.3"
dependencies = [
"serde",
]
[[package]]
name = "cadcraft-constraints"
version = "0.6.2"
version = "0.6.3"
dependencies = [
"cadcraft-doc",
"cadcraft-geom",
@@ -594,7 +594,7 @@ dependencies = [
[[package]]
name = "cadcraft-doc"
version = "0.6.2"
version = "0.6.3"
dependencies = [
"cadcraft-color",
"cadcraft-geom",
@@ -605,14 +605,14 @@ dependencies = [
[[package]]
name = "cadcraft-dwg"
version = "0.6.2"
version = "0.6.3"
dependencies = [
"acadrust",
]
[[package]]
name = "cadcraft-dxf"
version = "0.6.2"
version = "0.6.3"
dependencies = [
"encoding_rs",
"log",
@@ -621,7 +621,7 @@ dependencies = [
[[package]]
name = "cadcraft-engine"
version = "0.6.2"
version = "0.6.3"
dependencies = [
"cadcraft-color",
"cadcraft-constraints",
@@ -640,7 +640,7 @@ dependencies = [
[[package]]
name = "cadcraft-fonts"
version = "0.6.2"
version = "0.6.3"
dependencies = [
"cadcraft-geom",
"harfrust",
@@ -650,14 +650,14 @@ dependencies = [
[[package]]
name = "cadcraft-geom"
version = "0.6.2"
version = "0.6.3"
dependencies = [
"serde",
]
[[package]]
name = "cadcraft-io"
version = "0.6.2"
version = "0.6.3"
dependencies = [
"cadcraft-color",
"cadcraft-doc",
@@ -675,7 +675,7 @@ dependencies = [
[[package]]
name = "cadcraft-mcp"
version = "0.6.2"
version = "0.6.3"
dependencies = [
"cadcraft-engine",
"cadcraft-io",
@@ -686,7 +686,7 @@ dependencies = [
[[package]]
name = "cadcraft-render"
version = "0.6.2"
version = "0.6.3"
dependencies = [
"cadcraft-color",
"cadcraft-doc",
@@ -700,7 +700,7 @@ dependencies = [
[[package]]
name = "cadcraft-ui-egui"
version = "0.6.2"
version = "0.6.3"
dependencies = [
"cadcraft-color",
"cadcraft-doc",
@@ -721,7 +721,7 @@ dependencies = [
[[package]]
name = "cadcraft-web"
version = "0.6.2"
version = "0.6.3"
dependencies = [
"cadcraft-engine",
"cadcraft-io",
@@ -925,7 +925,7 @@ checksum = "7f8f80099a98041a3d1622845c271458a2d73e688351bf3cb999266764b81d48"
[[package]]
name = "craft-ui"
version = "0.1.0"
source = "git+https://github.com/storytold/craft-libs?rev=5c874d51eeb3de70e735c8ce87a59a7dedd47675#5c874d51eeb3de70e735c8ce87a59a7dedd47675"
source = "git+https://git.marcospaulo.dev.br/masi/craft-libs?rev=22544b6d619d4f16779b8bdfa3f0b642a86fc065#22544b6d619d4f16779b8bdfa3f0b642a86fc065"
dependencies = [
"egui",
"serde",
@@ -4772,7 +4772,7 @@ checksum = "e450f9b2ed1dff33c94c12589a87338689467b9c4f5d8a5710bd09a847d2c8a7"
[[package]]
name = "xtask"
version = "0.6.2"
version = "0.6.3"
dependencies = [
"serde_json",
]
+2 -2
View File
@@ -4,7 +4,7 @@ members = ["crates/*", "apps/*", "xtask"]
# default-members
[workspace.package]
version = "0.6.2"
version = "0.6.3"
edition = "2024"
license = "MIT OR Apache-2.0"
rust-version = "1.90"
@@ -46,7 +46,7 @@ encoding_rs = "0.8.35"
quick-xml = "0.41"
# ui
craft-ui = { version = "0.1.0", git = "https://github.com/storytold/craft-libs", rev = "5c874d51eeb3de70e735c8ce87a59a7dedd47675", features = ["serde"] }
craft-ui = { version = "0.1.0", git = "https://git.marcospaulo.dev.br/masi/craft-libs", rev = "22544b6d619d4f16779b8bdfa3f0b642a86fc065", features = ["serde"] }
egui = "0.36"
egui_kittest = "0.36"
eframe = { version = "0.36", default-features = false }
-4
View File
@@ -3,10 +3,6 @@ Copyright (c) 2026 ArtCraft Team and the CADCraft contributors.
Licensed under the MIT License or the Apache License, Version 2.0, at your option
(LICENSE-MIT, LICENSE-APACHE).
The ArtCraft name, wordmark and logos in docs/brand/ are trademarks of the ArtCraft Team. They are
not open source and are not covered by the license above; their terms are in
docs/brand/LICENSE-brand.txt.
Third-party material
Software dependencies are listed in Cargo.lock. One is under a weak-copyleft licence: the acadrust
+12 -71
View File
@@ -1,12 +1,3 @@
<p align="center">
<a href="https://getartcraft.com/">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="docs/brand/artcraft-logo-white.svg">
<img alt="ArtCraft" src="docs/brand/artcraft-logo.svg" width="200">
</picture>
</a>
</p>
<h1 align="center">CADCraft</h1>
<p align="center">
@@ -16,8 +7,7 @@
<p align="center">
A fast, open-source take on the AutoCAD workflow: the command line, object snaps, layers,
dimensions, hatches, blocks and DXF drawings you already know. It runs natively on macOS,
Windows, Linux and FreeBSD, and in the browser via WebAssembly.<br>
<i>By the ArtCraft team.</i>
Windows, Linux and FreeBSD, and in the browser via WebAssembly.
</p>
<p align="center">
@@ -28,16 +18,6 @@
<img alt="Status: early development" src="https://img.shields.io/badge/status-early%20development-f07a3a?style=flat-square">
</p>
<p align="center">
<a href="https://discord.gg/artcraft"><img alt="Join the ArtCraft community on Discord" src="https://img.shields.io/badge/Join%20us%20on%20Discord-5865F2?style=for-the-badge&logo=discord&logoColor=white" height="40"></a>
</p>
<p align="center">
<a href="https://getartcraft.com/apps/cadcraft"><b>CADCraft on getartcraft.com</b></a> ·
<a href="https://getartcraft.com/">ArtCraft</a> ·
<a href="https://getartcraft.com/apps">All Crafting Apps</a>
</p>
<br>
<p align="center">
@@ -45,11 +25,6 @@
<br><sub><b>Apartment plan</b> (<a href="examples/apartment.dxf">examples/apartment.dxf</a>): walls with pick-point hatching, TrueType MTEXT room labels, a TABLE, a multileader and architectural dimensions — built entirely from CADCraft commands.</sub>
</p>
> [!NOTE]
> **ArtCraft is a community of artists from all walks of life.** Painters, photographers,
> filmmakers, illustrators, designers, animators, hobbyists, and people who picked up a pencil
> last week. If you make things, you're one of us. **[Come say hi on Discord](https://discord.gg/artcraft).**
<p align="center">
<a href="#screenshots">Screenshots</a> ·
<a href="#why-cadcraft">Why CADCraft</a> ·
@@ -322,44 +297,20 @@ RISC-V (riscv64): `cadcraft-<ver>-linux-riscv64.tar.gz`, cross-compiled; needs g
## The Crafting Apps
CADCraft is one of the **Crafting Apps**: free, open-source creative tools from the
[ArtCraft](https://getartcraft.com/) team, each written from scratch in Rust and each able to
CADCraft is one of the **Crafting Apps**: free, open-source creative tools, each written from scratch in Rust and each able to
stand on its own.
| | App | What it's for | Code | Learn more |
|:-:|---|---|---|---|
| <img src="https://raw.githubusercontent.com/storytold/photocraft/main/assets/app-icon/hicolor/64x64/apps/ai.storyteller.photocraft.png" alt="" width="32" height="32"> | **PhotoCraft** | Image editing: layers, masks, type and real PSD files | [GitHub](https://github.com/storytold/photocraft) | [Website](https://getartcraft.com/apps/photocraft) |
| <img src="https://raw.githubusercontent.com/storytold/vectorcraft/main/assets/app-icon/hicolor/64x64/apps/ai.storyteller.vectorcraft.png" alt="" width="32" height="32"> | **VectorCraft** | Vector illustration | [GitHub](https://github.com/storytold/vectorcraft) | [Website](https://getartcraft.com/apps/vectorcraft) |
| <img src="https://raw.githubusercontent.com/storytold/filmcraft/main/assets/app-icon/hicolor/64x64/apps/ai.storyteller.filmcraft.png" alt="" width="32" height="32"> | **FilmCraft** | Video editing, color and sound | [GitHub](https://github.com/storytold/filmcraft) | [Website](https://getartcraft.com/apps/filmcraft) |
| <img src="https://raw.githubusercontent.com/storytold/lightcraft/main/assets/app-icon/hicolor/64x64/apps/ai.storyteller.lightcraft.png" alt="" width="32" height="32"> | **LightCraft** | Photo library and raw development | [GitHub](https://github.com/storytold/lightcraft) | [Website](https://getartcraft.com/apps/lightcraft) |
| <img src="https://raw.githubusercontent.com/storytold/pdfcraft/main/assets/app-icon/hicolor/64x64/apps/ai.storyteller.pdfcraft.png" alt="" width="32" height="32"> | **PdfCraft** | Reading, organizing and protecting PDFs | [GitHub](https://github.com/storytold/pdfcraft) | [Website](https://getartcraft.com/apps/pdfcraft) |
| <img src="https://raw.githubusercontent.com/storytold/effectcraft/main/assets/app-icon/hicolor/64x64/apps/ai.storyteller.effectcraft.png" alt="" width="32" height="32"> | **EffectCraft** | Motion graphics and visual effects | [GitHub](https://github.com/storytold/effectcraft) | [Website](https://getartcraft.com/apps/effectcraft) |
| <img src="https://raw.githubusercontent.com/storytold/designcraft/main/assets/app-icon/hicolor/64x64/apps/ai.storyteller.designcraft.png" alt="" width="32" height="32"> | **DesignCraft** | Page layout and publishing | [GitHub](https://github.com/storytold/designcraft) | [Website](https://getartcraft.com/apps/designcraft) |
| <img src="https://raw.githubusercontent.com/storytold/cadcraft/main/assets/app-icon/cadcraft-64.png" alt="" width="32" height="32"> | **CADCraft** | **Computer-aided design and drafting · you are here** | [GitHub](https://github.com/storytold/cadcraft) | [Website](https://getartcraft.com/apps/cadcraft) |
| | App | What it's for | Code |
|:-:|---|---|---|
| <img src="https://raw.githubusercontent.com/storytold/photocraft/main/assets/app-icon/hicolor/64x64/apps/ai.storyteller.photocraft.png" alt="" width="32" height="32"> | **PhotoCraft** | Image editing: layers, masks, type and real PSD files | [GitHub](https://github.com/storytold/photocraft) |
| <img src="https://raw.githubusercontent.com/storytold/vectorcraft/main/assets/app-icon/hicolor/64x64/apps/ai.storyteller.vectorcraft.png" alt="" width="32" height="32"> | **VectorCraft** | Vector illustration | [GitHub](https://github.com/storytold/vectorcraft) |
| <img src="https://raw.githubusercontent.com/storytold/filmcraft/main/assets/app-icon/hicolor/64x64/apps/ai.storyteller.filmcraft.png" alt="" width="32" height="32"> | **FilmCraft** | Video editing, color and sound | [GitHub](https://github.com/storytold/filmcraft) |
| <img src="https://raw.githubusercontent.com/storytold/lightcraft/main/assets/app-icon/hicolor/64x64/apps/ai.storyteller.lightcraft.png" alt="" width="32" height="32"> | **LightCraft** | Photo library and raw development | [GitHub](https://github.com/storytold/lightcraft) |
| <img src="https://raw.githubusercontent.com/storytold/pdfcraft/main/assets/app-icon/hicolor/64x64/apps/ai.storyteller.pdfcraft.png" alt="" width="32" height="32"> | **PdfCraft** | Reading, organizing and protecting PDFs | [GitHub](https://github.com/storytold/pdfcraft) |
| <img src="https://raw.githubusercontent.com/storytold/effectcraft/main/assets/app-icon/hicolor/64x64/apps/ai.storyteller.effectcraft.png" alt="" width="32" height="32"> | **EffectCraft** | Motion graphics and visual effects | [GitHub](https://github.com/storytold/effectcraft) |
| <img src="https://raw.githubusercontent.com/storytold/designcraft/main/assets/app-icon/hicolor/64x64/apps/ai.storyteller.designcraft.png" alt="" width="32" height="32"> | **DesignCraft** | Page layout and publishing | [GitHub](https://github.com/storytold/designcraft) |
| <img src="https://raw.githubusercontent.com/storytold/cadcraft/main/assets/app-icon/cadcraft-64.png" alt="" width="32" height="32"> | **CADCraft** | **Computer-aided design and drafting · you are here** | [GitHub](https://github.com/storytold/cadcraft) |
And [**ArtCraft**](https://getartcraft.com/) itself, our AI image and video studio for artists who want real control.
<br>
<p align="center">
<a href="https://discord.gg/artcraft"><img alt="Join the ArtCraft community on Discord" src="https://img.shields.io/badge/Join%20us%20on%20Discord-5865F2?style=for-the-badge&logo=discord&logoColor=white" height="40"></a>
</p>
<h3 align="center">Come make things with us</h3>
<p align="center">
Our Discord is where artists of every kind hang out: people who paint, shoot, draw, cut film,
set type, and people still figuring out what they like to make. Share what you're working on,
ask for help, tell us what's broken, or tell us what you wish these tools could do.
Whatever your medium and however long you've been at it, you're welcome here.
</p>
<p align="center">
<a href="https://discord.gg/artcraft"><b>discord.gg/artcraft</b></a> ·
<a href="https://getartcraft.com/">getartcraft.com</a> ·
<a href="https://getartcraft.com/apps">The Crafting Apps</a> ·
<a href="https://getartcraft.com/apps/cadcraft">CADCraft</a>
</p>
## License and credits
@@ -372,16 +323,6 @@ with its author, source and license in [ATTRIBUTION.md](ATTRIBUTION.md).
CADCraft's icons, its single-stroke drafting font, its hatch patterns and its linetypes are all
original work, drawn or defined in code. The sample drawings are generated in code too.
The ArtCraft name, wordmark and logos in [`docs/brand/`](docs/brand/) are trademarks of the
ArtCraft Team and are not covered by this license. They may be used only unmodified, and only as
part of this repository and CADCraft, under [`docs/brand/LICENSE-brand.txt`](docs/brand/LICENSE-brand.txt).
Forks and modified versions must remove them.
<sub>Autodesk, AutoCAD and DWG are trademarks or registered trademarks of Autodesk, Inc. in the United States and/or other countries. CADCraft is an independent, open-source project and is not affiliated with, sponsored by or endorsed by Autodesk, Inc.; these names are used only to describe the workflows and file formats it is compatible with.</sub>
<p align="center">
<a href="https://getartcraft.com/"><img alt="ArtCraft" src="docs/brand/artcraft-mark.svg" width="28"></a><br>
<sub>Made by the <a href="https://getartcraft.com/">ArtCraft</a> team and community.</sub>
</p>
Tool Sets, Layers, and Properties can be regrouped, split, floated within the app window, closed, and reopened. The drawing canvas stays visible and cannot be closed or turned into a tab. Drag a panel header to a target edge or another header. Its context menu offers Float panel, Move to group, and Close panel. Existing panel toggles reopen panels at their saved location; Reset Panel Layout restores the app layout. Floating panels remain inside the current app window.
+2 -8
View File
@@ -35,7 +35,6 @@ impl NativeMenu {
let mut counter = 0usize;
let app_menu = Submenu::new("CADCraft", true);
let about = MenuItem::with_id("cc-about", i18n::tr(language, "About CADCraft"), true, None);
let discord = MenuItem::with_id("cc-discord", i18n::tr(language, "Join the ArtCraft Discord…"), true, None);
let predefined = vec![
("Services", PredefinedMenuItem::services(Some(i18n::tr(language, "Services")))),
("Hide CADCraft", PredefinedMenuItem::hide(Some(i18n::tr(language, "Hide CADCraft")))),
@@ -45,7 +44,7 @@ impl NativeMenu {
];
// The Mac place for preferences: CADCraft ▸ Settings… (⌘,) opens the Options dialog.
let settings = MenuItem::with_id("cc-settings", i18n::tr(language, "Settings..."), true, accel("Cmd+Comma"));
let _ = app_menu.append_items(&[&about, &discord, &PredefinedMenuItem::separator(), &settings, &PredefinedMenuItem::separator()]);
let _ = app_menu.append_items(&[&about, &PredefinedMenuItem::separator(), &settings, &PredefinedMenuItem::separator()]);
for (label, item) in &predefined {
let _ = app_menu.append(item);
if ["Services", "Show All"].contains(label) {
@@ -53,7 +52,6 @@ impl NativeMenu {
}
}
items.insert("cc-about".into(), ("ui.dialog.about".into(), "About CADCraft".into(), about));
items.insert("cc-discord".into(), ("ui.discord".into(), "Join the ArtCraft Discord…".into(), discord));
items.insert("cc-settings".into(), ("options".into(), "Settings...".into(), settings));
let _ = menu.append(&app_menu);
for (title, entries) in menus::tree(app) {
@@ -69,11 +67,7 @@ impl NativeMenu {
pub fn poll(&mut self, app: &mut CadApp, ctx: &egui::Context) {
while let Ok(ev) = MenuEvent::receiver().try_recv() {
if let Some((cmd, _, _)) = self.items.get(ev.id.as_ref()) {
if cmd == "ui.discord" {
ctx.open_url(egui::OpenUrl::new_tab("https://discord.gg/artcraft"));
} else {
menus::activate(app, &cmd.clone());
}
menus::activate(app, &cmd.clone());
ctx.request_repaint();
}
}
-4
View File
@@ -321,10 +321,6 @@ fn about(ctx: &egui::Context, open: &mut bool) {
ui.label(crate::tf!("Version {version}", version = env!("CARGO_PKG_VERSION")));
ui.label(crate::tl!("Computer-aided design and drafting: an open-source, clean-room CAD application written in pure Rust."));
ui.add_space(6.0);
ui.label(RichText::new(crate::tl!("One of the Crafting Apps by the ArtCraft team and community.")).color(t.text_dim));
ui.hyperlink_to("getartcraft.com/apps/cadcraft", "https://getartcraft.com/apps/cadcraft");
ui.hyperlink_to(crate::tl!("Join us on Discord"), "https://discord.gg/artcraft");
ui.add_space(6.0);
ui.label(RichText::new(crate::tl!("MIT OR Apache-2.0. Not affiliated with Autodesk, Inc.")).small().color(t.text_faint));
}
}
-3
View File
@@ -434,8 +434,6 @@
Jogged Zalomená
Jogged Linear Zalomená lineární
Join Spojit
Join the ArtCraft Discord… Připojit se na Discord ArtCraft…
Join us on Discord Připojte se k nám na Discordu
Isometric Plane Izometrická rovina
Isometric snap Izometrické uchopení
Language Jazyk
@@ -575,7 +573,6 @@
Offset Ekvidistanta
On Zapnuto
On/Off Zapnout/Vypnout
One of the Crafting Apps by the ArtCraft team and community. Jedna z aplikací Crafting Apps od týmu ArtCraft a komunity.
Only in this drawing: {n} Pouze v tomto výkresu: {n}
Only in {name}: {n} Pouze v {name}: {n}
Open (⌘O) Otevřít (⌘O)
1 # CADCraft Czech interface catalog — original translations by @Losminek (AI-assisted).
434
435
436
437
438
439
573
574
575
576
577
578
+4 -3
View File
@@ -86,6 +86,10 @@
CADCraft Help CADCraft-Hilfe
Cancel Abbrechen
Cartesian (x, y) Kartesisch (x, y)
Catppuccin Latte Catppuccin Latte
Catppuccin Frappé Catppuccin Frappé
Catppuccin Macchiato Catppuccin Macchiato
Catppuccin Mocha Catppuccin Mocha
Center Zentrum
Center Line Mittellinie
Center Mark Zentrumsmarke
@@ -357,8 +361,6 @@
Isolate Layer Layer isolieren
Isometric Drafting Isometrisches Zeichnen
Join Verbinden
Join the ArtCraft Discord… Dem ArtCraft-Discord beitreten…
Join us on Discord Treten Sie uns auf Discord bei
Language Sprache
Last Letzter
Last commit Letzter Commit
@@ -486,7 +488,6 @@
Offset Versatz
On Ein
On/Off Ein/Aus
One of the Crafting Apps by the ArtCraft team and community. Eine der Crafting Apps vom ArtCraft-Team und seiner Community.
Open (⌘O) Öffnen (⌘O)
Open Sample Drawing Beispielzeichnung öffnen
Open sample drawing Beispielzeichnung öffnen
1 # CADCraft German interface catalog — original translations by the CADCraft contributors.
86
87
88
89
90
91
92
93
94
95
361
362
363
364
365
366
488
489
490
491
492
493
+4 -3
View File
@@ -110,6 +110,10 @@
CADCraft keeps these preferences, object snap modes and drafting toggles for your user account and restores them when it starts. CADCraft guarda estas preferencias, los modos de referencia a objetos y los ajustes de dibujo para tu cuenta de usuario y los restaura al iniciarse.
Cancel Cancelar
Cartesian (x, y) Cartesianas (x, y)
Catppuccin Latte Catppuccin Latte
Catppuccin Frappé Catppuccin Frappé
Catppuccin Macchiato Catppuccin Macchiato
Catppuccin Mocha Catppuccin Mocha
Center Centro
Center Line Línea de centro
Center Mark Marca de centro
@@ -455,8 +459,6 @@
Jogged Con recodo
Jogged Linear Lineal con recodo
Join Unir
Join the ArtCraft Discord… Únete al Discord de ArtCraft…
Join us on Discord Únete a nosotros en Discord
Keep the system cursor visible over the drawing area Mantener visible el cursor del sistema sobre el área de dibujo
Language Idioma
Largest array Matriz más grande
@@ -608,7 +610,6 @@
Offset Desfase
On Activado
On/Off Activar/desactivar
One of the Crafting Apps by the ArtCraft team and community. Una de las Crafting Apps del equipo y la comunidad de ArtCraft.
Only in this drawing: {n} Solo en este dibujo: {n}
Only in {name}: {n} Solo en {name}: {n}
Open Abrir
1 # CADCraft Spanish interface catalog — original translations.
110
111
112
113
114
115
116
117
118
119
459
460
461
462
463
464
610
611
612
613
614
615
-3
View File
@@ -356,8 +356,6 @@
Isolate Layer Isoler le calque
Isometric Drafting Dessin isométrique
Join Rejoindre
Join the ArtCraft Discord… Rejoindre le Discord d'ArtCraft…
Join us on Discord Rejoignez-nous sur Discord
Language Langue
Last Dernier
Last commit Dernière révision
@@ -485,7 +483,6 @@
Offset Décalage
On Activé
On/Off Activer/Désactiver
One of the Crafting Apps by the ArtCraft team and community. L'une des applications Crafting Apps de l'équipe et de la communauté ArtCraft.
Open (⌘O) Ouvrir (⌘O)
Open Sample Drawing Ouvrir un dessin d'exemple
Open sample drawing Ouvrir un dessin d'exemple
1 # CADCraft French interface catalog — original translations by @pechnikov2026-star.
356
357
358
359
360
361
483
484
485
486
487
488
+4 -3
View File
@@ -86,6 +86,10 @@
CADCraft Help Ajuda do CADCraft
Cancel Cancelar
Cartesian (x, y) Cartesiano (x, y)
Catppuccin Latte Catppuccin Latte
Catppuccin Frappé Catppuccin Frappé
Catppuccin Macchiato Catppuccin Macchiato
Catppuccin Mocha Catppuccin Mocha
Center Centro
Center Line Linha de centro
Center Mark Marca de centro
@@ -357,8 +361,6 @@
Isolate Layer Isolar camada
Isometric Drafting Desenho isométrico
Join Unir
Join the ArtCraft Discord… Entrar no Discord do ArtCraft…
Join us on Discord Junte-se a nós no Discord
Language Idioma
Last Último
Last commit Último commit
@@ -486,7 +488,6 @@
Offset Deslocar
On Ativado
On/Off Ativar/desativar
One of the Crafting Apps by the ArtCraft team and community. Um dos Crafting Apps da equipe e da comunidade ArtCraft.
Open (⌘O) Abrir (⌘O)
Open Sample Drawing Abrir desenho de exemplo
Open sample drawing Abrir desenho de exemplo
1 # CADCraft Brazilian Portuguese (pt-BR) interface catalog.
86
87
88
89
90
91
92
93
94
95
361
362
363
364
365
366
488
489
490
491
492
493
-3
View File
@@ -356,8 +356,6 @@
Isolate Layer Изолировать слой
Isometric Drafting Изометрическое черчение
Join Объединить
Join the ArtCraft Discord… Присоединяйтесь к Discord ArtCraft…
Join us on Discord Присоединяйтесь к нам в Discord
Language Язык
Last Последний
Last commit Последний коммит
@@ -485,7 +483,6 @@
Offset Смещение
On Включено
On/Off Включить/выключить
One of the Crafting Apps by the ArtCraft team and community. Одна из программ Crafting Apps от команды и сообщества ArtCraft.
Open (⌘O) Открыть (⌘O)
Open Sample Drawing Открыть образец чертежа
Open sample drawing Открыть образец чертежа
1 # CADCraft Russian interface catalog — original translations by @pechnikov2026-star.
356
357
358
359
360
361
483
484
485
486
487
488
+4 -3
View File
@@ -8,6 +8,10 @@
Apply Застосувати
Attach DWG... Приєднати DWG...
Bind Вбудувати
Catppuccin Latte Catppuccin Латте
Catppuccin Frappé Catppuccin Фраппе
Catppuccin Macchiato Catppuccin Макіато
Catppuccin Mocha Catppuccin Мока
Detach Від'єднати
Loaded Завантажено
Make it a block of this drawing, keeping its layer names Зробити блоком цього креслення зі збереженням назв шарів
@@ -438,8 +442,6 @@
Jogged Зі зламом
Jogged Linear Лінійний зі зламом
Join Об'єднати
Join the ArtCraft Discord… Приєднатися до Discord ArtCraft…
Join us on Discord Приєднуйтеся до нас у Discord
Isometric Plane Ізометрична площина
Isometric snap Ізометрична крокова прив'язка
Language Мова
@@ -579,7 +581,6 @@
Offset Зміщення
On Увімкнено
On/Off Увімкнути/вимкнути
One of the Crafting Apps by the ArtCraft team and community. Одна з програм Crafting Apps від команди та спільноти ArtCraft.
Only in this drawing: {n} Лише в цьому кресленні: {n}
Only in {name}: {n} Лише в {name}: {n}
Open (⌘O) Відкрити (⌘O)
1 # CADCraft Ukrainian interface catalog — original translations by @dmatviichuk.
8
9
10
11
12
13
14
15
16
17
442
443
444
445
446
447
581
582
583
584
585
586
-3
View File
@@ -357,8 +357,6 @@
Isolate Layer 隔离图层
Isometric Drafting 等轴测制图
Join 合并
Join the ArtCraft Discord… 加入 ArtCraft Discord…
Join us on Discord 在 Discord 上加入我们
Language 语言
Last 最后
Last commit 最后提交
@@ -486,7 +484,6 @@
Offset 偏移
On 开启
On/Off 开/关
One of the Crafting Apps by the ArtCraft team and community. 由 ArtCraft 团队和社区打造的 Crafting 系列应用之一。
Open (⌘O) 打开 (⌘O)
Open Sample Drawing 打开示例图形
Open sample drawing 打开示例图形
1 # CADCraft Simplified Chinese interface catalog — original translations.
357
358
359
360
361
362
484
485
486
487
488
489
+6 -1
View File
@@ -201,6 +201,7 @@ pub struct CadApp {
shown_theme: Option<egui::Theme>,
/// Whether the last applied theme was handed to egui as the System preference.
shown_follows_system: bool,
shown_flavor: Option<craft_ui::theme::catppuccin::Flavor>,
pub frame_ms: f64,
pub quit_requested: bool,
/// The app may close although drawings have unsaved changes (they were dealt with, or the
@@ -241,6 +242,7 @@ impl CadApp {
fonts_cjk: None,
shown_theme: None,
shown_follows_system: false,
shown_flavor: None,
frame_ms: 0.0,
quit_requested: false,
quit_confirmed: false,
@@ -423,12 +425,15 @@ impl CadApp {
// browser report changes as input); the saved choice itself never changes here.
let shown = self.ui.theme.resolve(ctx.system_theme());
theme::set_active(shown);
let flavor = self.ui.theme.flavor();
theme::set_flavor(flavor);
theme::set_canvas(self.options.canvas());
let follows_system = self.ui.theme == theme::ThemePref::System;
if self.shown_theme != Some(shown) || self.shown_follows_system != follows_system {
if self.shown_theme != Some(shown) || self.shown_follows_system != follows_system || self.shown_flavor != flavor {
theme::apply(ctx, shown, follows_system);
self.shown_theme = Some(shown);
self.shown_follows_system = follows_system;
self.shown_flavor = flavor;
}
self.drain_control(ctx);
if !self.synthetic.is_empty() {
+13 -3
View File
@@ -33,6 +33,10 @@ pub const UI_COMMANDS: &[(&str, &str, &[&str], Option<&str>)] = &[
("ui.theme.system", "Use System Setting", &["View", "Interface Theme", "Use System Setting"], None),
("ui.theme.light", "Light", &["View", "Interface Theme", "Light"], None),
("ui.theme.dark", "Dark", &["View", "Interface Theme", "Dark"], None),
("ui.theme.catppuccinLatte", "Catppuccin Latte", &["View", "Interface Theme", "Catppuccin Latte"], None),
("ui.theme.catppuccinFrappe", "Catppuccin Frappé", &["View", "Interface Theme", "Catppuccin Frappé"], None),
("ui.theme.catppuccinMacchiato", "Catppuccin Macchiato", &["View", "Interface Theme", "Catppuccin Macchiato"], None),
("ui.theme.catppuccinMocha", "Catppuccin Mocha", &["View", "Interface Theme", "Catppuccin Mocha"], None),
("ui.theme", "Interface Theme", &[], None),
("ui.saveformat.dxf", "DXF", &["File", "Default Save Format", "DXF"], None),
("ui.saveformat.dwg", "DWG", &["File", "Default Save Format", "DWG"], None),
@@ -223,15 +227,21 @@ fn run_ui_command_inner(app: &mut CadApp, id: &str, params: &Value) -> Option<Re
toggle(&mut app.ui.in_window_menu, params);
Ok(Value::Null)
}
"ui.theme.system" | "ui.theme.light" | "ui.theme.dark" => {
"ui.theme.system"
| "ui.theme.light"
| "ui.theme.dark"
| "ui.theme.catppuccinLatte"
| "ui.theme.catppuccinFrappe"
| "ui.theme.catppuccinMacchiato"
| "ui.theme.catppuccinMocha" => {
let pref = crate::theme::ThemePref::parse(id.trim_start_matches("ui.theme.")).unwrap_or_default();
set_theme(app, pref)
}
// `{"theme": "system"|"light"|"dark"}` sets the choice; without it, reports it.
// `{"theme": "system"|"light"|"dark"|"catppuccinLatte"|…}` (see `ThemePref::id_list`) sets the choice; without it, reports it.
"ui.theme" => match params.get("theme").and_then(Value::as_str) {
Some(name) => match crate::theme::ThemePref::parse(name) {
Some(pref) => set_theme(app, pref),
None => Err(format!("unknown theme \"{name}\" (system, light or dark)")),
None => Err(format!("unknown theme \"{name}\" ({})", crate::theme::ThemePref::id_list())),
},
None => Ok(theme_json(app)),
},
+4
View File
@@ -97,6 +97,10 @@ fn theme_label(t: ThemePref) -> &'static str {
ThemePref::System => crate::tl!("Use System Setting"),
ThemePref::Light => crate::tl!("Light"),
ThemePref::Dark => crate::tl!("Dark"),
ThemePref::CatppuccinLatte => crate::tl!("Catppuccin Latte"),
ThemePref::CatppuccinFrappe => crate::tl!("Catppuccin Frappé"),
ThemePref::CatppuccinMacchiato => crate::tl!("Catppuccin Macchiato"),
ThemePref::CatppuccinMocha => crate::tl!("Catppuccin Mocha"),
}
}
+1 -1
View File
@@ -136,7 +136,7 @@ fn color_param(key: &str, v: &Value) -> Result<Option<Color32>, String> {
fn parse_ui(key: &str, v: &Value, c: &mut UiChanges) -> Result<bool, String> {
let text = || v.as_str().ok_or_else(|| format!("{key} must be text"));
match key {
"theme" => c.theme = Some(ThemePref::parse(text()?).ok_or("theme must be system, light or dark")?),
"theme" => c.theme = Some(ThemePref::parse(text()?).ok_or_else(|| format!("theme must be {}", ThemePref::id_list()))?),
"interfaceLanguage" => {
c.language = Some(
crate::i18n::Preference::parse(text()?).ok_or_else(|| format!("interfaceLanguage must be {}", crate::i18n::Preference::codes()))?,
+115 -9
View File
@@ -6,35 +6,59 @@
//! dialogs); the drawing area keeps its model-space colours in both, as drawing colours are not
//! part of the interface theme. [`Tokens::get`] returns the palette of the theme in use, which
//! [`CadApp::logic`](crate::CadApp::logic) resolves once per frame from the user's [`ThemePref`].
//! The four Catppuccin flavours ([`Tokens::catppuccin`]) re-colour the same chrome.
use std::cell::Cell;
use craft_ui::theme::catppuccin::Flavor;
use egui::{Color32, FontFamily, FontId, Theme, Visuals};
use serde::{Deserialize, Serialize};
/// The interface theme the user chose.
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum ThemePref {
/// Follow the operating system's light/dark appearance, live.
#[serde(rename = "system")]
System,
#[serde(rename = "light")]
Light,
/// The default: CADCraft's original look.
#[default]
#[serde(rename = "dark")]
Dark,
#[serde(rename = "catppuccinLatte")]
CatppuccinLatte,
#[serde(rename = "catppuccinFrappe")]
CatppuccinFrappe,
#[serde(rename = "catppuccinMacchiato")]
CatppuccinMacchiato,
#[serde(rename = "catppuccinMocha")]
CatppuccinMocha,
}
/// The theme `System` uses when the OS (or browser) reports no appearance.
pub const SYSTEM_FALLBACK: Theme = Theme::Dark;
impl ThemePref {
pub const ALL: [ThemePref; 3] = [ThemePref::System, ThemePref::Light, ThemePref::Dark];
pub const ALL: [ThemePref; 7] = [
ThemePref::System,
ThemePref::Light,
ThemePref::Dark,
ThemePref::CatppuccinLatte,
ThemePref::CatppuccinFrappe,
ThemePref::CatppuccinMacchiato,
ThemePref::CatppuccinMocha,
];
pub fn as_str(self) -> &'static str {
match self {
ThemePref::System => "system",
ThemePref::Light => "light",
ThemePref::Dark => "dark",
ThemePref::CatppuccinLatte => "catppuccinLatte",
ThemePref::CatppuccinFrappe => "catppuccinFrappe",
ThemePref::CatppuccinMacchiato => "catppuccinMacchiato",
ThemePref::CatppuccinMocha => "catppuccinMocha",
}
}
@@ -42,12 +66,29 @@ impl ThemePref {
ThemePref::ALL.into_iter().find(|t| t.as_str().eq_ignore_ascii_case(s.trim()))
}
/// Every id, `|`-separated: for error messages and command docs.
pub fn id_list() -> String {
Self::ALL.map(ThemePref::as_str).join("|")
}
/// The Catppuccin flavour this choice shows, if it is one.
pub fn flavor(self) -> Option<Flavor> {
match self {
ThemePref::CatppuccinLatte => Some(Flavor::Latte),
ThemePref::CatppuccinFrappe => Some(Flavor::Frappe),
ThemePref::CatppuccinMacchiato => Some(Flavor::Macchiato),
ThemePref::CatppuccinMocha => Some(Flavor::Mocha),
ThemePref::System | ThemePref::Light | ThemePref::Dark => None,
}
}
/// The theme to show, given what the OS reports (`ctx.system_theme()`).
pub fn resolve(self, system: Option<Theme>) -> Theme {
match self {
ThemePref::System => system.unwrap_or(SYSTEM_FALLBACK),
ThemePref::Light => Theme::Light,
ThemePref::Dark => Theme::Dark,
p => p.flavor().map_or(SYSTEM_FALLBACK, |f| if f.is_dark() { Theme::Dark } else { Theme::Light }),
}
}
}
@@ -55,6 +96,8 @@ impl ThemePref {
thread_local! {
/// The theme in use on the UI thread (set by [`set_active`] each frame).
static ACTIVE: Cell<Theme> = const { Cell::new(Theme::Dark) };
/// The Catppuccin flavour in use, if any (set by [`set_flavor`] each frame).
static FLAVOR: Cell<Option<Flavor>> = const { Cell::new(None) };
}
/// The theme [`Tokens::get`] returns colours for.
@@ -66,6 +109,14 @@ pub fn set_active(theme: Theme) {
ACTIVE.with(|a| a.set(theme));
}
pub fn flavor() -> Option<Flavor> {
FLAVOR.with(Cell::get)
}
pub fn set_flavor(f: Option<Flavor>) {
FLAVOR.with(|c| c.set(f));
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Tokens {
pub chrome: Color32,
@@ -216,7 +267,42 @@ impl Tokens {
/// The palette of the theme in use, with the user's drawing-area colours ([`set_canvas`]).
pub fn get() -> Tokens {
CANVAS.with(Cell::get).over(Tokens::of(active()))
CANVAS.with(Cell::get).over(flavor().map_or_else(|| Tokens::of(active()), Tokens::catppuccin))
}
/// A Catppuccin flavour on CADCraft's chrome (mauve accent, blue selection). The drawing-area
/// colours stay [`Tokens::DARK`]'s, as in every interface theme.
pub fn catppuccin(f: Flavor) -> Tokens {
let p = f.palette();
let alpha = |c: Color32, a: u8| Color32::from_rgba_unmultiplied(c.r(), c.g(), c.b(), a);
Tokens {
chrome: p.mantle,
chrome_dark: p.crust,
panel: p.base,
tab_active: p.surface1,
control: p.surface0,
control_hover: p.surface1,
border: p.surface1,
text: p.text,
text_dim: p.subtext0,
text_faint: p.overlay1,
icon: p.subtext1,
icon_accent: p.blue,
icon_point: p.peach,
accent: p.mauve,
cmd_bg: alpha(p.base, 0xf0),
toggle_on: p.mauve,
field: if f.is_dark() { p.crust } else { p.base },
select_bg: mix(p.base, p.blue, 0.4),
cmd_history: alpha(p.mantle, 0xdc),
cmd_border: p.surface2,
cmd_keyword: p.blue,
cmd_keyword_hover: p.surface1,
list_bg: p.mantle,
list_row: p.surface0,
warn: if f.is_dark() { p.yellow } else { p.peach },
..Tokens::DARK
}
}
/// These tokens with `bg` as the model-space background: the grid, axes, crosshair and the
@@ -393,9 +479,9 @@ pub fn can_show(language: &str) -> bool {
!language.starts_with("zh") || cjk_font().is_some()
}
/// egui's visuals for `theme`, from its tokens.
fn visuals(theme: Theme) -> Visuals {
let t = Tokens::of(theme);
/// egui's visuals for `theme` (or the Catppuccin flavour `f` of it), from its tokens.
fn visuals(theme: Theme, f: Option<Flavor>) -> Visuals {
let t = f.map_or_else(|| Tokens::of(theme), Tokens::catppuccin);
let mut v = match theme {
Theme::Dark => Visuals::dark(),
Theme::Light => Visuals::light(),
@@ -424,13 +510,14 @@ fn visuals(theme: Theme) -> Visuals {
v
}
/// Install the styles of both themes and show `theme` (egui's own widgets, popups and menus
/// Install the styles of both themes (the active [`flavor`] colours its side) and show `theme` (egui's own widgets, popups and menus
/// follow it; our own painting follows [`Tokens::get`]). `follow_system` is true for the
/// [`ThemePref::System`] choice, whose `theme` was resolved from the OS report.
pub fn apply(ctx: &egui::Context, theme: Theme, follow_system: bool) {
set_active(theme);
ctx.set_visuals_of(Theme::Dark, visuals(Theme::Dark));
ctx.set_visuals_of(Theme::Light, visuals(Theme::Light));
for th in [Theme::Dark, Theme::Light] {
ctx.set_visuals_of(th, visuals(th, flavor().filter(|f| f.is_dark() == (th == Theme::Dark))));
}
// A System choice keeps egui's own System preference: a concrete Light/Dark would pin the native
// window appearance (winit then stops reporting OS changes) and the app would never follow again.
ctx.set_theme(if follow_system { egui::ThemePreference::System } else { egui::ThemePreference::from(theme) });
@@ -444,3 +531,22 @@ pub fn apply(ctx: &egui::Context, theme: Theme, follow_system: bool) {
s.text_styles.insert(egui::TextStyle::Monospace, mono());
});
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn catppuccin_themes_use_the_flavour_palette() {
let flavors: Vec<_> = ThemePref::ALL.iter().filter_map(|t| t.flavor()).collect();
assert_eq!(flavors, Flavor::ALL);
for t in ThemePref::ALL.into_iter().filter(|t| t.flavor().is_some()) {
let f = t.flavor().unwrap();
let tokens = Tokens::catppuccin(f);
assert_eq!((tokens.panel, tokens.text, tokens.accent), (f.palette().base, f.palette().text, f.palette().mauve), "{}", t.as_str());
assert_eq!(t.resolve(None) == Theme::Dark, f.is_dark());
assert_eq!(ThemePref::parse(t.as_str()), Some(t));
}
assert_eq!(ThemePref::id_list().split('|').count(), ThemePref::ALL.len());
}
}
-42
View File
@@ -1,42 +0,0 @@
ArtCraft brand assets: license
The ArtCraft name, wordmark and mark (the "ArtCraft Marks"), including every file in this
directory in every color, size and format, are owned by the ArtCraft Team. They are trademarks
and are NOT open source. They are not covered by CADCraft's MIT OR Apache-2.0 license, and nothing in
that license, in NOTICE or in any other file of this repository grants any right to them.
Permission
The ArtCraft Team grants a limited, non-exclusive, non-transferable, revocable, royalty-free
permission to use the ArtCraft Marks only:
1. as part of copies of this repository; and
2. within CADCraft itself, its documentation and its official builds, to identify CADCraft as made
by the ArtCraft team and community and to link to getartcraft.com and its community.
Conditions
The permission holds only while every one of these is true:
- The marks are used exactly as supplied in this directory. Do not redraw, recolor, crop,
stretch, rotate, animate, outline or add effects to them, extract parts of them, or combine
them with any other name, mark or artwork.
- They are used only in the context of CADCraft, and only to say that the ArtCraft team makes it.
They must never suggest that the ArtCraft Team made, sponsors, endorses, certifies or supports
any other product, service, fork, modified version, plug-in, organization or person.
- Neither the marks nor the ArtCraft name appear in the name, logo, icon, domain, social media
handle, app-store listing, advertising or marketing of anything other than CADCraft.
Forks and modified versions
If you distribute or publish a modified version of CADCraft, or any work derived from it, you must
remove the ArtCraft Marks from it (or replace them with your own) and must not call it ArtCraft or
present it as an ArtCraft product. You may say, in plain text, that your work is based on CADCraft by
the ArtCraft team. A fork kept only to propose changes back to this repository may keep the marks
unchanged.
Everything else
Any use not expressly permitted here needs prior written permission from the ArtCraft Team
(https://getartcraft.com/). The permission ends automatically for anyone who breaks these terms.
All other rights are reserved.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

-4
View File
@@ -1,4 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-10 -19.42 136.34 136.34" role="img" aria-label="ArtCraft">
<title>ArtCraft</title>
<path fill="#0b0b0c" d="M104.28,49.49L81.55,0h-31.23l-3.17,4.76L14.75,53.63,0,75.85l21.55,21.55,63.79-36.94,16.99,37.04,14.01-21.74-12.06-26.27ZM32.89,65.66l32.42-48.87,10.91,23.77-43.32,25.09Z"/>
</svg>

Before

Width:  |  Height:  |  Size: 341 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

-4
View File
@@ -1,4 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-10 -19.42 136.34 136.34" role="img" aria-label="ArtCraft">
<title>ArtCraft</title>
<path fill="#4e7bfb" d="M104.28,49.49L81.55,0h-31.23l-3.17,4.76L14.75,53.63,0,75.85l21.55,21.55,63.79-36.94,16.99,37.04,14.01-21.74-12.06-26.27ZM32.89,65.66l32.42-48.87,10.91,23.77-43.32,25.09Z"/>
</svg>

Before

Width:  |  Height:  |  Size: 341 B

@@ -20,10 +20,10 @@
<launchable type="desktop-id">ai.storyteller.cadcraft.desktop</launchable>
<icon type="stock">ai.storyteller.cadcraft</icon>
<!-- Only url types known to appstream 0.15 (Ubuntu 22.04, where CI validates): no vcs-browser. -->
<url type="homepage">https://getartcraft.com/apps/cadcraft</url>
<url type="homepage">https://github.com/storytold/cadcraft</url>
<url type="bugtracker">https://github.com/storytold/cadcraft/issues</url>
<url type="help">https://github.com/storytold/cadcraft</url>
<url type="contact">https://discord.gg/artcraft</url>
<url type="contact">https://github.com/storytold/cadcraft/issues</url>
<categories>
<category>Graphics</category>
<category>Engineering</category>
+1 -1
View File
@@ -14,7 +14,7 @@ section: graphics
priority: optional
maintainer: ${CADCRAFT_MAINTAINER}
vendor: Learning Machines LLC
homepage: https://getartcraft.com/apps/cadcraft
homepage: https://github.com/storytold/cadcraft
license: MIT OR Apache-2.0
description: |-
Open-source computer-aided design and drafting: draft, dimension and plot 2D
+3 -3
View File
@@ -31,9 +31,9 @@
<Icon Id="CadcraftIcon.ico" SourceFile="$(var.IconPath)" />
<Property Id="ARPPRODUCTICON" Value="CadcraftIcon.ico" />
<Property Id="ARPURLINFOABOUT" Value="https://getartcraft.com/apps/cadcraft" />
<Property Id="ARPURLUPDATEINFO" Value="https://getartcraft.com/apps/cadcraft" />
<Property Id="ARPHELPLINK" Value="https://discord.gg/artcraft" />
<Property Id="ARPURLINFOABOUT" Value="https://github.com/storytold/cadcraft" />
<Property Id="ARPURLUPDATEINFO" Value="https://github.com/storytold/cadcraft" />
<Property Id="ARPHELPLINK" Value="https://github.com/storytold/cadcraft/issues" />
<StandardDirectory Id="ProgramFiles6432Folder">
<Directory Id="INSTALLFOLDER" Name="CADCraft" />
Submodule tools/craft-skills added at 26c1c201a7