UTF-8 support
[pysize.git] / ui / char_matrix.py
bloba533901320fa53035900fb506a5053a7f97b4cbe
1 from ui.utils import human_unit, short_string
4 # 012
5 # 345
6 # 678
8 # 9: selection bit
10 # Example :
11 # '+' = 1, 3, 4, 5, 7 = (1<<1) + (1<<3) + (1<<4) + (1<<5) + (1<<7) = 186
13 HLINE_START = (1<<4) + (1<<5)
14 HLINE_END = (1<<3) + (1<<4)
15 HLINE = HLINE_START | HLINE_END
17 VLINE_START = (1<<4) + (1<<7)
18 VLINE_END = (1<<1) + (1<<4)
19 VLINE = VLINE_START | VLINE_END
21 MASK = (1<<9) - 1
22 SELECTED = 1<<9
24 class CharMatrix:
25 def __init__(self, width, height, tree, selected_item=None):
26 self.width = width
27 self.height = height
28 self.tree = tree
29 self.selected_item = selected_item
30 self.matrix = [[0 for i in xrange(width)] for j in xrange(height)]
31 self._horizontal_line(0, 0, width)
32 self._horizontal_line(0, height - 1, width)
33 self._vertical_line(0, 0, height)
34 self._vertical_line(width - 1, 0, height)
36 offset = 0
37 for child in tree.root.get_children():
38 self._draw_boxes(child, 0, offset)
39 offset += child.size
41 def _compose_point(self, x, y, new):
42 self.matrix[y][x] |= new
44 def _horizontal_line(self, x, y, length, mask=0):
45 self._compose_point(x, y, HLINE_START | mask)
46 for i in xrange(x + 1, x + length - 1):
47 self._compose_point(i, y, HLINE | mask)
48 self._compose_point(x + length - 1, y, HLINE_END | mask)
50 def _vertical_line(self, x, y, length, mask=0):
51 self._compose_point(x, y, VLINE_START | mask)
52 for i in xrange(y + 1, y + length - 1):
53 self._compose_point(x, i, VLINE | mask)
54 self._compose_point(x, y + length - 1, VLINE_END | mask)
56 def _draw_string(self, x, y, length, string):
57 print_string = short_string(string.decode('UTF-8'), length)
58 self.matrix[y][x:x+len(print_string)] = print_string
60 def _draw_box(self, x0, x1, y0, y1, item, mask):
61 length = x1 - x0
62 if y1 > y0:
63 self._horizontal_line(x0, y0, length + 1, mask)
64 self._horizontal_line(x0, y1, length + 1, mask)
65 self._vertical_line(x0, y0, y1 - y0 + 1, mask)
66 self._vertical_line(x1, y0, y1 - y0 + 1, mask)
68 if item.is_real():
69 if y1 > y0 + 1:
70 self._draw_string(x0+1, (y0+y1)/2, length - 2,
71 item.basename)
72 if y1 > y0 + 2:
73 self._draw_string(x0+1, (y0+y1)/2 + 1, length - 2,
74 human_unit(item.size))
75 else:
76 # For the 'remaining' item, the size is more important than
77 # the dumy name, so we print it instead of the name when there is
78 # room for a single line
79 size_string_y = (y0+y1)/2 + 1
80 if y1 > y0 + 2:
81 self._draw_string(x0+1, (y0+y1)/2, length - 2,
82 item.basename)
83 else:
84 size_string_y -= 1
85 if y1 > y0 + 1:
86 self._draw_string(x0 + 1, size_string_y, length - 2,
87 human_unit(item.size))
89 def _draw_boxes(self, item, depth, offset):
90 x0 = depth * (self.width - 1) / self.tree.height
91 x1 = (depth + 1) * (self.width - 1) / self.tree.height
92 y0 = (self.height - 1) * offset / self.tree.root.size
93 y1 = (self.height - 1) * (offset + item.size) / self.tree.root.size
95 if item == self.selected_item:
96 mask = SELECTED
97 else:
98 mask = 0
100 self._draw_box(x0, x1, y0, y1, item, mask)
101 depth += 1
102 for child in item.get_children():
103 self._draw_boxes(child, depth, offset)
104 offset += child.size