| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- from PySide6.QtCore import QAbstractListModel, Qt, Slot, Signal
- from PySide6.QtQml import QmlElement
- from pathlib import Path
- QML_IMPORT_NAME = "DuneWeaver"
- QML_IMPORT_MAJOR_VERSION = 1
- @QmlElement
- class PatternModel(QAbstractListModel):
- """Model for pattern list with direct file system access"""
-
- NameRole = Qt.UserRole + 1
- PathRole = Qt.UserRole + 2
- PreviewRole = Qt.UserRole + 3
-
- def __init__(self):
- super().__init__()
- self._patterns = []
- self._filtered_patterns = []
- # Look for patterns in the parent directory (main dune-weaver folder)
- self.patterns_dir = Path("../patterns")
- self.cache_dir = Path("../patterns/cached_images")
- self.refresh()
-
- def roleNames(self):
- return {
- self.NameRole: b"name",
- self.PathRole: b"path",
- self.PreviewRole: b"preview"
- }
-
- def rowCount(self, parent=None):
- return len(self._filtered_patterns)
-
- def data(self, index, role):
- if not index.isValid() or index.row() >= len(self._filtered_patterns):
- return None
-
- pattern = self._filtered_patterns[index.row()]
-
- if role == self.NameRole:
- return pattern["name"]
- elif role == self.PathRole:
- return pattern["path"]
- elif role == self.PreviewRole:
- # For patterns in subdirectories, check both flattened and hierarchical cache structures
- pattern_name = pattern["name"]
-
- # Try PNG format for kiosk compatibility
- # First try hierarchical structure (preserving subdirectories)
- preview_path_hierarchical = self.cache_dir / f"{pattern_name}.png"
- if preview_path_hierarchical.exists():
- return str(preview_path_hierarchical.absolute())
-
- # Then try flattened structure (replace / with _)
- preview_name_flat = pattern_name.replace("/", "_").replace("\\", "_")
- preview_path_flat = self.cache_dir / f"{preview_name_flat}.png"
- if preview_path_flat.exists():
- return str(preview_path_flat.absolute())
-
- # Fallback to WebP if PNG not found (for existing caches)
- preview_path_hierarchical_webp = self.cache_dir / f"{pattern_name}.webp"
- if preview_path_hierarchical_webp.exists():
- return str(preview_path_hierarchical_webp.absolute())
-
- preview_path_flat_webp = self.cache_dir / f"{preview_name_flat}.webp"
- if preview_path_flat_webp.exists():
- return str(preview_path_flat_webp.absolute())
-
- return ""
-
- return None
-
- @Slot()
- def refresh(self):
- print(f"Loading patterns from: {self.patterns_dir.absolute()}")
- self.beginResetModel()
- patterns = []
- for file_path in self.patterns_dir.rglob("*.thr"):
- relative = file_path.relative_to(self.patterns_dir)
- patterns.append({
- "name": str(relative),
- "path": str(file_path)
- })
- self._patterns = sorted(patterns, key=lambda x: x["name"])
- self._filtered_patterns = self._patterns.copy()
- print(f"Loaded {len(self._patterns)} patterns")
- self.endResetModel()
-
- @Slot(str)
- def filter(self, search_text):
- self.beginResetModel()
- if not search_text:
- self._filtered_patterns = self._patterns.copy()
- else:
- search_lower = search_text.lower()
- self._filtered_patterns = [
- p for p in self._patterns
- if search_lower in p["name"].lower()
- ]
- self.endResetModel()
|