ladish/gui/flowcanvas/Canvas.hpp

206 lines
6.6 KiB
C++

/* This file is part of FlowCanvas.
* Copyright (C) 2007-2009 David Robillard <http://drobilla.net>
*
* 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 <list>
#include <string>
#include <boost/enable_shared_from_this.hpp>
#include <boost/utility.hpp>
#include <libgnomecanvasmm.h>
#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<Canvas>
, public Gnome::Canvas::CanvasAA
{
public:
Canvas(double width, double height);
virtual ~Canvas();
void destroy();
void add_item(boost::shared_ptr<Item> i);
bool remove_item(boost::shared_ptr<Item> i);
boost::shared_ptr<Connection>
get_connection(boost::shared_ptr<Connectable> tail,
boost::shared_ptr<Connectable> head) const;
bool add_connection(boost::shared_ptr<Connectable> tail,
boost::shared_ptr<Connectable> head,
uint32_t color);
bool add_connection(boost::shared_ptr<Connection> connection);
boost::shared_ptr<Connection> remove_connection(boost::shared_ptr<Connectable> tail,
boost::shared_ptr<Connectable> head);
void set_default_placement(boost::shared_ptr<Module> m);
void clear_selection();
void select_item(boost::shared_ptr<Item> item);
void unselect_ports();
void unselect_item(boost::shared_ptr<Item> 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<Connectable> /*tail*/,
boost::shared_ptr<Connectable> /*head*/) {}
/** Disconnect two ports. Should be overridden by an implementation to do something */
virtual void disconnect(boost::shared_ptr<Connectable> /*tail*/,
boost::shared_ptr<Connectable> /*head*/) {}
static sigc::signal<void, Gnome::Canvas::Item*> signal_item_entered;
static sigc::signal<void, Gnome::Canvas::Item*> signal_item_left;
protected:
ItemList _items; ///< All items on this canvas
ConnectionList _connections; ///< All connections on this canvas
std::list< boost::shared_ptr<Item> > _selected_items; ///< All currently selected modules
std::list< boost::shared_ptr<Connection> > _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> port);
GVNodes layout_dot(bool use_length_hints, const std::string& filename);
void remove_connection(boost::shared_ptr<Connection> c);
bool are_connected(boost::shared_ptr<const Connectable> tail,
boost::shared_ptr<const Connectable> head);
void select_port(boost::shared_ptr<Port> p, bool unique = false);
void select_port_toggle(boost::shared_ptr<Port> p, int mod_state);
void unselect_port(boost::shared_ptr<Port> p);
void selection_joined_with(boost::shared_ptr<Port> port);
void join_selection();
boost::shared_ptr<Port> 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<Port> port1, boost::shared_ptr<Port> 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<Port> > SelectedPorts;
SelectedPorts _selected_ports; ///< Selected ports (hilited red)
boost::shared_ptr<Port> _connect_port; ///< Port for which a connection is being made
boost::shared_ptr<Port> _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