[tor-commits] [arm/master] Binding handlers for the graph submenu

atagar at torproject.org atagar at torproject.org
Sun Jun 12 21:09:40 UTC 2011


commit ea0b39251a9371cd81262bc360c644ab18acf1c8
Author: Damian Johnson <atagar at torproject.org>
Date:   Sun Jun 12 12:11:23 2011 -0700

    Binding handlers for the graph submenu
---
 src/cli/graphing/graphPanel.py |  121 ++++++++++++++++++++++++++++------------
 src/cli/menu/actions.py        |   75 +++++++++++++++++++------
 src/util/uiTools.py            |   10 ++-
 3 files changed, 150 insertions(+), 56 deletions(-)

diff --git a/src/cli/graphing/graphPanel.py b/src/cli/graphing/graphPanel.py
index 0207604..69b9121 100644
--- a/src/cli/graphing/graphPanel.py
+++ b/src/cli/graphing/graphPanel.py
@@ -239,6 +239,40 @@ class GraphPanel(panel.Panel):
     self.stats = {}               # available stats (mappings of label -> instance)
     self.setPauseAttr("stats")
   
+  def getUpdateInterval(self):
+    """
+    Provides the rate that we update the graph at.
+    """
+    
+    return self.updateInterval
+  
+  def setUpdateInterval(self, updateInterval):
+    """
+    Sets the rate that we update the graph at.
+    
+    Arguments:
+      updateInterval - update time enum
+    """
+    
+    self.updateInterval = updateInterval
+  
+  def getBoundsType(self):
+    """
+    Provides the type of graph bounds used.
+    """
+    
+    return self.bounds
+  
+  def setBoundsType(self, boundsType):
+    """
+    Sets the type of graph boundaries we use.
+    
+    Arguments:
+      boundsType - graph bounds enum
+    """
+    
+    self.bounds = boundsType
+  
   def getHeight(self):
     """
     Provides the height requested by the currently displayed GraphStats (zero
@@ -260,44 +294,54 @@ class GraphPanel(panel.Panel):
     
     self.graphHeight = max(MIN_GRAPH_HEIGHT, newGraphHeight)
   
+  def resizeGraph(self):
+    """
+    Prompts for user input to resize the graph panel. Options include...
+      down arrow - grow graph
+      up arrow - shrink graph
+      enter / space - set size
+    """
+    
+    control = cli.controller.getController()
+    
+    panel.CURSES_LOCK.acquire()
+    try:
+      while True:
+        # redraws the resized panels
+        displayPanels = control.getDisplayPanels()
+        
+        occupiedContent = 0
+        for panelImpl in displayPanels:
+          panelImpl.setTop(occupiedContent)
+          occupiedContent += panelImpl.getHeight()
+        
+        for panelImpl in displayPanels:
+          panelImpl.redraw(True)
+        
+        msg = "press the down/up to resize the graph, and enter when done"
+        control.setMsg(msg, curses.A_BOLD, True)
+        curses.cbreak()
+        key = control.getScreen().getch()
+        
+        if key == curses.KEY_DOWN:
+          # don't grow the graph if it's already consuming the whole display
+          # (plus an extra line for the graph/log gap)
+          maxHeight = self.parent.getmaxyx()[0] - self.top
+          currentHeight = self.getHeight()
+          
+          if currentHeight < maxHeight + 1:
+            self.setGraphHeight(self.graphHeight + 1)
+        elif key == curses.KEY_UP:
+          self.setGraphHeight(self.graphHeight - 1)
+        elif uiTools.isSelectionKey(key): break
+    finally:
+      control.setMsg()
+      panel.CURSES_LOCK.release()
+  
   def handleKey(self, key):
     isKeystrokeConsumed = True
     if key == ord('r') or key == ord('R'):
-      control = cli.controller.getController()
-      
-      panel.CURSES_LOCK.acquire()
-      try:
-        while True:
-          msg = "press the down/up to resize the graph, and enter when done"
-          control.setMsg(msg, curses.A_BOLD, True)
-          curses.cbreak()
-          key = control.getScreen().getch()
-          
-          if key == curses.KEY_DOWN:
-            # don't grow the graph if it's already consuming the whole display
-            # (plus an extra line for the graph/log gap)
-            maxHeight = self.parent.getmaxyx()[0] - self.top
-            currentHeight = self.getHeight()
-            
-            if currentHeight < maxHeight + 1:
-              self.setGraphHeight(self.graphHeight + 1)
-          elif key == curses.KEY_UP:
-            self.setGraphHeight(self.graphHeight - 1)
-          elif uiTools.isSelectionKey(key): break
-          
-          # redraws the resized panels
-          displayPanels = control.getDisplayPanels()
-          
-          occupiedContent = 0
-          for panelImpl in displayPanels:
-            panelImpl.setTop(occupiedContent)
-            occupiedContent += panelImpl.getHeight()
-          
-          for panelImpl in displayPanels:
-            panelImpl.redraw(True)
-      finally:
-        control.setMsg()
-        panel.CURSES_LOCK.release()
+      self.resizeGraph()
     elif key == ord('b') or key == ord('B'):
       # uses the next boundary type
       self.bounds = Bounds.next(self.bounds)
@@ -447,6 +491,13 @@ class GraphPanel(panel.Panel):
     stats._graphPanel = self
     self.stats[label] = stats
   
+  def getStats(self):
+    """
+    Provides the currently selected stats label.
+    """
+    
+    return self.currentDisplay
+  
   def setStats(self, label):
     """
     Sets the currently displayed stats instance, hiding panel if None.
diff --git a/src/cli/menu/actions.py b/src/cli/menu/actions.py
index f81a162..9d69cb4 100644
--- a/src/cli/menu/actions.py
+++ b/src/cli/menu/actions.py
@@ -6,6 +6,7 @@ import functools
 
 import cli.controller
 import cli.menu.item
+import cli.graphing.graphPanel
 
 from util import torTools, uiTools
 
@@ -18,6 +19,12 @@ def makeMenu():
   baseMenu.add(makeActionsMenu())
   baseMenu.add(makeViewMenu())
   
+  control = cli.controller.getController()
+  
+  for pagePanel in control.getDisplayPanels(includeSticky = False):
+    if pagePanel.getName() == "graph":
+      baseMenu.add(makeGraphMenu(pagePanel))
+  
   logsMenu = cli.menu.item.Submenu("Logs")
   logsMenu.add(cli.menu.item.MenuItem("Events", None))
   logsMenu.add(cli.menu.item.MenuItem("Clear", None))
@@ -30,23 +37,6 @@ def makeMenu():
   logsMenu.add(duplicatesSubmenu)
   baseMenu.add(logsMenu)
   
-  graphMenu = cli.menu.item.Submenu("Graph")
-  graphMenu.add(cli.menu.item.MenuItem("Stats", None))
-  
-  sizeSubmenu = cli.menu.item.Submenu("Size")
-  sizeSubmenu.add(cli.menu.item.MenuItem("Increase", None))
-  sizeSubmenu.add(cli.menu.item.MenuItem("Decrease", None))
-  graphMenu.add(sizeSubmenu)
-  
-  graphMenu.add(cli.menu.item.MenuItem("Update Interval", None))
-  
-  boundsSubmenu = cli.menu.item.Submenu("Bounds")
-  boundsSubmenu.add(cli.menu.item.MenuItem("Local Max", None))
-  boundsSubmenu.add(cli.menu.item.MenuItem("Global Max", None))
-  boundsSubmenu.add(cli.menu.item.MenuItem("Tight", None))
-  graphMenu.add(boundsSubmenu)
-  baseMenu.add(graphMenu)
-  
   connectionsMenu = cli.menu.item.Submenu("Connections")
   connectionsMenu.add(cli.menu.item.MenuItem("Identity", None))
   connectionsMenu.add(cli.menu.item.MenuItem("Resolver", None))
@@ -121,3 +111,54 @@ def makeViewMenu():
   
   return viewMenu
 
+def makeGraphMenu(graphPanel):
+  """
+  Submenu for the graph panel, consisting of...
+    [X] <Stat 1>
+    [ ] <Stat 2>
+    [ ] <Stat 2>
+        Resize
+        Interval (Submenu)
+        Bounds (Submenu)
+  
+  Arguments:
+    graphPanel - instance of the graph panel
+  """
+  
+  graphMenu = cli.menu.item.Submenu("Graph")
+  
+  # stats options
+  statGroup = cli.menu.item.SelectionGroup(graphPanel.setStats, graphPanel.getStats())
+  availableStats = graphPanel.stats.keys()
+  availableStats.sort()
+  
+  for statKey in ["None"] + availableStats:
+    label = uiTools.camelCase(statKey, divider = " ")
+    statKey = None if statKey == "None" else statKey
+    graphMenu.add(cli.menu.item.SelectionMenuItem(label, statGroup, statKey))
+  
+  # resizing option
+  graphMenu.add(cli.menu.item.MenuItem("Resize", graphPanel.resizeGraph))
+  
+  # interval submenu
+  intervalMenu = cli.menu.item.Submenu("Interval")
+  intervalGroup = cli.menu.item.SelectionGroup(graphPanel.setUpdateInterval, graphPanel.getUpdateInterval())
+  
+  for i in range(len(cli.graphing.graphPanel.UPDATE_INTERVALS)):
+    label = cli.graphing.graphPanel.UPDATE_INTERVALS[i][0]
+    label = uiTools.camelCase(label, divider = " ")
+    intervalMenu.add(cli.menu.item.SelectionMenuItem(label, intervalGroup, i))
+  
+  graphMenu.add(intervalMenu)
+  
+  # bounds submenu
+  boundsMenu = cli.menu.item.Submenu("Bounds")
+  boundsGroup = cli.menu.item.SelectionGroup(graphPanel.setBoundsType, graphPanel.getBoundsType())
+  
+  for boundsType in cli.graphing.graphPanel.Bounds.values():
+    boundsMenu.add(cli.menu.item.SelectionMenuItem(boundsType, boundsGroup, boundsType))
+  
+  graphMenu.add(boundsMenu)
+  
+  return graphMenu
+
diff --git a/src/util/uiTools.py b/src/util/uiTools.py
index 34d9210..5204960 100644
--- a/src/util/uiTools.py
+++ b/src/util/uiTools.py
@@ -272,23 +272,25 @@ def cropStr(msg, size, minWordLen = 4, minCrop = 0, endType = Ending.ELLIPSE, ge
   if getRemainder: return (returnMsg, remainder)
   else: return returnMsg
 
-def camelCase(label):
+def camelCase(label, divider = "_", joiner = " "):
   """
   Converts the given string to camel case, ie:
   >>> camelCase("I_LIKE_PEPPERJACK!")
   'I Like Pepperjack!'
   
   Arguments:
-    label - input string to be converted
+    label   - input string to be converted
+    divider - character to be used for word breaks
+    joiner  - character used to fill between word breaks
   """
   
   words = []
-  for entry in label.split("_"):
+  for entry in label.split(divider):
     if len(entry) == 0: words.append("")
     elif len(entry) == 1: words.append(entry.upper())
     else: words.append(entry[0].upper() + entry[1:].lower())
   
-  return " ".join(words)
+  return joiner.join(words)
 
 def drawBox(panel, top, left, width, height, attr=curses.A_NORMAL):
   """





More information about the tor-commits mailing list