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).
Algorithms are encouraged to preserve the current layout as much as possible, taking into account items that have been moved manually by the user, so that the latter can preserver his mental map of the graph. However, if Force is set to True, then the whole layout should be recomputed as if all items had just been inserted.
Items that have just been inserted in the graph, but whose position has never been computed, are set at coordinates (Gint'First, Gint'First). Check the result of Get_Coord.
This function doesn't need to align items, this is done automatically by the canvas if necessary.
Screen_Rect is the rectangle on the screen that needs to be refreshed. These are canvas coordinates, therefore you must take into account the current zoom level while drawing.
The default implementation draws a grid.
An example implementation that draws a background image is shown at the end of this file.
You mustn't destroy items yourself, this is done automatically when the canvas is destroyed.
If Linked_From_Or_To is not null, then only the items linked to this one will be processed. It is possible that a given item will be returned twice, if it is both linked to and from the item.
Steps is the number of successive zooms that will be done to provide smooth scrolling.
Note that one possible use for this function is to refresh the canvas and emit the "zoomed" signal, which might redraw all the items. This can be accomplished by keeping the default 100 value for Percent.
(From, To) can be used to limit what links are looked for.
??? Would be nicer to give direct access to the Graph iterators
The link should be drawn directly in Get_Window (Canvas).
GC is a possible graphic context that could be used to draw the link. You shouldn't destroy it or modify its attributes. However, you can use any other graphic context specific to your application, for instance if you want to draw the link in various colors or shapes. The graphic context you use must be in Invert mode (see Gdk.GC.Set_Function) if and only if Invert_Mode is true, so that when items are moved on the canvas, the links properly follow the items they are attached to. This graphic context is only used to draw links, so you don't need to restore it on exit if your Draw_Link function always sets it at the beginning.
Edge_Number indicates the index of link in the list of links that join the same source to the same destination. It should be used so that two links do not overlap (for instance, the default is to draw the first link straight, and the others as arcs).