206 lines
5.2 KiB
Markdown
206 lines
5.2 KiB
Markdown
# 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
|