[FIX] config blacklist stop_after_init
[odoo/odoo.git] / openerp / pychart / text_box.py
1 # -*- coding: utf-8 -*-
2 #
3 # Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
4
5 # Jockey is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by the
7 # Free Software Foundation; either version 2, or (at your option) any
8 # later version.
9 #
10 # Jockey is distributed in the hope that it will be useful, but WITHOUT
11 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 # FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13 # for more details.
14 #
15 import canvas
16 import line_style
17 import pychart_util
18 import fill_style
19 import font
20 import chart_object
21 import color
22 import arrow
23 import text_box_doc
24 from pychart_types import *
25 from types import *
26
27 class T(chart_object.T):
28     __doc__ = text_box_doc.doc
29     keys = {"text": (StringType, "???", "Text body. <<font>>"),
30             "loc": (TupleType, (0,0),
31                     "The location of the text box."),
32             "line_style": (line_style.T, line_style.default,
33                            """The line style of the surrounding frame."""),
34             "fill_style": (fill_style.T, fill_style.white,
35                            "Specifies the fill style of the text box."),
36             "top_fudge": (UnitType, 0,
37                           "The amount of space (in points) above the first line"),
38             "bottom_fudge": (UnitType, 5,
39                              "The amount of space below the last line"),
40             "left_fudge": (UnitType, 5,
41                            "The amount of space left of the box"),
42             "right_fudge": (UnitType, 5,
43                             "The amount of space right of the box"),
44             "_arrows": (ListType, pychart_util.new_list, "The list of arrows. Not to be touched by the user directly"),
45             "radius": (UnitType, 0,
46                        """Radius of the four corners of the rectangle.
47                        If the value is zero, a sharp-cornered
48                        rectangle is drawn."""),
49             "shadow": (ShadowType, None,
50                        pychart_util.shadow_desc)
51             }
52 ##AUTOMATICALLY GENERATED
53
54 ##END AUTOMATICALLY GENERATED
55     def get_dimension(self):
56         x = self.loc[0] - self.left_fudge
57         y = self.loc[1] - self.bottom_fudge
58         width = font.text_width(self.text) + self.right_fudge + self.left_fudge
59         height = (font.text_height(self.text))[0] + self.top_fudge + self.bottom_fudge
60         return (x, y, width, height)
61     
62     def choose_end_point(self, tipx, tipy):
63         (x, y, width, height) = self.get_dimension()
64         
65         minDist = -1
66         minPoint = None
67         vertices = [(x, y),
68                     (x+width, y),
69                     (x+width, y+height),
70                     (x, y+height)]
71             
72         if tipx >= x and tipx < x+width:
73             vertices.append((tipx, y))
74             vertices.append((tipx, y+height))
75         if tipy >= y and tipy < y+height:
76             vertices.append((x, tipy))
77             vertices.append((x+width, tipy))
78             
79         for startPoint in vertices:
80             dist = ((startPoint[0] - tipx) **2 + (startPoint[1] - tipy) **2)
81             if not minPoint or dist < minDist:
82                 minPoint = startPoint
83                 minDist = dist
84             
85         return minPoint
86     
87     def add_arrow(self, tipLoc, tail=None, arrow = arrow.default):
88         """This method adds a straight arrow that points to
89         @var{TIPLOC}, which is a tuple of integers. @var{TAIL}
90         specifies the starting point of the arrow. It is either None
91         or a string consisting of the following letters: 'l', 'c',
92         'r', 't', 'm,', and 'b'.  Letters 'l', 'c', or 'r' means to
93         start the arrow from the left, center, or right of the text
94         box, respectively. Letters 't', 'm', or 'b' means to start the
95         arrow from the top, middle or bottom of the text box.  For
96         example, when @samp{tail = 'tc'} then arrow is drawn from
97         top-center point of the text box. ARROW specifies the style of
98         the arrow. <<arrow>>.
99         """
100         self._arrows.append((tipLoc, tail, arrow))
101         
102     def draw(self, can = None):
103         if can == None:
104             can = canvas.default_canvas()
105         x = self.loc[0]
106         y = self.loc[1]
107         text_width = font.text_width(self.text)
108         text_height = font.text_height(self.text)[0]
109         (halign, valign, angle) = font.get_align(self.text)
110         
111         if self.line_style or self.fill_style:
112             width = text_width+self.left_fudge+self.right_fudge
113             height = text_height+self.bottom_fudge+self.top_fudge
114             can.round_rectangle(self.line_style, self.fill_style,
115                                    x-self.left_fudge, y-self.bottom_fudge,
116                                    x-self.left_fudge+width, y-self.bottom_fudge+height,
117                                    self.radius, self.shadow)
118
119         if halign == 'L':
120             can.show(x, y, self.text)
121         elif halign == 'C':
122             can.show(x+text_width/2.0, y, self.text)
123         elif halign == 'R':
124             can.show(x+text_width, y, self.text)
125         else:
126             raise Exception, "Unsupported alignment (" + halign + ")"
127
128         # draw arrows
129         for t in self._arrows:
130             (tipLoc, tail, arrow) = t
131             if tail:
132                 (x, y, width, height) = self.get_dimension()
133                 origin = [x, y]
134                 for ch in tail:
135                     if ch == 'l':
136                         origin[0] = x
137                     elif ch == 'c':
138                         origin[0] = x+width/2.0
139                     elif ch == 'r':
140                         origin[0] = x+width
141                     elif ch == 'b':
142                         origin[1] = y
143                     elif ch == 'm':
144                         origin[1] = y+height/2.0
145                     elif ch == 't':
146                         origin[1] = y+height
147                     else:
148                         raise ValueError, tail +  ": unknown tail location spec."
149             else:
150                 origin = self.choose_end_point(tipLoc[0], tipLoc[1])
151             arrow.draw((origin, tipLoc), can)
152             
153