"Fossies" - the Fresh Open Source Software Archive

Member "pysize-0.2/pysize/ui/char_matrix.py" (11 Mar 2007, 4758 Bytes) of package /linux/privat/old/pysize-0.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. For more information about "char_matrix.py" see the Fossies "Dox" file reference documentation.

    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.
    5 #
    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.
   10 #
   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.
   14 #
   15 # See the COPYING file for license information.
   16 #
   17 # Copyright (c) 2006, 2007 Guillaume Chazarain <guichaz@yahoo.fr>
   18 
   19 import math
   20 from pysize.ui.utils import human_unit, short_string, sanitize_string
   21 
   22 # A character is composed of 9 positions
   23 # 012
   24 # 345
   25 # 678
   26 #
   27 # 9: selection bit
   28 #
   29 # Example :
   30 # '+' = 1, 3, 4, 5, 7 = (1<<1) + (1<<3) + (1<<4) + (1<<5) + (1<<7) = 186
   31 
   32 HLINE_START = (1<<4) + (1<<5)
   33 HLINE_END = (1<<3) + (1<<4)
   34 HLINE = HLINE_START | HLINE_END
   35 
   36 VLINE_START = (1<<4) + (1<<7)
   37 VLINE_END = (1<<1) + (1<<4)
   38 VLINE = VLINE_START | VLINE_END
   39 
   40 MASK = (1<<9) - 1
   41 SELECTED = 1<<9
   42 
   43 class CharMatrix(object):
   44     """A 2D array of characters."""
   45     def __init__(self, width, height, tree, selected_node=None):
   46         self.width = width
   47         self.height = height
   48         self.tree = tree
   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)
   55 
   56         if not tree.root:
   57             return
   58 
   59         offset = 0
   60         total_size = tree.root.size
   61         for child in tree.root.children or [tree.root]:
   62             if child.size:
   63                 offset += self._draw_boxes(child, 0, offset,
   64                                            self.height - 1 - offset, total_size)
   65                 total_size -= child.size
   66 
   67     def _compose_point(self, x, y, new):
   68         self.matrix[y][x] |= new
   69 
   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)
   75 
   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)
   81 
   82     def _draw_string(self, x, y, length, string):
   83         print_string = short_string(sanitize_string(string), length)
   84         self.matrix[y][x:x+len(print_string)] = print_string
   85 
   86     def _draw_box(self, x0, x1, y0, y1, node, mask):
   87         node.rectangle = x0, x1, y0, y1
   88         length = x1 - x0
   89         name = node.get_name()
   90         name_length = len(name)
   91         size = human_unit(node.size)
   92         if y1 > y0:
   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)
   97 
   98         if y1 > y0 + 1:
   99             self._draw_string(x0 + 1, (y0 + y1) / 2, length - 2, name)
  100 
  101         if y1 > y0 + 2:
  102             self._draw_string(x0 + 1, (y0 + y1) / 2 + 1, length - 2, size)
  103         elif name_length + 1 + len(size) < length:
  104             self._draw_string(x0 + 2 + name_length, (y0 + y1) / 2, length - 2,
  105                               size)
  106 
  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)
  110         y0 = offset
  111         y1 = offset + min(length, int(math.ceil(float(node.size) * length /
  112                                                 total_size)))
  113 
  114         if node == self.selected_node:
  115             mask = SELECTED
  116         else:
  117             mask = 0
  118 
  119         self._draw_box(x0, x1, y0, y1, node, mask)
  120         depth += 1
  121         child_offset = 0
  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,
  127                                              total_size)
  128             total_size -= child.size
  129         return y1 - y0