initial version
[synfig.git] / synfig-studio / trunk / src / gtkmm / workarea.h
1 /* === S I N F G =========================================================== */
2 /*!     \file workarea.h
3 **      \brief Template Header
4 **
5 **      $Id: workarea.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
6 **
7 **      \legal
8 **      Copyright (c) 2002 Robert B. Quattlebaum Jr.
9 **
10 **      This software and associated documentation
11 **      are CONFIDENTIAL and PROPRIETARY property of
12 **      the above-mentioned copyright holder.
13 **
14 **      You may not copy, print, publish, or in any
15 **      other way distribute this software without
16 **      a prior written agreement with
17 **      the copyright holder.
18 **      \endlegal
19 */
20 /* ========================================================================= */
21
22 /* === S T A R T =========================================================== */
23
24 #ifndef __SINFG_GTKMM_WORKAREA_H
25 #define __SINFG_GTKMM_WORKAREA_H
26
27 /* === H E A D E R S ======================================================= */
28
29 #include <list>
30 #include <map>
31 #include <set>
32
33 #include <ETL/smart_ptr>
34 #include <ETL/handle>
35
36 #include <gtkmm/drawingarea.h>
37 #include <gtkmm/table.h>
38 #include <gtkmm/adjustment.h>
39 #include <gtkmm/ruler.h>
40 #include <gtkmm/image.h>
41 #include <gdkmm/pixbuf.h>
42 #include <gdkmm/cursor.h>
43 #include <gdkmm/device.h>
44
45 #include <sinfg/time.h>
46 #include <sinfg/vector.h>
47 #include <sinfg/general.h>
48 #include <sinfg/renddesc.h>
49 #include <sinfg/canvas.h>
50
51 #include "zoomdial.h"
52 #include "duckmatic.h"
53 #include "instance.h"
54
55 /* === M A C R O S ========================================================= */
56
57 /* === T Y P E D E F S ===================================================== */
58
59 /* === C L A S S E S & S T R U C T S ======================================= */
60
61 /*
62 namespace etl {
63
64 template <typename T_, typename C_=std::less<T_,T_> >
65 class dereferenced_compare
66 {
67 public:
68         typedef etl::loose_handle<T_> first_argument_type;
69         typedef etl::loose_handle<T_> second_argument_type;
70         typedef bool result_type;
71         
72 }
73 };
74 */
75
76 class WorkAreaTarget;
77 class WorkAreaTarget_Full;
78 namespace sinfgapp { class CanvasInterface; };
79
80 namespace sinfg { class Layer; };
81 namespace Gtk { class Frame; };
82
83 namespace studio
84 {
85 class Instance;
86 class CanvasView;
87 class WorkArea;
88 class WorkAreaRenderer;
89 class AsyncRenderer;
90 class DirtyTrap
91 {
92         friend class WorkArea;
93         WorkArea *work_area;
94 public:
95         DirtyTrap(WorkArea *work_area);
96         ~DirtyTrap();
97 };
98
99
100 class WorkArea : public Gtk::Table, public Duckmatic
101 {
102         friend class WorkAreaTarget;
103         friend class WorkAreaTarget_Full;
104         friend class DirtyTrap;
105         friend class WorkAreaRenderer;
106                 
107         /*
108  -- ** -- P U B L I C   T Y P E S ---------------------------------------------
109         */
110         
111 public:
112
113         void insert_renderer(const etl::handle<WorkAreaRenderer> &x);
114         void insert_renderer(const etl::handle<WorkAreaRenderer> &x,int priority);
115         void erase_renderer(const etl::handle<WorkAreaRenderer> &x);
116         void resort_render_set();
117
118         enum DragMode
119         {
120                 DRAG_NONE=0,
121                 DRAG_WINDOW,
122                 DRAG_DUCK,
123                 DRAG_GUIDE,
124                 DRAG_BOX
125         };
126
127         /*
128  -- ** -- P R I V A T E   D A T A ---------------------------------------------
129         */
130
131 private:
132
133         std::set<etl::handle<WorkAreaRenderer> > renderer_set_;
134
135         etl::handle<studio::AsyncRenderer> async_renderer;
136
137
138         etl::loose_handle<sinfgapp::CanvasInterface> canvas_interface;
139         etl::handle<sinfg::Canvas> canvas;
140         etl::loose_handle<studio::Instance> instance;
141         etl::loose_handle<studio::CanvasView> canvas_view;
142
143         // Widgets
144         Gtk::DrawingArea *drawing_area;
145         Gtk::Adjustment scrollx_adjustment;
146         Gtk::Adjustment scrolly_adjustment;
147         Gtk::VRuler *vruler;
148         Gtk::HRuler *hruler;
149         Gtk::Button *menubutton;
150         Gtk::Frame *drawing_frame;
151
152         GdkDevice* curr_input_device;
153         
154         // Bleh!
155         int     w;                                              //!< Width of the image (in pixels)
156         int     h;                                              //!< Height of the image (in pixels)
157         sinfg::Real     canvaswidth;    //!< Width of the canvas
158         sinfg::Real     canvasheight;   //!< Height of the canvas
159         sinfg::Real     pw;                             //!< The width of a pixel
160         sinfg::Real     ph;                             //!< The height of a pixel
161         float zoom;                                     //!< Zoom factor
162         float prev_zoom;                        //!< Previous Zoom factor
163         sinfg::Point window_tl;         //!< The (theoretical) top-left corner of the view window
164         sinfg::Point window_br;         //!< The (theoretical) bottom-right corner of the view window
165
166         guint32 last_event_time;
167
168         int bpp;
169         //unsigned char *buffer;
170         
171         //! ???
172         sinfg::ProgressCallback *progresscallback;
173
174         //! ???
175         sinfg::RendDesc desc;
176         
177         //! This flag is set if the user is dragging the video window
178         /*! \see drag_point */
179         DragMode dragging;
180                 
181         etl::handle<Duckmatic::Duck> clicked_duck;
182         etl::handle<Duckmatic::Duck> hover_duck;
183
184         //! When dragging the viewport, this is set to the origin of the drag
185         sinfg::Point drag_point;
186
187         sinfg::Point curr_point;
188
189         //! ???
190         sinfg::Point previous_focus;
191
192         //! This flag is set if the grid should be drawn
193         bool show_grid;
194
195         //! This flag is set if the guides should be drawn
196         bool show_guides;
197
198         bool low_resolution;
199         
200         bool meta_data_lock;
201
202         //! This flag is set if the entire frame is rendered rather than using tiles    
203         bool full_frame;
204         
205         //Glib::RefPtr<Gdk::Pixbuf> pix_buf;
206         
207         //! This vector holds all of the tiles for this image
208         std::vector< std::pair<Glib::RefPtr<Gdk::Pixbuf>,int> > tile_book;
209
210         //! This integer describes the total times that the work are has been refreshed
211         int refreshes;
212         
213         //! This list holds the queue of tiles that need to be rendered
214         //std::list<int> tile_queue;
215         
216         int tile_w, tile_h;
217
218         gint render_idle_func_id;
219
220         //! The coordinates of the focus the last time a part of the screen was refreshed
221         sinfg::Point last_focus_point;
222
223         bool canceled_;
224         
225         int quality;
226
227         bool dirty_trap_enabled;
228         
229         int dirty_trap_queued;
230         
231         
232         bool onion_skin;
233                 
234         etl::loose_handle<sinfg::ValueNode> selected_value_node_;
235
236
237         /*
238  -- ** -- P U B L I C   D A T A -----------------------------------------------
239         */
240
241 public:
242
243         const etl::loose_handle<sinfg::ValueNode>& get_selected_value_node() { return  selected_value_node_; }
244         const sinfg::Point& get_drag_point()const { return drag_point; }
245         std::vector< std::pair<Glib::RefPtr<Gdk::Pixbuf>,int> >& get_tile_book(){ return tile_book; }
246         int get_refreshes()const { return refreshes; }
247         bool get_canceled()const { return canceled_; }
248         bool get_queued()const { return queued; }
249         bool get_rendering()const { return rendering; }
250         bool get_full_frame()const { return full_frame; }
251         //int get_w()const { return w; }
252         //int get_h()const { return h; }
253
254         int get_tile_w()const { return tile_w; }
255         int get_tile_h()const { return tile_h; }
256         
257         bool solid_lines;
258         bool rendering;
259         bool dirty;
260         bool queued;
261         bool cancel;
262         bool allow_layer_clicks;
263         bool allow_duck_clicks;
264
265         GuideList::iterator curr_guide;
266         bool curr_guide_is_x;
267
268         /*
269  -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
270         */
271
272 private:
273
274         //unsigned char *get_buffer() { return buffer; }
275         bool set_wh(int w, int h,int chan=3);
276
277         int next_unrendered_tile(int refreshes)const;
278         int next_unrendered_tile()const { return next_unrendered_tile(refreshes); }
279
280         /*
281  -- ** -- S I G N A L S -------------------------------------------------------
282         */
283
284 private:
285
286         sigc::signal<void,GdkDevice* > signal_input_device_changed_;
287
288         //! One signal per button
289         sigc::signal<void,sinfg::Point> signal_user_click_[5];
290
291         sigc::signal<void> signal_popup_menu_;
292
293         sigc::signal<void> signal_cursor_moved_;
294         sigc::signal<void> signal_rendering_;
295
296         sigc::signal<void> signal_onion_skin_changed_;
297
298         //! Signal for when the user clicks on a layer
299         sigc::signal<void, etl::handle<sinfg::Layer> > signal_layer_selected_;
300
301         sigc::signal<void> signal_view_window_changed_;
302
303 public:
304
305         sigc::signal<void>& signal_onion_skin_changed() { return signal_onion_skin_changed_; }
306
307         sigc::signal<void>& signal_rendering() { return signal_rendering_; }
308
309         sigc::signal<void>& signal_cursor_moved() { return signal_cursor_moved_; }
310
311         sigc::signal<void>& signal_view_window_changed() { return signal_view_window_changed_; }
312         void view_window_changed() { signal_view_window_changed()(); }
313
314         sigc::signal<void,GdkDevice* >& signal_input_device_changed() { return signal_input_device_changed_; }
315
316         sigc::signal<void> &signal_popup_menu() { return signal_popup_menu_; }
317
318         //! One signal per button (5 buttons)
319         sigc::signal<void,sinfg::Point> &signal_user_click(int button=0){ return signal_user_click_[button]; }
320
321         sigc::signal<void, etl::handle<sinfg::Layer> >& signal_layer_selected() { return signal_layer_selected_; }
322
323         /*
324  -- ** -- P U B L I C   M E T H O D S -----------------------------------------
325         */
326
327 public:
328         void set_onion_skin(bool x);
329         bool get_onion_skin()const;
330         void toggle_onion_skin() { set_onion_skin(!get_onion_skin()); }
331
332         void set_selected_value_node(etl::loose_handle<sinfg::ValueNode> x);
333
334         bool is_dragging() { return dragging!=DRAG_NONE; }
335
336         DragMode get_dragging_mode() { return dragging; }
337
338         WorkArea(etl::loose_handle<sinfgapp::CanvasInterface> canvas_interface);
339         virtual ~WorkArea();
340
341         void set_cursor(const Gdk::Cursor& x);
342         void set_cursor(Gdk::CursorType x);
343
344         const sinfg::Point& get_cursor_pos()const { return curr_point; }
345
346         Gtk::Adjustment *get_scrollx_adjustment() { return &scrollx_adjustment; }
347         Gtk::Adjustment *get_scrolly_adjustment() { return &scrolly_adjustment; }
348         const Gtk::Adjustment *get_scrollx_adjustment()const { return &scrollx_adjustment; }
349         const Gtk::Adjustment *get_scrolly_adjustment()const { return &scrolly_adjustment; }
350
351         void set_instance(etl::loose_handle<studio::Instance> x) { instance=x; }
352         void set_canvas(etl::handle<sinfg::Canvas> x) { canvas=x; }
353         void set_canvas_view(etl::loose_handle<studio::CanvasView> x) { canvas_view=x; }
354         etl::handle<sinfg::Canvas> get_canvas()const { return canvas; }
355         etl::handle<studio::Instance> get_instance()const { return instance; }
356         etl::loose_handle<studio::CanvasView> get_canvas_view()const { return canvas_view; }
357
358         void refresh_dimension_info();
359         
360         //! Enables showing of the grid
361         void enable_grid();
362         
363         //! Disables showing of the grid
364         void disable_grid();
365         
366         //! Toggles the showing of the grid
367         void toggle_grid();
368         
369         //! Returns the state of the show_grid flag
370         bool grid_status()const { return show_grid; }
371
372         void toggle_grid_snap() { Duckmatic::toggle_grid_snap(); }
373
374         bool get_show_guides()const { return show_guides; }
375         void set_show_guides(bool x);
376         void toggle_show_guides() { set_show_guides(!get_show_guides()); }
377                 
378         bool get_low_resolution_flag()const { return low_resolution; }
379         void set_low_resolution_flag(bool x);
380         void toggle_low_resolution_flag();
381         
382         //! ???
383         void queue_scroll();
384         
385         //! Sets the size of the grid
386         void set_grid_size(const sinfg::Vector &s);
387                 
388         //! ??
389         void popup_menu();
390         
391         int get_quality()const { return quality; }
392
393         void set_quality(int x);
394         
395
396         int get_w()const { return w; }
397         int get_h()const { return h; }
398         int get_bpp()const { return bpp; }
399
400         //! ??
401         const sinfg::RendDesc &get_rend_desc()const { return desc; }
402         
403         //! ??
404         void set_rend_desc(const sinfg::RendDesc &x) { desc=x; }
405         
406         //! Converts screen coords (ie: pixels) to composition coordinates
407         sinfg::Point screen_to_comp_coords(sinfg::Point pos)const;
408
409         //! Converts composition coordinates to screen coords (ie: pixels)
410         sinfg::Point comp_to_screen_coords(sinfg::Point pos)const;
411
412         float get_pw()const { return pw; }
413         float get_ph()const { return ph; }
414         
415         const sinfg::Point &get_window_tl()const { return window_tl; }
416         const sinfg::Point &get_window_br()const { return window_br; }
417
418
419         bool async_update_preview();
420         void async_update_finished();
421         void async_render_preview(sinfg::Time time);
422         void async_render_preview();
423         
424         bool sync_update_preview();
425         bool sync_render_preview(sinfg::Time time);
426         bool sync_render_preview();
427         void sync_render_preview_hook();
428
429         void queue_render_preview();
430         
431         
432         void queue_draw_preview();
433         
434         void zoom_in();
435         void zoom_out();
436         void zoom_fit();
437         void zoom_norm();
438         float get_zoom()const { return zoom; }
439         
440         void set_zoom(float z);
441
442
443         void set_progress_callback(sinfg::ProgressCallback *x)  { progresscallback=x; }
444         sinfg::ProgressCallback *get_progress_callback() { return progresscallback; }
445
446         void set_focus_point(const sinfg::Point &x);
447
448         sinfg::Point get_focus_point()const;
449
450         void done_rendering();
451         
452         bool refresh(GdkEventExpose*bleh=NULL);
453         
454         void reset_cursor();
455         void refresh_cursor();
456
457         void save_meta_data();
458         void load_meta_data();
459         
460         /*
461  -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
462         */
463
464 private:
465         bool on_key_press_event(GdkEventKey* event);
466         bool on_drawing_area_event(GdkEvent* event);
467         bool on_hruler_event(GdkEvent* event);
468         bool on_vruler_event(GdkEvent* event);
469
470         /*
471  -- ** -- S T A T I C   P U B L I C   M E T H O D S ---------------------------
472         */
473
474 public:
475
476         /*
477  -- ** -- S T A T I C   P R I V A T E   M E T H O D S -------------------------
478         */
479
480 private:
481
482         static gboolean __render_preview(gpointer data);
483
484 }; // END of class WorkArea
485
486 }; // END of namespace studio
487
488 /* === E N D =============================================================== */
489
490 #endif