Restructure ORA editor into modular blueprints with browse dialog
- Split app.py into route blueprints (files, layers, images, polygon, mask, krita) - Create services layer (polygon_storage, comfyui, file_browser) - Extract config constants to config.py - Split templates into Jinja partials (base, components, modals) - Add browse dialog for visual file navigation - Add /api/browse endpoint for directory listing
This commit is contained in:
@@ -65,11 +65,82 @@ All file paths are relative to the project root: `/home/noti/dev/ai-game-2`
|
||||
- **PNG**: Auto-converted to ORA on open
|
||||
|
||||
### Open Flow
|
||||
1. User enters path relative to project root (e.g., `scenes/kq4_010/pic.png`)
|
||||
2. Backend checks if file exists
|
||||
3. If PNG: auto-create ORA with single `base` layer
|
||||
4. Parse ORA structure, extract layers
|
||||
5. Return layer list + image data URLs
|
||||
1. User clicks "Browse" button to open file browser dialog
|
||||
2. Backend lists directories and files (PNG, ORA) from project root
|
||||
3. User navigates directories, selects file
|
||||
4. Backend checks if file exists
|
||||
5. If PNG: auto-create ORA with single `base` layer
|
||||
6. Parse ORA structure, extract layers
|
||||
7. Return layer list + image data URLs
|
||||
|
||||
---
|
||||
|
||||
## Browse Dialog
|
||||
|
||||
### Purpose
|
||||
Allows users to visually navigate the project directory and select PNG/ORA files without manually typing paths.
|
||||
|
||||
### UI Layout
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ OPEN FILE │
|
||||
│ ───────────────────────────────────────────────────── │
|
||||
│ 📁 .. │
|
||||
│ 📁 scenes/ │
|
||||
│ 📁 tools/ │
|
||||
│ 🖼️ pic_010.ora │
|
||||
│ 🖼️ pic_011.png │
|
||||
│ │
|
||||
│ Current: scenes/kq4_010/ │
|
||||
│ │
|
||||
│ [Cancel] [Open Selected] │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Behavior
|
||||
- **Double-click folder**: Navigate into folder
|
||||
- **Double-click file**: Select and open immediately
|
||||
- **Single-click + Enter**: Select and open
|
||||
- ** ".." entry**: Navigate to parent directory
|
||||
- **File types**: Only show `.png` and `.ora` files
|
||||
- **Hidden files**: Excluded (dot-prefixed)
|
||||
|
||||
### Backend Implementation
|
||||
|
||||
#### `GET /api/browse`
|
||||
List directory contents for browsing.
|
||||
|
||||
**Query params:**
|
||||
- `path`: Directory path relative to project root (default: "")
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"current_path": "scenes/kq4_010",
|
||||
"parent_path": "scenes",
|
||||
"directories": [
|
||||
{"name": "subdir1", "path": "scenes/kq4_010/subdir1"}
|
||||
],
|
||||
"files": [
|
||||
{"name": "pic.png", "path": "scenes/kq4_010/pic.png", "type": "png"},
|
||||
{"name": "scene.ora", "path": "scenes/kq4_010/scene.ora", "type": "ora"}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Frontend State
|
||||
```javascript
|
||||
// Added to main store
|
||||
browseModal: false,
|
||||
browsePath: '', // Current directory being browsed
|
||||
browseDirectories: [], // List of {name, path}
|
||||
browseFiles: [], // List of {name, path, type}
|
||||
browseSelected: null, // Currently selected file path
|
||||
```
|
||||
|
||||
### Entry Point
|
||||
- Button next to path input: `[Browse...]`
|
||||
- Or clicking into the path input field (if empty)
|
||||
|
||||
---
|
||||
|
||||
@@ -247,6 +318,29 @@ Since browser cannot detect when Krita saves:
|
||||
|
||||
## API Reference
|
||||
|
||||
### File Browser
|
||||
|
||||
#### `GET /api/browse`
|
||||
List directory contents for file browsing.
|
||||
|
||||
**Query params:**
|
||||
- `path`: Directory path relative to project root (default: "")
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"current_path": "scenes/kq4_010",
|
||||
"parent_path": "scenes",
|
||||
"directories": [
|
||||
{"name": "subdir1", "path": "scenes/kq4_010/subdir1"}
|
||||
],
|
||||
"files": [
|
||||
{"name": "pic.png", "path": "scenes/kq4_010/pic.png", "type": "png"},
|
||||
{"name": "scene.ora", "path": "scenes/kq4_010/scene.ora", "type": "ora"}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### File Operations
|
||||
|
||||
#### `POST /api/open`
|
||||
@@ -525,7 +619,7 @@ Check if temp file was modified.
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────────────────┐
|
||||
│ [Open: ________________________] [🌀 Open] [Settings ⚙] │
|
||||
│ [Open: ________________________] [📁 Browse] [🌀 Open] [Settings ⚙] │
|
||||
├───────────────────┬──────────────────────────────────────────────────┤
|
||||
│ LAYERS │ │
|
||||
│ ☑ □ base │ │
|
||||
@@ -584,6 +678,31 @@ Legend: ☑ = visible checkbox, ☒ = tint red checkbox (red when checked)
|
||||
|
||||
---
|
||||
|
||||
## Browse Modal
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ OPEN FILE │
|
||||
│ ───────────────────────────────────────────────────── │
|
||||
│ 📁 .. (parent directory) │
|
||||
│ 📁 scenes/ │
|
||||
│ 📁 tools/ │
|
||||
│ 🖼️ pic_010.ora │
|
||||
│ 🖼️ pic_011.png │
|
||||
│ │
|
||||
│ Path: scenes/kq4_010/ │
|
||||
│ │
|
||||
│ [Cancel] [Open Selected] │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
- Double-click folder to navigate
|
||||
- Double-click file to open immediately
|
||||
- Single-click to select, then click "Open Selected"
|
||||
- Only shows `.png` and `.ora` files
|
||||
|
||||
---
|
||||
|
||||
## Settings Modal
|
||||
|
||||
```
|
||||
@@ -622,6 +741,7 @@ Legend: ☑ = visible checkbox, ☒ = tint red checkbox (red when checked)
|
||||
- [ ] `get_layer_image(ora_path, layer_name)` - Extract PNG
|
||||
- [ ] `get_base_image(ora_path)` - Get merged/composited base
|
||||
- [ ] Create `app.py` with Flask routes:
|
||||
- [ ] File browser (`/api/browse`)
|
||||
- [ ] File operations (`/api/open`, `/api/save`)
|
||||
- [ ] Layer operations (all `/api/layer/*`)
|
||||
- [ ] Image serving (`/api/image/*`)
|
||||
@@ -632,6 +752,7 @@ Legend: ☑ = visible checkbox, ☒ = tint red checkbox (red when checked)
|
||||
### Phase 3: Frontend UI
|
||||
- [ ] Create `editor.html` with Tailwind + Alpine.js
|
||||
- [ ] File open input and handler
|
||||
- [ ] Browse modal for file selection
|
||||
- [ ] Layer list with visibility toggles
|
||||
- [ ] Canvas area with stacked layer images
|
||||
- [ ] Layer operations (rename, delete, reorder buttons)
|
||||
|
||||
Reference in New Issue
Block a user