/* This file is part of FlowCanvas. * Copyright (C) 2007-2009 David Robillard * * FlowCanvas is free software; you can redistribute it and/or modify it under the * terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * FlowCanvas is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef FLOWCANVAS_CANVAS_HPP #define FLOWCANVAS_CANVAS_HPP #include #include #include #include #include #include "Connection.hpp" #include "Item.hpp" #include "Module.hpp" /** FlowCanvas namespace, everything is defined under this. * * \ingroup FlowCanvas */ namespace FlowCanvas { class Port; class Module; class GVNodes; /** \defgroup FlowCanvas FlowCanvas * * A generic dataflow widget using libgnomecanvas. */ /** The 'master' canvas widget which contains all other objects. * * Applications must override some virtual methods to make the widget actually * do anything (ie connect). * * \ingroup FlowCanvas */ class Canvas : boost::noncopyable , public boost::enable_shared_from_this , public Gnome::Canvas::CanvasAA { public: Canvas(double width, double height); virtual ~Canvas(); void destroy(); void add_item(boost::shared_ptr i); bool remove_item(boost::shared_ptr i); boost::shared_ptr get_connection(boost::shared_ptr tail, boost::shared_ptr head) const; bool add_connection(boost::shared_ptr tail, boost::shared_ptr head, uint32_t color); bool add_connection(boost::shared_ptr connection); boost::shared_ptr remove_connection(boost::shared_ptr tail, boost::shared_ptr head); void set_default_placement(boost::shared_ptr m); void clear_selection(); void select_item(boost::shared_ptr item); void unselect_ports(); void unselect_item(boost::shared_ptr item); void unselect_connection(Connection* c); ItemList& items() { return _items; } ItemList& selected_items() { return _selected_items; } ConnectionList& connections() { return _connections; } ConnectionList& selected_connections() { return _selected_connections; } void lock(bool l); bool locked() const { return _locked; } double get_zoom() { return _zoom; } void set_zoom(double pix_per_unit); void zoom_full(); void render_to_dot(const std::string& filename); virtual void arrange(bool use_length_hints=false, bool center=true); void move_contents_to(double x, double y); double width() const { return _width; } double height() const { return _height; } void resize(double width, double height); void resize_all_items(); void scroll_to_center(); enum FlowDirection { HORIZONTAL, VERTICAL }; void set_direction(FlowDirection d) { _direction = d; } FlowDirection direction() const { return _direction; } /** Dash applied to selected items. * Set an object's property_dash() to this for the "rubber band" effect */ ArtVpathDash* select_dash() { return _select_dash; } /** Make a connection. Should be overridden by an implementation to do something. */ virtual void connect(boost::shared_ptr /*tail*/, boost::shared_ptr /*head*/) {} /** Disconnect two ports. Should be overridden by an implementation to do something */ virtual void disconnect(boost::shared_ptr /*tail*/, boost::shared_ptr /*head*/) {} static sigc::signal signal_item_entered; static sigc::signal signal_item_left; protected: ItemList _items; ///< All items on this canvas ConnectionList _connections; ///< All connections on this canvas std::list< boost::shared_ptr > _selected_items; ///< All currently selected modules std::list< boost::shared_ptr > _selected_connections; ///< All currently selected connections virtual bool canvas_event(GdkEvent* event); virtual bool frame_event(GdkEvent* ev); private: friend class Module; bool port_event(GdkEvent* event, boost::weak_ptr port); GVNodes layout_dot(bool use_length_hints, const std::string& filename); void remove_connection(boost::shared_ptr c); bool are_connected(boost::shared_ptr tail, boost::shared_ptr head); void select_port(boost::shared_ptr p, bool unique = false); void select_port_toggle(boost::shared_ptr p, int mod_state); void unselect_port(boost::shared_ptr p); void selection_joined_with(boost::shared_ptr port); void join_selection(); boost::shared_ptr get_port_at(double x, double y); bool scroll_drag_handler(GdkEvent* event); bool select_drag_handler(GdkEvent* event); bool connection_drag_handler(GdkEvent* event); void ports_joined(boost::shared_ptr port1, boost::shared_ptr port2); bool animate_selected(); void move_contents_to_internal(double x, double y, double min_x, double min_y); void on_parent_changed(Gtk::Widget* old_parent); sigc::connection _parent_event_connection; typedef std::list< boost::shared_ptr > SelectedPorts; SelectedPorts _selected_ports; ///< Selected ports (hilited red) boost::shared_ptr _connect_port; ///< Port for which a connection is being made boost::shared_ptr _last_selected_port; Gnome::Canvas::Rect _base_rect; ///< Background Gnome::Canvas::Rect* _select_rect; ///< Rectangle for drag selection ArtVpathDash* _select_dash; ///< Animated selection dash style double _zoom; ///< Current zoom level double _width; double _height; enum DragState { NOT_DRAGGING, CONNECTION, SCROLL, SELECT }; DragState _drag_state; FlowDirection _direction; bool _remove_objects :1; // flag to avoid removing objects from destructors when unnecessary bool _locked :1; }; } // namespace FlowCanvas #endif // FLOWCANVAS_CANVAS_HPP