commit ea0b39251a9371cd81262bc360c644ab18acf1c8 Author: Damian Johnson atagar@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): """
tor-commits@lists.torproject.org