Swatch libraries: only a built-in pattern library's own swatches draw its pattern tiles

This commit is contained in:
dotCooCoo
2026-11-02 12:04:03 +07:00
committed by bflatastic
parent 6b7513c0a0
commit 284b5b45b6
3 changed files with 18 additions and 13 deletions
+8 -4
View File
@@ -71,10 +71,14 @@ pub fn library(id: &str) -> Option<(LibraryInfo, Arc<SwatchLibrary>)> {
Some((infos().nth(i)?, MADE.get(i)?.clone()))
}
/// The built-in library document that holds pattern `name` (a library panel draws its pattern
/// swatches from it). Pattern names are unique across the built-in libraries.
pub fn pattern_source(name: &str) -> Option<Arc<Document>> {
PATTERN_LIBRARIES.iter().filter_map(|b| library_doc(b.id)).find(|d| d.pattern(name).is_some())
/// The built-in library document that holds the pattern of swatch `w`, when `w` is one of a
/// built-in pattern library's own swatches (a library panel draws them from it). A swatch of
/// another library is not, even under the same name.
pub fn swatch_source(w: &Swatch) -> Option<Arc<Document>> {
let Paint::Pattern { pattern, .. } = &w.paint else { return None };
let own = |lib: &SwatchLibrary| lib.swatches.iter().any(|s| std::ptr::eq(s, w));
let b = PATTERN_LIBRARIES.iter().find(|b| library(b.id).is_some_and(|(_, lib)| own(&lib)))?;
library_doc(b.id).filter(|d| d.pattern(pattern).is_some())
}
/// Add pattern `name` of library `lib` to `d` with the resources its art uses, as pasting art
+7 -4
View File
@@ -719,10 +719,10 @@ fn pattern_libraries_bring_their_patterns_and_add_each_once() {
}
/// The built-in pattern libraries: unique, tiling patterns with art, whose names no two libraries
/// share.
/// share. Each library's own swatches draw from it; a swatch of the same name elsewhere does not.
#[test]
fn built_in_pattern_libraries_hold_tiling_patterns_with_unique_names() {
use crate::cmd::patternlib::{PATTERN_LIBRARIES, library_doc, pattern_source};
use crate::cmd::patternlib::{PATTERN_LIBRARIES, library, library_doc, swatch_source};
let mut names = std::collections::HashSet::new();
for b in PATTERN_LIBRARIES {
let d = library_doc(b.id).unwrap();
@@ -731,10 +731,13 @@ fn built_in_pattern_libraries_hold_tiling_patterns_with_unique_names() {
assert!(names.insert(p.name.clone()), "{} is in two libraries", p.name);
assert!(!p.art.is_empty() && p.width() > 0.0 && p.height() > 0.0, "{}", p.name);
assert!(vectorcraft_render::render_pattern_swatch(&d, &p.name, 16).is_some(), "{}", p.name);
assert!(std::sync::Arc::ptr_eq(&pattern_source(&p.name).unwrap(), &d));
}
let (_, lib) = library(b.id).unwrap();
for w in &lib.swatches {
assert!(std::sync::Arc::ptr_eq(&swatch_source(w).unwrap(), &d), "{}", w.name);
assert!(swatch_source(&w.clone()).is_none(), "a copy of {} is another library's swatch", w.name);
}
}
assert!(pattern_source("No Such Pattern").is_none());
}
/// #3602: a library titled with a Windows device name is saved under a name that is not one.
@@ -2,8 +2,8 @@ use super::actions::deletable;
use super::dnd::selection;
use super::tiles::{describe, global_mark, list_icons, pattern_thumb_in};
use super::{
Arc, BuiltinLibrary, GRADIENT_LIBRARIES, Item, LibraryKind, LibraryRef, PATTERN_LIBRARIES, Paint, Rect, Row, SWATCH_LIBRARIES, Swatch,
SwatchLibrary, Ui, Value, VectorcraftApp, json, library_panel, menu_item, patternlib, swatch_tile, swatchlib,
Arc, BuiltinLibrary, GRADIENT_LIBRARIES, Item, LibraryKind, LibraryRef, PATTERN_LIBRARIES, Rect, Row, SWATCH_LIBRARIES, Swatch, SwatchLibrary,
Ui, Value, VectorcraftApp, json, library_panel, menu_item, patternlib, swatch_tile, swatchlib,
};
fn library_refs(libs: Vec<swatchlib::LibraryInfo>) -> Vec<LibraryRef> {
@@ -100,9 +100,7 @@ impl LibraryKind for SwatchLibraries {
fn draw(_: &VectorcraftApp, ui: &Ui, r: Rect, w: &Swatch, selected: bool, hovered: bool) {
swatch_tile(ui, r, &w.paint, selected, hovered);
// A built-in pattern library's pattern, drawn from the library.
if let Paint::Pattern { pattern, .. } = &w.paint
&& let Some(src) = patternlib::pattern_source(pattern)
{
if let Some(src) = patternlib::swatch_source(w) {
pattern_thumb_in(&src, ui, r.shrink(1.0), &w.paint);
}
if w.global {