Blame platform-demos/cs/photo-wall.c.page

Packit 1470ea
Packit 1470ea
<page xmlns="http://projectmallard.org/1.0/" xmlns:its="http://www.w3.org/2005/11/its" type="topic" id="photo-wall.c" xml:lang="cs">
Packit 1470ea
  <info>
Packit 1470ea
    <title type="text">Fotostěna (C)</title>
Packit 1470ea
    <link type="guide" xref="c#examples"/>
Packit 1470ea
Packit 1470ea
    <desc>Prohlížeč obrázků používající Clutter.</desc>
Packit 1470ea
Packit 1470ea
    <revision pkgversion="0.1" version="0.1" date="2011-03-22" status="review"/>
Packit 1470ea
    <credit type="author">
Packit 1470ea
      <name>Chris Kühl</name>
Packit 1470ea
      <email its:translate="no">chrisk@openismus.com</email>
Packit 1470ea
    </credit>
Packit 1470ea
    <credit type="author">
Packit 1470ea
      <name>Johannes Schmid</name>
Packit 1470ea
      <email its:translate="no">jhs@gnome.org</email>
Packit 1470ea
    </credit>
Packit 1470ea
    <credit type="editor">
Packit 1470ea
      <name>Marta Maria Casetti</name>
Packit 1470ea
      <email its:translate="no">mmcasetti@gmail.com</email>
Packit 1470ea
      <years>2013</years>
Packit 1470ea
    </credit>
Packit 1470ea
  </info>
Packit 1470ea
Packit 1470ea
<title>Fotostěna</title>
Packit 1470ea
Packit 1470ea
<synopsis>
Packit 1470ea
  

Pro tento příklad vytvoříme jednoduchý prohlížeč obrázků používající Clutter. Naučíte se:

Packit 1470ea
  <list>
Packit 1470ea
    <item>

jak nastavit velikost a pozici objektů ClutterActor

</item>
Packit 1470ea
    <item>

jak umístit obrázek do objektu ClutterActor

</item>
Packit 1470ea
    <item>

jak udělat jednoduché přechody pomocí základní animační konstrukce Clutter

</item>
Packit 1470ea
    <item>

jak přimět objekty ClutterActor reagovat na události myši

</item>
Packit 1470ea
    <item>

jak získat názvy souborů ze složky

</item>
Packit 1470ea
  </list>
Packit 1470ea
</synopsis>
Packit 1470ea
Packit 1470ea
<section id="intro">
Packit 1470ea
  <title>Úvod</title>
Packit 1470ea
  

Clutter je knihovna sloužící k vytváření dynamického uživatelského rozhraní pomocí OpenGL s podporou hardwarové akcelerace. Tento příklad předvádí malou, ale podstatnou část knihovny Clutter na vytvoření jednoduchého, ale atraktivního programu k prohlížení obrázků.

Packit 1470ea
  

Abychom dosáhli našeho cíle, využijeme také pár dalších částí GLib. Nejpodstatnější je použití GPtrArray, což je dynamické pole ukazatelů, pro uchování názvů cest. Dále použijeme GDir, což je pomůcka pro práci se složkami, k přístupu k našim složkám s obrázky a ke shromáždění cest k souborům.

Packit 1470ea
</section>
Packit 1470ea
Packit 1470ea
<section id="anjuta">
Packit 1470ea
  <title>Vytvoření projektu ve studiu Anjuta</title>
Packit 1470ea
  

Než začnete s kódováním, musíte ve studiu Anjuta vytvořit nový projekt. Tím se vytvoří všechny soubory, které budete později potřebovat k sestavení a spuštění kódu. Je to také užitečné kvůli udržení všeho pohromadě.

Packit 1470ea
  <steps>
Packit 1470ea
    <item>
Packit 1470ea
    

Spusťte IDE Anjuta a klikněte na <guiseq><gui>Soubor</gui> <gui>Nový</gui> <gui>Projekt</gui></guiseq>, aby se otevřel průvodce projektem.

Packit 1470ea
    </item>
Packit 1470ea
    <item>
Packit 1470ea
    

Na kartě <gui>C</gui> zvolte <gui>GTK+ (jednoduchý)</gui>, klikněte na <gui>Pokračovat</gui> a na několika následujících stránkách vyplňte své údaje. Jako název projektu a složky použijte <file>photo-wall</file>.

Packit 1470ea
   	</item>
Packit 1470ea
    <item>
Packit 1470ea
    

Ujistěte se, že <gui>Použít GtkBuilder k tvorbě uživatelského rozhraní</gui> je vypnuto, protože jej chceme v této lekci vytvořit ručně. Na použití návrháře uživatelského rozhraní se podívejte do lekce <link xref="guitar-tuner.c">Kytarová ladička</link>.

Packit 1470ea
    </item>
Packit 1470ea
    <item>
Packit 1470ea
    

Zapněte <gui>Konfigurovat externí balíčky</gui>. Na následující stránce vyberte v seznamu clutter-1.0, aby se knihovna Clutter zahrnula do vašeho projektu.

Packit 1470ea
    </item>
Packit 1470ea
    <item>
Packit 1470ea
    

Klikněte na <gui>Použít</gui> a vytvoří se vám projekt. Otevřete <file>src/main.c</file> na kartě <gui>Projekt</gui> nebo <gui>Soubor</gui>. Měli byste vidět kód, který začíná řádky:

Packit 1470ea
    
Packit 1470ea
#include <config.h>
Packit 1470ea
#include <gtk/gtk.h>
Packit 1470ea
    </item>
Packit 1470ea
  </steps>
Packit 1470ea
</section>
Packit 1470ea
Packit 1470ea
<section id="look">
Packit 1470ea
  <title>Pohled na fotostěnu</title>
Packit 1470ea
  

Náš prohlížeč obrázků zobrazuje uživateli stěnu plnou obrázků.

Packit 1470ea
  <media type="image" mime="image/png" src="media/photo-wall.png"/>
Packit 1470ea
  

Když se na obrázek klikne, je animován s cílem vyplnit prohlížecí oblast. Když se na zaměřený obrázek klikne, vrátí se na své původní místo, opět pomocí animace. Obě animace trvají 500 milisekund.

Packit 1470ea
  <media type="image" mime="image/png" src="media/photo-wall-focused.png"/>
Packit 1470ea
</section>
Packit 1470ea
Packit 1470ea
<section id="setup">
Packit 1470ea
  <title>Počáteční nastavení</title>
Packit 1470ea
  

Následující úseku kódu obsahuje řadu definic a proměnných, které budeme používat v následujících částech. Použijte to jako vodítko pro následující části. Zkopírujte tento kód na začátek <file>src/main.c</file>:

Packit 1470ea
Packit 1470ea
#include <gdk-pixbuf/gdk-pixbuf.h>
Packit 1470ea
#include <clutter/clutter.h>
Packit 1470ea
Packit 1470ea
#define STAGE_WIDTH  800
Packit 1470ea
#define STAGE_HEIGHT 600
Packit 1470ea
Packit 1470ea
#define THUMBNAIL_SIZE 200
Packit 1470ea
#define ROW_COUNT (STAGE_HEIGHT / THUMBNAIL_SIZE)
Packit 1470ea
#define COL_COUNT (STAGE_WIDTH  / THUMBNAIL_SIZE)
Packit 1470ea
#define THUMBNAIL_COUNT (ROW_COUNT * COL_COUNT)
Packit 1470ea
Packit 1470ea
#define ANIMATION_DURATION_MS 500
Packit 1470ea
Packit 1470ea
#define IMAGE_DIR_PATH "./berlin_images/"
Packit 1470ea
Packit 1470ea
static GPtrArray *img_paths;
Packit 1470ea
Packit 1470ea
static ClutterPoint unfocused_pos;
Packit 1470ea
Packit 1470ea
Packit 1470ea
</section>
Packit 1470ea
Packit 1470ea
<section id="code">
Packit 1470ea
  <title>Vzhůru do kódu</title>
Packit 1470ea
  

Začneme tím, že se podíváme na celou funkci main(). Pak rozebereme podrobně další části kódu. Změňte <file>src/main.c</file>, aby obsahoval tuto funkci main(). Funkci create_window() můžete smazat, protože ji v tomto příkladu nebudeme potřebovat.

Packit 1470ea
  
Packit 1470ea
int
Packit 1470ea
main(int argc, char *argv[])
Packit 1470ea
{
Packit 1470ea
    ClutterColor stage_color = { 16, 16, 16, 255 };
Packit 1470ea
    ClutterActor *stage = NULL;
Packit 1470ea
Packit 1470ea
    if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
Packit 1470ea
        return 1;
Packit 1470ea
Packit 1470ea
    stage = clutter_stage_new();
Packit 1470ea
    clutter_actor_set_size(stage, STAGE_WIDTH, STAGE_HEIGHT);
Packit 1470ea
    clutter_actor_set_background_color(stage, &stage_color);
Packit 1470ea
    clutter_stage_set_title(CLUTTER_STAGE (stage), "Photo Wall");
Packit 1470ea
    g_signal_connect(stage, "destroy", G_CALLBACK(clutter_main_quit), NULL);
Packit 1470ea
Packit 1470ea
    load_image_path_names();
Packit 1470ea
Packit 1470ea
    guint row = 0;
Packit 1470ea
    guint col = 0;
Packit 1470ea
    for(row=0; row < ROW_COUNT; ++row)
Packit 1470ea
    {
Packit 1470ea
        for(col=0; col < COL_COUNT; ++col)
Packit 1470ea
        {
Packit 1470ea
            const char *img_path = g_ptr_array_index(img_paths, (row * COL_COUNT) + col);
Packit 1470ea
            GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file_at_size(img_path, STAGE_HEIGHT, STAGE_HEIGHT, NULL);
Packit 1470ea
            ClutterContent *image = clutter_image_new ();
Packit 1470ea
            ClutterActor *actor = clutter_actor_new ();
Packit 1470ea
Packit 1470ea
            if (pixbuf != NULL)
Packit 1470ea
            {
Packit 1470ea
                clutter_image_set_data(CLUTTER_IMAGE(image),
Packit 1470ea
                                       gdk_pixbuf_get_pixels(pixbuf),
Packit 1470ea
                                       gdk_pixbuf_get_has_alpha(pixbuf)
Packit 1470ea
                                           ? COGL_PIXEL_FORMAT_RGBA_8888
Packit 1470ea
                                           : COGL_PIXEL_FORMAT_RGB_888,
Packit 1470ea
                                       gdk_pixbuf_get_width(pixbuf),
Packit 1470ea
                                       gdk_pixbuf_get_height(pixbuf),
Packit 1470ea
                                       gdk_pixbuf_get_rowstride(pixbuf),
Packit 1470ea
                                       NULL);
Packit 1470ea
            }
Packit 1470ea
Packit 1470ea
            clutter_actor_set_content(actor, image);
Packit 1470ea
            g_object_unref(image);
Packit 1470ea
            g_object_unref(pixbuf);
Packit 1470ea
Packit 1470ea
            initialize_actor(actor, row, col);
Packit 1470ea
            clutter_actor_add_child(stage, actor);
Packit 1470ea
        }
Packit 1470ea
    }
Packit 1470ea
Packit 1470ea
    /* Zobrazí scénu */
Packit 1470ea
    clutter_actor_show(stage);
Packit 1470ea
Packit 1470ea
    /* Spustí hlavní smyčku clutter */
Packit 1470ea
    clutter_main();
Packit 1470ea
Packit 1470ea
    g_ptr_array_unref(img_paths);
Packit 1470ea
Packit 1470ea
    return 0;
Packit 1470ea
}
Packit 1470ea
  <list>
Packit 1470ea
    <item>

Řádek 4: Je definován ClutterColor nastavením hodnot červené, zelené, modré a průhledné (alfa). Hodnoty jsou z rozsahu 0 až 255. Pro průhlednou složku znamená 255 plné krytí.

</item>
Packit 1470ea
    <item>

Řádek 7: Musíte inicializovat Clutter. Pokud na to zapomenete, obdržíte velmi podivné chyby. Dávejte si na to pozor.

</item>
Packit 1470ea
    <item>

Řádky 10 – 14: Zde vytvoříme nový ClutterStage. Pak nastavíme jeho velikost pomocí definicí z předchozí části a adresu objektu ClutterColor, který jsme právě nadefinovali.

Packit 1470ea
      <note>

ClutterStage je ClutterActor nejvyšší úrovně, do kterého jsou umístěny ostatní objekty ClutterActor.

</note>
Packit 1470ea
</item>
Packit 1470ea
    <item>

Řádek 16: Zde voláme naši funkci pro získání cest k souborům s obrázky. Pojďme se na to trochu podívat.

</item>
Packit 1470ea
    <item>

Řádky 18 – 49: Zde nastavujeme objekty ClutterActor, načítáme obrázky a umisťujeme na správné místo na fotostěně. Podrobněji se na to podíváme v následující části.

</item>
Packit 1470ea
    <item>

Řádek 52: Zobrazí scénu a všechny její potomky, tzn. naše obrázky.

</item>
Packit 1470ea
    <item>

Řádek 55: Spuštění hlavní smyčky Clutter.

</item>
Packit 1470ea
  </list>
Packit 1470ea
</section>
Packit 1470ea
Packit 1470ea
<section id="actors">
Packit 1470ea
  <title>Nastavení našich obrázkových účinkujících</title>
Packit 1470ea
 <note>

V knihovně Clutter je účinkující (actor) nejzákladnější vizuální prvek. Zjednodušeně, vše co vidíte, jsou účinkující.

</note>
Packit 1470ea

V této části se podrobněji podíváme na smyčku použitou k nastavení objektů ClutterActor, který budou zobrazovat naše obrázky.

Packit 1470ea
  
Packit 1470ea
guint row = 0;
Packit 1470ea
guint col = 0;
Packit 1470ea
for(row=0; row < ROW_COUNT; ++row)
Packit 1470ea
{
Packit 1470ea
    for(col=0; col < COL_COUNT; ++col)
Packit 1470ea
    {
Packit 1470ea
        const char *img_path = g_ptr_array_index(img_paths, (row * COL_COUNT) + col);
Packit 1470ea
        GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file_at_size(img_path, STAGE_HEIGHT, STAGE_HEIGHT, NULL);
Packit 1470ea
        ClutterContent *image = clutter_image_new ();
Packit 1470ea
        ClutterActor *actor = clutter_actor_new ();
Packit 1470ea
Packit 1470ea
        if (pixbuf != NULL)
Packit 1470ea
        {
Packit 1470ea
            clutter_image_set_data(CLUTTER_IMAGE(image),
Packit 1470ea
                                   gdk_pixbuf_get_pixels(pixbuf),
Packit 1470ea
                                   gdk_pixbuf_get_has_alpha(pixbuf)
Packit 1470ea
                                       ? COGL_PIXEL_FORMAT_RGBA_8888
Packit 1470ea
                                       : COGL_PIXEL_FORMAT_RGB_888,
Packit 1470ea
                                   gdk_pixbuf_get_width(pixbuf),
Packit 1470ea
                                   gdk_pixbuf_get_height(pixbuf),
Packit 1470ea
                                   gdk_pixbuf_get_rowstride(pixbuf),
Packit 1470ea
                                   NULL);
Packit 1470ea
        }
Packit 1470ea
Packit 1470ea
        clutter_actor_set_content(actor, image);
Packit 1470ea
        g_object_unref(image);
Packit 1470ea
        g_object_unref(pixbuf);
Packit 1470ea
Packit 1470ea
        initialize_actor(actor, row, col);
Packit 1470ea
        clutter_actor_add_child(stage, actor);
Packit 1470ea
    }
Packit 1470ea
}
Packit 1470ea
Packit 1470ea
Packit 1470ea
<list>
Packit 1470ea
  <item>

Řádek 7: Zde chceme získat cestu na n-tém místě v poli GPtrArray, které obsahuje názvy cest k našim obrázkům. n-tá pozice je vypočítána na základě řádku row a sloupce col.

Packit 1470ea
  </item>
Packit 1470ea
  <item>

Řádek 8 – 23: Zde doopravdy vytvoříme ClutterActor a umístíme do něj obrázek. První argument je cesta, přes kterou přistupujeme přes náš uzel GList. Druhý argument je pro hlášení chyb, ale zde jej budeme ignorovat, abychom udrželi rozumnou délku příkladu.

Packit 1470ea
  </item>
Packit 1470ea
  <item>

Řádek 47: Tímto se přidá ClutterActor do scény, což je vlastně kontejner. Předpokládá to také vlastnictví objektu ClutterActor, což je něco, kvůli čemuž byste se museli podívat hlouběji do vývoje GNOME. Drsné podrobnosti viz <link href="http://library.gnome.org/devel/gobject/stable/gobject-memory.html">dokumentace k GObject</link>.

Packit 1470ea
  </item>
Packit 1470ea
</list>
Packit 1470ea
</section>
Packit 1470ea
Packit 1470ea
<section id="load">
Packit 1470ea
  <title>Načítání obrázků</title>
Packit 1470ea
  

Nyní se na chvíli ponechme Clutter stranou a podívejme se, jak získat názvy souborů z naší složky s obrázky.

Packit 1470ea
  
Packit 1470ea
static void
Packit 1470ea
load_image_path_names()
Packit 1470ea
{
Packit 1470ea
    /* Ujištění, že máme přístup do složky. */
Packit 1470ea
    GError *error = NULL;
Packit 1470ea
    GDir *dir = g_dir_open(IMAGE_DIR_PATH, 0, &error);
Packit 1470ea
    if(error)
Packit 1470ea
    {
Packit 1470ea
        g_warning("g_dir_open() failed with error: %s\n", error->message);
Packit 1470ea
        g_clear_error(&error);
Packit 1470ea
        return;
Packit 1470ea
    }
Packit 1470ea
Packit 1470ea
    img_paths = g_ptr_array_new_with_free_func (g_free);
Packit 1470ea
Packit 1470ea
    const gchar *filename = g_dir_read_name(dir);
Packit 1470ea
    while(filename)
Packit 1470ea
    {
Packit 1470ea
        if(g_str_has_suffix(filename, ".jpg") || g_str_has_suffix(filename, ".png"))
Packit 1470ea
        {
Packit 1470ea
            gchar *path = g_build_filename(IMAGE_DIR_PATH, filename, NULL);
Packit 1470ea
            g_ptr_array_add (img_paths, path);
Packit 1470ea
        }
Packit 1470ea
        filename = g_dir_read_name(dir);
Packit 1470ea
    }
Packit 1470ea
}
Packit 1470ea
  <list>
Packit 1470ea
    <item>

Řádky 5 a 12: Otevře naši složku nebo, když se objeví chyba, vrátí se po vypsání chybové zprávy.

</item>
Packit 1470ea
    <item>

Řádky 16 – 25: První řádek získá jiný název souboru z objektu GDir, který jsem otevřeli již dříve. Pokud se jednalo o soubor s obrázkem (což zkontrolujeme podle jeho přípony „.png“ nebo „.jpg“) ve složce, kterou zpracováváme, přidáme před název souboru cestu a celé to vložíme na začátek seznamu, který jsem dříve vytvořili. Nakonec se pokusíme získat následující název v cestě, a když je nějaký soubor nalezen, vrátíme se do smyčky.

</item>
Packit 1470ea
  </list>
Packit 1470ea
</section>
Packit 1470ea
Packit 1470ea
<section id="actors2">
Packit 1470ea
  <title>Nastavení účinkujících</title>
Packit 1470ea
  

Nyní se pojďme podívat na nastavení velikosti a polohy objektů ClutterActor a také na jejich přípravu pro komunikaci s uživatelem.

Packit 1470ea
  
Packit 1470ea
/* Tato funkce se stará o vytvoření a umístění obdélníků. */
Packit 1470ea
static void
Packit 1470ea
initialize_actor(ClutterActor *actor, guint row, guint col)
Packit 1470ea
{
Packit 1470ea
    clutter_actor_set_size(actor, THUMBNAIL_SIZE, THUMBNAIL_SIZE);
Packit 1470ea
    clutter_actor_set_position(actor, col * THUMBNAIL_SIZE, row * THUMBNAIL_SIZE);
Packit 1470ea
    clutter_actor_set_reactive(actor, TRUE);
Packit 1470ea
Packit 1470ea
    g_signal_connect(actor,
Packit 1470ea
                     "button-press-event",
Packit 1470ea
                     G_CALLBACK(actor_clicked_cb),
Packit 1470ea
                     NULL);
Packit 1470ea
}
Packit 1470ea
  <list>
Packit 1470ea
    <item>
Packit 1470ea
      

Řádek 7: Nastavení účinkujícího jako reagujícího znamená, že reaguje na události, jako je v našem případě "button-press-event". Pro fotostěnu by měli být všechny objekty ClutterActor nastaveny jako reagující.

Packit 1470ea
    </item>
Packit 1470ea
    <item>
Packit 1470ea
      

Řádek 9 – 12: Nyní připojíme button-press-event na zpětné volání actor_clicked_cb, na které se podíváme posléze.

Packit 1470ea
    </item>
Packit 1470ea
  </list>
Packit 1470ea
  

V tomto bodě máme stěnu s obrázky, která je připravena k zobrazení.

Packit 1470ea
</section>
Packit 1470ea
Packit 1470ea
<section id="click">
Packit 1470ea
  <title>Reakce na kliknutí</title>
Packit 1470ea
  

Packit 1470ea
Packit 1470ea
  

Packit 1470ea
  
Packit 1470ea
static gboolean
Packit 1470ea
actor_clicked_cb(ClutterActor *actor,
Packit 1470ea
                 ClutterEvent *event,
Packit 1470ea
                 gpointer      user_data)
Packit 1470ea
{
Packit 1470ea
    /* Příznak, který bude uchovávat náš stav */
Packit 1470ea
    static gboolean is_focused = FALSE;
Packit 1470ea
    ClutterActorIter iter;
Packit 1470ea
    ClutterActor *child;
Packit 1470ea
Packit 1470ea
    /* Vynuluje stav zaměření u všech obrázků */
Packit 1470ea
    clutter_actor_iter_init (&iter, clutter_actor_get_parent(actor));
Packit 1470ea
    while (clutter_actor_iter_next(&iter, &child))
Packit 1470ea
      clutter_actor_set_reactive(child, is_focused);
Packit 1470ea
Packit 1470ea
    clutter_actor_save_easing_state(actor);
Packit 1470ea
    clutter_actor_set_easing_duration(actor, ANIMATION_DURATION_MS);
Packit 1470ea
Packit 1470ea
    if(is_focused)
Packit 1470ea
    {
Packit 1470ea
        /* Obnoví staré umístění a velikost */
Packit 1470ea
        clutter_actor_set_position(actor, unfocused_pos.x, unfocused_pos.y);
Packit 1470ea
        clutter_actor_set_size(actor, THUMBNAIL_SIZE, THUMBNAIL_SIZE);
Packit 1470ea
    }
Packit 1470ea
    else
Packit 1470ea
    {
Packit 1470ea
        /* Uloží aktuální umístění, než se začne animovat */
Packit 1470ea
        clutter_actor_get_position(actor, &unfocused_pos.x, &unfocused_pos.y);
Packit 1470ea
        /* Only the currently focused image should receive events. */
Packit 1470ea
        clutter_actor_set_reactive(actor, TRUE);
Packit 1470ea
Packit 1470ea
        /* Vloží zaměřený obrázek nahoru */
Packit 1470ea
        clutter_actor_set_child_above_sibling(clutter_actor_get_parent(actor), actor, NULL);
Packit 1470ea
Packit 1470ea
        clutter_actor_set_position(actor, (STAGE_WIDTH - STAGE_HEIGHT) / 2.0, 0);
Packit 1470ea
        clutter_actor_set_size(actor, STAGE_HEIGHT, STAGE_HEIGHT);
Packit 1470ea
    }
Packit 1470ea
Packit 1470ea
    clutter_actor_restore_easing_state(actor);
Packit 1470ea
Packit 1470ea
    /* Přepne náš příznak */
Packit 1470ea
    is_focused = !is_focused;
Packit 1470ea
Packit 1470ea
    return TRUE;
Packit 1470ea
}
Packit 1470ea
  <list>
Packit 1470ea
    <item>

Řádek 1 – 4: Musíme zajistit, že naše funkce zpětného volání bude formálně odpovídat požadavkům signálu button_clicked_event. Například musíme použít jen první argument, konkrétně ClutterActor, na který bylo kliknuto.

Packit 1470ea
<note>
Packit 1470ea
  

Pár slov k argumentům, které v tomto příkladu nepoužíváme. ClutterEvent se liší podle toho, která událost je obsluhována. Například událost klávesy zapříčiní ClutterKeyEvent, ze které můžeme mimo jiné údaje zjistit, která klávesa byla zmáčknuta. Pro událost kliknutí myší získáte ClutterButtonEvent, ze kterého můžete zjistit souřadnice x a y. Na další typy objektu ClutterEvent se podívejte do dokumentace knihovny Clutter.

Packit 1470ea
  

Argment user_data jsou data předávaná funkci. Může být předán například ukazatel na libovolná data, takže když potřebujete zpětnému volání předat více údajů, umístěte data do struktury a předejte adresu na ni.

Packit 1470ea
</note></item>
Packit 1470ea
    <item>

Ředek: Vytvoříme statický příznak pro sledování stavu, ve kterém se nacházíme: režim stěny nebo režim zaměření. Začínáme v režimu stěny, kdy žádný obrázek nemá zaměření. Proto nastavíme počáteční hodnotu příznaku na FALSE.

</item>
Packit 1470ea
    <item>

Řádek 12 – 14: Toto nastaví obrázkové účinkující, aby přijímali události, když jsou zaměření.

</item>
Packit 1470ea
    <item>

Řádek 16 – 17: Zde nastavíme délku trvání animace a uložíme aktuální stav.

</item>
Packit 1470ea
    <item>

Řádky 21 – 3: Dosažení tohoto místa znamená, že obrázek je právě zaměřen a my se chceme vrátit do režimu stěny. Nastavením pozice objektu ClutterActor začne animace v délce trvání nastavené na řádku 17.

Packit 1470ea
    </item>
Packit 1470ea
    <item>

Řádek 24: Dosažení tohoto místa v kódu znamená, že jsem právě v režimu stěny a chystáme se dát objektu ClutterActor zaměření. Uložíme zde počáteční pozici, abychom se na ni později mohli vrátit.

</item>
Packit 1470ea
    <item>

Řádek 25: Nastavení vlastnosti reactive objektu ClutterActor na TRUE zajistí, že bude ClutterActor reagovat na události. Ve stavu zaměření bude jediným účinkujícím, u kterého chceme, aby přijímal událost, ten, který je právě zobrazován. Kliknutí na účinkujícího jej vrátí na původní místo.

</item>
Packit 1470ea
    <item>

Řádek 27 – 36: Zde ukládáme aktuální pozici obrázku, nastavujeme jej, aby přijímal události a pak jej necháme objevit na ostatními obrázky a začneme jej animovat, aby zaplnil scénu.

</item>
Packit 1470ea
    <item>

Řádek 39: Zde obnovíme uvolněný stav na hodnotu nastavenou, než jsme ji změnili na řádku 16.

</item>
Packit 1470ea
    <item>

Řádek 42: Zde přepneme příznak is_focused (je zaměřeno) na aktuální stav.

</item>
Packit 1470ea
<item>

Jak už jsem se zmínili dříve, události přijímá ClutterActor s vyšší hodnotou depth, ale můžete to umožnit i ostatním objektům ClutterActor pod ním. Když je vráceno TRUE, předávání událostí dolů se zastaví, zatímco FALSE bude předávat události dolů.

Packit 1470ea
 <note>
Packit 1470ea
   

Pamatujte ale, že aby objekty ClutterActor přijímaly události, musí být nastavené jako reactive (reagující).

Packit 1470ea
 </note>
Packit 1470ea
</item>
Packit 1470ea
 </list>
Packit 1470ea
</section>
Packit 1470ea
Packit 1470ea
<section id="run">
Packit 1470ea
  <title>Sestavení a spuštění aplikace</title>
Packit 1470ea
  

Veškerý kód by nyní měl být připraven k běhu. Vše, co nyní potřebujete, jsou nějaké obrázky k načtení. Ve výchozím stavu se obrázky načítají ze složky <file>berlin_images</file>. Jestli chcete, můžete změnit řádek #define IMAGE_DIR_PATH někde na začátku, který odkazuje na vaší složku s fotografiemi, nebo vytvořit složku <file>berlin_images</file> kliknutím na <guiseq><gui>Projekt</gui><gui>Nová složka…</gui></guiseq> a vytvořením složky <file>berlin_images</file> jako podsložky ve složce <file>photo-wall</file>. Do složky umístěte aspoň dvanáct obrázků!

Packit 1470ea
  

Až to budete mít přichystané, klikněte na <guiseq><gui>Sestavit</gui> <gui>Sestavit projekt</gui></guiseq>, aby se vše znovu sestavilo, a pak na <guiseq><gui>Spustit</gui> <gui>Spustit</gui></guiseq>, aby se spustila aplikace.

Packit 1470ea
  

Pokud jste tak ještě neučinili, zvolte aplikaci <file>Debug/src/photo-wall</file> v dialogovém okně, které se objeví. Nakonec klikněte na <gui>Spustit</gui> a užijte si ji!

Packit 1470ea
</section>
Packit 1470ea
Packit 1470ea
<section id="impl">
Packit 1470ea
 <title>Ukázková implementace</title>
Packit 1470ea
 

Pokud v této lekci narazíte na nějaké problémy, porovnejte si svůj kód s tímto <link href="photo-wall/photo-wall.c">ukázkovým kódem</link>.

Packit 1470ea
</section>
Packit 1470ea
Packit 1470ea
</page>