docs: Add project documentation
- README.md: Project overview, features, installation guide - DEVELOPMENT.md: Lessons learned, common errors to avoid, VLC Skins2 reference, and development checklist - CLAUDE.md: Project-specific Claude Code instructions Key documented issues: - Invalid XML attributes (action on Video, var on Playtree) - Non-existent actions (dialogs.equalizer, vlc.setLoop) - Shadow rendering problems in VLC Skins2 - Margin calculations for element positioning Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
ca28ec51f6
commit
63e7e645dd
|
|
@ -0,0 +1,78 @@
|
|||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
AppleVLC is a VLC Media Player skin implementing Apple Human Interface Guidelines (HIG) design principles. It creates a macOS-style interface with superellipse corners, SF Symbols-inspired icons, and Apple color palette.
|
||||
|
||||
## Build Commands
|
||||
|
||||
```bash
|
||||
# Generate all PNG assets (buttons, sliders, background)
|
||||
python3 generate_assets_v3.py
|
||||
|
||||
# Package skin as .vlt file (zip archive)
|
||||
zip -r AppleVLC.vlt theme.xml images/ fonts/
|
||||
|
||||
# Install skin to VLC
|
||||
cp AppleVLC.vlt ~/.local/share/vlc/skins2/
|
||||
|
||||
# Test skin with VLC
|
||||
vlc --intf skins2 --skins2-last ~/.local/share/vlc/skins2/AppleVLC.vlt
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
### File Structure
|
||||
- `theme.xml` - VLC Skins2 XML definition (layout, controls, bitmaps, fonts)
|
||||
- `generate_assets_v3.py` - Python/PIL script generating all PNG assets
|
||||
- `images/` - Generated PNG files with alpha transparency
|
||||
- `fonts/` - TTF fonts (LiberationSans)
|
||||
- `AppleVLC.vlt` - Final packaged skin (zip format)
|
||||
|
||||
### VLC Skins2 Key Concepts
|
||||
|
||||
**Bitmap declarations require `alphacolor`:**
|
||||
```xml
|
||||
<Bitmap id="play_up" file="images/play_up.png" alphacolor="#FF00FF"/>
|
||||
```
|
||||
|
||||
**Button states:** Each button needs 3 images: `_up`, `_down`, `_over`
|
||||
|
||||
**Checkbox states:** 6 images: `_off_up/down/over` and `_on_up/down/over`
|
||||
|
||||
**Window dragging:** Use `action="move"` on background Image
|
||||
|
||||
**Text variables:**
|
||||
- `$N` - Track name
|
||||
- `$T` / `$D` - Current time / Duration
|
||||
- `$B` - Audio bitrate (kb/s)
|
||||
- `$V` - Volume percentage
|
||||
|
||||
**VLC Actions:**
|
||||
- `vlc.play()`, `vlc.pause()`, `vlc.stop()`
|
||||
- `playlist.previous()`, `playlist.next()`
|
||||
- `playlist.setRandom(true/false)`, `playlist.setLoop(true/false)`, `playlist.setRepeat(true/false)`
|
||||
|
||||
### Design Constants (Apple HIG)
|
||||
|
||||
```python
|
||||
APPLE = {
|
||||
'blue': (0, 122, 255, 255), # Primary action color
|
||||
'bg_primary': (242, 242, 247, 255), # Window background
|
||||
'win_close': (255, 95, 87, 255), # macOS red
|
||||
'win_min': (255, 189, 46, 255), # macOS yellow
|
||||
'win_max': (39, 201, 63, 255), # macOS green
|
||||
}
|
||||
```
|
||||
|
||||
**Touch targets:** Minimum 44px for all interactive controls
|
||||
|
||||
### Workflow
|
||||
|
||||
1. Edit `generate_assets_v3.py` to modify icons/colors
|
||||
2. Run `python3 generate_assets_v3.py` to regenerate PNGs
|
||||
3. Edit `theme.xml` to modify layout/controls
|
||||
4. Package with `zip -r AppleVLC.vlt theme.xml images/ fonts/`
|
||||
5. Test with VLC using skins2 interface
|
||||
|
|
@ -0,0 +1,205 @@
|
|||
# Guía de Desarrollo - AppleVLC Skin
|
||||
|
||||
## Lecciones Aprendidas y Errores a Evitar
|
||||
|
||||
### 1. Validación XML Estricta
|
||||
|
||||
VLC Skins2 usa un DTD estricto. **SIEMPRE** verificar que los atributos sean válidos.
|
||||
|
||||
#### Atributos NO válidos encontrados:
|
||||
```xml
|
||||
<!-- INCORRECTO - "action" no existe en Video -->
|
||||
<Video id="videoArea" action="dialogs.popup()"/>
|
||||
|
||||
<!-- INCORRECTO - "var" y "action" no existen en Playtree -->
|
||||
<Playtree id="playtree" var="playlist" action="dialogs.playlist()"/>
|
||||
```
|
||||
|
||||
#### Corrección:
|
||||
```xml
|
||||
<!-- CORRECTO -->
|
||||
<Video id="videoArea" autoresize="false"/>
|
||||
<Playtree id="playtree" flat="false"/>
|
||||
```
|
||||
|
||||
### 2. Acciones Válidas en VLC Skins2
|
||||
|
||||
#### Acciones que SÍ funcionan:
|
||||
```
|
||||
vlc.play() vlc.pause() vlc.stop()
|
||||
vlc.quit() vlc.minimize() vlc.fullscreen()
|
||||
vlc.mute() vlc.volumeUp() vlc.volumeDown()
|
||||
|
||||
playlist.next() playlist.previous()
|
||||
playlist.setRandom(true/false)
|
||||
playlist.setLoop(true/false)
|
||||
playlist.setRepeat(true/false)
|
||||
|
||||
dialogs.popup() # Menú contextual
|
||||
windowName.show() windowName.hide()
|
||||
```
|
||||
|
||||
#### Acciones que NO funcionan:
|
||||
```
|
||||
dialogs.equalizer() # NO EXISTE
|
||||
dialogs.extended() # NO EXISTE
|
||||
dialogs.playlist() # NO EXISTE
|
||||
vlc.setLoop() # NO EXISTE (usar playlist.setLoop)
|
||||
```
|
||||
|
||||
### 3. Márgenes y Posicionamiento
|
||||
|
||||
#### Problema encontrado:
|
||||
Elementos aparecían cortados o fuera del fondo.
|
||||
|
||||
#### Solución:
|
||||
- **Siempre** dejar mínimo 20px de margen en todos los bordes
|
||||
- Calcular posiciones desde el margen, no desde 0
|
||||
- Fórmula: `elemento_x = margen + offset_deseado`
|
||||
|
||||
```xml
|
||||
<!-- Ventana 500x225 con márgenes de ~25px -->
|
||||
<Layout width="500" height="225">
|
||||
<!-- Elementos empiezan en x=24-30, no en x=0 -->
|
||||
<Button id="closeBtn" x="24" y="24"/>
|
||||
</Layout>
|
||||
```
|
||||
|
||||
### 4. Sombras en VLC Skins
|
||||
|
||||
#### Problema:
|
||||
Las sombras difusas NO funcionan correctamente en VLC Skins2. Aparecen como bordes negros sólidos en lugar de sombras suaves.
|
||||
|
||||
#### Solución:
|
||||
- **NO usar sombras** en los assets PNG
|
||||
- Usar bordes sutiles con alpha bajo: `rgba(0,0,0,0.08)`
|
||||
- El fondo debe ser limpio sin efectos de sombra
|
||||
|
||||
```python
|
||||
# INCORRECTO - sombra que no funciona
|
||||
shadow = img.filter(ImageFilter.GaussianBlur(10))
|
||||
|
||||
# CORRECTO - borde sutil
|
||||
draw.rounded_rectangle([0,0,w-1,h-1], radius=20,
|
||||
outline=(0,0,0,20), width=1)
|
||||
```
|
||||
|
||||
### 5. Checkbox vs Button para Estados
|
||||
|
||||
#### Usar Checkbox cuando:
|
||||
- El control tiene dos estados persistentes (on/off)
|
||||
- Ejemplos: Shuffle, Repeat, Mute
|
||||
|
||||
```xml
|
||||
<Checkbox id="shuffleBtn"
|
||||
up1="shuffle_off_up" down1="shuffle_off_down" over1="shuffle_off_over"
|
||||
up2="shuffle_on_up" down2="shuffle_on_down" over2="shuffle_on_over"
|
||||
action1="playlist.setRandom(true)" action2="playlist.setRandom(false)"
|
||||
state="playlist.isRandom"/>
|
||||
```
|
||||
|
||||
#### Usar Button cuando:
|
||||
- Es una acción momentánea
|
||||
- Ejemplos: Play, Stop, Next, Previous
|
||||
|
||||
### 6. Variables de Texto VLC
|
||||
|
||||
```
|
||||
$N - Nombre del track (título)
|
||||
$T - Tiempo actual (0:00:00)
|
||||
$D - Duración total
|
||||
$B - Bitrate (kb/s)
|
||||
$S - Sample rate (kHz)
|
||||
$V - Volumen (%)
|
||||
$F - Nombre del archivo
|
||||
$P - Posición (%)
|
||||
```
|
||||
|
||||
### 7. Visibilidad Condicional
|
||||
|
||||
```xml
|
||||
<!-- Mostrar Play cuando NO está reproduciendo -->
|
||||
<Button id="playBtn" visible="not vlc.isPlaying"/>
|
||||
|
||||
<!-- Mostrar Pause cuando SÍ está reproduciendo -->
|
||||
<Button id="pauseBtn" visible="vlc.isPlaying"/>
|
||||
|
||||
<!-- Volumen normal vs Mute -->
|
||||
<Button id="volumeBtn" visible="not vlc.isMute"/>
|
||||
<Button id="muteBtn" visible="vlc.isMute"/>
|
||||
```
|
||||
|
||||
### 8. Estructura de Slider
|
||||
|
||||
```xml
|
||||
<!-- Track de fondo (imagen estática) -->
|
||||
<Image id="sliderBg" x="30" y="70" image="slider_track"/>
|
||||
|
||||
<!-- Slider interactivo (encima del track) -->
|
||||
<Slider id="timeSlider" x="30" y="63"
|
||||
up="slider_knob_up" down="slider_knob_down" over="slider_knob_over"
|
||||
points="(0,10),(440,10)" thickness="20"
|
||||
value="time"/>
|
||||
```
|
||||
|
||||
- `points`: Define inicio y fin del recorrido del knob
|
||||
- `thickness`: Área clickeable vertical
|
||||
- El knob debe posicionarse ~7px arriba del track para centrado visual
|
||||
|
||||
### 9. Generación de Assets PNG
|
||||
|
||||
#### Requisitos:
|
||||
- Canal alpha real (RGBA)
|
||||
- `alphacolor="#FF00FF"` en theme.xml para compatibilidad
|
||||
- Tamaño exacto según uso (44x44 para botones, etc.)
|
||||
|
||||
```python
|
||||
# Crear imagen con alpha
|
||||
img = Image.new('RGBA', (44, 44), (0, 0, 0, 0))
|
||||
|
||||
# Guardar con alpha
|
||||
img.save('button.png', 'PNG')
|
||||
```
|
||||
|
||||
### 10. Empaquetado del Skin
|
||||
|
||||
```bash
|
||||
# El .vlt es simplemente un ZIP
|
||||
zip -r AppleVLC.vlt theme.xml images/ fonts/
|
||||
|
||||
# Verificar contenido
|
||||
unzip -l AppleVLC.vlt
|
||||
```
|
||||
|
||||
### 11. Testing y Debugging
|
||||
|
||||
```bash
|
||||
# Ejecutar VLC con skin específica
|
||||
vlc -I skins2 --skins2-last /ruta/AppleVLC.vlt
|
||||
|
||||
# Ver errores en terminal
|
||||
vlc -I skins2 --skins2-last /ruta/AppleVLC.vlt 2>&1 | grep -E "(error|warning)"
|
||||
|
||||
# Forzar cierre si se cuelga
|
||||
pkill -9 vlc
|
||||
```
|
||||
|
||||
### 12. Referencia DTD
|
||||
|
||||
El DTD oficial está en:
|
||||
`http://www.videolan.org/vlc/skins2-0.dtd`
|
||||
|
||||
Elementos principales válidos:
|
||||
- Theme, ThemeInfo, Bitmap, Font, Window, Layout
|
||||
- Button, Checkbox, Image, Text, Slider, Video, Playtree
|
||||
|
||||
## Checklist Pre-Release
|
||||
|
||||
- [ ] Verificar que theme.xml valida contra el DTD
|
||||
- [ ] Probar todos los botones y controles
|
||||
- [ ] Verificar que no hay elementos cortados
|
||||
- [ ] Probar con audio y video
|
||||
- [ ] Verificar estados hover/down en todos los botones
|
||||
- [ ] Probar shuffle, repeat, repeat one
|
||||
- [ ] Verificar slider de tiempo y volumen
|
||||
- [ ] Probar minimizar y cerrar ventana
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
# AppleVLC - VLC Media Player Skin
|
||||
|
||||
Skin moderna para VLC Media Player inspirada en Apple Human Interface Guidelines.
|
||||
|
||||
## Características
|
||||
|
||||
- **Diseño limpio**: Fondo con esquinas redondeadas (superelipse/squircle) estilo Apple
|
||||
- **Controles intuitivos**: Botones de 44px siguiendo las guías de Apple para touch targets
|
||||
- **Información completa**: Título, tiempo, bitrate y sample rate visibles
|
||||
- **Controles de ventana**: Solo cerrar y minimizar (sin maximizar, al estilo macOS)
|
||||
- **Estados visuales**: Hover con tinte azul Apple (#007AFF), estados disabled
|
||||
- **Iconos secundarios**: Color gris sistema (#8E8E93) para jerarquía visual
|
||||
|
||||
## Controles Disponibles
|
||||
|
||||
### Fila Principal
|
||||
- Stop, Playlist, Shuffle, Previous, Play/Pause, Next, Repeat All, Repeat One, Fullscreen
|
||||
|
||||
### Fila Inferior
|
||||
- Volume (con slider), Equalizer, A-B Loop, Speed
|
||||
|
||||
### Ventanas Adicionales
|
||||
- Video Window (640x480, redimensionable)
|
||||
- Playlist Window (320x400)
|
||||
- Fullscreen Controller
|
||||
|
||||
## Instalación
|
||||
|
||||
1. Copiar `AppleVLC.vlt` a `~/.local/share/vlc/skins2/`
|
||||
2. En VLC: Herramientas → Preferencias → Interfaz → Usar skin personalizado
|
||||
3. Seleccionar AppleVLC.vlt
|
||||
4. Reiniciar VLC
|
||||
|
||||
O ejecutar directamente:
|
||||
```bash
|
||||
vlc -I skins2 --skins2-last /ruta/a/AppleVLC.vlt
|
||||
```
|
||||
|
||||
## Estructura del Proyecto
|
||||
|
||||
```
|
||||
PielVLC/
|
||||
├── AppleVLC.vlt # Skin empaquetada (ZIP)
|
||||
├── theme.xml # Definición de la interfaz
|
||||
├── generate_assets_v3.py # Script para generar PNGs
|
||||
├── images/ # Assets PNG generados
|
||||
├── fonts/ # Fuentes Liberation Sans
|
||||
└── DEVELOPMENT.md # Guía de desarrollo
|
||||
```
|
||||
|
||||
## Especificaciones Técnicas
|
||||
|
||||
- **Dimensiones**: 500x225 px (ventana principal)
|
||||
- **Márgenes**: 20-30px en todos los bordes
|
||||
- **Track slider**: 8px de altura, 440px de ancho
|
||||
- **Volume slider**: 6px de altura, 80px de ancho
|
||||
- **Colores**:
|
||||
- Fondo: #F5F5F7 (Apple Light Gray)
|
||||
- Texto primario: #000000
|
||||
- Texto secundario: #3C3C43
|
||||
- Iconos secundarios: #8E8E93
|
||||
- Acento: #007AFF (Apple Blue)
|
||||
- Borde sutil: rgba(0,0,0,0.08)
|
||||
|
||||
## Regenerar Assets
|
||||
|
||||
```bash
|
||||
python3 generate_assets_v3.py
|
||||
zip -r AppleVLC.vlt theme.xml images/ fonts/
|
||||
```
|
||||
|
||||
## Requisitos
|
||||
|
||||
- VLC 3.0+ con soporte skins2
|
||||
- Python 3 + Pillow (solo para regenerar assets)
|
||||
|
||||
## Autor
|
||||
|
||||
Claude Code - Anthropic
|
||||
|
||||
## Licencia
|
||||
|
||||
MIT License
|
||||
Loading…
Reference in New Issue