1 /* === S Y N F I G ========================================================= */ 2 /*! \file workarea.h 3 ** \brief Template Header 4 ** 5 ** $Id$ 6 ** 7 ** \legal 8 ** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley 9 ** Copyright (c) 2007, 2008 Chris Moore 10 ** Copyright (c) 2011 Nikita Kitaev 11 ** 12 ** This package is free software; you can redistribute it and/or 13 ** modify it under the terms of the GNU General Public License as 14 ** published by the Free Software Foundation; either version 2 of 15 ** the License, or (at your option) any later version. 16 ** 17 ** This package is distributed in the hope that it will be useful, 18 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 19 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20 ** General Public License for more details. 21 ** \endlegal 22 */ 23 /* ========================================================================= */ 24 25 /* === S T A R T =========================================================== */ 26 27 #ifndef __SYNFIG_GTKMM_WORKAREA_H 28 #define __SYNFIG_GTKMM_WORKAREA_H 29 30 /* === H E A D E R S ======================================================= */ 31 32 #include <list> 33 #include <map> 34 #include <set> 35 36 #include <ETL/smart_ptr> 37 #include <ETL/handle> 38 39 #include <gtkmm/drawingarea.h> 40 #include <gtkmm/table.h> 41 #include <gtkmm/adjustment.h> 42 #include <gtkmm/image.h> 43 #include <gdkmm/pixbuf.h> 44 #include <gdkmm/cursor.h> 45 #include <gdkmm/device.h> 46 47 #include <synfig/time.h> 48 #include <synfig/vector.h> 49 #include <synfig/renddesc.h> 50 #include <synfig/canvas.h> 51 52 #include "dials/zoomdial.h" 53 #include "widgets/widget_ruler.h" 54 #include "duckmatic.h" 55 #include "instance.h" 56 #include "app.h" 57 58 /* === M A C R O S ========================================================= */ 59 60 /* === T Y P E D E F S ===================================================== */ 61 62 /* === C L A S S E S & S T R U C T S ======================================= */ 63 64 /* 65 namespace etl { 66 67 template <typename T_, typename C_=std::less<T_,T_> > 68 class dereferenced_compare 69 { 70 public: 71 typedef etl::loose_handle<T_> first_argument_type; 72 typedef etl::loose_handle<T_> second_argument_type; 73 typedef bool result_type; 74 75 } 76 }; 77 */ 78 79 namespace synfigapp { class CanvasInterface; }; 80 81 namespace synfig { class Layer; }; 82 namespace Gtk { class Frame; }; 83 84 namespace studio 85 { 86 class WorkAreaTarget; 87 class WorkAreaTarget_Full; 88 class WorkAreaTarget_GL; 89 90 class Instance; 91 class CanvasView; 92 class WorkArea; 93 class WorkAreaRenderer; 94 class AsyncRenderer; 95 96 class DirtyTrap 97 { 98 friend class WorkArea; 99 WorkArea *work_area; 100 public: 101 DirtyTrap(WorkArea *work_area); 102 ~DirtyTrap(); 103 }; 104 105 class WorkAreaTile 106 { 107 public: 108 typedef std::list<WorkAreaTile> List; 109 110 int refresh_id; 111 synfig::RectInt rect; 112 Glib::RefPtr<Gdk::Pixbuf> pixbuf; 113 cairo_surface_t* surface; 114 WorkAreaTile()115 WorkAreaTile(): refresh_id(), surface() 116 { } WorkAreaTile(int refresh_id,int left,int top,const Glib::RefPtr<Gdk::Pixbuf> & pixbuf)117 WorkAreaTile(int refresh_id, int left, int top, const Glib::RefPtr<Gdk::Pixbuf> &pixbuf): 118 refresh_id(refresh_id), 119 rect( left, 120 top, 121 left + (pixbuf ? pixbuf->get_width() : 0), 122 top + (pixbuf ? pixbuf->get_height() : 0) ), 123 pixbuf(pixbuf), 124 surface() { } WorkAreaTile(int refresh_id,int left,int top,cairo_surface_t * surface)125 WorkAreaTile(int refresh_id, int left, int top, cairo_surface_t *surface): 126 refresh_id(refresh_id), 127 rect( left, 128 top, 129 left + (surface ? cairo_image_surface_get_width(surface) : 0), 130 top + (surface ? cairo_image_surface_get_height(surface) : 0) ), 131 surface() { } 132 133 bool operator< (const WorkAreaTile &other) const { return refresh_id < other.refresh_id; } 134 }; 135 136 class WorkAreaTileBook 137 { 138 private: 139 WorkAreaTile::List tiles; 140 141 public: get_tiles()142 const WorkAreaTile::List& get_tiles() const { return tiles; } 143 144 WorkAreaTile* find_tile(int refresh_id, const synfig::RectInt &rect); 145 clear()146 void clear() { tiles.clear(); } 147 148 void sort(); 149 150 void add(const WorkAreaTile &tile); 151 add(int refresh_id,int left,int top,const Glib::RefPtr<Gdk::Pixbuf> & pixbuf)152 void add(int refresh_id, int left, int top, const Glib::RefPtr<Gdk::Pixbuf> &pixbuf) 153 { add(WorkAreaTile(refresh_id, left, top, pixbuf)); } add(int refresh_id,int left,int top,cairo_surface_t * surface)154 void add(int refresh_id, int left, int top, cairo_surface_t *surface) 155 { add(WorkAreaTile(refresh_id, left, top, surface)); } 156 157 void get_dirty_rects( 158 std::vector<synfig::RectInt> &out_rects, 159 int refresh_id, 160 const synfig::RectInt &bounds, 161 const synfig::VectorInt &max_size = synfig::VectorInt(INT_MAX, INT_MAX) ) const; 162 }; 163 164 165 class WorkArea : public Gtk::Table, public Duckmatic 166 { 167 friend class WorkAreaTarget; 168 friend class WorkAreaTarget_Full; 169 friend class WorkAreaTarget_Cairo; 170 friend class WorkAreaTarget_Cairo_Tile; 171 friend class WorkAreaTarget_GL; 172 friend class DirtyTrap; 173 friend class WorkAreaRenderer; 174 friend class WorkAreaProgress; 175 176 /* 177 -- ** -- P U B L I C T Y P E S --------------------------------------------- 178 */ 179 180 public: 181 182 class PushState; 183 friend class PushState; 184 185 void insert_renderer(const etl::handle<WorkAreaRenderer> &x); 186 void insert_renderer(const etl::handle<WorkAreaRenderer> &x,int priority); 187 void erase_renderer(const etl::handle<WorkAreaRenderer> &x); 188 void resort_render_set(); 189 190 enum DragMode 191 { 192 DRAG_NONE=0, 193 DRAG_WINDOW, 194 DRAG_DUCK, 195 DRAG_GUIDE, 196 DRAG_BOX, 197 DRAG_BEZIER, 198 DRAG_ZOOM_WINDOW, 199 DRAG_ROTATE_WINDOW 200 }; 201 // Class used to store the cairo surface 202 class SurfaceElement 203 { 204 public: 205 cairo_surface_t* surface; 206 int refreshes; SurfaceElement()207 SurfaceElement() 208 { 209 surface=NULL; 210 refreshes=0; 211 } 212 //Copy constructor SurfaceElement(const SurfaceElement & other)213 SurfaceElement(const SurfaceElement& other): surface(cairo_surface_reference(other.surface)), refreshes(other.refreshes) 214 { 215 } ~SurfaceElement()216 ~SurfaceElement() 217 { 218 if(surface) 219 cairo_surface_destroy(surface); 220 } 221 }; 222 223 typedef std::vector<SurfaceElement> SurfaceBook; 224 225 /* 226 -- ** -- P R I V A T E D A T A --------------------------------------------- 227 */ 228 229 private: 230 231 std::set<etl::handle<WorkAreaRenderer> > renderer_set_; 232 233 etl::handle<studio::AsyncRenderer> async_renderer; 234 235 236 etl::loose_handle<synfigapp::CanvasInterface> canvas_interface; 237 etl::handle<synfig::Canvas> canvas; 238 etl::loose_handle<studio::Instance> instance; 239 etl::loose_handle<studio::CanvasView> canvas_view; 240 241 // Widgets 242 Gtk::DrawingArea *drawing_area; 243 Glib::RefPtr<Gtk::Adjustment> scrollx_adjustment; 244 Glib::RefPtr<Gtk::Adjustment> scrolly_adjustment; 245 Widget_Ruler *vruler; 246 Widget_Ruler *hruler; 247 Gtk::Frame *drawing_frame; 248 ZoomDial *zoomdial; 249 250 GdkDevice* curr_input_device; 251 252 // Bleh! 253 int w; //!< Width of the image (in pixels) 254 int h; //!< Height of the image (in pixels) 255 synfig::Real canvaswidth; //!< Width of the canvas 256 synfig::Real canvasheight; //!< Height of the canvas 257 synfig::Real pw; //!< The width of a pixel 258 synfig::Real ph; //!< The height of a pixel 259 // float zoom and prev_zoom are declared in Duckmatic 260 synfig::Point window_tl; //!< The (theoretical) top-left corner of the view window 261 synfig::Point window_br; //!< The (theoretical) bottom-right corner of the view window 262 263 guint32 last_event_time; 264 265 int bpp; 266 //unsigned char *buffer; 267 268 //! ??? 269 synfig::ProgressCallback *progresscallback; 270 271 //! ??? 272 synfig::RendDesc desc; 273 274 //! This flag is set if the user is dragging the video window 275 /*! \see drag_point */ 276 DragMode dragging; 277 278 etl::handle<Duckmatic::Duck> clicked_duck; 279 etl::handle<Duckmatic::Duck> hover_duck; 280 281 //! When dragging the viewport, this is set to the origin of the drag 282 synfig::Point drag_point; 283 284 synfig::Point curr_point; 285 286 //! ??? 287 synfig::Point previous_focus; 288 289 //! This flag is set if the grid should be drawn 290 bool show_grid; 291 292 //! This flag is set if the guides should be drawn 293 bool show_guides; 294 295 //! Checker background size 296 synfig::Vector background_size; 297 //! Checker background first color 298 synfig::Color background_first_color; 299 //! Checker background second color 300 synfig::Color background_second_color; 301 302 synfig::Time jack_offset; 303 304 bool low_resolution; 305 306 bool meta_data_lock; 307 308 //! This flag is set if the entire frame is rendered rather than using tiles 309 bool full_frame; 310 311 //Glib::RefPtr<Gdk::Pixbuf> pix_buf; 312 313 //! This vector holds all of the tiles for this frame 314 WorkAreaTileBook tile_book; 315 316 //! This integer describes the total times that the work area has been refreshed 317 int refreshes; 318 319 //! This list holds the queue of tiles that need to be rendered 320 //std::list<int> tile_queue; 321 322 int tile_w, tile_h; 323 324 gint render_idle_func_id; 325 326 //! The coordinates of the focus the last time a part of the screen was refreshed 327 synfig::Point last_focus_point; 328 329 bool canceled_; 330 331 int quality; 332 int low_res_pixel_size; 333 334 bool dirty_trap_enabled; 335 336 int dirty_trap_queued; 337 338 // This flag is set if onion skin is visible 339 bool onion_skin; 340 //! stores the future [1] and past [0] onion skins based on keyframes 341 int onion_skins[2]; 342 343 etl::loose_handle<synfig::ValueNode> selected_value_node_; 344 345 bool allow_duck_clicks; 346 bool allow_bezier_clicks; 347 bool allow_layer_clicks; 348 bool cancel; 349 bool curr_guide_is_x; 350 bool dirty; 351 bool queued; 352 bool rendering; 353 354 #ifdef SINGLE_THREADED 355 /* resize bug workaround */ 356 int old_window_width; 357 int old_window_height; 358 #endif 359 360 /* 361 -- ** -- P U B L I C D A T A ----------------------------------------------- 362 */ 363 364 public: 365 get_selected_value_node()366 const etl::loose_handle<synfig::ValueNode>& get_selected_value_node() { return selected_value_node_; } get_drag_point()367 const synfig::Point& get_drag_point()const { return drag_point; } get_tile_book()368 const WorkAreaTileBook& get_tile_book() const { return tile_book; } get_tile_book()369 WorkAreaTileBook& get_tile_book() { return tile_book; } get_refreshes()370 int get_refreshes()const { return refreshes; } get_canceled()371 bool get_canceled()const { return canceled_; } get_queued()372 bool get_queued()const { return queued; } get_rendering()373 bool get_rendering()const { return rendering; } 374 #ifdef SINGLE_THREADED 375 bool get_updating()const; 376 void stop_updating(bool cancel = false); 377 #endif get_full_frame()378 bool get_full_frame()const { return full_frame; } 379 //int get_w()const { return w; } 380 //int get_h()const { return h; } 381 382 synfig::VectorInt get_windows_offset() const; 383 synfig::RectInt get_window_rect(int stepx = 1, int stepy = 1) const; get_tile_w()384 int get_tile_w()const { return tile_w; } get_tile_h()385 int get_tile_h()const { return tile_h; } 386 get_allow_layer_clicks()387 bool get_allow_layer_clicks() { return allow_layer_clicks; } set_allow_layer_clicks(bool value)388 void set_allow_layer_clicks(bool value) { allow_layer_clicks=value; } 389 get_allow_duck_clicks()390 bool get_allow_duck_clicks() { return allow_duck_clicks; } set_allow_duck_clicks(bool value)391 void set_allow_duck_clicks(bool value) { allow_duck_clicks=value; } 392 get_allow_bezier_clicks()393 bool get_allow_bezier_clicks() { return allow_bezier_clicks; } set_allow_bezier_clicks(bool value)394 void set_allow_bezier_clicks(bool value) { allow_bezier_clicks=value; } 395 396 // used in renderer_ducks.cpp 397 bool solid_lines; 398 399 // used in renderer_guides.cpp 400 GuideList::iterator curr_guide; 401 402 // used in renderer_timecode.cpp 403 int timecode_width, timecode_height; 404 405 // used in renderer_bonesetup.cpp 406 int bonesetup_width, bonesetup_height; 407 408 /* 409 -- ** -- P R I V A T E M E T H O D S --------------------------------------- 410 */ 411 412 private: 413 414 //unsigned char *get_buffer() { return buffer; } 415 bool set_wh(int w, int h,int chan=3); 416 417 /* 418 -- ** -- S I G N A L S ------------------------------------------------------- 419 */ 420 421 private: 422 423 sigc::signal<void,GdkDevice* > signal_input_device_changed_; 424 425 //! One signal per button 426 sigc::signal<void,synfig::Point> signal_user_click_[5]; 427 428 sigc::signal<void> signal_popup_menu_; 429 430 sigc::signal<void> signal_cursor_moved_; 431 sigc::signal<void> signal_rendering_; 432 433 //! Signal for when the user clicks on a layer 434 sigc::signal<void, etl::handle<synfig::Layer> > signal_layer_selected_; 435 436 sigc::signal<void> signal_view_window_changed_; 437 438 sigc::signal<void> signal_meta_data_changed_; 439 440 public: 441 signal_rendering()442 sigc::signal<void>& signal_rendering() { return signal_rendering_; } 443 signal_cursor_moved()444 sigc::signal<void>& signal_cursor_moved() { return signal_cursor_moved_; } 445 signal_view_window_changed()446 sigc::signal<void>& signal_view_window_changed() { return signal_view_window_changed_; } 447 signal_meta_data_changed()448 sigc::signal<void>& signal_meta_data_changed() { return signal_meta_data_changed_; } 449 view_window_changed()450 void view_window_changed() { signal_view_window_changed()(); } 451 signal_input_device_changed()452 sigc::signal<void,GdkDevice* >& signal_input_device_changed() { return signal_input_device_changed_; } 453 signal_popup_menu()454 sigc::signal<void> &signal_popup_menu() { return signal_popup_menu_; } 455 456 //! One signal per button (5 buttons) 457 sigc::signal<void,synfig::Point> &signal_user_click(int button=0){ return signal_user_click_[button]; } 458 signal_layer_selected()459 sigc::signal<void, etl::handle<synfig::Layer> >& signal_layer_selected() { return signal_layer_selected_; } 460 461 /* 462 -- ** -- P U B L I C M E T H O D S ----------------------------------------- 463 */ 464 465 public: 466 void set_onion_skin(bool x); 467 bool get_onion_skin()const; toggle_onion_skin()468 void toggle_onion_skin() { set_onion_skin(!get_onion_skin()); } 469 void set_onion_skins(int *onions); 470 int const * get_onion_skins()const; 471 472 void set_selected_value_node(etl::loose_handle<synfig::ValueNode> x); 473 is_dragging()474 bool is_dragging() { return dragging!=DRAG_NONE; } 475 get_dragging_mode()476 DragMode get_dragging_mode() { return dragging; } 477 478 WorkArea(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface); 479 virtual ~WorkArea(); 480 481 void set_cursor(const Glib::RefPtr<Gdk::Cursor> &x); 482 void set_cursor(Gdk::CursorType x); 483 get_cursor_pos()484 const synfig::Point& get_cursor_pos()const { return curr_point; } 485 get_scrollx_adjustment()486 Glib::RefPtr<Gtk::Adjustment> get_scrollx_adjustment() { return scrollx_adjustment; } get_scrolly_adjustment()487 Glib::RefPtr<Gtk::Adjustment> get_scrolly_adjustment() { return scrolly_adjustment; } get_scrollx_adjustment()488 Glib::RefPtr<const Gtk::Adjustment> get_scrollx_adjustment() const { return scrollx_adjustment; } get_scrolly_adjustment()489 Glib::RefPtr<const Gtk::Adjustment> get_scrolly_adjustment() const { return scrolly_adjustment; } 490 set_instance(etl::loose_handle<studio::Instance> x)491 void set_instance(etl::loose_handle<studio::Instance> x) { instance=x; } set_canvas(etl::handle<synfig::Canvas> x)492 void set_canvas(etl::handle<synfig::Canvas> x) { canvas=x; } set_canvas_view(etl::loose_handle<studio::CanvasView> x)493 void set_canvas_view(etl::loose_handle<studio::CanvasView> x) { canvas_view=x; } get_canvas()494 etl::handle<synfig::Canvas> get_canvas()const { return canvas; } get_instance()495 etl::handle<studio::Instance> get_instance()const { return instance; } get_canvas_view()496 etl::loose_handle<studio::CanvasView> get_canvas_view()const { return canvas_view; } 497 498 void refresh_dimension_info(); 499 500 //! Enables showing of the grid 501 void enable_grid(); 502 //! Disables showing of the grid 503 void disable_grid(); 504 //! Toggles the showing of the grid 505 void toggle_grid(); 506 //! Returns the state of the show_grid flag grid_status()507 bool grid_status()const { return show_grid; } 508 //! Toggles the snap of the grid 509 void toggle_grid_snap(); 510 //! Sets the size of the grid 511 void set_grid_size(const synfig::Vector &s); 512 //! Sets the color of the grid 513 void set_grid_color(const synfig::Color &c); 514 //! Returns the color of the grid get_grid_color()515 const synfig::Color &get_grid_color()const { return Duckmatic::get_grid_color();} 516 517 //! Returns the state of the show_guides flag get_show_guides()518 bool get_show_guides()const { return show_guides; } 519 //! Sets the showing of the grid 520 void set_show_guides(bool x); 521 //! Toggles the showing of the guides toggle_show_guides()522 void toggle_show_guides() { set_show_guides(!get_show_guides()); } 523 //! Toggles the snap of the guides 524 void toggle_guide_snap(); 525 //! Sets the color of the guides 526 void set_guides_color(const synfig::Color &c); 527 //! Returns the color of the guides get_guides_color()528 const synfig::Color &get_guides_color()const { return Duckmatic::get_guides_color();} 529 get_jack_offset()530 synfig::Time get_jack_offset()const { return jack_offset; } 531 void set_jack_offset(const synfig::Time &x); 532 533 //! Sets the size of the checker background 534 void set_background_size(const synfig::Vector &s); 535 //! Sets the first color of the checker background 536 void set_background_first_color(const synfig::Color &c); 537 //! Sets the second color of the checker background 538 void set_background_second_color(const synfig::Color &c); 539 //! Sets the size of the checker background get_background_size()540 const synfig::Vector &get_background_size()const { return background_size;} 541 //! Returns the first color of the checker background get_background_first_color()542 const synfig::Color &get_background_first_color()const { return background_first_color;} 543 //! Returns the second color of the checker background get_background_second_color()544 const synfig::Color &get_background_second_color()const { return background_second_color;} 545 get_low_resolution_flag()546 bool get_low_resolution_flag()const { return low_resolution; } 547 void set_low_resolution_flag(bool x); 548 void toggle_low_resolution_flag(); 549 550 //! ??? 551 void queue_scroll(); 552 553 //! ?? 554 void popup_menu(); 555 get_quality()556 int get_quality()const { return quality; } get_low_res_pixel_size()557 int get_low_res_pixel_size()const { return low_res_pixel_size; } 558 synfig::String get_renderer() const; 559 560 void set_quality(int x); 561 void set_low_res_pixel_size(int x); 562 563 get_w()564 int get_w()const { return w; } get_h()565 int get_h()const { return h; } get_bpp()566 int get_bpp()const { return bpp; } 567 568 //! ?? get_rend_desc()569 const synfig::RendDesc &get_rend_desc()const { return desc; } 570 571 //! ?? set_rend_desc(const synfig::RendDesc & x)572 void set_rend_desc(const synfig::RendDesc &x) { desc=x; } 573 574 //! Converts screen coords (ie: pixels) to composition coordinates 575 synfig::Point screen_to_comp_coords(synfig::Point pos)const; 576 577 //! Converts composition coordinates to screen coords (ie: pixels) 578 synfig::Point comp_to_screen_coords(synfig::Point pos)const; 579 get_pw()580 float get_pw()const { return pw; } get_ph()581 float get_ph()const { return ph; } 582 get_window_tl()583 const synfig::Point &get_window_tl()const { return window_tl; } get_window_br()584 const synfig::Point &get_window_br()const { return window_br; } 585 586 587 bool async_update_preview(); 588 void async_update_finished(); 589 void async_render_preview(synfig::Time time); 590 void async_render_preview(); 591 592 bool sync_update_preview(); 593 bool sync_render_preview(synfig::Time time); 594 bool sync_render_preview(); 595 void sync_render_preview_hook(); 596 597 void queue_render_preview(); 598 599 600 void queue_draw_preview(); 601 602 void zoom_in(); 603 void zoom_out(); 604 void zoom_fit(); 605 void zoom_norm(); 606 void zoom_edit(); get_zoom()607 float get_zoom()const { return zoom; } // zoom is declared in Duckmatic 608 609 void set_zoom(float z); 610 611 set_progress_callback(synfig::ProgressCallback * x)612 void set_progress_callback(synfig::ProgressCallback *x) { progresscallback=x; } get_progress_callback()613 synfig::ProgressCallback *get_progress_callback() { return progresscallback; } 614 615 void set_focus_point(const synfig::Point &x); 616 617 synfig::Point get_focus_point()const; 618 619 void done_rendering(); 620 621 #ifdef SINGLE_THREADED 622 /* resize bug workaround */ 623 void refresh_second_check(); 624 #endif 625 bool refresh(const Cairo::RefPtr<Cairo::Context> &cr); 626 627 void reset_cursor(); 628 void refresh_cursor(); 629 630 void save_meta_data(); 631 void load_meta_data(); 632 //! Test initial meta data values 633 bool have_meta_data(); 634 635 /* 636 -- ** -- S I G N A L T E R M I N A L S ------------------------------------- 637 */ 638 639 private: 640 bool on_key_press_event(GdkEventKey* event); 641 bool on_key_release_event(GdkEventKey* event); 642 bool on_drawing_area_event(GdkEvent* event); 643 bool on_hruler_event(GdkEvent* event); 644 bool on_vruler_event(GdkEvent* event); 645 void on_duck_selection_single(const etl::handle<Duck>& duck_guid); 646 647 /* 648 -- ** -- S T A T I C P U B L I C M E T H O D S --------------------------- 649 */ 650 651 public: 652 653 /* 654 -- ** -- S T A T I C P R I V A T E M E T H O D S ------------------------- 655 */ 656 657 private: 658 659 static gboolean __render_preview(gpointer data); 660 #ifdef SINGLE_THREADED 661 /* resize bug workaround */ 662 static gboolean __refresh_second_check(gpointer data); 663 #endif 664 665 }; // END of class WorkArea 666 667 /*! \class WorkArea::PushState 668 ** Saves the current duck view and editing options 669 ** Should be used by tools that hide ducks or change clickability settings */ 670 class WorkArea::PushState 671 { 672 WorkArea *workarea_; 673 Type type_mask; 674 bool allow_duck_clicks; 675 bool allow_bezier_clicks; 676 bool allow_layer_clicks; 677 678 bool needs_restore; 679 680 public: 681 PushState(WorkArea *workarea_); 682 ~PushState(); 683 void restore(); 684 }; // END of class WorkArea::PushState 685 686 }; // END of namespace studio 687 688 /* === E N D =============================================================== */ 689 690 #endif 691