Commit 227c4c87 authored by Tiago Peixoto's avatar Tiago Peixoto
Browse files

graph_draw(): Fix fit_view behavior

This fixes issue #385
parent 5d160cf0
Pipeline #297 passed with stage
in 341 minutes and 12 seconds
...@@ -633,8 +633,10 @@ def cairo_draw(g, pos, cr, vprops=None, eprops=None, vorder=None, eorder=None, ...@@ -633,8 +633,10 @@ def cairo_draw(g, pos, cr, vprops=None, eprops=None, vorder=None, eorder=None,
output_size = (extents[2] - extents[0], extents[3] - extents[1]) output_size = (extents[2] - extents[0], extents[3] - extents[1])
try: try:
x, y, w, h = fit_view x, y, w, h = fit_view
cr.scale(output_size[0] / w, output_size[1] / h) zoom = min(output_size[0] / w, output_size[1] / h)
cr.translate(-x, -y) offset = (x * zoom, y * zoom)
cr.translate(x, y)
cr.scale(zoom, zoom)
except TypeError: except TypeError:
pad = fit_view if fit_view != True else 0.95 pad = fit_view if fit_view != True else 0.95
offset, zoom = fit_to_view(g, pos, output_size, offset, zoom = fit_to_view(g, pos, output_size,
...@@ -647,8 +649,6 @@ def cairo_draw(g, pos, cr, vprops=None, eprops=None, vorder=None, eorder=None, ...@@ -647,8 +649,6 @@ def cairo_draw(g, pos, cr, vprops=None, eprops=None, vorder=None, eorder=None,
_vdefaults["font_size"]), _vdefaults["font_size"]),
pad, cr) pad, cr)
cr.translate(offset[0], offset[1]) cr.translate(offset[0], offset[1])
if not isinstance(fit_view, bool):
zoom /= fit_view
cr.scale(zoom, zoom) cr.scale(zoom, zoom)
if "control_points" not in eprops: if "control_points" not in eprops:
...@@ -1102,10 +1102,9 @@ def graph_draw(g, pos=None, vprops=None, eprops=None, vorder=None, eorder=None, ...@@ -1102,10 +1102,9 @@ def graph_draw(g, pos=None, vprops=None, eprops=None, vorder=None, eorder=None,
output = io.BytesIO() output = io.BytesIO()
if output is None: if output is None:
fit_area = fit_view if fit_view != True else 0.95
return interactive_window(g, pos, vprops, eprops, vorder, eorder, return interactive_window(g, pos, vprops, eprops, vorder, eorder,
nodesfirst, geometry=output_size, nodesfirst, geometry=output_size,
fit_area=fit_area, **kwargs) fit_view=fit_view, **kwargs)
else: else:
if isinstance(output, (str, unicode)): if isinstance(output, (str, unicode)):
out, auto_fmt = open_file(output, mode="wb") out, auto_fmt = open_file(output, mode="wb")
...@@ -1137,7 +1136,8 @@ def graph_draw(g, pos=None, vprops=None, eprops=None, vorder=None, eorder=None, ...@@ -1137,7 +1136,8 @@ def graph_draw(g, pos=None, vprops=None, eprops=None, vorder=None, eorder=None,
if fit_view != False: if fit_view != False:
try: try:
x, y, w, h = fit_view x, y, w, h = fit_view
offset, zoom = [0, 0], 1 zoom = min(output_size[0] / w, output_size[1] / h)
offset = (x * zoom, y * zoom)
except TypeError: except TypeError:
pad = fit_view if fit_view != True else 0.95 pad = fit_view if fit_view != True else 0.95
offset, zoom = fit_to_view(g, pos, output_size, vprops["size"], offset, zoom = fit_to_view(g, pos, output_size, vprops["size"],
...@@ -1148,7 +1148,7 @@ def graph_draw(g, pos=None, vprops=None, eprops=None, vorder=None, eorder=None, ...@@ -1148,7 +1148,7 @@ def graph_draw(g, pos=None, vprops=None, eprops=None, vorder=None, eorder=None,
vprops.get("font_size", vprops.get("font_size",
_vdefaults["font_size"]), _vdefaults["font_size"]),
pad, cr) pad, cr)
fit_view = False fit_view = False
else: else:
offset, zoom = [0, 0], 1 offset, zoom = [0, 0], 1
......
...@@ -133,7 +133,7 @@ class GraphWidget(Gtk.DrawingArea): ...@@ -133,7 +133,7 @@ class GraphWidget(Gtk.DrawingArea):
def __init__(self, g, pos, vprops=None, eprops=None, vorder=None, def __init__(self, g, pos, vprops=None, eprops=None, vorder=None,
eorder=None, nodesfirst=False, update_layout=False, eorder=None, nodesfirst=False, update_layout=False,
layout_K=1., multilevel=False, display_props=None, layout_K=1., multilevel=False, display_props=None,
display_props_size=11, fit_area=0.95, bg_color=None, display_props_size=11, fit_view=True, bg_color=None,
max_render_time=300, layout_callback=None, max_render_time=300, layout_callback=None,
key_press_callback=None, highlight_color=None, **kwargs): key_press_callback=None, highlight_color=None, **kwargs):
r"""Interactive GTK+ widget displaying a given graph. r"""Interactive GTK+ widget displaying a given graph.
...@@ -169,8 +169,12 @@ class GraphWidget(Gtk.DrawingArea): ...@@ -169,8 +169,12 @@ class GraphWidget(Gtk.DrawingArea):
List of properties to be displayed when the mouse passes over a vertex. List of properties to be displayed when the mouse passes over a vertex.
display_props_size : float (optional, default: ``11.``) display_props_size : float (optional, default: ``11.``)
Font size used to display the vertex properties. Font size used to display the vertex properties.
fit_area : float (optional, default: ``.95``) fit_view : bool, float or tuple (optional, default: ``True``)
Fraction of the drawing area to fit the graph initially. If ``True``, the layout will be scaled to fit the entire clip region.
If a float value is given, it will be interpreted as ``True``, and in
addition the viewport will be scaled out by that factor. If a tuple
value is given, it should have four values ``(x, y, w, h)`` that
specify the view in user coordinates.
bg_color : str or sequence (optional, default: ``None``) bg_color : str or sequence (optional, default: ``None``)
Background color. The default is white. Background color. The default is white.
max_render_time : int (optional, default: ``300``) max_render_time : int (optional, default: ``300``)
...@@ -274,7 +278,7 @@ class GraphWidget(Gtk.DrawingArea): ...@@ -274,7 +278,7 @@ class GraphWidget(Gtk.DrawingArea):
self.drag_begin = None self.drag_begin = None
self.moved_picked = False self.moved_picked = False
self.vertex_matrix = None self.vertex_matrix = None
self.pad = fit_area self.fit_view = fit_view
self.display_prop = g.vertex_index if display_props is None \ self.display_prop = g.vertex_index if display_props is None \
else display_props else display_props
...@@ -476,8 +480,8 @@ class GraphWidget(Gtk.DrawingArea): ...@@ -476,8 +480,8 @@ class GraphWidget(Gtk.DrawingArea):
m = cairo.Matrix() m = cairo.Matrix()
m.translate(self.get_allocated_width(), m.translate(self.get_allocated_width(),
self.get_allocated_height()) self.get_allocated_height())
self.smatrix = self.smatrix * m self.smatrix = self.smatrix.multiply(m)
self.tmatrix = self.tmatrix * self.smatrix self.tmatrix = self.tmatrix.multiply(self.smatrix)
self.smatrix = cairo.Matrix() self.smatrix = cairo.Matrix()
self.smatrix.translate(-self.get_allocated_width(), self.smatrix.translate(-self.get_allocated_width(),
-self.get_allocated_height()) -self.get_allocated_height())
...@@ -607,7 +611,7 @@ class GraphWidget(Gtk.DrawingArea): ...@@ -607,7 +611,7 @@ class GraphWidget(Gtk.DrawingArea):
eprops["pen_width"] *= 1.1 eprops["pen_width"] *= 1.1
cr.save() cr.save()
cr.set_matrix(self.tmatrix * self.smatrix) cr.set_matrix(self.tmatrix.multiply(self.smatrix))
cairo_draw(u, self.pos, cr, vprops, eprops, self.vorder, cairo_draw(u, self.pos, cr, vprops, eprops, self.vorder,
self.eorder, self.nodesfirst) self.eorder, self.nodesfirst)
cr.restore() cr.restore()
...@@ -622,7 +626,7 @@ class GraphWidget(Gtk.DrawingArea): ...@@ -622,7 +626,7 @@ class GraphWidget(Gtk.DrawingArea):
efilt=self.sel_edge_filt) efilt=self.sel_edge_filt)
cr.save() cr.save()
cr.set_matrix(self.tmatrix * self.smatrix) cr.set_matrix(self.tmatrix.multiply(self.smatrix))
cairo_draw(u, self.pos, cr, vprops, eprops, self.vorder, cairo_draw(u, self.pos, cr, vprops, eprops, self.vorder,
self.eorder, self.nodesfirst) self.eorder, self.nodesfirst)
cr.restore() cr.restore()
...@@ -677,7 +681,7 @@ class GraphWidget(Gtk.DrawingArea): ...@@ -677,7 +681,7 @@ class GraphWidget(Gtk.DrawingArea):
if surface: if surface:
cr.set_matrix(self.smatrix) cr.set_matrix(self.smatrix)
else: else:
cr.set_matrix(self.tmatrix * self.smatrix) cr.set_matrix(self.tmatrix.multiply(self.smatrix))
if dist: if dist:
return cr.user_to_device_distance(pos[0], pos[1]) return cr.user_to_device_distance(pos[0], pos[1])
else: else:
...@@ -692,7 +696,7 @@ class GraphWidget(Gtk.DrawingArea): ...@@ -692,7 +696,7 @@ class GraphWidget(Gtk.DrawingArea):
if surface: if surface:
cr.set_matrix(self.smatrix) cr.set_matrix(self.smatrix)
else: else:
cr.set_matrix(self.tmatrix * self.smatrix) cr.set_matrix(self.tmatrix.multiply(self.smatrix))
if dist: if dist:
return cr.device_to_user_distance(pos[0], pos[1]) return cr.device_to_user_distance(pos[0], pos[1])
else: else:
...@@ -701,11 +705,11 @@ class GraphWidget(Gtk.DrawingArea): ...@@ -701,11 +705,11 @@ class GraphWidget(Gtk.DrawingArea):
def apply_transform(self): def apply_transform(self):
r"""Apply current transform matrix to vertex coordinates.""" r"""Apply current transform matrix to vertex coordinates."""
zoom = self.pos_from_device((1, 0), dist=True)[0] zoom = self.pos_from_device((1, 0), dist=True)[0]
apply_transforms(self.g, self.pos, self.smatrix * self.tmatrix) apply_transforms(self.g, self.pos, self.smatrix.multiply(self.tmatrix))
self.tmatrix = cairo.Matrix() self.tmatrix = cairo.Matrix()
self.tmatrix.scale(zoom, zoom) self.tmatrix.scale(zoom, zoom)
self.smatrix = cairo.Matrix() self.smatrix = cairo.Matrix()
apply_transforms(self.g, self.pos, self.smatrix * self.tmatrix) apply_transforms(self.g, self.pos, self.smatrix.multiply(self.tmatrix))
self.tmatrix = cairo.Matrix() self.tmatrix = cairo.Matrix()
self.tmatrix.scale(1. / zoom, 1. / zoom) self.tmatrix.scale(1. / zoom, 1. / zoom)
if self.vertex_matrix is not None: if self.vertex_matrix is not None:
...@@ -722,21 +726,30 @@ class GraphWidget(Gtk.DrawingArea): ...@@ -722,21 +726,30 @@ class GraphWidget(Gtk.DrawingArea):
g = self.g g = self.g
pos = g.own_property(self.pos) pos = g.own_property(self.pos)
cr = self.get_window().cairo_create() cr = self.get_window().cairo_create()
offset, zoom = fit_to_view(g, pos, geometry, if self.fit_view != False:
self.vprops.get("size", 0), try:
self.vprops.get("pen_width", 0), x, y, w, h = self.fit_view
self.tmatrix * self.smatrix, zoom = min(geometry[0] / w, geometry[1] / h)
self.vprops.get("text", None), offset = (x * zoom, y * zoom)
self.vprops.get("font_family", except TypeError:
_vdefaults["font_family"]), pad = self.fit_view if self.fit_view != True else 0.95
self.vprops.get("font_size", offset, zoom = fit_to_view(g, pos, geometry,
_vdefaults["font_size"]), self.vprops.get("size", 0),
self.pad, self.vprops.get("pen_width", 0),
cr) self.tmatrix.multiply(self.smatrix),
self.vprops.get("text", None),
self.vprops.get("font_family",
_vdefaults["font_family"]),
self.vprops.get("font_size",
_vdefaults["font_size"]),
pad,
cr)
else:
offset, zoom = (0,0), 1
m = cairo.Matrix() m = cairo.Matrix()
m.translate(offset[0] + ox, offset[1] + oy) m.translate(offset[0] + ox, offset[1] + oy)
m.scale(zoom, zoom) m.scale(zoom, zoom)
self.tmatrix = self.tmatrix * self.smatrix * m self.tmatrix = self.tmatrix.multiply(self.smatrix.multiply(m))
self.smatrix = cairo.Matrix() self.smatrix = cairo.Matrix()
if ink: if ink:
scale_ink(zoom, self.vprops, self.eprops) scale_ink(zoom, self.vprops, self.eprops)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment