4 assert gtk
.pygtk_version
>= (2, 8)
11 from pysize
.ui
.utils
import human_unit
, min_size_to_consider
, sanitize_string
16 class PysizeWidget_Draw(object):
17 def __init__(self
, options
, args
):
18 self
.connect('expose-event', type(self
)._expose
_event
)
19 self
.modify_font(pango
.FontDescription('Monospace 12'))
20 self
.max_text_height
= self
.measure_font_height()
21 self
.fast
= options
.fast
23 def measure_font_height(self
):
24 w
, h
= self
.create_pango_layout('a').get_pixel_size()
27 def _get_requested_height(self
):
28 return self
.max_text_height
* self
.tree
.root
.size
/ \
29 min_size_to_consider(self
.options
.min_size
)
31 def queue_node_redraw(self
, node
):
33 x0
, x1
, y0
, y1
= map(int, node
.rectangle
)
34 self
.queue_draw_area(x0
, y0
, x1
- x0
, y1
- y0
)
36 def _draw_text(self
, context
, text
, x0
, x1
, y0
, y1
):
37 pl
= self
.create_pango_layout(text
)
38 pl
.set_alignment(pango
.ALIGN_CENTER
)
41 pl
.set_width(int(w
*pango
.SCALE
))
42 pl
.set_ellipsize(pango
.ELLIPSIZE_MIDDLE
)
43 real_w
, real_h
= pl
.get_pixel_size()
44 if real_h
> self
.max_text_height
:
45 self
.max_text_height
= real_h
48 context
.move_to(x0
, y0
+(h
-real_h
)/2.0)
49 context
.set_source_rgb(0, 0, 0)
50 context
.show_layout(pl
)
53 def _get_node_colors(self
, node
, colors
):
54 if node
== self
.cursor_node
:
55 colors
= map(lambda c
: c
+0.1, colors
)
56 if node
in self
.selected_nodes
+ [self
.button_press_node
]:
57 colors
= map(lambda c
: c
-0.3, colors
)
60 def _draw_box(self
, context
, x0
, x1
, y0
, y1
, node
):
71 node
.rectangle
= x0
, x1
, y0
, y1
74 context
.rectangle(x0
, y0
, x1
- x0
, y1
- y0
)
75 context
.set_source_rgb(0, 0, 0)
76 context
.stroke_preserve()
78 colors
= self
._get
_node
_colors
(node
, [0, 0.5, 1.0])
79 context
.set_source_rgb(*colors
)
83 context
.arc(x0
+ RADIUS
, y0
+ RADIUS
, RADIUS
,
84 - math
.pi
, - math
.pi
/ 2.0)
85 context
.rel_line_to(x1
- x0
- 2*RADIUS
, 0)
86 context
.arc(x1
- RADIUS
, y0
+ RADIUS
, RADIUS
,
88 context
.rel_line_to(0, y1
- y0
- 2*RADIUS
)
89 context
.arc(x1
- RADIUS
, y1
- RADIUS
, RADIUS
,
91 context
.rel_line_to(- x1
+ x0
+ 2*RADIUS
, 0)
92 context
.arc(x0
+ RADIUS
, y1
- RADIUS
, RADIUS
,
93 math
.pi
/ 2.0, math
.pi
)
96 context
.set_source_rgb(0, 0, 0)
97 context
.stroke_preserve()
99 gradient
= cairo
.LinearGradient(0, y0
, 0, y1
)
100 colors
= self
._get
_node
_colors
(node
, [0.5, 0.5, 1.0, 0.0, 0.5, 1.0])
101 gradient
.add_color_stop_rgb(0.0, *colors
[:3])
102 gradient
.add_color_stop_rgb(1.0, *colors
[3:])
103 context
.set_source(gradient
)
106 name
= sanitize_string(node
.get_name())
107 size
= human_unit(node
.size
)
108 self
._draw
_text
(context
, name
+ '\n' + size
, x0
, x1
, y0
, y1
) or \
109 self
._draw
_text
(context
, name
, x0
, x1
, y0
, y1
) or \
110 self
._draw
_text
(context
, size
, x0
, x1
, y0
, y1
)
112 def _draw_boxes(self
, context
, node
, depth
, offset
):
113 w
= self
.allocation
.width
114 h
= self
.allocation
.height
115 x0
= depth
* (w
- 1.0) / self
.tree
.height
116 x1
= (depth
+ 1.0) * (w
- 1.0) / self
.tree
.height
117 y0
= (h
- 1.0) * offset
/ self
.tree
.root
.size
118 y1
= (h
- 1.0) * (offset
+ node
.size
) / self
.tree
.root
.size
120 self
._draw
_box
(context
, x0
, x1
, y0
, y1
, node
)
122 for child
in node
.children
:
123 self
._draw
_boxes
(context
, child
, depth
, offset
)
126 def _draw(self
, context
):
127 max_text_height_before
= self
.max_text_height
128 context
.set_line_width(LINE_WIDTH
)
130 for child
in self
.tree
.root
.children
:
131 self
._draw
_boxes
(context
, child
, 0, offset
)
133 if self
.max_text_height
!= max_text_height_before
:
134 self
.schedule_new_tree()
136 def _expose_event(self
, event
):
137 context
= self
.window
.cairo_create()
139 # set a clip region for the expose event
140 context
.rectangle(event
.area
.x
, event
.area
.y
,
141 event
.area
.width
, event
.area
.height
)
147 def max_number_of_nodes(self
):
148 return max(2, self
.allocation
.height
/ self
.max_text_height
)
150 def _get_actual_min_size(self
):
151 min_size
= self
.options
.min_size
152 if min_size
== 'auto':
153 min_size
= self
.tree
.root
.size
* self
.min_size_requested()
156 def _zoom(self
, func
):
157 min_size
= self
._get
_actual
_min
_size
()
158 self
.options
.min_size
= func(min_size
)
159 self
.schedule_new_tree()
162 self
._zoom
(lambda min_size
: 'auto')
165 self
._zoom
(lambda min_size
: str(int(min_size
/ 1.5)))
168 self
._zoom
(lambda min_size
: str(int(min_size
* 1.5)))