Gnumed.timelinelib.canvas.drawing.drawers.legenddrawer

Package Gnumed :: Package timelinelib :: Package canvas :: Package drawing :: Package drawers :: Module legenddrawer |
[frames] | no frames]

# Source Code for Module Gnumed.timelinelib.canvas.drawing.drawers.legenddrawer

      1  # Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018  Rickard Lindberg, Roger Lindberg
      2  #
      3  # This file is part of Timeline.
      4  #
      5  # Timeline is free software: you can redistribute it and/or modify
      6  # it under the terms of the GNU General Public License as published by
      7  # the Free Software Foundation, either version 3 of the License, or
      8  # (at your option) any later version.
      9  #
     10  # Timeline is distributed in the hope that it will be useful,
     11  # but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13  # GNU General Public License for more details.
     14  #
     15  # You should have received a copy of the GNU General Public License
     16  # along with Timeline.  If not, see <http://www.gnu.org/licenses/>.
     17
     18  """
     19  Contains the LegendDrawer class.
     20  Tests are defined :doc:`Here <unit_canvas_drawing_drawers_legenddrawer>`.
     21  """
     22
     23  import wx
     24  import timelinelib.wxgui.components.font as font
     25  from timelinelib.canvas.drawing.graphobject import GraphObject
     26  from timelinelib.canvas.drawing.utils import darken_color
     27
     28
     29  # INNER_PADDING = 3  # Space inside event box to text (pixels)
     30  # OUTER_PADDING = 5  # Space between event boxes (pixels)
     31  IP = 3
     32  OP = 5
     33
     34  BOTTOM_LEFT = 0
     35  """Default value."""
     36  TOP_LEFT = 1
     37  """."""
     38  TOP_RIGHT = 2
     39  """."""
     40  BOTTOM_RIGHT = 3
     41  """."""
     42
     43
     44 -class LegendDrawer():
     45      """
     46      The legend is a box containing one item row for each category
     47      displayed in a timeline. An item contains a text and colored
     48      box. The text is the category text and the color is the color
     49      of the category. The legend box can be placed at different
     50      locations on the Teimeline panel. When measures are calculated
     51      it's assumed that it will be placed in the upper left corner::
     52                                        OP
     53             IP                        |  |
     54            |  |              >|   |< text_height
     55            +--------------------------+---
     56            |                          |    IP
     57            |                  +---+   |---
     58            |   Xxxxxxx yyyy   |   |   |
     59            |                  +---+   |---
     60            |                          |    IP
     61            |                  +---+   |---
     62            |   Xxxxxxx yyyy   |   |   |    text_height
     63            |                  +---+   |---
     64            |   |          |     :     |
     65            |    text_width      :     |
     66            |                    :     |
     67            +--------------------------+
     68                            |  |    |  |
     69                             OP      IP
     70      """
     71
     72 -    def __init__(self, dc, scene, categories):
     73          self._dc = dc
     74          self._scene = scene
     75          self._categories = categories
     76
     77 -    def draw(self):
     78          """Draw the legend on the Timeline panel."""
     79          go = self._create_graph_object()
     80          self._draw_rectangle(go)
     81          self._draw_legend_items(go)
     82
     83 -    def _draw_legend_items(self, go):
     84          for item in go.childs:
     85              self._draw_legend_item(item)
     86
     87 -    def _draw_legend_item(self, go):
     88          self._dc.DrawText(go.text, *go.point)
     89          self._draw_Legend_item_color_box(go.first_child)
     90
     91 -    def _draw_Legend_item_color_box(self, go):
     92          self._draw_rectangle(go)
     93
     94 -    def _draw_rectangle(self, go):
     95          self._dc.SetBrush(go.brush_color)
     96          self._dc.SetPen(go.pen_color)
     97          self._dc.DrawRectangle(wx.Rect(*go.rect))
     98
     99 -    def _create_graph_object(self):
    100          tw, th = self._get_text_metrics(self._categories)
    101          box_width = tw + th + OP + 2 * IP
    102          box_height = len(self._categories) * (IP + th) + IP
    103          return self._create_legend(box_width, box_height, tw, th)
    104
    105 -    def _get_text_metrics(self, categories):
    106          """
    107          Return the text width of the longest category text and the
    108          height of the first category text.
    109          """
    110          font.set_legend_text_font(self._scene._appearance.get_legend_font(), self._dc)
    111          twth = [self._dc.GetTextExtent(cat.name) for cat in categories]
    112          maxw = max(twth, key=lambda x: x[0])[0]
    113          return maxw, twth[0][1]
    114
    115 -    def _create_legend(self, box_width, box_height, tw, th):
    116          go = GraphObject(w=box_width, h=box_height)
    117          go.brush_color = wx.Brush(wx.Colour(255, 255, 255), wx.BRUSHSTYLE_SOLID)
    118          go.pen_color = wx.Pen(wx.Colour(0, 0, 0), 1, wx.PENSTYLE_SOLID)
    119          go.childs = self._legend_items(tw, th)
    120          go.translate(OP, OP)
    121          self._set_legend_pos(go)
    122          return go
    123
    124 -    def _legend_items(self, tw, th):
    125          collector = []
    126          for i in range(len(self._categories)):
    127              y = i * (th + IP)
    128              go = GraphObject(y=y, text=self._categories[i].name)
    129              go.add_child(self._color_box(tw, th, y, self._categories[i]))
    130              go.translate(IP, IP)
    131              collector.append(go)
    132          return collector
    133
    134 -    def _color_box(self, tw, th, y, category):
    135          go = GraphObject(x=tw + OP, y=y, w=th, h=th)
    136          go.brush_color = wx.Brush(wx.Colour(*category.color))
    137          go.pen_color = wx.Pen(wx.Colour(*darken_color(category.color)))
    138          return go
    139
    140 -    def _set_legend_pos(self, go):
    141          x = self._scene.width - 2 * OP - go.width
    142          y = self._scene.height - 2 * OP - go.height
    143          poses = {TOP_LEFT: (0, 0),
    144                   TOP_RIGHT: (x, 0),
    145                   BOTTOM_LEFT: (0, y),
    146                   BOTTOM_RIGHT: (x, y)}
    147          go.translate(*poses[self._scene._view_properties.legend_pos])
    148