AppleVLC/DEVELOPMENT.md

5.2 KiB

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:

<!-- 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:

<!-- 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
<!-- 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
# 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
<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

<!-- 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

<!-- 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.)
# 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

# El .vlt es simplemente un ZIP
zip -r AppleVLC.vlt theme.xml images/ fonts/

# Verificar contenido
unzip -l AppleVLC.vlt

11. Testing y Debugging

# 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