Model#

Protocols#

Although gaphas.Canvas can be used as a default model, any class that adhere’s to the Model protocol can be used as a model.

class gaphas.model.Model(*args, **kwargs)[source]#

Any class that adhere’s to the Model protocol can be used as a model for GtkView.

property connections: Connections#

The connections instance used for this model.

get_all_items() Iterable[Item][source]#

Iterate over all items in the order they need to be rendered in.

Normally that will be depth-first.

get_parent(item: Item) Item | None[source]#

Get the parent item of an item.

Returns None if there is no parent item.

get_children(item: Item | None) Iterable[Item][source]#

Iterate all direct child items of an item.

sort(items: Collection[Item]) Iterable[Item][source]#

Sort a collection of items in the order they need to be rendered in.

request_update(item: Item) None[source]#

Request update for an item.

Parameters:

item (Item) – The item to be updated

update_now(dirty_items: Collection[Item]) None[source]#

This method is called during the update process.

It will allow the model to do some additional updating of it’s own.

register_view(view: View) None[source]#

Allow a view to be registered.

Registered views should receive update requests for modified items.

unregister_view(view: View) None[source]#

Unregister a previously registered view.

If a view is not registered, nothing should happen.

An item should implement these methods, so it can be rendered by the View. Not that painters or tools can require additional methods.

class gaphas.item.Item(*args, **kwargs)[source]#

This protocol should be implemented by model items.

All items that are rendered on a view.

property matrix: Matrix#

The “local”, item-to-parent matrix.

property matrix_i2c: Matrix#

Matrix from item to toplevel.

handles() Sequence[Handle][source]#

Return a list of handles owned by the item.

ports() Sequence[Port][source]#

Return list of ports owned by the item.

point(x: float, y: float) float[source]#

Get the distance from a point (x, y) to the item.

x and y are in item coordinates.

A distance of 0 means the point is on the item.

draw(context: DrawContext) None[source]#

Render the item to a canvas view. Context contains the following attributes:

  • cairo: the CairoContext use this one to draw

  • selected, focused, hovered: view state of items (True/False)

Default implementations#

Canvas#

The default implementation for a Model, is a class called Canvas.

class gaphas.canvas.Canvas[source]#

Container class for items.

add(item, parent=None, index=None)[source]#

Add an item to the canvas.

>>> c = Canvas()
>>> from gaphas import item
>>> i = item.Item()
>>> c.add(i)
>>> len(c._tree.nodes)
1
>>> i._canvas is c
True
remove(item)[source]#

Remove item from the canvas.

>>> c = Canvas()
>>> from gaphas import item
>>> i = item.Item()
>>> c.add(i)
>>> c.remove(i)
>>> c._tree.nodes
[]
>>> i._canvas
reparent(item, parent, index=None)[source]#

Set new parent for an item.

get_all_items() Iterable[Item][source]#

Get a list of all items.

>>> c = Canvas()
>>> c.get_all_items()
[]
>>> from gaphas import item
>>> i = item.Item()
>>> c.add(i)
>>> c.get_all_items() 
[<gaphas.item.Item ...>]
get_root_items()[source]#

Return the root items of the canvas.

>>> c = Canvas()
>>> c.get_all_items()
[]
>>> from gaphas import item
>>> i = item.Item()
>>> c.add(i)
>>> ii = item.Item()
>>> c.add(ii, i)
>>> c.get_root_items() 
[<gaphas.item.Item ...>]
get_parent(item: Item) Item | None[source]#

See tree.Tree.get_parent().

>>> c = Canvas()
>>> from gaphas import item
>>> i = item.Item()
>>> c.add(i)
>>> ii = item.Item()
>>> c.add(ii, i)
>>> c.get_parent(i)
>>> c.get_parent(ii) 
<gaphas.item.Item ...>
get_children(item: Item | None) Iterable[Item][source]#

See tree.Tree.get_children().

>>> c = Canvas()
>>> from gaphas import item
>>> i = item.Item()
>>> c.add(i)
>>> ii = item.Item()
>>> c.add(ii, i)
>>> iii = item.Item()
>>> c.add(iii, ii)
>>> list(c.get_children(iii))
[]
>>> list(c.get_children(ii)) 
[<gaphas.item.Item ...>]
>>> list(c.get_children(i)) 
[<gaphas.item.Item ...>]
sort(items: Iterable[Item]) Iterable[Item][source]#

Sort a list of items in the order in which they are traversed in the canvas (Depth first).

>>> c = Canvas()
>>> from gaphas import item
>>> i1 = item.Line()
>>> c.add(i1)
>>> i2 = item.Line()
>>> c.add(i2)
>>> i3 = item.Line()
>>> c.add (i3)
>>> c.update_now((i1, i2, i3)) # ensure items are indexed
>>> s = c.sort([i2, i3, i1])
>>> s[0] is i1 and s[1] is i2 and s[2] is i3
True
get_matrix_i2c(item: Item) Matrix[source]#

Get the Item to Canvas matrix for item.

item:

The item who’s item-to-canvas transformation matrix should be found

calculate:

True will allow this function to actually calculate it, instead of raising an AttributeError when no matrix is present yet. Note that out-of-date matrices are not recalculated.

request_update(item: Item) None[source]#

Set an update request for the item.

>>> c = Canvas()
>>> from gaphas import item
>>> i = item.Item()
>>> ii = item.Item()
>>> c.add(i)
>>> c.add(ii, i)
>>> len(c._dirty_items)
0
>>> c.update_now((i, ii))
>>> len(c._dirty_items)
0
request_matrix_update(item)[source]#

Schedule only the matrix to be updated.

update_now(**kwargs)#

Decorate function with a mutex that prohibits recursive execution.

register_view(view: View) None[source]#

Register a view on this canvas.

This method is called when setting a canvas on a view and should not be called directly from user code.

unregister_view(view: View) None[source]#

Unregister a view on this canvas.

This method is called when setting a canvas on a view and should not be called directly from user code.

Items#

Gaphas provides two default items, an box-like element and a line shape.

class gaphas.item.Element(connections: Connections, width: float = 10, height: float = 10, **kwargs: object)[source]#

An Element has 4 handles (for a start):

NW +---+ NE
   |   |
SW +---+ SE
property width: float#

Width of the box, calculated as the distance from the left and right handle.

property height: float#

Height.

handles() Sequence[Handle][source]#

Return a list of handles owned by the item.

ports() Sequence[Port][source]#

Return list of ports.

point(x: float, y: float) float[source]#

Distance from the point (x, y) to the item.

>>> e = Element()
>>> e.point(20, 10)
10.0
class gaphas.item.Line(connections: Connections, **kwargs: object)[source]#

A Line item.

Properties:
  • fuzziness (0.0..n): an extra margin that should be taken into

    account when calculating the distance from the line (using point()).

  • orthogonal (bool): whether or not the line should be

    orthogonal (only straight angles)

  • horizontal: first line segment is horizontal

  • line_width: width of the line to be drawn

This line also supports arrow heads on both the begin and end of the line. These are drawn with the methods draw_head(context) and draw_tail(context). The coordinate system is altered so the methods do not have to know about the angle of the line segment (e.g. drawing a line from (10, 10) via (0, 0) to (10, -10) will draw an arrow point).

update_orthogonal_constraints() None[source]#

Update the constraints required to maintain the orthogonal line.

opposite(handle: Handle) Handle[source]#

Given the handle of one end of the line, return the other end.

handles() Sequence[Handle][source]#

Return a list of handles owned by the item.

ports() Sequence[Port][source]#

Return list of ports.

point(x: float, y: float) float[source]#
>>> a = Line()
>>> a.handles()[1].pos = 25, 5
>>> a._handles.append(a._create_handle((30, 30)))
>>> a.point(-1, 0)
1.0
>>> f"{a.point(5, 4):.3f}"
'2.942'
>>> f"{a.point(29, 29):.3f}"
'0.784'
draw_head(context: DrawContext) None[source]#

Default head drawer: move cursor to the first handle.

draw_tail(context: DrawContext) None[source]#

Default tail drawer: draw line to the last handle.

draw(context: DrawContext) None[source]#

Draw the line itself.

See Item.draw(context).