Commit Graph
7 Commits
Author SHA1 Message Date
adminandClaude Sonnet 4.6 1054ab6236 feat: implement export panel UI with output settings and single export
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 09:18:39 +08:00
adminandClaude Sonnet 4.6 abc92cbdcb feat: implement template panel UI with picker, save, save-as, reset
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 09:15:33 +08:00
adminandClaude Sonnet 4.6 8bb6a8e53a feat: implement transform panel UI with position, size, rotation controls
TransformPanel provides the right-panel parameter editing section:

- Position: X/Y QDoubleSpinBox (range ±99999 px, 0.1 step)
- Size: Width/Height QDoubleSpinBox (min 10 px) + 锁定宽高比例 checkbox
  - When locked and width changes, height is auto-updated to maintain ratio
  - When locked and height changes, width is auto-updated to maintain ratio
  - Locking captures the current ratio at that moment
- Rotation: angle QDoubleSpinBox + 左旋 90° / 右旋 90° buttons

Signal-loop prevention:
- set_transform() sets self._updating = True and blockSignals on all inputs
  before updating values, preventing valueChanged from re-firing _emit()
- _on_width_changed/_on_height_changed also blockSignals on the companion
  spinbox when adjusting for aspect ratio to avoid double emission

Public API:
- set_transform(TransformState): programmatic update, no signal emitted
- get_transform() -> TransformState: read current inputs
- transform_changed signal: emitted whenever user edits any input

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 09:06:24 +08:00
adminandClaude Sonnet 4.6 3e3e06b7a1 feat: implement image canvas with drag/scale/rotate and preview zoom
Replace placeholder ImageCanvas with full QGraphicsView/QGraphicsScene editor:

Layout: ImageCanvas(QWidget) = top bar + _CanvasView(QGraphicsView) + hint bar

Top bar: garment/print filenames, mode buttons (移动/缩放/旋转, context-aware),
zoom controls (−/% label/+, scroll wheel).

_CanvasView:
- drawBackground: checkerboard in garment area, gray outside
- wheelEvent: zoom in/out anchored at cursor
- mousePressEvent/mouseMoveEvent/mouseReleaseEvent: delegate to ImageCanvas

Scene (1:1 with garment pixel coords):
- garment QGraphicsPixmapItem at (0,0), not interactive
- print QGraphicsPixmapItem positioned/rotated from TransformState
- cosmetic selection rect (blue, 1.5px)
- 4 corner handles (white circle, blue border) for scaling
- rotation arm (dashed) + handle (blue circle) above top-center

Interaction:
- Hit test: rotation handle > corner handles > print body (priority order)
- Move: delta in scene coords added to TransformState.x/y
- Scale: _scene_to_local_xy() maps mouse to item local coords, computes
  new size keeping opposite corner fixed (_do_scale); supports aspect
  ratio lock via Shift or keep_aspect_ratio flag; correct with rotation
- Rotate: atan2(mouse - center) + angle offset at press

Coordinate helpers (static):
- _local_to_scene_xy(lx, ly, state): item-local → scene
- _scene_to_local_xy(sx, sy, state): scene → item-local (inverse rotation)
Both use TransformState snapshot, not live item state, to avoid stale-pixmap issues.

transform_changed signal fires on mouse release with final TransformState.
Preview zoom changes only QGraphicsView transform; TransformState is unaffected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 09:01:15 +08:00
adminandClaude Sonnet 4.6 94d30ab183 feat: implement image list panel UI for garment and print assets
Implement ImageListPanel with two _AssetPanel sub-widgets (garment/print)
separated by a vertical QSplitter:

- _AssetItemWidget: checkbox (batch select) + 52px thumbnail + subfolder
  label + filename; WA_StyledBackground enables preview highlight (#cce4f7)
- _AssetPanel: open-folder button → scan_image_folder(); stats row with
  tristate 全选 checkbox + "含子文件夹·共N 已选M" label + sort selector
  (文件夹+名称 / 名称); QListWidget with NoSelection mode so preview
  highlight and batch checkbox are visually distinct
- ImageListPanel: exposes garment_preview_changed, print_preview_changed,
  garments_changed, prints_changed signals for downstream panels

File scanning delegates to services/file_service.scan_image_folder();
no scanning logic duplicated in UI layer.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 08:44:17 +08:00
adminandClaude Sonnet 4.6 0887cb35aa feat: implement main window layout with panels and style
Expand MainWindow from placeholder to full structural layout:
- Header bar: app name, version label, settings button
- Flow tab bar (QTabBar): tabs 2/3 disabled, click redirects to status bar message
- Work area (QSplitter): ImageListPanel (left 374px) | ImageCanvas (center, stretch) | right scroll with TemplatePanel/TransformPanel/ExportPanel (318px)
- Queue panel (188px, collapsible ▲/▼ toggle)
- QStatusBar with Windows-style styling

Applies color/font spec from docs/07-ui-design.md §10.
No business logic in main_window.py; panel stubs remain for tasks 8–13.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 18:04:29 +08:00
QiuSW e91207357b chore: scaffold PySide6 application 2026-06-15 15:53:01 +08:00