[or-cvs] r24239: {arm} Using ui util for drawing borders (common code used by both (in arm/trunk: . src/interface src/util)

Damian Johnson atagar1 at gmail.com
Sat Feb 19 08:25:58 UTC 2011


Author: atagar
Date: 2011-02-19 08:25:58 +0000 (Sat, 19 Feb 2011)
New Revision: 24239

Modified:
   arm/trunk/TODO
   arm/trunk/src/interface/configPanel.py
   arm/trunk/src/interface/controller.py
   arm/trunk/src/interface/descriptorPopup.py
   arm/trunk/src/util/panel.py
   arm/trunk/src/util/uiTools.py
Log:
Using ui util for drawing borders (common code used by both the config and connection panels)



Modified: arm/trunk/TODO
===================================================================
--- arm/trunk/TODO	2011-02-19 08:21:17 UTC (rev 24238)
+++ arm/trunk/TODO	2011-02-19 08:25:58 UTC (rev 24239)
@@ -68,6 +68,7 @@
     > 'GETINFO config-text' has been introduced in 0.2.2.7, while I am
     > running 0.2.1.28. Maybe a check in arm for the version-number for that
     > feature to be enabled might be an idea?
+    also: https://trac.torproject.org/projects/tor/ticket/2501
   * When saving the config the Log entry should be filtered out if unnecessary.
   * The config write dialog (ie, the one for saving the config) has its a
     misaligned border when it's smaller than the top detail section.

Modified: arm/trunk/src/interface/configPanel.py
===================================================================
--- arm/trunk/src/interface/configPanel.py	2011-02-19 08:21:17 UTC (rev 24238)
+++ arm/trunk/src/interface/configPanel.py	2011-02-19 08:25:58 UTC (rev 24239)
@@ -255,9 +255,6 @@
     configType = "Tor" if self.configType == State.TOR else "Arm"
     hiddenMsg = "press 'a' to hide most options" if self.showAll else "press 'a' to show all options"
     
-    titleLabel = "%s Configuration (%s):" % (configType, hiddenMsg)
-    self.addstr(0, 0, titleLabel, curses.A_STANDOUT)
-    
     # panel with details for the current selection
     detailPanelHeight = self._config["features.config.selectionDetails.height"]
     isScrollbarVisible = False
@@ -275,8 +272,11 @@
       cursorSelection = self.getSelection()
       isScrollbarVisible = len(self._getConfigOptions()) > height - detailPanelHeight - 1
       
-      self._drawSelectionPanel(cursorSelection, width, detailPanelHeight, titleLabel, isScrollbarVisible)
+      self._drawSelectionPanel(cursorSelection, width, detailPanelHeight, isScrollbarVisible)
     
+    titleLabel = "%s Configuration (%s):" % (configType, hiddenMsg)
+    self.addstr(0, 0, titleLabel, curses.A_STANDOUT)
+    
     # draws left-hand scroll bar if content's longer than the height
     scrollOffset = 1
     if isScrollbarVisible:
@@ -305,27 +305,15 @@
   def _getConfigOptions(self):
     return self.confContents if self.showAll else self.confImportantContents
   
-  def _drawSelectionPanel(self, cursorSelection, width, detailPanelHeight, titleLabel, isScrollbarVisible):
+  def _drawSelectionPanel(self, cursorSelection, width, detailPanelHeight, isScrollbarVisible):
     """
     Renders a panel for the selected configuration option.
     """
     
-    # border (top)
-    if width >= len(titleLabel):
-      self.win.hline(0, len(titleLabel), curses.ACS_HLINE, width - len(titleLabel))
-      self.win.addch(0, width, curses.ACS_URCORNER)
-    
-    # border (sides)
-    self.win.vline(1, 0, curses.ACS_VLINE, detailPanelHeight - 1)
-    self.win.vline(1, width, curses.ACS_VLINE, detailPanelHeight - 1)
-    
-    # border (bottom)
     # This is a solid border unless the scrollbar is visible, in which case a
     # 'T' pipe connects the border to the bar.
-    self.win.addch(detailPanelHeight, 0, curses.ACS_LLCORNER)
-    if width >= 2: self.win.hline(detailPanelHeight, 1, curses.ACS_HLINE, width - 1)
+    uiTools.drawBox(self, 0, 0, width, detailPanelHeight)
     if width >= 2 and isScrollbarVisible: self.win.addch(detailPanelHeight, 1, curses.ACS_TTEE)
-    self.win.addch(detailPanelHeight, width, curses.ACS_LRCORNER)
     
     selectionFormat = curses.A_BOLD | uiTools.getColor(CATEGORY_COLOR[cursorSelection.get(Field.CATEGORY)])
     

Modified: arm/trunk/src/interface/controller.py
===================================================================
--- arm/trunk/src/interface/controller.py	2011-02-19 08:21:17 UTC (rev 24238)
+++ arm/trunk/src/interface/controller.py	2011-02-19 08:25:58 UTC (rev 24239)
@@ -247,7 +247,7 @@
       popup.recreate(stdscr, newWidth)
       
       key = 0
-      while key not in (curses.KEY_ENTER, 10, ord(' ')):
+      while not uiTools.isSelectionKey(key):
         popup.clear()
         popup.win.box()
         popup.addstr(0, 0, title, curses.A_STANDOUT)
@@ -348,7 +348,7 @@
       elif key == curses.KEY_RIGHT: cursorLoc = min(len(selectionOptions) - 1, cursorLoc + 1)
       elif key == curses.KEY_UP: cursorLoc = max(0, cursorLoc - 4)
       elif key == curses.KEY_DOWN: cursorLoc = min(len(selectionOptions) - 1, cursorLoc + 4)
-      elif key in (curses.KEY_ENTER, 10, ord(' ')):
+      elif uiTools.isSelectionKey(key):
         # selected entry (the ord of '10' seems needed to pick up enter)
         selection = selectionOptions[cursorLoc]
         if selection == "Cancel": break
@@ -997,6 +997,12 @@
           
           popup.addfstr(4, 2, "<b>r</b>: reload torrc")
           popup.addfstr(4, 41, "<b>x</b>: reset tor (issue sighup)")
+        elif page == 4:
+          popup.addfstr(1, 2, "<b>up arrow</b>: scroll up a line")
+          popup.addfstr(1, 41, "<b>down arrow</b>: scroll down a line")
+          popup.addfstr(2, 2, "<b>page up</b>: scroll up a page")
+          popup.addfstr(2, 41, "<b>page down</b>: scroll down a page")
+          popup.addfstr(3, 2, "<b>enter</b>: connection details")
         
         popup.addstr(7, 2, "Press any key...")
         popup.refresh()
@@ -1273,7 +1279,8 @@
       panels["control"].resolvingCounter = -1
       hostnames.setPaused(True)
       panels["conn"].sortConnections()
-    elif page == 1 and panels["conn"].isCursorEnabled and key in (curses.KEY_ENTER, 10, ord(' ')):
+    elif page == 1 and panels["conn"].isCursorEnabled and uiTools.isSelectionKey(key):
+      # TODO: deprecated when migrated to the new connection panel
       # provides details on selected connection
       panel.CURSES_LOCK.acquire()
       try:
@@ -1291,7 +1298,7 @@
         curses.cbreak() # wait indefinitely for key presses (no timeout)
         key = 0
         
-        while key not in (curses.KEY_ENTER, 10, ord(' ')):
+        while not uiTools.isSelectionKey(key):
           popup.clear()
           popup.win.box()
           popup.addstr(0, 0, "Connection Details:", curses.A_STANDOUT)
@@ -1617,7 +1624,7 @@
           popup.recreate(stdscr)
         
         key, selection = 0, 2
-        while key not in (curses.KEY_ENTER, 10, ord(' ')):
+        while not uiTools.isSelectionKey(key):
           # if the popup has been resized then recreate it (needed for the
           # proper border height)
           newHeight, newWidth = panels["popup"].getPreferredSize()
@@ -1740,7 +1747,7 @@
         panels["config"].setSortOrder(resultEnums)
       
       panels["config"].redraw(True)
-    elif page == 2 and key in (curses.KEY_ENTER, 10, ord(' ')):
+    elif page == 2 and uiTools.isSelectionKey(key):
       # let the user edit the configuration value, unchanged if left blank
       panel.CURSES_LOCK.acquire()
       try:

Modified: arm/trunk/src/interface/descriptorPopup.py
===================================================================
--- arm/trunk/src/interface/descriptorPopup.py	2011-02-19 08:21:17 UTC (rev 24238)
+++ arm/trunk/src/interface/descriptorPopup.py	2011-02-19 08:25:58 UTC (rev 24239)
@@ -106,7 +106,7 @@
         draw(popup, properties)
         key = stdscr.getch()
         
-        if key in (curses.KEY_ENTER, 10, ord(' '), ord('d'), ord('D')):
+        if uiTools.isSelectionKey(key) or key in (ord('d'), ord('D')):
           # closes popup
           isVisible = False
         elif key in (curses.KEY_LEFT, curses.KEY_RIGHT):

Modified: arm/trunk/src/util/panel.py
===================================================================
--- arm/trunk/src/util/panel.py	2011-02-19 08:21:17 UTC (rev 24238)
+++ arm/trunk/src/util/panel.py	2011-02-19 08:25:58 UTC (rev 24239)
@@ -248,6 +248,44 @@
     finally:
       CURSES_LOCK.release()
   
+  def hline(self, y, x, length):
+    """
+    Draws a horizontal line. This should only be called from the context of a
+    panel's draw method.
+    
+    Arguments:
+      y      - vertical location
+      x      - horizontal location
+      length - length the line spans
+    """
+    
+    if self.win and self.maxX > x and self.maxY > y:
+      try:
+        drawLength = min(length, self.maxX - x)
+        self.win.hline(y, x, curses.ACS_HLINE, drawLength)
+      except:
+        # in edge cases drawing could cause a _curses.error
+        pass
+  
+  def vline(self, y, x, length):
+    """
+    Draws a vertical line. This should only be called from the context of a
+    panel's draw method.
+    
+    Arguments:
+      y      - vertical location
+      x      - horizontal location
+      length - length the line spans
+    """
+    
+    if self.win and self.maxX > x and self.maxY > y:
+      try:
+        drawLength = min(length, self.maxY - y)
+        self.win.vline(y, x, curses.ACS_VLINE, drawLength)
+      except:
+        # in edge cases drawing could cause a _curses.error
+        pass
+  
   def addstr(self, y, x, msg, attr=curses.A_NORMAL):
     """
     Writes string to subwindow if able. This takes into account screen bounds

Modified: arm/trunk/src/util/uiTools.py
===================================================================
--- arm/trunk/src/util/uiTools.py	2011-02-19 08:21:17 UTC (rev 24238)
+++ arm/trunk/src/util/uiTools.py	2011-02-19 08:25:58 UTC (rev 24239)
@@ -194,10 +194,61 @@
   if getRemainder: return (returnMsg, remainder)
   else: return returnMsg
 
+def drawBox(panel, top, left, width, height):
+  """
+  Draws a box in the panel with the given bounds.
+  
+  Arguments:
+    panel  - panel in which to draw
+    top    - vertical position of the box's top
+    left   - horizontal position of the box's left side
+    width  - width of the drawn box
+    height - height of the drawn box
+  """
+  
+  panelHeight, panelWidth = panel.getPreferredSize()
+  
+  # checks if there's nothing to display
+  if left > panelWidth or top > panelHeight: return
+  
+  # draws the top and bottom
+  panel.hline(top, left + 1, width - 1)
+  panel.hline(top + height, left + 1, width - 1)
+  
+  # draws the left and right sides
+  panel.vline(top + 1, left, height - 1)
+  panel.vline(top + 1, left + width, height - 1)
+  
+  # draws the corners
+  corners = ((0, 0, curses.ACS_ULCORNER),
+             (0, 1, curses.ACS_URCORNER),
+             (1, 0, curses.ACS_LLCORNER),
+             (1, 1, curses.ACS_LRCORNER))
+  
+  for isBottom, isRight, cornerType in corners:
+    yLoc = top + height * isBottom
+    xLoc = left + width * isRight
+    
+    if yLoc < panelHeight and xLoc < panelWidth:
+      panel.win.addch(yLoc, xLoc, cornerType)
+
+def isSelectionKey(key):
+  """
+  Returns true if the keycode matches the enter or space keys.
+  
+  Argument:
+    key - keycode to be checked
+  """
+  
+  return key in (curses.KEY_ENTER, 10, ord(' '))
+
 def isScrollKey(key):
   """
   Returns true if the keycode is recognized by the getScrollPosition function
   for scrolling.
+  
+  Argument:
+    key - keycode to be checked
   """
   
   return key in SCROLL_KEYS



More information about the tor-commits mailing list