root/branches/clutter-experiments/pdfcube.hh

Revision 59, 8.1 KB (checked in by mirko, 3 years ago)

Keybindings core.

Line 
1#pragma once
2
3#include <cassert>
4
5namespace pdfcube {
6 
7  class app
8  {
9  public:
10   
11    app(const app&);
12    app& operator=(const app&);
13
14    /** @brief */
15    app()
16      : the_doc_m(),
17        the_stage_m(),
18        filename_m(),
19        progress_m(),
20        progress_label_m(),
21        current_page_m(),
22        next_page_m(),
23        current_page_no_m(0)
24    { }
25
26    bool init(int* argc, char** argv[])
27    {
28      gchar **file_array;
29      GOptionEntry options[] = {
30        // TODO: add stage color/image and cube top color/image options
31        { G_OPTION_REMAINING, 
32          0, 
33          0, 
34          G_OPTION_ARG_FILENAME_ARRAY, 
35          &file_array, 
36          "Presentation PDF file to load", 
37          "FILE" },
38        { 0, 0, 0, (GOptionArg)0, 0, 0, 0 }
39      };
40      g_thread_init(NULL);
41      clutter_threads_init();
42      clutter_init_with_args (argc, argv, "PDFCube 0.1.0",
43                              options, NULL, NULL);
44     
45      // FIXME
46      if(file_array[0] == 0 || file_array[1] != 0) 
47        return false;
48      filename_m = file_array[0];
49      g_print(_("File is: %s\n"), filename_m);
50
51      ClutterColor stage_color;
52      the_stage_m = clutter_stage_get_default();
53      clutter_actor_set_size(the_stage_m, 1024, 768);
54      clutter_color_from_string(&stage_color, "Black");
55      clutter_stage_set_color(CLUTTER_STAGE(the_stage_m), &stage_color);
56      return true;
57    }
58
59    /** @brief Loads the PDF document. */
60    bool load()
61    {
62      // poppler needs an URI (e.g. file:///....)
63      g_print(_("Loading %s...\n"), filename_m);
64      PopplerDocument* active_document = 
65        poppler_document_new_from_file(filename_m, NULL, NULL);
66      if(active_document == NULL)
67        {
68          g_print(_("PDF file %s cannot be opened,"
69                    " check that it exists, permissions"
70                    " and that is \nnot encrypted.\n"), filename_m);
71          return false;
72        }
73      g_print(_("Done.\n"));
74      if(the_doc_m) delete the_doc_m;
75      the_doc_m = new pdfcube::document(active_document);
76      return true;
77    }
78
79    /** @brief Main application loop. */
80    void
81    main_loop()
82    {
83      //clutter_stage_hide_cursor (CLUTTER_STAGE (stage));
84      ClutterColor label_color = { 0xff, 0xff, 0xff, 0x99 };
85      progress_label_m = 
86        clutter_text_new_full("Mono 36", "0%", &label_color);
87      gfloat screen_w, screen_h;
88      clutter_actor_get_size(CLUTTER_ACTOR(the_stage_m), 
89                             &screen_w, &screen_h);
90      clutter_actor_set_position(progress_label_m, 
91                                 screen_w/2.0, screen_h/2.0);
92      clutter_actor_set_anchor_point_from_gravity(progress_label_m, 
93                                                  CLUTTER_GRAVITY_CENTER);
94      clutter_container_add_actor(CLUTTER_CONTAINER(the_stage_m), 
95                                  progress_label_m);
96      clutter_actor_show(the_stage_m);
97      g_thread_create(render_thread, this, FALSE, NULL);
98     
99      clutter_actor_set_reactive(the_stage_m, TRUE);
100      g_signal_connect(the_stage_m, 
101                       "key-press-event",
102                       G_CALLBACK (pdfcube::app::keypress_event), 
103                       NULL);
104      clutter_threads_enter();
105      clutter_main();
106      clutter_threads_leave();
107    }
108
109    /** @brief The document. */
110    document* the_doc_m;
111   
112  protected:
113    ClutterActor* the_stage_m;
114    gchar *filename_m;
115    std::string progress_m;
116    ClutterActor* progress_label_m;
117    ClutterActor* current_page_m;
118    ClutterActor* next_page_m;
119    int current_page_no_m;
120
121    static gboolean
122    progress_indicator_update(gpointer data)
123    {
124      app* me = static_cast<app*>(data);
125      gfloat screen_w, screen_h;
126      clutter_actor_get_size(CLUTTER_ACTOR(me->the_stage_m), 
127                             &screen_w, &screen_h);
128      clutter_text_set_text(CLUTTER_TEXT(me->progress_label_m), 
129                            me->progress_m.c_str());
130      clutter_actor_set_anchor_point_from_gravity(me->progress_label_m, 
131                                                  CLUTTER_GRAVITY_CENTER);
132      clutter_actor_set_position(me->progress_label_m, 
133                                 screen_w/2.0, screen_h/2.0);
134      return FALSE;
135    }
136
137    static gboolean
138    progress_indicator_end(gpointer data)
139    {
140      app* me = static_cast<app*>(data);
141      clutter_container_remove_actor(CLUTTER_CONTAINER(me->the_stage_m), 
142                               me->progress_label_m);
143      g_object_unref(me->progress_label_m);
144
145      GError* error = 0;
146      GdkPixbuf* buffer = me->the_doc_m->page(0).pixbuf(pdfcube::page::HI_RES);
147      me->current_page_m = clutter_texture_new();
148      clutter_texture_set_filter_quality
149        (CLUTTER_TEXTURE(me->current_page_m), 
150         CLUTTER_TEXTURE_QUALITY_HIGH);
151      clutter_texture_set_from_rgb_data
152        (CLUTTER_TEXTURE(me->current_page_m),
153         gdk_pixbuf_get_pixels(buffer),
154         gdk_pixbuf_get_has_alpha(buffer),
155         gdk_pixbuf_get_width(buffer),
156         gdk_pixbuf_get_height(buffer),
157         gdk_pixbuf_get_rowstride(buffer),
158         4, (ClutterTextureFlags)0,
159         &error);
160
161      gfloat screen_w, screen_h;
162      clutter_actor_get_size(CLUTTER_ACTOR(me->the_stage_m), 
163                             &screen_w, &screen_h);
164     
165     
166      // Check if our slot ratio is less or more than owr own
167      double aspect = me->the_doc_m->page(0).aspect_ratio();
168     
169      double w = 0.0, h = 0.0;
170      if(screen_h > screen_w/aspect)
171        {
172          w = screen_w;
173          h = w/aspect;
174        }
175      else 
176        {
177          h = screen_h;
178          w = h*aspect;
179        }
180     
181      clutter_actor_set_size(me->current_page_m, w, h);
182      clutter_container_add_actor(CLUTTER_CONTAINER(me->the_stage_m), 
183                                  me->current_page_m);
184
185      ClutterBindingPool *binding_pool;
186      std::cerr << G_OBJECT_TYPE_NAME(me->the_stage_m) << std::endl;
187      binding_pool = clutter_binding_pool_new(G_OBJECT_TYPE_NAME(me->the_stage_m));
188
189      clutter_binding_pool_install_action(binding_pool, 
190                                          "move-up",
191                                          CLUTTER_Up, (ClutterModifierType)0,
192                                          G_CALLBACK(pdfcube::app::action_move_up),
193                                          me, 
194                                          NULL);
195
196      clutter_binding_pool_install_action(binding_pool, 
197                                          "move-up",
198                                          CLUTTER_KP_Up, (ClutterModifierType)0,
199                                          G_CALLBACK(pdfcube::app::action_move_up),
200                                          me, 
201                                          NULL);
202
203      return FALSE;
204    }
205
206    static gpointer
207    render_thread(gpointer data)
208    {
209      app* me = static_cast<app*>(data);
210      std::cerr << me->filename_m << std::endl;
211      me->load();
212      // ----------------------------------------------
213      // render low res version of all pages
214      // ----------------------------------------------
215      for(int ii(0); ii != me->the_doc_m->n_pages(); ++ii)
216        {
217          me->the_doc_m->page(ii).render(pdfcube::page::LOW_RES);
218          int percent = (100*(ii))/(me->the_doc_m->n_pages()+2);
219          std::ostringstream pt;
220          pt << percent << "%"; 
221          me->progress_m = pt.str();
222          clutter_threads_add_timeout(0, progress_indicator_update, data);
223        }
224      me->the_doc_m->page(0).render(pdfcube::page::HI_RES);
225      int percent = (100*(me->the_doc_m->n_pages())) /
226        (me->the_doc_m->n_pages()+2);
227      std::ostringstream pt;
228      pt << percent << "%"; 
229      me->progress_m = pt.str();
230      clutter_threads_add_timeout(0, progress_indicator_update, data);
231     
232      me->the_doc_m->page(1).render(pdfcube::page::HI_RES);
233      me->progress_m = "100%";
234      clutter_threads_add_timeout(0, progress_indicator_update, data);
235      clutter_threads_add_timeout(250, progress_indicator_end, data);
236      return 0;
237    }
238
239    //////////////////////////////////////////////////////////////////////
240    //
241    // Callbacks
242    //
243    static gboolean keypress_event(ClutterActor* actor,
244                                   ClutterEvent* evt,
245                                   gpointer data)
246    {
247      pdfcube::app* self = (pdfcube::app*)data;
248      ClutterKeyEvent* key_evt = (ClutterKeyEvent*)evt;
249      ClutterBindingPool *pool = NULL;
250     
251      std::cerr << " * " << G_OBJECT_TYPE_NAME(actor) << std::endl;
252      /* retrieve the binding pool for the type of the actor */
253      pool = clutter_binding_pool_find(G_OBJECT_TYPE_NAME(actor));
254     
255      assert(pool);
256      /* activate any callback matching the key symbol and modifiers
257       * mask of the key event. the returned value can be directly
258       * used to signal that the actor has handled the event.
259       */
260      return clutter_binding_pool_activate (pool, 
261                                            (guint)key_evt->keyval,
262                                            (ClutterModifierType)key_evt->modifier_state,
263                                            G_OBJECT(actor));
264     
265    }
266
267    static gboolean action_move_up(GObject             *instance,
268                                   const gchar         *action_name,
269                                   guint                key_val,
270                                   ClutterModifierType  modifiers,
271                                   gpointer             user_data)
272    {
273      std::cerr << "move-up" << std::endl;
274    }
275
276
277
278  };
279}
Note: See TracBrowser for help on using the browser.