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