root/branches/clutter-experiments/main.cc

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

Keybindings core.

Line 
1// note: If we will end up using GObject + C++ the result will seem
2// always an horrible hack. We need either a good (for our purposes)
3// C++ interface (or binding) for Poppler and Clutter or to code the
4// whole thing in C using GObjects.
5#include <iostream>
6#include <sstream>
7#include <cmath>
8#include <cstdlib>
9#include <cstring>
10#include <clutter/clutter.h>
11#include <poppler.h>
12#include <libintl.h>
13#define _(String) gettext(String)
14
15#include "document.hh"
16#include "page.hh"
17#include "pdfcube.hh"
18
19using namespace std;
20
21
22void usage()
23{
24  cerr << _("pdfcube filename.pdf") << endl;
25  exit(1);
26}
27
28
29/*
30static gboolean
31on_page_enter(ClutterActor* actor, ClutterEvent *event, gpointer data)
32{
33  double sx, sy;
34  clutter_actor_get_scale(actor, &sx, &sy);
35  if(sx > 1.0 || sy > 1.0) return FALSE;
36  // Code snippet for a static member of the index class,
37  // data should point to the index instance, so one can
38  // also click on a page and have its number.
39  // FIXME: cancel previous animation before starting a new one.
40  ClutterTimeline *timeline = clutter_timeline_new(20, 60);
41  clutter_timeline_set_loop(timeline, TRUE);
42  clutter_timeline_start(timeline);
43  ClutterEffectTemplate *effect_template =
44    clutter_effect_template_new(timeline,
45                                clutter_sine_half_func);
46  clutter_effect_scale(effect_template, actor, 1.12, 1.12, NULL, NULL);
47  g_object_unref(effect_template);
48  g_object_unref(timeline);
49  return TRUE;
50}
51
52static gboolean
53on_page_leave(ClutterActor* actor, ClutterEvent *event, gpointer data)
54{
55  return TRUE;
56}
57*/
58static gboolean
59on_stage_button_press (ClutterStage *stage, ClutterEvent *event, gpointer data)
60{
61  gfloat x, y;
62  clutter_event_get_coords (event, &x, &y);
63  g_print ("Stage clicked at (%f, %f)\n", x, y);
64  // clutter cluttered my first draw, so redraw on click to allow testing.
65  // clutter_actor_queue_redraw(CLUTTER_ACTOR(stage));
66  return TRUE; /* Stop further handling of this event. */
67}
68
69/**
70 * The index class will contain methods to show all the pages in an
71 * index page, to hilight a different page and to restore the selected
72 * page in full screen.
73 *
74 */
75class index
76{
77  // ...
78  // 1. animate to index when tab is pressed
79  // 2. navigate with the keyboard and/or mouse (see on_page_enter)
80  // 3. animate to the single page choosen (clicked or previous on esc)
81  //
82};
83
84/**
85 * @brief Abstract animator class.
86 *
87 * Animations are for transitions between two pages. They start from
88 * one page and go to another one. The prepare() method whoud be
89 * called before starting and is indended to render the hi resolution
90 * version of the needed pages and to setup the scene
91 * graph. render(frame) is used to position the actors for the given
92 * frame number and unprepare() will free the unneded hi-res versions.
93 */
94class animator
95{
96public:
97  virtual ~animator() {}
98
99  virtual void
100  setup() = 0;
101 
102  virtual void
103  render(int frame) = 0;
104 
105  virtual void
106  tear_down() = 0;
107};
108
109class replace_animator : public animator
110{
111public:
112  replace_animator(pdfcube::document& doc, int page_no) {};
113  void
114  setup() {}
115  void
116  render(int frame) {}
117  void
118  tear_down() {}
119};
120
121
122class cube_animator : public animator
123{
124public:
125  cube_animator(pdfcube::document& doc, int page_no) {};
126  void
127  setup() {}
128  void
129  render(int frame) {}
130  void
131  tear_down() {}
132};
133
134
135/**
136 * An animator factory returns an animator for the give page number of
137 * a document.
138 *
139 */
140class animator_factory
141{
142  animator* make_animator(pdfcube::document& doc, int page_no)
143  {
144    switch(doc.page(page_no).transition_type())
145      {
146      case POPPLER_PAGE_TRANSITION_REPLACE:
147        return new replace_animator(doc, page_no);
148      case POPPLER_PAGE_TRANSITION_BOX:
149        return new cube_animator(doc, page_no);
150      default:
151        return new replace_animator(doc, page_no);
152      }
153    return NULL;
154  }
155};
156
157// a main to quick-test some clutter api
158int main(int argc, char* argv[])
159{
160  // --------------
161  // Initialization
162  // --------------
163
164  pdfcube::app the_app;
165
166  the_app.init(&argc, &argv);
167
168  the_app.main_loop();
169
170  /*
171  // --------------------------
172  // arrange pages in an index
173  // TODO: move in an animation
174  // --------------------------
175  guint screen_w = 0;
176  guint screen_h = 0;
177  clutter_stage_fullscreen (CLUTTER_STAGE (stage));
178  clutter_actor_get_size(CLUTTER_ACTOR(stage), &screen_w, &screen_h);
179
180  double frows = ::sqrt(doc.n_pages());
181  double fcols = std::ceil(((double)doc.n_pages())/std::floor(frows));
182
183  int cols = std::floor(fcols);
184  int rows = frows;
185
186  double box_w = ((double)screen_w)/cols;
187  double box_h = ((double)screen_h)/rows;
188  double min_padding = 6;
189
190  for(int ii(0); ii != doc.n_pages(); ++ii)
191    {
192      int row = ii%cols;
193      int col = ii/cols;
194      double box_x = ((double)row*screen_w)/cols;
195      double box_y = ((double)col*screen_h)/rows;
196
197      double aspect = doc.page(ii).aspect_ratio();
198     
199      double w = 0.0, h = 0.0;
200     
201      // Check if our slot ratio is less or more than owr own
202      if(box_h > box_w/aspect)
203        {
204          w = box_w - min_padding*2;
205          h = w/aspect;
206        }
207      else
208        {
209          h = box_h - min_padding*2;
210          w = h*aspect;
211        }
212     
213
214      //cerr << w << ", " << h << ", " << aspect << endl;
215
216      ClutterActor* page =
217        CLUTTER_ACTOR(doc.page(ii).actor(pdfcube::page::LOW_RES));
218      clutter_actor_set_size(page, (int)w, (int)h);
219      clutter_actor_set_position(page,
220                                 (int)(box_x + box_w/2),
221                                 (int)(box_y + box_h/2));
222      // THIS IS NOT RELATIVE TO ACTOR REAL SIZE, BUT TO ACTOR PERCEIVED SIZE
223      clutter_actor_set_anchor_point_from_gravity(page, CLUTTER_GRAVITY_CENTER);
224      clutter_group_add_many(CLUTTER_GROUP(stage), page, NULL);
225      // Make actor reactive
226      clutter_actor_set_reactive(page, TRUE);
227      g_signal_connect (page, "enter-event",
228                        G_CALLBACK (on_page_enter), NULL);
229      g_signal_connect (page, "leave-event",
230                        G_CALLBACK (on_page_leave), NULL);
231    }
232
233  // -------------------------
234
235  // Connect a signal handler to handle mouse clicks and key presses
236  //   on the stage:
237  g_signal_connect (stage, "button-press-event",
238                    G_CALLBACK (on_stage_button_press), NULL);
239
240
241  //clutter_stage_hide_cursor (CLUTTER_STAGE (stage));
242  clutter_actor_show (stage);
243  clutter_main ();
244*/ 
245  return 0;
246}
Note: See TracBrowser for help on using the browser.