type Interactive_Canvas_Record is new Gtk.Layout.Gtk_Layout_Record with private;
type Canvas_Item_Record is abstract new Glib.Graphs.Vertex with private;
type Canvas_Link_Record is new Glib.Graphs.Edge with private;
type Buffered_Item_Record is new Canvas_Item_Record with private;
type Interactive_Canvas is access all Interactive_Canvas_Record'Class;
type Canvas_Item is access all Canvas_Item_Record'Class;
type Canvas_Link is access all Canvas_Link_Record'Class;
type Canvas_Link_Access is access all Canvas_Link_Record;
type Arrow_Type is (No_Arrow, -- the link does not have an arrow Start_Arrow, -- the link has an arrow at its beginning End_Arrow, -- the link has an arrow at the end Both_Arrow -- the link has an arrow on both sides );
type Item_Processor is access function (Canvas : access Interactive_Canvas_Record'Class; Item : access Canvas_Item_Record'Class) return Boolean;
type Layout_Algorithm is access procedure (Canvas : access Interactive_Canvas_Record'Class; Graph : Glib.Graphs.Graph; Force : Boolean; Vertical_Layout : Boolean);
type Link_Processor is access function (Canvas : access Interactive_Canvas_Record'Class; Link : access Canvas_Link_Record'Class) return Boolean;
type Item_Side is (East, West, North, South);
type Buffered_Item is access all Buffered_Item_Record'Class;
Default_Annotation_Font : constant String := "Helvetica 8";
Default_Grid_Size : constant := 15;
Default_Arc_Link_Offset : constant := 25;
Default_Motion_Threshold : constant := 4.0;
Signal_Background_Click : constant Glib.Signal_Name := "background_click";
Signal_Item_Selected : constant Glib.Signal_Name := "item_selected";
Signal_Item_Unselected : constant Glib.Signal_Name := "item_unselected";
Signal_Item_Moved : constant Glib.Signal_Name := "item_moved";
Signal_Zoomed : constant Glib.Signal_Name := "zoomed";
Signal_Set_Scroll_Adjustments : constant Glib.Signal_Name := "set_scroll_adjustments";
procedure Gtk_New
( | Canvas | : out Interactive_Canvas; |
Auto_Layout | : Boolean := True); |
procedure Initialize
( | Canvas | : access Interactive_Canvas_Record'Class; |
Auto_Layout | : Boolean := True); |
procedure Configure
( | Canvas | : access Interactive_Canvas_Record; |
Grid_Size | : Glib.Guint := Default_Grid_Size; | |
Annotation_Font | : Pango.Font.Pango_Font_Description := Pango.Font.From_String (Default_Annotation_Font); | |
Arc_Link_Offset | : Glib.Gint := Default_Arc_Link_Offset; | |
Arrow_Angle | : Glib.Gint := Default_Arrow_Angle; | |
Arrow_Length | : Glib.Gint := Default_Arrow_Length; | |
Motion_Threshold | : Glib.Gdouble := Default_Motion_Threshold; | |
Background | : Gdk.RGBA.Gdk_RGBA := Gdk.RGBA.White_RGBA); |
function Get_Vadj
( | Canvas | : access Interactive_Canvas_Record'Class) return Gtk.Adjustment.Gtk_Adjustment; |
function Get_Hadj
( | Canvas | : access Interactive_Canvas_Record'Class) return Gtk.Adjustment.Gtk_Adjustment; |
procedure Get_Bounding_Box
( | Canvas | : access Interactive_Canvas_Record'Class; |
Width | : out Glib.Gdouble; | |
Height | : out Glib.Gdouble); |
procedure Draw_Area
( | Canvas | : access Interactive_Canvas_Record'Class; |
Rect | : Cairo.Region.Cairo_Rectangle_Int); |
procedure Draw_All
( | Canvas | : access Interactive_Canvas_Record'Class; |
Cr | : Cairo.Cairo_Context); |
procedure Draw_Background
( | Canvas | : access Interactive_Canvas_Record; |
Cr | : Cairo.Cairo_Context); |
procedure Draw_Grid
( | Canvas | : access Interactive_Canvas_Record; |
Cr | : Cairo.Cairo_Context); |
procedure Set_Orthogonal_Links
( | Canvas | : access Interactive_Canvas_Record; |
Orthogonal | : Boolean); |
function Get_Orthogonal_Links
( | Canvas | : access Interactive_Canvas_Record) return Boolean; |
procedure Align_On_Grid
( | Canvas | : access Interactive_Canvas_Record; |
Align | : Boolean := True); |
function Get_Align_On_Grid
( | Canvas | : access Interactive_Canvas_Record) return Boolean; |
procedure Move_To
( | Canvas | : access Interactive_Canvas_Record; |
Item | : access Canvas_Item_Record'Class; | |
X, Y | : Glib.Gint := Glib.Gint'First); |
procedure Set_Items
( | Canvas | : access Interactive_Canvas_Record; |
Items | : Glib.Graphs.Graph); |
procedure Put
( | Canvas | : access Interactive_Canvas_Record; |
Item | : access Canvas_Item_Record'Class; | |
X, Y | : Glib.Gint := Glib.Gint'First); |
function Item_At_Coordinates
( | Canvas | : access Interactive_Canvas_Record; |
X, Y | : Glib.Gint) return Canvas_Item; |
function Item_At_Coordinates
( | Canvas | : access Interactive_Canvas_Record; |
Event | : Gdk.Event.Gdk_Event) return Canvas_Item; |
procedure Item_At_Coordinates
( | Canvas | : access Interactive_Canvas_Record; |
Event | : Gdk.Event.Gdk_Event; | |
Item | : out Canvas_Item; | |
X, Y | : out Glib.Gint); |
procedure Remove
( | Canvas | : access Interactive_Canvas_Record; |
Item | : access Canvas_Item_Record'Class); |
procedure Item_Updated
( | Canvas | : access Interactive_Canvas_Record; |
Item | : access Canvas_Item_Record'Class); |
procedure Refresh_Canvas
( | Canvas | : access Interactive_Canvas_Record); |
procedure Refresh
( | Self | : not null access Interactive_Canvas_Record; |
Item | : access Canvas_Item_Record'Class := null); |
procedure Raise_Item
( | Canvas | : access Interactive_Canvas_Record; |
Item | : access Canvas_Item_Record'Class); |
procedure Lower_Item
( | Canvas | : access Interactive_Canvas_Record; |
Item | : access Canvas_Item_Record'Class); |
function Is_On_Top
( | Canvas | : access Interactive_Canvas_Record; |
Item | : access Canvas_Item_Record'Class) return Boolean; |
procedure Show_Item
( | Canvas | : access Interactive_Canvas_Record; |
Item | : access Canvas_Item_Record'Class); |
procedure Align_Item
( | Canvas | : access Interactive_Canvas_Record; |
Item | : access Canvas_Item_Record'Class; | |
X_Align | : Float := 0.5; | |
Y_Align | : Float := 0.5); |
function Get_Arrow_Angle
( | Canvas | : access Interactive_Canvas_Record'Class) return Glib.Gdouble; |
function Get_Arrow_Length
( | Canvas | : access Interactive_Canvas_Record'Class) return Glib.Gint; |
procedure For_Each_Item
( | Canvas | : access Interactive_Canvas_Record; |
Execute | : Item_Processor; | |
Linked_From_Or_To | : Canvas_Item := null); |
function Start
( | Canvas | : access Interactive_Canvas_Record; |
Linked_From_Or_To | : Canvas_Item := null; | |
Selected_Only | : Boolean := False) return Item_Iterator; |
procedure Next
( | Iter | : in out Item_Iterator); |
function Next
( | Iter | : Item_Iterator) return Item_Iterator; |
function Get
( | Iter | : Item_Iterator) return Canvas_Item; |
function Is_Linked_From
( | Iter | : Item_Iterator) return Boolean; |
procedure Zoom
( | Canvas | : access Interactive_Canvas_Record; |
Percent | : Glib.Gdouble := 1.0; | |
Length | : Duration := 0.0); |
function Get_Zoom
( | Canvas | : access Interactive_Canvas_Record) return Glib.Gdouble; |
procedure Get_World_Coordinates
( | Canvas | : access Interactive_Canvas_Record'Class; |
X, Y | : out Glib.Gdouble; | |
Width | : out Glib.Gdouble; | |
Height | : out Glib.Gdouble); |
procedure Set_Layout_Algorithm
( | Canvas | : access Interactive_Canvas_Record; |
Algorithm | : Layout_Algorithm); |
procedure Default_Layout_Algorithm
( | Canvas | : access Interactive_Canvas_Record'Class; |
Graph | : Glib.Graphs.Graph; | |
Force | : Boolean; | |
Vertical_Layout | : Boolean); |
procedure Set_Auto_Layout
( | Canvas | : access Interactive_Canvas_Record; |
Auto_Layout | : Boolean); |
procedure Set_Layout_Orientation
( | Canvas | : access Interactive_Canvas_Record; |
Vertical_Layout | : Boolean := False); |
procedure Layout
( | Canvas | : access Interactive_Canvas_Record; |
Force | : Boolean := False); |
procedure Configure
( | Link | : access Canvas_Link_Record; |
Arrow | : Arrow_Type := End_Arrow; | |
Descr | : Glib.UTF8_String := ""); |
function Get_Descr
( | Link | : access Canvas_Link_Record) return Glib.UTF8_String; |
function Get_Arrow_Type
( | Link | : access Canvas_Link_Record) return Arrow_Type; |
procedure Set_Src_Pos
( | Link | : access Canvas_Link_Record; |
X_Pos, Y_Pos | : Glib.Gfloat := 0.5); |
procedure Set_Dest_Pos
( | Link | : access Canvas_Link_Record; |
X_Pos, Y_Pos | : Glib.Gfloat := 0.5); |
procedure Get_Src_Pos
( | Link | : access Canvas_Link_Record; |
X, Y | : out Glib.Gfloat); |
procedure Get_Dest_Pos
( | Link | : access Canvas_Link_Record; |
X, Y | : out Glib.Gfloat); |
function Has_Link
( | Canvas | : access Interactive_Canvas_Record; |
From, To | : access Canvas_Item_Record'Class; | |
Name | : Glib.UTF8_String := "") return Boolean; |
procedure Add_Link
( | Canvas | : access Interactive_Canvas_Record; |
Link | : access Canvas_Link_Record'Class; | |
Src | : access Canvas_Item_Record'Class; | |
Dest | : access Canvas_Item_Record'Class; | |
Arrow | : Arrow_Type := End_Arrow; | |
Descr | : Glib.UTF8_String := ""); |
procedure Remove_Link
( | Canvas | : access Interactive_Canvas_Record; |
Link | : access Canvas_Link_Record'Class); |
procedure For_Each_Link
( | Canvas | : access Interactive_Canvas_Record; |
Execute | : Link_Processor; | |
From, To | : Canvas_Item := null); |
procedure Destroy
( | Link | : in out Canvas_Link_Record); |
procedure Update_Links
( | Canvas | : access Interactive_Canvas_Record; |
Cr | : Cairo.Cairo_Context; | |
Invert_Mode | : Boolean; | |
From_Selection | : Boolean); |
procedure Draw_Link
( | Canvas | : access Interactive_Canvas_Record'Class; |
Link | : access Canvas_Link_Record; | |
Cr | : Cairo.Cairo_Context; | |
Edge_Number | : Glib.Gint; | |
Show_Annotation | : Boolean := True); |
procedure Clip_Line
( | Src | : access Canvas_Item_Record; |
Canvas | : access Interactive_Canvas_Record'Class; | |
To_X | : Glib.Gint; | |
To_Y | : Glib.Gint; | |
X_Pos | : Glib.Gfloat; | |
Y_Pos | : Glib.Gfloat; | |
Side | : out Item_Side; | |
X_Out | : out Glib.Gint; | |
Y_Out | : out Glib.Gint); |
procedure Draw_Straight_Line
( | Link | : access Canvas_Link_Record; |
Cr | : Cairo.Cairo_Context; | |
Src_Side | : Item_Side; | |
X1, Y1 | : Glib.Gdouble; | |
Dest_Side | : Item_Side; | |
X2, Y2 | : Glib.Gdouble); |
procedure Clear_Selection
( | Canvas | : access Interactive_Canvas_Record); |
procedure Add_To_Selection
( | Canvas | : access Interactive_Canvas_Record; |
Item | : access Canvas_Item_Record'Class); |
procedure Remove_From_Selection
( | Canvas | : access Interactive_Canvas_Record; |
Item | : access Canvas_Item_Record'Class); |
procedure Select_All
( | Canvas | : access Interactive_Canvas_Record); |
function Is_Selected
( | Canvas | : access Interactive_Canvas_Record; |
Item | : access Canvas_Item_Record'Class) return Boolean; |
function Canvas
( | Item | : access Canvas_Item_Record) return Interactive_Canvas; |
procedure Selected
( | Item | : access Canvas_Item_Record; |
Canvas | : access Interactive_Canvas_Record'Class; | |
Is_Selected | : Boolean); |
function Point_In_Item
( | Item | : access Canvas_Item_Record; |
X, Y | : Glib.Gint) return Boolean; |
procedure Set_Screen_Size
( | Item | : access Canvas_Item_Record; |
Width | : Glib.Gint; | |
Height | : Glib.Gint); |
procedure Draw_Selected
( | Item | : access Canvas_Item_Record; |
Cr | : Cairo.Cairo_Context); |
procedure Draw
( | Item | : access Canvas_Item_Record; |
Cr | : Cairo.Cairo_Context) is abstract; |
procedure Destroy
( | Item | : in out Canvas_Item_Record); |
function On_Button_Click
( | Item | : access Canvas_Item_Record; |
Event | : Gdk.Event.Gdk_Event_Button) return Boolean; |
function Get_Coord
( | Item | : access Canvas_Item_Record) return Cairo.Region.Cairo_Rectangle_Int; |
procedure Set_Visibility
( | Item | : access Canvas_Item_Record; |
Visible | : Boolean); |
function Is_Visible
( | Item | : access Canvas_Item_Record) return Boolean; |
function Is_From_Auto_Layout
( | Item | : access Canvas_Item_Record) return Boolean; |
function Surface
( | Item | : access Buffered_Item_Record) return Cairo.Cairo_Surface; |
This package provides an interactive canvas, on which the user can put items, move them with the mouse, etc. The items can be connected together, and the connections remain active while the items are moved.
It also supports scrolling if put in a Gtk_Scrolled_Window.
The canvas will be scrolled (and the selected items moved) if an item is selected and the mouse is dragged on a small area on the side of the canvas or even directly outside of the canvas. Scrolling will continue until the mouse is either released or moved back inside the canvas.
The scrolling speed will slightly increase over time if the mouse is kept outside of the canvas. This makes the canvas much more comfortable to use for the user.
All items put in this canvas must inherit from the type Canvas_Item_Record.
However, it is your responsability, as a programmer, to provide drawing routines. In fact, all these items should draw in a pixmap, which is then copied automatically to the screen whenever the canvas needs to redraw itself.
The items can also react to mouse events: mouse clicks are transmitted to the item if the mouse did not move more than a given amount of pixels.
To decide what their reaction should be, you should override the On_Button_Click subprogram.
This canvas is not intended for cases where you want to put hundreds of items on the screen. For instance, it does not provide any smart double-buffering other than the one provided by gtk+ itself, and thus you would get some flicker if there are too many items.
There are three coordinate systems used by widget. All the subprograms expect a specific coordinate system as input or output. Here are the three systems: - World coordinates The position of an item is reported in pixels, as if the canvas currently had a zoom level of 100%. This is fully independent, at any time, from the current zoom level of the canvas. Since the canvas is considered to expand ad infinitum, the top-left corner doesn't have any specific fixed coordinates. It can be known by checking the current lower value of the adjustments (aka scrollbars). - Canvas coordinates This is similar to world coordinates, except these depend on the current zoom level of the canvas. This also affect the width and height of the objects in the canvas. The subprograms To_Canvas_Coordinates and To_World_Coordinates can be used to convert lengths from world to canvas coordinates. The same behavior as world coordinates applies for the top-left corner. All drawing to the screen, in particular for Draw_Background, must be done using this coordinate systems - Item coordinates The position of a point is relative to the top-left corner of the current item. This corner therefore has coordinates (0, 0). This coordinate systems assumes a zoom-level of 100% Items are selected automatically when they are clicked. If Control is pressed at the same time, multiple items can be selected.
If the background is clicked (and control is not pressed), then all items are unselected.
Pressing and dragging the mouse in the backgroudn draws a virtual box on the screen. All the items fully included in this box when it is released will be selected (this will replace the current selection if Control was not pressed).