206 lines
6.6 KiB
C++
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
|