# Manual de &ksplash;

## Introducción

&ksplash; es una bonita pantalla que muestra el progreso de una aplicación que se esté cargando. Por favor, informe de cualquier problema o petición de característica a través de las listas de correo de &kde;. Las características principales de &ksplash; son:

- Es posible utilizar temas.
- Utiliza extensiones para conseguir una personalización completa.
- Puede ser utilizado por cualquier aplicación que utilice DCOP.

Este manual le mostrará cómo crear temas para utilizar con las extensiones que estén disponibles. Si ninguna de las extensiones disponibles satisface sus gustos, puede aprender a personalizar por completo el aspecto de &ksplash; escribiendo una extensión en C++.

## Utilizar temas

Para utilizar los temas de KDE-Look, extraígalos a `~/.kde/share/apps/ksplash/Themes/` para un usuario concreto, o a `$`KDEDIR`/share/apps/ksplash/Themes/` para que estén disponibles para todos los usuarios de su sistema.

También puede utilizar el módulo Pantalla anunciadora en Aspecto en el centro de control de &kde; para hacer esto automáticamente.

### Utilizar el módulo de &kcontrol;

Este módulo le permite instalar, comprobar y eliminar temas de &ksplash;.Este módulo le permite instalar, comprobar y eliminar temas de &ksplash;.

En la parte inferior de este módulo hay una lista con los temas disponibles para &ksplash;. Una vez que haya seleccionado una, se mostrará una previsualización en la parte principal de la ventana. Una vez que haya seleccionado la que desea utilizar, pulse Aceptar o Aplicar. Pulse Cancelar para salir del módulo sin hacer cambios, y Predeterminados para restaurar los valores predeterminados de la pantalla.

Para instalar nuevos módulos, pulse Añadir..., y encuentre el tema en su ordenador. No necesita desempaquetar el archivo con el tema, solo tiene que seleccionar el archivo comprimido. El hecho de instalar un tema no hace de él el tema en uso, deberá seleccionarlo de la lista y pulsar Aceptar o Aplicar.

Aunque pueda ver una vista previa de la pantalla anunciadora, puede que quiera ver cómo aparece realmente, por ejemplo, para ver cómo es la animación. Podrá verificar los temas seleccionables pulsando el botón Test.

También podrá eliminar temas que no vaya a volver a utilizar, seleccionándolos y pulsando el botón Eliminar. Tenga en cuenta que su cuenta de usuario puede no tener permisos para eliminar los temas instalados para todo el sistema. También es recomendable no desinstalar la pantalla anunciadora predeterminada.

## Cómo hacer temas para &ksplash;

### General

Hacer sus propios temas para &ksplash; es sencillo. Una vez que haya terminado su tema podrá enviarlo a KDE-Look para que otros puedan utilizarlo.

#### Identificar su tema

Permítanos crear un tema llamado `MiBonitoTema`. Para que el tema sea reconocido por &ksplash;, debería guardarse en una carpeta llamada `MiBonitoTema` en `~/.kde/apps/ksplash/Themes/`. Debería tener un archivo llamado `Theme.rc`, conteniendo las configuraciones del tema. Puede especificar numerosas cosas en el tema, cambiar la extensión del motor de uso, etc. No necesita utilizar todas las configuraciones disponibles. Normalmente los valores predeterminados suelen ser correctos. La sintaxis básica para las entradas del archivo `Theme.rc` es `[opción] = [valor]`. Podrá encontrar las definiciones de varias opciones en las siguientes secciones.

##### Un archivo `Theme.rc` sencillo

    [KSplash Theme: MiBonitoTema]
    Name = MiBonitoTema
    Description = Un bonito tema utilizando el motor XpLike
    Version = 1.0
    Author = Nombre real <nombrereal@correo.com>
    ## Utiliza el motor XpLike para este tema.
    Engine = XpLike
    Show Icon = false
    Welcome Text = Cargando KDE

Después de especificar el nombre, la descripción y el autor del tema, debe seleccionar el motor del tema (es una extensión). A continuación podrá personalizar varias características del motor del tema asignando pares clave-valor como en el ejemplo anterior.

Es importante que el nombre del directorio bajo el que se hayan guardado los archivos del tema (`~/.kde/apps/ksplash/Themes/MiBonitoTema` en nuestro caso) y el identificador (`[KSplash Theme: MiBonitoTema]` en nuestro caso) en el archivo `Theme.rc` sean idénticos. Sino &ksplash; no reconocerá el tema.

#### Archivos de fondo

Cuando se inicia &ksplash;, intenta encontrar una imagen de fondo para su resolución de pantalla actual, si es que el motor del tema utiliza una. El archivo de imagen del fondo debería tener un nombre que siga el formato `Background-`WWWxHHH`.png`.

Por ejemplo, podría utilizar un archivo llamado `Background-1024x768`. Sino puede encontrar una imagen de fondo para su resolución de pantalla, intenta redimensionar el `Background.png` original o el archivo especificado en `Theme.rc` para adaptarlo a la resolución actual. Redimensionar la imagen sobre la marcha llevará cierto tiempo, por tanto, debería proporcionar imágenes de fondo, al menos para los siguientes tamaños: 1280x1024, 1024x768 y 800x600.

### Opciones del motor de temas

#### Tema predeterminado

#### Opciones del tema predeterminado

Nombre | Argumento | Descripción
Mostrar siempre el progreso | [true/false] (verdadero/falso) | Indica si se debe mostrar el progreso de carga. El valor predeterminado es true (verdadero).
Etiqueta del segundo plano | [color] | Determina el color que se utilizará en el texto de la barra de estado. El valor predeterminado es #FFFFFF (blanco).
Iconos destelleantes | [true/false] (verdadero/falso) | Indica si se mostrarán los iconos con «destellos». El valor predeterminado es true (verdadero).

#### Tema estándar

#### Opciones del tema estándar

Nombre | Argumento | Descripción
Statusbar Position | [top/bottom] (arriba/abajo) | Cambia la posición de la barra de estado en la pantalla. El valor predeterminado es bottom (abajo).
Statusbar Visible | [true/false] (verdadero/falso) | Indica si se debe mostrar la barra de estado. El valor predeterminado es true (verdadero).Indica si se debe mostrar la barra de estado. El valor predeterminado es true (verdadero).
Progress Visible | [true/false] (verdadero/falso) | Indica si se debe mostrar el progreso de carga. El valor predeterminado es true (verdadero).
Statusbar Font | [nombreletra] | El tipo de letra utilizado en la barra de estado. El valor predeterminado es Helvetica.El tipo de letra utilizado en la barra de estado. El valor predeterminado es Helvetica.
Statusbar Font Size | [tamaño] | El tamaño de la letra para la barra de estado. El valor predeterminado es 16.El tamaño de la letra para la barra de estado. El valor predeterminado es 16.
Statusbar Font Bold | [true/false] (verdadero/falso) | Indica si la letra de la barra de estado debe estar en negrita. El valor predeterminado es true (verdadero).Indica si la letra de la barra de estado debe estar en negrita. El valor predeterminado es true (verdadero).
Statusbar Font Italic | [true/false] (verdadero/falso) | Indica si la letra de la barra de estado debe estar en cursiva. El valor predeterminado es false (falso).Indica si la letra de la barra de estado debe estar en cursiva. El valor predeterminado es false (falso).
Statusbar Foreground | [color] | El color del primer plano de la barra de estado. El valor predeterminado es white (blanco).El color del primer plano de la barra de estado. El valor predeterminado es white (blanco).
Statusbar Background | [color] | El color del fondo de la barra de estado. El valor predeterminado es black (negro).El color del fondo de la barra de estado. El valor predeterminado es black (negro).
Statusbar Icon | [true/false] (verdadero/falso) | Indica si la barra de estado tendrá un icono.
Icons Visible | [true/false] (verdadero/falso) | Indica si los iconos serán visibles. El valor predeterminado es true (verdadero).Indica si los iconos serán visibles. El valor predeterminado es true (verdadero).
Icons Jumping | [true/false] (verdadero/falso) | Indica si los iconos saltarán. El valor predeterminado es true (verdadero).Indica si los iconos saltarán. El valor predeterminado es true (verdadero).
Icon Position | [0-3,10-13] | Indica la posición en la que se muestran los iconos. El valor predeterminado es abajo a la izquierda.Indica la posición en la que se muestran los iconos. El valor predeterminado es abajo a la izquierda.
Splash Screen | [nombre] | Cambia la imagen que se muestra en la pantalla de inicio.

#### Tema Redmond

#### Opciones del tema Redmon

Nombre | Argumento | Descripción
Background Image | [nombrearchivo] | Imagen a utilizar como fondo.
User Icon | [nombreicono] | Nombre del icono estándar que se utilizará para el usuario. El valor predeterminado es `go`.
Welcome Text | [texto] | Texto que se muestra en la pantalla de inicio. El valor predeterminado es «Bienvenido».Texto que se muestra en la pantalla de inicio. El valor predeterminado es «Bienvenido».
Username Text | [texto] | Texto que se muestra en lugar del nombre real del usuario.
Welcome Text Position | [x,y] | Posición en la que se mostrará el texto de Bienvenida.
Username Text Position | [x,y] | Posición de la pantalla en la que se mostrará el nombre del usuario.
Action Text Position | [x,y] | Posición de la pantalla en la que se mostrará la acción que se está realizando.Posición de la pantalla en la que se mostrará la acción que se está realizando.
Icon Position | [x,y] | Posición de la pantalla en la que se mostrará el icono de usuario.
Show Welcome Text | [true/false] (verdadero/falso) | Indica si se mostrará el texto de bienvenida. El valor predeterminado es true (verdadero).Indica si se mostrará el texto de bienvenida. El valor predeterminado es true (verdadero).
Show Welcome Shadow | [true/false] (verdadero/falso) | Indica si se sombreará el texto de bienvenida. El valor predeterminado es true (verdadero).Indica si se sombreará el texto de bienvenida. El valor predeterminado es true (verdadero).
Show Username | [true/false] (verdadero/falso) | Indica si se mostrará el nombre de usuario. El valor predeterminado es true (verdadero).Indica si se mostrará el nombre de usuario. El valor predeterminado es true (verdadero).
Show Action | [true/false] (verdadero/falso) | Indica si se mostrará la acción que se está llevando a cabo. El valor predeterminado es true (verdadero).Indica si se mostrará la acción que se está llevando a cabo. El valor predeterminado es true (verdadero).
Show Icon | [true/false] (verdadero/falso) | Indica si se mostrará el icono. El valor predeterminado es true (verdadero).Indica si se mostrará el icono. El valor predeterminado es true (verdadero).
Use KDM User Icon | [true/false] (verdadero/falso) | Indica si se mostrará el icono de acceso del usuario. El valor predeterminado es true (verdadero).Indica si se mostrará el icono de acceso del usuario. El valor predeterminado es true (verdadero).

#### Tema MacX

#### Opciones del tema MacX

Nombre | Argumento | Descripción
Icon Size Minimum | [tamaño] | Establece el tamaño mínimo de los iconos. El valor predeterminado es 16.Establece el tamaño mínimo de los iconos. El valor predeterminado es 16.
Icon Size Maximum | [tamaño] | Establece el tamaño máximo de los iconos. El valor predeterminado es 64.Establece el tamaño máximo de los iconos. El valor predeterminado es 64.
Optimized Icon Rendering | [true/false] (verdadero/falso) | Indica si se optimizará la presentación del icono. El valor predeterminado es true (verdadero).Indica si se optimizará la presentación del icono. El valor predeterminado es true (verdadero).
Progress Bar Visible | [true/false] (verdadero/falso) | Indica si la barra de progreso estará visible. El valor predeterminado es true (verdadero).Indica si la barra de progreso estará visible. El valor predeterminado es true (verdadero).
Progress Bar Position | [top/bottom] (arriba/abajo) | Indica si la barra de estado se situará en la parte superior o inferior. El valor predeterminado es bottom (abajo).
Icons Jumping | [true/false] (verdadero/falso) | Indica si los iconos saltarán. El valor predeterminado es false (falso).Indica si los iconos saltarán. El valor predeterminado es false (falso).

#### Tema MacClassic

#### Opciones del tema MacClassic

Nombre | Argumento | Descripción
Icon Position | [0-3,10-13] | Posición de los iconos en la pantalla. El valor predeterminado es abajo a la izquierda.Posición de los iconos en la pantalla. El valor predeterminado es abajo a la izquierda.
Icons Jumping | [true/false] (verdadero/falso) | Indica si los iconos saltarán. El valor predeterminado es false (falso).Indica si los iconos saltarán. El valor predeterminado es false (falso).
Icons Visible | [true/false] (verdadero/falso) | Indica si los iconos serán visibles. El valor predeterminado es true (verdadero).Indica si los iconos serán visibles. El valor predeterminado es true (verdadero).
Splash Screen | [nombre] | Cambia la imagen que se muestra en la pantalla de inicio.

#### Tema 2k

#### Opciones del tema 2k

Nombre | Argumento | Descripción
Title Background Color | [color] | Color del fondo del título. El valor predeterminado es dark blue (azul oscuro).Color del fondo del título. El valor predeterminado es dark blue (azul oscuro).
Title Foreground Color | [color] | Color del primer plano del título. El valor predeterminado es white (blanco).Color del primer plano del título. El valor predeterminado es white (blanco).
Status Text Color | [color] | Color del texto de estado. De forma predeterminada será el mismo que el del fondo.Color del texto de estado. De forma predeterminada será el mismo que el del fondo.
Rotator Color 1 | [color] | Define el color del rotador 1. El valor predeterminado es dark blue (azul oscuro).Define el color del rotador 1. El valor predeterminado es dark blue (azul oscuro).
Rotator Color 2 | [color] | Define el color del rotador 2. El valor predeterminado es cyan (azul cian).Define el color del rotador 2. El valor predeterminado es cyan (azul cian).
Rotator Speed | [valor] | Define la velocidad de giro. El valor predeterminado es 30.
Window Title | [texto] | Especifica el texto del título de la ventana.
Logo File | [nombrearchivo] | Define el logotipo utilizado.

## Utilizar &ksplash; dentro de su aplicación.

En este capítulo describiremos un método sencillo para utilizar &ksplash; como la pantalla de inicio de su aplicación &kde;. Sino desarrolla aplicaciones para &kde; puede saltarse este capítulo.

### Requisitos básicos

Sus aplicaciones &kde;, deberían ser capaces de utilizar &DCOP;. &DCOP; es la tecnología de &kde; utilizada para la comunicación entre aplicaciones. Si utiliza la estructura de aplicación &kde; estándar, se incluirá automáticamente. Para obtener información sobre &DCOP; y las tecnologías relacionadas con &kde;, vea la página de los desarrolladores de &kde;.

### Iniciando &ksplash;

Antes de que su aplicación se inicie comience a trabajar, o antes de que comience a cargar extensiones, &etc;, llame a &ksplash; de la siguiente forma:

    DCOPClient *c = kapp->dcopClient();
    QString error;
    QCString KSplashName;
    int pid = 0;
    QStringList args;
    args << "--theme=MiBonitoTema" << "--managed";
    if (kapp->startServiceByDesktopName("ksplash", args, &error, &KSplashName, &pid))
    {
      KMessageBox::sorry(0, error, "Imposible llamar a KSplash");
      // Aquí se procesará el error.
    }

Asumiremos que solo hay una instancia de &ksplash; en ejecución. El resto de los casos son algo más complejos. Por favor, vea la documentación de &DCOP; para obtener detalles más amplios.

### Mostrar mensajes

Antes de mostrar cualquier mensaje, necesitará definir el número de pasos que se mostrarán. Por ejemplo, el procedimiento de inicio de &kde; utiliza 7 pasos.

    QByteArray data;
        QDataStream arg(data,IO_WriteOnly);
        arg << cualquierNumero;
        if (!(c->send(KSplashName, "KSplashIface", "setStartupItemCount(int)", data))
          // Aquí se procesará el error.

Cuando quiera mostrar un mensaje, con o sin icono, utilice:

    arg << QString("nombreIcono") << QString("nombrePrograma") << QString("Alguna descripción");
        if (!(c->send(KSplashName, "KSplashIface", "programStarted(QString,QString,QString)", data))
        {
          // Aquí se procesará el error.
        }

Cada vez que llame a `programStarted`, se incrementarán los pasos completados. Cuando su programa haya terminado de iniciarse, haga lo siguiente para hacer que la pantalla de inicio desaparezca:

    if (!(c->send(KSplashName, "KSplashIface", "startupComplete()", data))
        {
          // Aquí se procesará el error.
        }

¡Ya está! si es que no necesita nada más de todas las posibilidades que le ofrece &ksplash;.¡Ya está! si es que no necesita nada más de todas las posibilidades que le ofrece &ksplash;.

## Escribiendo nuevas extensiones para &ksplash;

Escribir extensiones nuevas para &ksplash; no es difícil. En este capítulo, escribiremos una extensión sencilla que emulará la pantalla de inicio de un sistema operativo bien conocido. Este tutorial asume que tiene conocimientos básicos de C++ y un poco de programación KDE/Qt.

### Requisitos básicos

Crearemos una extensión llamada `2k`. El nombre de la extensión se utiliza en varios lugares, y es importante que lo utilice consistentemente para que la extensión sea reconocida por &ksplash;. Las extensiones de &ksplash; son bibliotecas que se pueden cargar dinámicamente y que siguen la siguiente convención para los nombres:

- La biblioteca debería llamarse `ksplash+nombretemaenminusculas`. En nuestro caso será `ksplash2k`.
- Debería tener su correspondiente archivo desktop llamado `ksplash+nombretemaenminusculas.desktop`. En nuestro caso será `ksplash2k.desktop`.
- Finalmente, el objeto devuelto por la biblioteca debería ser una clase llamada `Theme+nombretema`. En nuestro caso, será `Theme2k`.

No se preocupe sino entiende todo lo anterior. Veremos cada uno de estos puntos con más detalle posteriormente. Otro detalle importante es que la clase de la extensión debería derivar de `ThemeEngine`.

### Construir la estructura del esqueleto

Utilizaremos la estructura de una aplicación &kde; para construir la extensión de forma que sea independiente de la plataforma, y ello, sin ningún trabajo por nuestra parte. Para hacer esto asegúrese de que tiene instalado el paquete `kdesdk`. Ejecute la orden `kapptemplate` para crear una aplicación llamada «2k». Esto creará una estructura de carpetas que contendrán archivos genéricos tales como AUTHORS, &etc;. Estamos más interesados en la subcarpeta llamada `2k`. Vaya a la subcarpeta y borre todos sus archivos. Ahora ya tenemos el esqueleto que necesitamos.

El siguiente paso es crear un archivo `.desktop` que, cuando se instale, le diga a &ksplash; que nuestra extensión está disponible. De acuerdo con la convención de nombre tratada en la sección anterior, crearemos un archivo llamado `ksplash2k.desktop` en esta carpeta. Debería contener las siguientes líneas:

    [Desktop Entry]
    Encoding=UTF-8
    Type=Service
    Comment=Extensión KSplash
    Name=KSplash2k
    ServiceTypes=KSplash/Plugin
    X-KDE-Library=ksplash2k
    X-KSplash-Default=true
    X-KSplash-PluginName=2k
    X-KSplash-ObjectName=Theme2k

`Encoding`, `Type`, `Comment` y `ServiceTypes` son iguales para todas las extensiones. El nombre de la extensión y de la biblioteca siguen las convenciones tratadas antes. La entrada `X-KSplash-Default` es un valor lógico que determina si se mostrará en el módulo de configuración del panel de control de forma predeterminada. Excepto para casos muy raros debería ser `true` (verdadero).

### Declaración de la clase de extensión

Ya tenemos el trabajo previo hecho, déjenos introducirle en la parte más divertida, crear una clase que proporcionará el comportamiento deseado. A pesar de que somos libres para que esta clase haga lo que queramos, existen algunas restricciones.

1. Las clases de las extensiones deben heredarse de la clase `ThemeEngine`.Las clases de las extensiones deben heredarse de la clase `ThemeEngine`.

2. Las clases de las extensiones deben nombrarse de acuerdo con la regla: `Theme+NombreExtension`.

3. Las clases de las extensiones deberían proporcionar una función `static` llamada `names` que devuelva una lista de nombres que puedan ser llamados.

4. Si la extensión puede configurarse en el módulo del centro de control, debería proporcionar una clase basada en `ThemeEngineConfig` para la configuración.

5. Las clases de las extensiones pueden sobreescribir, al menos, las funciones virtuales `slotSetText`, `slotSetPixmap`, `slotUpdateProgress` y `slotUpdateSteps` para hacerlo utilizable.

6. El constructor debería tener la forma `ThemeEngine( QWidget *parent, const char *name, const QStringList &args )`, y por tanto, puede ser utilizado con `KGenericFactory`.

El último requisito puede parecer complicado, pero, como se verá posteriormente bastará con añadir una línea a sus archivos fuente, y que generalmente podrá ignorar.

### Código para el archivo de cabecera

Proporciona las constantes, y veremos que el archivo de cabecera `theme2k.h` debería ser algo parecido a esto:

#### Listado de `theme2k.h`

    #ifndef __THEME2K_H__
    #define __THEME2K_H__

    #include <qlabel.h>
    #include <qwidget.h>

    #include <kdialogbase.h>
    #include <kpixmap.h>
    #include <ksplash/themeengine.h>

    class RotWidget;

    class Cfg2k: public ThemeEngineConfig
    {
      Q_OBJECT
    public:
      Cfg2k( KConfig * );
    };

    class ObjKsTheme;
    class Theme2k: public ThemeEngine
    {
      Q_OBJECT
    public:
      Theme2k( QWidget *, const char *, const QStringList& );

      inline const QString name()
      {
        return( QString("KSplash2k") );
      }
      inline const KDialogBase *config( KConfig *kc )
      {
        return new Cfg2k( kc );
      }
      static QStringList names()
      {
        QStringList Names;
        Names << "KSplash2k";
        Names << "ks2k";
        Names << "2k";
        Names << "2000";
        return( Names );
      };

    public slots:
      inline void slotSetText( const QString& s )
      {
        if( mText && mText->text() != s ) mText->setText( s );
      };

    private:
      void initUi();
      void readSettings();

      QLabel *mText;
      RotWidget *mRotator;
      QColor mTBgColor, mTFgColor, mRotColor1, mRotColor2, mStatusColor;
      int mRotSpeed;
      QString mWndTitle, mLogoFile;
    };

    #endif

Analicemos el listado anterior. La clase `Theme2k` cumple con la convención de nombres, y está heredada de `ThemeEngine`. Proporciona `Theme2k::names()`, y tiene un constructor que toma los parámetros requeridos: `Theme2k( QWidget *, const char *, const QStringList& );` y también proporciona un método simple `Theme2k::slotSetText()`. Por el momento no se preocupe de la clase `RotWidget`. Es un pequeño componente que proporcionará algo que le gustará al usuario. Nuestra extensión es muy simple y no muestra iconos en la barra de progreso. Si desea mostrar iconos, sobreescriba la función `slotSetPixmap`. Existen funciones similares para configurar los pasos de la barra de progreso (`slotUpdateSteps`) e incrementan el paso actual (`slotUpdateProgress`).

### Implementación de la extensión

Sólo examinaremos las partes relevantes de la implementación. Para obtener la impletación completa, véa el apéndice. Lo primero que haremos es cargar la librería:

#### Librería requerida

    K_EXPORT_COMPONENT_FACTORY( ksplash2k, KGenericFactory<Theme2k> );K_EXPORT_COMPONENT_FACTORY( ksplash2k, KGenericFactory<Theme2k> );

La macro `K_EXPORT_COMPONENT_FACTORY` está declarada en `kgenericfactory.h`. ¡Ahora vamos con el constructor! Como esta es una extensión muy sencilla, el constructor es muy sencillo.

#### Constructor de la extensión

    Theme2k::Theme2k( QWidget *parent, const char *name, const QStringList &args
     )
        :ThemeEngine( parent, name, args )
    {
      readSettings();
      initUi();
    }

El método `readSettings()` ilustra la forma de obtener la configuración de su tema (Desea que la gente utilice sus extensiones ¿no es cierto?).

#### Obtener las configuraciones del tema

    void Theme2k::readSettings()
    {
      if( !mTheme )
        return;

      KConfig *cfg = mTheme->themeConfig();
      if( !cfg )
        return;

      cfg->setGroup( QString("Tema KSplash: %1").arg(mTheme->theme()) );

      QColor DefaultTBgColor( Qt::darkBlue );
      QColor DefaultTFgColor( Qt::white );

      mTBgColor = cfg->readColorEntry( "Color del fondo del título", &DefaultTBgColor );
      mTFgColor = cfg->readColorEntry( "Color del primer plano del título", &DefaultTFgColor );
      mStatusColor = cfg->readColorEntry("Status Text Color", &mTBgColor );

      QColor DefaultRot1( Qt::darkBlue );
      QColor DefaultRot2( Qt::cyan );
      mRotColor1 = cfg->readColorEntry( "Color del rotator 1", &DefaultRot1 );
      mRotColor2 = cfg->readColorEntry( "Color del rotador 2", &DefaultRot2 );

      mRotSpeed = cfg->readNumEntry( "Velocidad de rotación", 30 );
      mWndTitle = cfg->readEntry( "Título de la ventana", i18n("Por favor espere...") );
      mLogoFile = cfg->readEntry( "Archivo de logotipo", QString::null );
    }

Cómo deseamos que nuestros usuarios sean razonables proporcionaremos valores predeterminados adecuados a los parámetros que no existan en el archivo del tema. Tenga en cuenta que siempre debería configurar nuestro grupo con «KSplash Theme: nombretema» para hacerlo compatible con futuras especificaciones del tema. El método `initUI` no es muy interesante, y simplemente construye el componente. Por favor, véa el apéndice para obtener más detalles.

### Compilar la extensión

Puesto que hemos decidido utilizar una estructura &kde; para compilar la extensión, necesitaremos crear un `Makefile.am`. Debería ser algo similar a:

#### Contenido de `Makefile.am`

    INCLUDES = $(all_includes)

    kde_module_LTLIBRARIES = ksplash2k.la

    ksplash2k_la_SOURCES = theme2k.cpp rotwidget.cpp
    ksplash2k_la_LDFLAGS = $(all_libraries) $(KDE_RPATH)
    ksplash2k_la_LIBADD = $(LIB_KDEUI) -lksplashthemes

    METASOURCES = AUTO

    noinst_HEADERS        = theme2k.h rotwidget.h

    servicesdir = $(kde_servicesdir)
    services_DATA = ksplash2k.desktop

    themedir = $(kde_datadir)/ksplash/Themes/2k
    theme_DATA = Theme.rc Preview.png

Para obtener más información de cómo escribir archivos `Makefile.am` para &kde;, por favor vea el sitio web de los desarrolladores de &kde;. Lo único que debe tener en cuenta es proporcionar un tema predeterminado basado en esta extensión y proporcionar una imagen para ella. Como muestra de cortesía hacia nuestros usuarios, debería proporcionar un archivo `Theme.rc` de ejemplo ilustrando el uso de las diferentes opciones.

## Preguntas y respuestas

&reporting.bugs; &updating.documentation;

No puedo encontrar ningún tema que funcione en &ksplash; ¿Por qué?

Probablemente no tenga las extensiones correctas para el tema. Las extensiones se encuentran en el paquete `kde-artwork`. Descárguelo, instálelo e inténtelo de nuevo.

¿Qué es el archivo `Theme.rc` y cómo puedo hacer uno?¿Qué es el archivo `Theme.rc` y cómo puedo hacer uno?

`Theme.rc` es el archivo en el que puede especificar una configuración del tema. Para obtener más información, eche un vistazo a Cómo hacer temas para &ksplash;.

## Créditos y licencia

&ksplash;

Derechos de autor del programa © 2003 &Ravikiran.Rajagopal; &Ravikiran.Rajagopal.mail;.

## Contribuciones

- &Brian.C.Ledbetter; &Brian.C.Ledbetter.mail;.

Derechos de autor de la documentación © 2003 &Teemu.Rytilahti; &Teemu.Rytilahti.mail;.

&underFDL; &underGPL;

## Instalación

### Requisitos

Para utilizar &ksplash;, necesita &kde; 3.2 o superior. Algunos temas puede requerir también extensiones adicionales. Si un tema no funciona, contacte con su autor para pedirle información.

### Compilación e instalación

&install.compile.documentation;

## Código fuente

### Listado de `theme2k.cpp`

    #include <qlabel.h>
    #include <qwidget.h>

    #include <kapplication.h>
    #include <kconfig.h>
    #include <kdebug.h>
    #include <kdialogbase.h>
    #include <kgenericfactory.h>
    #include <kglobalsettings.h>
    #include <klocale.h>
    #include <ksplash/objkstheme.h>
    #include <kstandarddirs.h>

    #include "rotwidget.h"
    #include "theme2k.h"
    #include "theme2k.moc"

    K_EXPORT_COMPONENT_FACTORY( ksplash2k, KGenericFactory<Theme2k> );

    Cfg2k::Cfg2k( KConfig * )
    {}

    Theme2k::Theme2k( QWidget *parent, const char *name, const QStringList &args
     )
        :ThemeEngine( parent, name, args )
    {
      readSettings();
      initUi();
    }

    void Theme2k::initUi()
    {
      QVBox *vbox = new QVBox( this );
      vbox->setFrameShape( QFrame::WinPanel );
      vbox->setFrameShadow( QFrame::Raised );

      QHBox *labelBox = new QHBox( vbox );
      labelBox->setPalette( mTBgColor );
      labelBox->setMargin( 1 );
      QLabel *lbl = new QLabel( mWndTitle, labelBox );
      lbl->setFont( QFont( "Arial", 12, QFont::Bold ) );
      lbl->setPaletteForegroundColor( mTFgColor );

      QLabel *logo = new QLabel( vbox );
      logo->setPalette( Qt::white );

      QString px( locate( "appdata", mTheme->themeDir() +
    (mLogoFile.isNull()?QString("/Logo.png"):mLogoFile) ) );
      if (px.isNull())
        px = locate("appdata","Themes/Default/splash_top.png");
      if( !px.isNull() )
      {
        QPixmap pix( px );
        logo->setPixmap( pix );
      }
      else
      {
        logo->setText( "<B>KDE</B>2000" );
        logo->setAlignment( AlignCenter|AlignVCenter );
      }

      mRotator = new RotWidget( vbox, mRotColor1, mRotColor2, mRotSpeed );

      QHBox *hbox = new QHBox( vbox );
      labelBox->setSpacing( 4 );
      labelBox->setMargin( 4 );

      mText = new QLabel( hbox );
      mText->setPaletteForegroundColor( mStatusColor );
      mText->setPaletteBackgroundColor( mTFgColor );
      mText->setText( mWndTitle );
      mText->setFixedHeight( 48 );

      setFixedSize( vbox->sizeHint() );
      QRect rect(KGlobalSettings::splashScreenDesktopGeometry());
      move( rect.x() + (rect.width() - size().width())/2,
            rect.y() + (rect.height() - size().height())/2 );
    }

    void Theme2k::readSettings()
    {
      if( !mTheme )
        return;

      KConfig *cfg = mTheme->themeConfig();
      if( !cfg )
        return;

      cfg->setGroup( QString("KSplash Theme: %1").arg(mTheme->theme()) );

      QColor DefaultTBgColor( Qt::darkBlue );
      QColor DefaultTFgColor( Qt::white );

      mTBgColor = cfg->readColorEntry( "Title Background Color",
    &DefaultTBgColor );
      mTFgColor = cfg->readColorEntry( "Title Foreground Color",
    &DefaultTFgColor );
      mStatusColor = cfg->readColorEntry("Status Text Color", &mTBgColor );

      QColor DefaultRot1( Qt::darkBlue );
      QColor DefaultRot2( Qt::cyan );
      mRotColor1 = cfg->readColorEntry( "Color del rotador 1", &DefaultRot1 );
      mRotColor2 = cfg->readColorEntry( "Color del rotador 2", &DefaultRot2 );

      mRotSpeed = cfg->readNumEntry( "Velocidad del rotador", 30 );
      mWndTitle = cfg->readEntry( "Ventana del título", i18n("Por favor, espere...") );
      mLogoFile = cfg->readEntry( "Archivo de logotipo", QString::null );
    }

### Listado de `rotwidget.h`

    #ifndef         __ROTWIDGET_H__
    #define         __ROTWIDGET_H__

    #include <qlabel.h>
    #include <qtimer.h>
    #include <qwidget.h>

    #include <kdialogbase.h>
    #include <kpixmap.h>

    /**
     * @short Muestra un gradiente girando.
     */
    class         RotWidget: public QWidget
    {
      Q_OBJECT
    public:
      RotWidget( QWidget *, const QColor&, const QColor&, int );
      ~RotWidget();

    private slots:
      void stepEvent();

    protected:
      void        preparePixmap( int );
      void        paintEvent( QPaintEvent * );
      void        resizeEvent( QResizeEvent * );

      QColor m_color1, m_color2;
      int m_step, m_speed;
      QTimer *m_stepTimer;

      QList<KPixmap> m_stepPixmap;
    };

    #endif

### Listado de `rotwidget.cpp`

    #include <kdebug.h>
    #include <kdialogbase.h>
    #include <kpixmapeffect.h>

    #include <qlabel.h>
    #include <qpainter.h>
    #include <qwidget.h>

    #include "rotwidget.h"
    #include "rotwidget.moc"

    RotWidget::RotWidget( QWidget *parent, const QColor& c1, const QColor& c2, int sp )
        :QWidget(parent), m_color1(c1), m_color2(c2), m_step(0), m_speed(sp)
    {
      if( (m_speed <= 0) || (m_speed > 20) )
        m_speed = 1;
      setFixedHeight( 6 );

      for( int i = 0; i <= width(); i++ )
        preparePixmap( i );

      m_stepTimer = new QTimer( this );
      connect(m_stepTimer, SIGNAL(timeout()), this, SLOT(stepEvent()));
      m_stepTimer->start( 50 );
    }

    RotWidget::~RotWidget()
    {
    }

    void RotWidget::stepEvent()
    {
      // Esto es ineficaz dado que creamos demasiados mapas de imagen, a optimizar después.
      m_step += m_speed;
      if( m_step > width() )
        m_step = 0;
      repaint( true );
    }

    // por hacer. Optimizar el dibujado.
    void RotWidget::paintEvent( QPaintEvent *pe )
    {
      QPainter p;
      p.begin( this );

      QRect r = pe->rect();

      if( m_stepPixmap.at( m_step ) )
        bitBlt( this, r.x(), r.y(), m_stepPixmap.at( m_step ), r.x(), r.y(), r.width(), r.height() );
      else
        p.fillRect( rect(), Qt::black );
      p.end();
    }

    void RotWidget::resizeEvent( QResizeEvent *re )
    {
      m_stepPixmap.clear();
      for( int i = 0; i <= re->size().width(); i++ )
        preparePixmap( i );
    }

    void RotWidget::preparePixmap( int step )
    {
      if( step < 0 )
        return;

      // Dibujaremos explícitamente nuestro primer punto. El resto lo hará bitBlt().
      if( step == 0 )
      {
        KPixmap tmp; tmp.resize( size().width() / 2, size().height() );
        KPixmap tmp2(tmp);
        KPixmapEffect::gradient( tmp, m_color1, m_color2, KPixmapEffect::HorizontalGradient );
        KPixmapEffect::gradient( tmp2, m_color2, m_color1, KPixmapEffect::HorizontalGradient );
        KPixmap *px = new KPixmap( size() );
        QPainter p;
        p.begin( px );
        p.drawPixmap( 0, 0, tmp );
        p.drawPixmap( size().width()/2, 0, tmp2 );
        p.end();
        m_stepPixmap.append( px );
      }
      else if( m_stepPixmap.at( step-1 ) )
      {
        QPixmap *prev = m_stepPixmap.at( step-1 );
        QPixmap next; next.resize( size() );
        // convert
        // prev = "[------------]"
        // to
        // next = "------------]["
        bitBlt( &next, 0, 0, prev, 1, 0, prev->width()-1, prev->height() );
        bitBlt( &next, width()-1, 0, prev, 0, 0, 1, prev->height() );
        KPixmap *n = new KPixmap( next );
        m_stepPixmap.append( n );
      }
    }

&documentation.index;