# Manuale di &ksplash;

&Teemu.Rytilahti; &Teemu.Rytilahti.mail;
&Brian.C.Ledbetter; &Brian.C.Ledbetter.mail;
&Ravikiran.Rajagopal; &Ravikiran.Rajagopal.mail;
Massimiliano
Donno

    massidonno@infinito.it

Traduzione del manuale
2003
Teemu Rytilahti
2003-04
Ravikiran Rajagopal
&FDLNotice;
2003-01-10
1.01.00

&ksplash; è un ottimo splash screen che visualizza il progresso di una applicazione in caricamento.

KDE
kdebase
ksplash
ksplashml
splashscreen
sciroppo per gli occhi

## Introduzione

&ksplash; è un ottimo splash screen che visualizza il progresso di una applicazione in caricamento. Per favore riporta qualsiasi problema o richieste di funzionalità aggiuntive alla mailing list di &kde;. Le funzionalità principali di &ksplash;:

- Possibilità di usare Temi
- Usa i plugin per una completa personalizzazione
- Può essere usato da qualsiasi applicazione che usa DCOP

Questo manuale ti mostra come creare dei temi usabili con i plugin che sono già disponibili. Se nessuno dei plugin disponibili soddisfa i tuoi gusti, puoi imparare come personalizzare completamente le sembianze di &ksplash; scrivendo un plugin in C++.

## Usare Temi

Per usare i temi del sito KDE-Look, estraili in `~/.kde/share/apps/ksplash/Themes/` per ogni singolo utente, o in `$`KDEDIR`/share/apps/ksplash/Themes/` per renderli disponibili a tutti gli utenti del sistema.

Puoi anche usare il modulo Schermata d'avvioin Aspetto e Temi nel centro di controllo di &kde; per fare ciò in automatico.

### Usare il modulo di &kcontrol;

Questo modulo permette di installare, testare e rimuovere temi di &ksplash;.

Su un lato del modulo c'è una lista di temi di &ksplash; subito disponibili. Appena se ne seleziona uno, verrà visualizzata un'anteprima nella parte centrale della finestra. Quando ne hai selezionato uno che desideri usare, premi Applica. Premi Ripristina per uscire dal modulo senza effettuare le modifiche, e Valori predefiniti per ripristinare la schermata di avvio predefinita.

Per installare nuovi moduli, premi Aggiungi..., e trova il tema sul tuo computer. Non devi decomprimere il file del tema, puoi tranquillamente selezionare il file del tema compresso. Installare un tema non significa cambiare quello attualmente in uso fin quando non lo si seleziona esplicitamente dalla lista e si preme Applica.

Puoi anche vedere un'anteprima dello splash screen in azione, per vedere come si comporta nell'uso reale, per esempio per renderti conto di come sono le animazioni. Puoi testare il tema selezionandolo dalla lista e fare clic sul bottone Prova.

Puoi anche rimuovere un tema che non vuoi più usare, selezionandolo e premendo il bottone Rimuovi. Nota che un utente semplice potrebbe non avere i permessi per rimuovere il tema installato per tutti gli utenti del sistema. Ti raccomando inoltre di non rimuovere lo splash screen Predefinito.

## Come creare temi per &ksplash;

### Generale

Creare un tuo tema per &ksplash; è semplice. Una volta terminato il tuo tema, puoi postarlo a KDE-Look per permettere ad altri utenti di utilizzarlo.

#### Identifica il tuo tema

Creiamo un tema chiamato `MyCoolTheme`. Per permettere al tema di essere riconosciuto da &ksplash; deve essere memorizzato nella cartella chiamata `MyCoolTheme` sotto `~/.kde/apps/ksplash/Themes/`. Deve contenere anche un file chiamato `Theme.rc`, contenente le impostazioni per il tema. Puoi specificare un gran numero di elementi speciali del tema, cambiare il motore dei plugin da usare, e così via. Non hai bisogno di utilizzare tutte le impostazioni disponibili, perché generalmente le opzioni predefinite sono già buone. La sintassi di base per le linee nel file`Theme.rc` è `[opzione] = [valore]`. Puoi trovare la definizione delle varie opzioni nelle sezioni successive.

##### Semplice file `Theme.rc`

    [KSplash Theme: MyCoolTheme]
    Name = MioTemaFico
    Description = Un tema simpatico usando il motore XpLike
    Version = 1.0
    Author = Real Name <realmail@mail.com>
    ## Usa il motore XpLike per questo tema.
    Engine = XpLike
    Show Icon = false
    Welcome Text = Sto caricando KDE

Dopo aver specificato il nome, la descrizione e l'autore del tema, devi scegliere un motore per il tema (anche conosciuto come plugin). Dopodiché puoi personalizzare le varie funzionalità del motore assegnando una coppia di valori chiave come nel seguente file di esempio.

Il nome della cartella sotto la quale i file del tema sono memorizzati (`~/.kde/apps/ksplash/Themes/MyCoolTheme` nel nostro caso) e l'identificativo del tema (`[KSplash Theme: MyCoolTheme]` nel nostro caso) nel file `Theme.rc` DEVE essere lo stesso. Altrimenti &ksplash; non riconoscerà il tema.

#### File di Sfondo

Quando &ksplash; parte, tenta di cercare un immagine di sfondo per la risoluzione dello schermo attuale, sempre se il motore del tema ne usa uno. Il file dell'immagine di sfondo deve essere chiamto nel seguente formato: `Background-LLLxAAA .png`.

Per esempio potresti usare un file chiamato `Background-1024x768` . Se l'immagine di sfondo per la risoluzione dello schermo attuale non può essere trovata, ksplash tenta di ridimensionare la immagine originale `Background.png` o il file specificato in `Theme.rc` per meglio asservire la risoluzione corrente. Il ridimensionamento al volo prenderà un certo tempo, quindi dovresti provvedere diverse immagini di sfondo per almeno le seguenti risoluzioni: 1280x1024, 1024x768 e 800x600.

### Opzioni per i motori del tema

#### Tema Predefinito

##### Opzioni del tema predefinito

Name #Nome | Argument #Argomento | Explanation #Spiegazione
Always Show Progress #Mostra sempre la barra di progresso | [true/false] #si/no | Indica se il progresso del caricamento deve essere mostrato. Predefinito è true (visualizzato).
Label Foreground #Primo piano dell'etichetta | [color] #colore | Il colore di primo piano per il testo della barra di stato. Predefinito è #FFFFFF (bianco).
Icons Flashing #lampeggio delle icone | [true/false] #si/no | Decide se l'icona deve lampeggiare o meno. Predefinito è true (si).

#### Tema standard

##### Opzioni del tema standard (nel file di configurazione vanno riportati i comandi in inglese, la traduzione è solo esplicativa ed è un commento, in stile script per la shell, cioè tutto quello che segue il carattere #)

Name #Nome | Argument #Argomento | Explanation #Spiegazione
Statusbar Position #posizione della barra di stato | [top/bottom] #alto/basso | Scambia la posizione della barra di stato sullo schermo. Predefinito è bottom (in basso).
Statusbar Visible #barra di stato visibile | [true/false] #si/no | Indica se la barra di stato deve essere visualizzata. Predefinito è true (visualizzata).
Progress Visible #barra di progresso visibile | [true/false] #si/no | Indica se il progresso del caricamento deve essere mostrato. Predefinito è true (visualizzato).
Statusbar Font #Carattere della barra di stato | [fontname] #nome del carattere | Il carattere usato nella barra di stato. Predefinito è Helvetica.
Statusbar Font Size #dimensione del carattere della barra di stato | [size] #dimensione | La dimensione del carattere nella barra di stato. Predefinito è 16.
Statusbar Font Bold #Carattere grassetto per la barra di stato | [true/false] #si/no | Indica se il carattere della barra di stato deve essere grassetto. Predefinito è true (grassetto).
Statusbar Font Italic #Carattere corsivo per la barra di stato | [true/false] #si/no | Indica se il carattere della barra di stato deve essere corsivo. Predefinito è false (non in corsivo).
Statusbar Foreground #Primo piano della barra di stato | [color] #colore | Il colore di primo piano della barra di stato. Predefinito è white (bianco).
Statusbar Background #sfondo della barra di stato | [color] #colore | Il colore di sfondo della barra di stato. Predefinito è black (nero).
Statusbar Icon #Icona della barra di stato | [true/false] #si/no | Indica se la barra di stato deve avere un'icona.
Icons Visible #icone visibili | [true/false] #si/no | Indica se l'icona deve essere visibile. Predefinito è true (visibile).
Icons Jumping #salto tra icone | [true/false] #si/no | Indica se l'icona deve saltare. Predefinito è true (salta).
Icon Position #posizione delle icone | [0-3,10-13] | Posizione dove le icone sono mostrate. Predefinito è bottom-left (in basso a sinistra).
Splash Screen #schermata di splash | [name] #nome | Cambia l'immagine dello splash screen visualizzato.

#### tema Redmond

##### opzioni del tema Redmond

Name #Nome | Argument #Argomento | Explanation #Spiegazione
Background Image #immagine di sfondo | [filename] #nome del file | Immagine di sfondo definita dall'utente.
User Icon #icona utente | [Iconname] #nome icona | Nome dell'icona standard da usare. Predefinito è`go`.
Welcome Text #messaggio di benvenuto | [text] #testo | Testo mostrato nello splash screen. Predefinito è "Welcome".
Username Text #testo del nome utente | [text] #testo | Testo mostrato al posto del nome reale dell'utente.
Welcome Text Position #posizione del testo di benvenuto | [x,y] | Posizione dello schermo dove è piazzato il testo di benvenuto.
Username Text Position #posizione del testo del nome utente | [x,y] | Posizione dello schermo dove è piazzato il nome utente.
Action Text Position #posizione del testo dove è l'azione corrente | [x,y] | Posizione dello schermo dove avviene la azione corrente.
Icon Position #posizione delle icone | [x,y] | Posizione dello schermo dove è visualizzata l'icona dell'utente.
Show Welcome Text #mostra testo di benvenuto | [true/false] #si/no | Decide se mostrare o no il testo di benvenuto. Predefinito è true (si).
Show Welcome Shadow #mostra l'ombra del testo di benvenuto | [true/false] #si/no | Decide se mostrare o no l'ombra del testo di benvenuto. Predefinito è true.
Show Username #mostra nome utente | [true/false] #si/no | Decide se mostrare o no il nome utente. Predefinito è true.
Show Action #mostra l'azione corrente | [true/false] #si/no | Decide se mostrare o no l'azione corrente. Predefinito è true.
Show Icon #mostra l'icona | [true/false] #si/no | Decide se mostrare o no l'icona. Predefinito è true.
Use KDM User Icon #usa le icone utenti di KDM | [true/false] #si/no | Mostra le icone di login dell'utente. Predefinito è true.

#### Tema MacX

##### Opzioni del tema MacX

Name #Nome | Argument #Argomento | Explanation #Spiegazione
Icon Size Minimum #minima dimensione icone | [size] #dimensione | Assegna la dimensione minima delle icone. Predefinito è 16.
Icon Size Maximum #massima dimensione delle icone | [size] #dimensione | Assegna la dimensione massima delle icone. Predefinito è 64.
Optimized Icon Rendering #ottimizzazione presentazione icone | [true/false] #si/no | Ottimizza il rendering delle icone. Predefinito è true.
Progress Bar Visible #barra di progresso visibile | [true/false] #si/no | Predefinito è true
Progress Bar Position #posizione barra di progresso | [top/bottom] #alto/basso | Decide se mostrare la barra di stato in basso o in alto. Predefinito è bottom (basso).
Icons Jumping #salto tra icone | [true/false] #si/no | Indica se le icone devono saltare. Predefinito è false.

#### Tema MacClassic

##### Opzioni del tema MacClassic

Name #Nome | Argument #Argomento | Explanation #Spiegazione
Icon Position #posizione delle icone | [0-3,10-13] | Posizione delle icone sullo schermo. Predefinito è bottom-left (giu-sinistra).
Icons Jumping #salto tra icone | [true/false] #si/no | Indica se le icone devono saltare. Predefinito è false.
Icons Visible #icone visibili | [true/false] #si/no | Indica se l'icona deve essere visibile. Predefinito è true (visibile).
Splash Screen #schermata di splash | [name] #nome | Cambia l'immagine dello splash screen visualizzato.

#### Tema 2k

##### Opzioni del tema 2k

Name #Nome | Argument #Argomento | Explanation #Spiegazione
Title Background Color #colore dello sfondo del titolo | [color] #colore | Il colore di sfondo del titolo. Predefinito è dark blue (blu).
Title Foreground Color #colore del primo piano del titolo | [color] #colore | Il colore di primo piano del titolo. Predefinito è white (bianco).
Status Text Color #Colore del testo di stato | [color] #colore | Il colore del testo della barra di stato. Predefinito è lo stesso colore dello sfondo del titolo.
Rotator Color 1 #colore rotatore 1 | [color] #colore | Definisce il colore del rotatore 1. Predefinito è dark blue.
Rotator Color 2 #colore rotatore 2 | [color] #colore | Definisce il colore del rotatore 2. Predefinito è cyan (celeste).
Rotator Speed #velocità del rotatore | [value] #valore | Definisce la velocità del rotatore. Predefinito è 30.
Window Title #Titolo della finestra | [text] #testo | Specifica il titolo della finestra.
Logo File #file dello stemma | [filename] #nome del file | Definisce il logo usato.

## Usare &ksplash; Dalle proprie applicazioni.

In questo capitolo descriviamo un semplice metodo per usare &ksplash; come splash screen per le tue applicazioni &kde;. Se non sviluppi applicazioni per &kde; puoi saltare questo capitolo.

### Requisiti di base

Le tue applicazioni &kde; devono esportare funzioni &DCOP;. &DCOP; è la tecnologia di &kde; usata per comunicare con le applicazioni. Se usi l'infrastruttura delle applicazioni di &kde; standard, questo avverrà automaticamente. Per informazioni su &DCOP; e le tecnologie &kde; visita l'angolo dello sviluppatore &kde;.

### Avviare &ksplash;

Prima che l'applicazione inizi intensivi cicli di calcolo, o prima di caricare i plugin, &etc;, invoca &ksplash; nel seguente modo:

    DCOPClient *c = kapp->dcopClient();
    QString error;
    QCString KSplashName;
    int pid = 0;
    QStringList args;
    args << "--theme=MyCoolTheme" << "--managed";
    if (kapp->startServiceByDesktopName("ksplash", args, &error, &KSplashName, &pid))
    {
      KMessageBox::sorry(0, error, "Impossibile invocare KSplash");
      // Qui gestisci gli errori.
    }

Qui assumiamo che esiste una sola istanza di &ksplash; in esecuzione. Altri casi sono leggermente più complessi. Per favore vedi la documentazione &DCOP; per maggiori dettagli.

### Mostrare messaggi

Prima di visualizzare qualsiasi messaggio, devi impostare il numero di passi che vuoi visualizzare. Per esempio la procedura di partenza di &kde; impiega 7 passi.

    QByteArray data;
        QDataStream arg(data,IO_WriteOnly);
        arg << someNumber;
        if (!(c->send(KSplashName, "KSplashIface", "setStartupItemCount(int)", data))
          // Processamento degli errori qui.

Quando vuoi mostrare un messaggio con o senza un'icona, usa

    arg << QString("iconName") << QString("programName") << QString("Some description");
        if (!(c->send(KSplashName, "KSplashIface", "programStarted(QString,QString,QString)", data))
        {
          // Processamento degli errori qui .
        }

Ogni volta che chiami la funzione `programStarted`, il passo compiuto viene incrementato. Quando il tuo programma ha finito la fase di startup, fai la seguente cosa per mandar via lo splash screen:

    if (!(c->send(KSplashName, "KSplashIface", "startupComplete()", data))
        {
          // Qui gestisci gli errori.
        }

Ecco fatto! Non hai bisogno di nient'altro per sfruttare tutto quello che &ksplash; ti offre.

## Scrivere nuovi plugin per &ksplash;

Scrivere un nuovo plugin di &ksplash; non è difficile. In questo capitolo scriveremo un semplice plugin che emula lo splash screen di un noto sistema operativo. Questo tutorial premette che tu conosca le basi del C++ e un po' di programmazione di KDE/Qt.

### Requisiti di base

Creeremo un plugin chiamato `2k`. Il nome del plugin è usato in vari posti, ed è importante che questo nome venga usato sempre senza modifiche, per permettere a &ksplash; di riconoscerlo. I plugin di &ksplash; sono librerie caricabili dinamicamente con la seguente convenzione sui nomi:

- La libreria deve essere chiamata come `ksplash+nomedeltemaminuscolo`. Nel nostro esempio sarà `ksplash2k`.
- Deve esserci un file .desktop corrispondente chiamato `ksplash+nomedeltemaminuscolo.desktop`. Nel nostro esempio sarà `ksplash2k.desktop`.
- Infine l'oggetto restituito dalla libreria deve essere una classe, chiamata `Theme+nometema`. Nel nostro esempio la classe si chiamerà `Theme2k`.

Non preoccuparti se non hai capito quanto detto. Considereremo ognuno di questi punti in maggior dettaglio più avanti nel manuale. Un altro dettaglio molto importante è che la classe del plugin deve essere derivata dalla classe `ThemeEngine`.

### Creare l'infrastruttura.

Useremo l'infrastrurrura delle applicazioni di &kde;, che si prenderà cura della compilazione del plugin e ci garantirà l'indipendenza dalla piattaforma senza nessun lavoro da parte nostra. Per fare ciò assicurati di avere il pacchetto `kdesdk` installato. Esegui il comando `kapptemplate` per produrre un applicazione chiamata "2k". Verrà creata una cartella che contiene file generici come AUTHORS, &etc;. Quello che ci interessa è una sottocartella chiamata `2k`. Vai in questa cartella e cancella tutti i file presenti. Ora abbiamo lo scheletro di applicazione che ci serve.

Il prossimo passo consiste nel creare un file `.desktop` che, una volta installato, dirà a &ksplash; che il nostro plugin è disponibile. Coerentemente con la nomenclatura portata avanti nella sezione precedente, crea un file chiamato `ksplash2k.desktop` nella sottocartella suddetta. Deve contenere le seguenti linee.

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

Le linee `Encoding`, `Type`, `Comment` e `ServiceTypes` sono le stesse per tutti i plugin. Il nome del plugin e della libreria seguono la stessa nomenclatura già usata. La linea `X-KSplash-Default` accetta un valore booleano che determina se il plugin deve essere visualizzato nel modulo di configurazione nel centro di controllo. Ad eccezione di pochi casi, questa linea deve essere `true`.

### Dichiarazione delle classi dei plugin

Adesso che abbiamo svolto le faccende preliminari, andiamo con la parte più divertente, creando una classe che fornirà il comportamento che vogliamo. Siete liberi di fare quasi tutto quello che volete con questa classe, segendo delle semplici restrizioni.

1. Le classi dei plugin devono ereditare la classe `ThemeEngine`.

2. Le classi dei plugin devono essere nominate in accordo al ruolo: `Tema+NomePlugin`.

3. Le classi dei plugin devono avere una funzione `static` chiamata `names` che ritorna una lista di nomi attraverso i quali possono essere invocate.

4. Se il plugin può essere configurato nel modulo del centro di controllo, dovrebbe provvedere una classe basata su `ThemeEngineConfig` per la configurazione.

5. Le classi dei plugin devono sovrascrivere almeno una delle seguenti funzioni `slotSetText`, `slotSetPixmap`, `slotUpdateProgress` e `slotUpdateSteps` per renderle funzionanti.

6. Il costruttore deve prendere la forma `ThemeEngine( QWidget *parent, const char *name, const QStringList &args )` di modo che possa essere usato con la classe `KGenericFactory`.

L'ultima richiesta può sembrare complicata ma, come vedremo dopo, aggiungendo una singola linea al tuo file sorgente, puoi ignorarla.

### Codice per il file di header

Dati i vincoli, possiamo ora vedere il file header `theme2k.h` che sarà:

#### Listato di `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

Analizziamo il listato precedente. La classe `Theme2k` soddisfa la convenzione di nomi voluta, ed è ereditata dalla classe `ThemeEngine`. Fornisce un metodo `Theme2k::names()`, ed ha un costruttore che prende i parametri richiesti: `Theme2k( QWidget *, const char *, const QStringList& );` e fornisce un semplice metodo `Theme2k::slotSetText()`. Per il momento non dobbiamo preoccuparci della classe `RotWidget`. Si tratta di un piccolo widget che fornisce alcuni effetti grafici. Il nostro plugin è molto semplice e non mostra icone o barre di progresso. Se vuoi mostrare delle icone devi overloadare la funzione `slotSetPixmap` . Funzioni simili esistono per impostare l'intervallo della barra di progresso (`slotUpdateSteps`) e incrementare il passo corrente (`slotUpdateProgress`).

### Implementazione dei plugin

Esamineremo solo le parti rilevanti dell'implementazione. Per il listato completo vedi in appendice. La prima cosa che faremo è ottenere i requisiti delle librerie:

#### Requisiti delle librerie

    K_EXPORT_COMPONENT_FACTORY( libksplash2k, KGenericFactory<Theme2k> );

La macro `K_EXPORT_COMPONENT_FACTORY` è dichiarata in `kgenericfactory.h`. E ora il costruttore! Dato che questo plugin è super semplice, il costruttore è alquanto semplice.

#### Costruttore del plugin

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

Il metodo `readSettings()` illustra il modo giusto per ottenere le impostazioni del tuo tema (Di sicuro vuoi che altre persone utilizzino il tuo plugin nel loro tema, giusto?)

#### Ottenere le impostazioni del tema

    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( "Rotator Color 1", &DefaultRot1 );
      mRotColor2 = cfg->readColorEntry( "Rotator Color 2", &DefaultRot2 );

      mRotSpeed = cfg->readNumEntry( "Rotator Speed", 30 );
      mWndTitle = cfg->readEntry( "Window Title", i18n("Please wait...") );
      mLogoFile = cfg->readEntry( "Logo File", QString::null );
    }

Siccome noi amiamo i nostri utenti, forniremo dei parametri di default che non sono presenti nel file del tema. Nota che dovresti sempre impostare il gruppo come "KSplash Theme: nome del tema" per rimanere compatibili con le future spacifiche per i temi. Il metodo `initUI()` non è interessante, in quanto crea semplicemente il widget. Per favore vedi in appendice per i dettagli.

### Compilare il plugin

Dato che abbiamo deciso di utilizzare l'infrastruttura delle applicazioni di &kde; per compilare il plugin, dobbiamo creare un `Makefile.am`. Dovrebbe apparire come segue:

#### Listato di `Makefile.am`

    INCLUDES = $(all_includes)

    kde_module_LTLIBRARIES = libksplash2k.la

    libksplash2k_la_SOURCES = theme2k.cpp rotwidget.cpp
    libksplash2k_la_LDFLAGS = $(all_libraries) $(KDE_RPATH)
    libksplash2k_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

Per maggiori informazioni su come scrivere un file `Makefile.am` per &kde;, per favore vedi il sito degli sviluppatori di &kde;. La cosa da notare è che noi forniamo un tema predefinito basato su questo plugin, nonché un'anteprima di esso. Per una questione di cortesia ai tuoi utenti, dovresti fornire un file di esempio `Theme.rc` che illustra le varie opzioni.

## Domande e risposte

&reporting.bugs; &updating.documentation;

Non riesco a trovare nessun tema che funzioni in &ksplash;. Perché?

Probabilmente non hai il corretto plugin per il tema. I plugin sono nel pacchetto `kde-artwork`. Scaricalo e installalo, e poi riprova.

Cos'è il file `Theme.rc` e come ne faccio uno?

`Theme.rc` è il file dove puoi specificare le impostazioni del tema. Per maggiori informazioni guarda Come to fare temi per &ksplash;.

## Riconoscimenti e License

&ksplash;

Copyright © programma 2003 &Ravikiran.Rajagopal; &Ravikiran.Rajagopal.mail;

### Contribuenti

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

Copyright © documentazione 2003 &Teemu.Rytilahti; &Teemu.Rytilahti.mail;

&underFDL; &underGPL;

## installazione

### Requisiti

Per usare correttamente &ksplash; hai bisogno di &kde; versione 3.2 o superiore. Alcuni temi potrebbero richiedere specifici plugin. Se un tema non funziona, per favore contatta l'autore del tema per trovare come ottenere i plugin appropriati.

### Compilazione e Installazione

&install.compile.documentation;

## Codice sorgente

### Listato di `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( libksplash2k, 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( "Rotator Color 1", &DefaultRot1 );
      mRotColor2 = cfg->readColorEntry( "Rotator Color 2", &DefaultRot2 );

      mRotSpeed = cfg->readNumEntry( "Rotator Speed", 30 );
      mWndTitle = cfg->readEntry( "Window Title", i18n("Please wait...") );
      mLogoFile = cfg->readEntry( "Logo File", QString::null );
    }

### Listato di `rotwidget.h`

    #ifndef         __ROTWIDGET_H__
    #define         __ROTWIDGET_H__

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

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

    /**
     * @short Display a rotating-gradient widget.
     */
    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

### Listato di `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()
    {
      // This is inefficient as we create too many pixmaps, optimize later.
      m_step += m_speed;
      if( m_step > width() )
        m_step = 0;
      repaint( true );
    }

    // Todo: Optimize drawing.
    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;

      // Explicitly draw our first pixmap. The rest we will bitBlt() from here.
      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;