Package libxyz :: Package ui :: Module box_button

[hide private]
[frames] | no frames]

# Source Code for Module libxyz.ui.box_button

      1  #-*- coding: utf8 -*
      2  #
      3  # Max E. Kuznecov ~syhpoon <syhpoon@syhpoon.name> 2008
      4  #
      5  # This file is part of XYZCommander.
      6  # XYZCommander is free software: you can redistribute it and/or modify
      7  # it under the terms of the GNU Lesser Public License as published by
      8  # the Free Software Foundation, either version 3 of the License, or
      9  # (at your option) any later version.
     10  # XYZCommander 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 Lesser Public License for more details.
     14  # You should have received a copy of the GNU Lesser Public License
     15  # along with XYZCommander. If not, see <http://www.gnu.org/licenses/>.
     16
     17  from libxyz.ui import lowui
     18  from libxyz.ui import align
     19  from libxyz.ui import Box
     20  from libxyz.ui import Border
     21
     22  import libxyz.ui
     23
     24 -class ButtonBox(Box):
     25      """
     26      Button box. Shows a message and waits for button pressed
     27      """
     28
     29      # Skin rulesets resolution order
     30      resolution = (u"button_box", u"box", u"widget")
     31
     32 -    def __init__(self, xyz, body, message, buttons, title="", width=70):
     33          """
     34          @param xyz: XYZ dictionary
     35          @param body: Top-level widget
     36          @param message: Message to display
     37          @param buttons: List of button pairs (text, value).
     38                          Text is what button shows and value is what
     39                          being returned.
     40          @param title: Box title
     41          @param width: Box width (including mount box)
     42
     43          Required resources: title, box, border, mount, button
     44          """
     45
     46          super(ButtonBox, self).__init__(xyz, body, message, title, width)
     47          self.calc_size(6)
     48
     49          self.buttons = buttons
     50          self.keys = libxyz.ui.Keys()
     51          self._buttons = self._init_buttons(self.buttons)
     52
     53          _title = self._strip_title(title.replace(u"\n", u" "))
     54
     55          if _title:
     56              _title_attr = self._attr(u"title")
     57          else:
     58              _title = None
     59              _title_attr = None
     60
     61          _mount = lowui.AttrWrap(lowui.Filler(lowui.Text(u"")),
     62                                  self._attr(u"mount"))
     63
     64          # Main dialog text
     65          _text = lowui.Text((self._attr(u"box"), message), align.CENTER)
     66          _blank = lowui.Text((self._attr(u"box"), ""))
     67
     68          _widgets = [_text, _blank, self._buttons]
     69          _box = lowui.Filler(lowui.Pile(_widgets), valign=align.BOTTOM)
     70          _box = Border(_box, _title, _title_attr, self._attr(u"border"))
     71          _box = lowui.AttrWrap(_box, self._attr(u"box"))
     72
     73          _mount = lowui.Overlay(_mount, body, align.CENTER, self.full_width,
     74                               align.MIDDLE, self.full_height)
     75          _box = lowui.Overlay(_box, _mount, align.CENTER, self.box_width,
     76                               align.MIDDLE, self.box_height)
     77
     78          self.parent_init(_box)
     79
     80      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     81
     82 -    def show(self, dim=None):
     83          """
     84          Show box and return pressed button value.
     85          """
     86
     87          if dim is None:
     88              dim = self.screen.get_cols_rows()
     89          while True:
     90              try:
     91                  self.screen.draw_screen(dim, self.render(dim, True))
     92
     93                  _keys = self.xyz.input.get()
     94
     95                  if self.xyz.input.WIN_RESIZE in _keys:
     96                      dim = self.screen.get_cols_rows()
     97                      continue
     98
     99                  if [x for x in (self.keys.LEFT,
    100                                  self.keys.RIGHT,
    101                                  self.keys.UP,
    102                                  self.keys.DOWN,
    103                                  ) if x in _keys]:
    104                      self._change_focus(_keys)
    105
    106                  if self.keys.ESCAPE in _keys:
    107                      return None
    108
    109                  if self.keys.ENTER in _keys:
    110                      _button = self._buttons.focus_cell.get_w()
    111                      return self._pressed(_button)
    112              except KeyboardInterrupt:
    113                  continue
    114
    115      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    116
    117 -    def _init_buttons(self, buttons):
    118          _b_attr = self._attr("button")
    119          _actb_attr = self._attr("button_active")
    120
    121          _b_size = max([len(b[0]) for b in buttons]) + 4 # [ ... ]
    122
    123          data = [lowui.AttrWrap(libxyz.ui.XYZButton(x[0]), _b_attr)
    124                  for x in buttons]
    125
    126          buttons = lowui.GridFlow(data, _b_size, 2, 0, align.CENTER)
    127          buttons.focus_cell.set_attr(_actb_attr)
    128
    129          return buttons
    130
    131      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    132
    133 -    def _change_focus(self, keys):
    134          """
    135          Move focus
    136          """
    137
    138          _inact = self._attr("button")
    139          _act = self._attr("button_active")
    140
    141          _cells = self._buttons.cells
    142          _index = lambda: _cells.index(self._buttons.focus_cell)
    143
    144          for key in keys:
    145              _widget = None
    146
    147              # Move right
    148              if key in (self.keys.RIGHT, self.keys.UP):
    149                  i = _index()
    150
    151                  if i < len(_cells) - 1:
    152                      _widget = i + 1 # index
    153                  else:
    154                      _widget = 0
    155              # Move left
    156              elif key in (self.keys.LEFT, self.keys.DOWN):
    157                  i = _index()
    158
    159                  if i > 0:
    160                      _widget = i - 1
    161                  else:
    162                      _widget = len(_cells) - 1
    163              else:
    164                  pass
    165
    166              if _widget is not None:
    167                  self._buttons.focus_cell.set_attr(_inact)
    168                  self._buttons.set_focus(_widget)
    169                  self._buttons.focus_cell.set_attr(_act)
    170
    171      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    172
    173 -    def _pressed(self, button):
    174          """
    175          Button pressed
    176          """
    177
    178          _label = button.get_label()
    179
    180          for txt, val in self.buttons:
    181              if _label == txt:
    182                  return val
    183
    184          return None
    185