1 # This program is free software; you can redistribute it and/or modify
2 # it under the terms of the GNU General Public License as published by
3 # the Free Software Foundation; either version 2 of the License, or
4 # (at your option) any later version.
6 # This program is distributed in the hope that it will be useful,
7 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 # GNU Library General Public License for more details.
11 # You should have received a copy of the GNU General Public License
12 # along with this program; if not, write to the Free Software
13 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15 # See the COPYING file for license information.
17 # Copyright (c) 2006, 2007, 2008 Guillaume Chazarain <guichaz@gmail.com>
20 from pysize
.ui
.utils
import human_unit
, sanitize_string
22 # A character is composed of 9 positions
30 # '+' = 1, 3, 4, 5, 7 = (1<<1) + (1<<3) + (1<<4) + (1<<5) + (1<<7) = 186
32 HLINE_START
= (1<<4) + (1<<5)
33 HLINE_END
= (1<<3) + (1<<4)
34 HLINE
= HLINE_START | HLINE_END
36 VLINE_START
= (1<<4) + (1<<7)
37 VLINE_END
= (1<<1) + (1<<4)
38 VLINE
= VLINE_START | VLINE_END
43 class CharMatrix(object):
44 """A 2D array of characters."""
45 def __init__(self
, width
, height
, tree
, selected_node
=None):
49 self
.selected_node
= selected_node
50 self
.matrix
= [[0 for i
in xrange(width
)] for j
in xrange(height
)]
51 self
._horizontal
_line
(0, 0, width
)
52 self
._horizontal
_line
(0, height
- 1, width
)
53 self
._vertical
_line
(0, 0, height
)
54 self
._vertical
_line
(width
- 1, 0, height
)
60 total_size
= tree
.root
.size
61 for child
in tree
.root
.children
or [tree
.root
]:
63 offset
+= self
._draw
_boxes
(child
, 0, offset
,
64 self
.height
- 1 - offset
, total_size
)
65 total_size
-= child
.size
67 def _compose_point(self
, x
, y
, new
):
68 self
.matrix
[y
][x
] |
= new
70 def _horizontal_line(self
, x
, y
, length
, mask
=0):
71 self
._compose
_point
(x
, y
, HLINE_START | mask
)
72 for i
in xrange(x
+ 1, x
+ length
- 1):
73 self
._compose
_point
(i
, y
, HLINE | mask
)
74 self
._compose
_point
(x
+ length
- 1, y
, HLINE_END | mask
)
76 def _vertical_line(self
, x
, y
, length
, mask
=0):
77 self
._compose
_point
(x
, y
, VLINE_START | mask
)
78 for i
in xrange(y
+ 1, y
+ length
- 1):
79 self
._compose
_point
(x
, i
, VLINE | mask
)
80 self
._compose
_point
(x
, y
+ length
- 1, VLINE_END | mask
)
82 def _draw_string(self
, x
, y
, length
, string
):
83 print_string
= sanitize_string(string
, max_length
=length
)
84 self
.matrix
[y
][x
:x
+len(print_string
)] = print_string
86 def _draw_box(self
, x0
, x1
, y0
, y1
, node
, mask
):
87 node
.rectangle
= x0
, x1
, y0
, y1
89 name
= node
.get_name()
90 name_length
= len(name
)
91 size
= human_unit(node
.size
)
93 self
._horizontal
_line
(x0
, y0
, length
+ 1, mask
)
94 self
._horizontal
_line
(x0
, y1
, length
+ 1, mask
)
95 self
._vertical
_line
(x0
, y0
, y1
- y0
+ 1, mask
)
96 self
._vertical
_line
(x1
, y0
, y1
- y0
+ 1, mask
)
99 self
._draw
_string
(x0
+ 1, (y0
+ y1
) / 2, length
- 1, name
)
102 self
._draw
_string
(x0
+ 1, (y0
+ y1
) / 2 + 1, length
- 1, size
)
103 elif name_length
+ 1 + len(size
) < length
:
104 self
._draw
_string
(x0
+ 2 + name_length
, (y0
+ y1
) / 2, length
- 1,
107 def _draw_boxes(self
, node
, depth
, offset
, length
, total_size
):
108 x0
= depth
* (self
.width
- 1) / (self
.tree
.height
or 1)
109 x1
= (depth
+ 1) * (self
.width
- 1) / (self
.tree
.height
or 1)
111 y1
= offset
+ min(length
, int(math
.ceil(float(node
.size
) * length
/
114 if node
== self
.selected_node
:
119 self
._draw
_box
(x0
, x1
, y0
, y1
, node
, mask
)
122 total_size
= node
.size
123 for child
in node
.children
:
124 child_offset
+= self
._draw
_boxes
(child
, depth
,
125 offset
+ child_offset
,
126 y1
- y0
- child_offset
,
128 total_size
-= child
.size