[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [arm/master] Initial commit for the menu code. Currently displays a top-bar in a
commit 5fd9b5f74a86eb7e641366ae1c0a1a47404cf873
Author: Kamran Riaz Khan <krkhan@xxxxxxxxxxxxxx>
Date: Fri May 27 18:01:25 2011 +0500
Initial commit for the menu code. Currently displays a top-bar in a
popup and dispatches the menu entry to the callback function, which
shall later on be used to determine the panel/key combination for
taking specified action.
---
src/cli/controller.py | 18 +++++++-
src/cli/menu.py | 99 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 114 insertions(+), 3 deletions(-)
diff --git a/src/cli/controller.py b/src/cli/controller.py
index e94f7f6..c506302 100644
--- a/src/cli/controller.py
+++ b/src/cli/controller.py
@@ -17,6 +17,7 @@ import cli.graphing.bandwidthStats
import cli.graphing.connStats
import cli.graphing.resourceStats
import cli.connections.connPanel
+import cli.menu
from util import connections, conf, enum, log, panel, sysTools, torConfig, torTools
@@ -76,8 +77,11 @@ def initController(stdscr, startTime):
# fourth page: torrc
pagePanels.append([cli.torrcPanel.TorrcPanel(stdscr, cli.torrcPanel.Config.TORRC, config)])
+ # top menu
+ menu = cli.menu.Menu()
+
# initializes the controller
- ARM_CONTROLLER = Controller(stdscr, stickyPanels, pagePanels)
+ ARM_CONTROLLER = Controller(stdscr, stickyPanels, pagePanels, menu)
# additional configuration for the graph panel
graphPanel = ARM_CONTROLLER.getPanel("graph")
@@ -131,7 +135,7 @@ class Controller:
Tracks the global state of the interface
"""
- def __init__(self, stdscr, stickyPanels, pagePanels):
+ def __init__(self, stdscr, stickyPanels, pagePanels, menu):
"""
Creates a new controller instance. Panel lists are ordered as they appear,
top to bottom on the page.
@@ -140,11 +144,13 @@ class Controller:
stdscr - curses window
stickyPanels - panels shown at the top of each page
pagePanels - list of pages, each being a list of the panels on it
+ menu - popup drop-down menu
"""
self._screen = stdscr
self._stickyPanels = stickyPanels
self._pagePanels = pagePanels
+ self._menu = menu
self._page = 0
self._isPaused = False
self._forceRedraw = False
@@ -182,6 +188,9 @@ class Controller:
self._forceRedraw = True
self.setMsg()
+ def getMenu(self):
+ return self._menu
+
def isPaused(self):
"""
True if the interface is paused, false otherwise.
@@ -299,7 +308,7 @@ class Controller:
if attr == None:
if not self._isPaused:
- msg = "page %i / %i - q: quit, p: pause, h: page help" % (self._page + 1, len(self._pagePanels))
+ msg = "page %i / %i - m: menu, q: quit, p: pause, h: page help" % (self._page + 1, len(self._pagePanels))
attr = curses.A_NORMAL
else:
msg = "Paused"
@@ -507,6 +516,9 @@ def drawTorMonitor(stdscr, startTime):
control.prevPage()
elif key == ord('p') or key == ord('P'):
control.setPaused(not control.isPaused())
+ elif key == ord('m') or key == ord('M'):
+ menu = control.getMenu()
+ menu.draw()
elif key == ord('q') or key == ord('Q'):
# provides prompt to confirm that arm should exit
if CONFIG["features.confirmQuit"]:
diff --git a/src/cli/menu.py b/src/cli/menu.py
new file mode 100644
index 0000000..315d349
--- /dev/null
+++ b/src/cli/menu.py
@@ -0,0 +1,99 @@
+"""
+A drop-down menu for sending actions to panels.
+"""
+
+import curses
+from collections import namedtuple
+from operator import attrgetter
+
+import cli.controller
+import popups
+from util import log, panel, uiTools
+
+LeafEntry = namedtuple('LeafEntry', ['title', 'callback'])
+ParentEntry = namedtuple('ParentEntry', ['title', 'children'])
+
+class Menu():
+ """Displays a popup menu and sends keys to appropriate panels"""
+
+ def __init__(self, entry=None):
+ DEFAULT_ROOT = ParentEntry(title="Root", children=(
+ LeafEntry(title="File" , callback=self._callbackDefault),
+ LeafEntry(title="Logs" , callback=self._callbackDefault),
+ LeafEntry(title="View" , callback=self._callbackDefault),
+ LeafEntry(title="Graph" , callback=self._callbackDefault),
+ LeafEntry(title="Connections" , callback=self._callbackDefault),
+ LeafEntry(title="Configuration" , callback=self._callbackDefault)))
+
+ self._selection = [0]
+ self._rootEntry = (entry and isinstance(entry, ParentEntry)) and entry or DEFAULT_ROOT
+
+ def draw(self):
+ popup, width, height = popups.init(height=3)
+ if popup:
+ try:
+ popup.win.box()
+
+ while True:
+ self._drawTopLevel(popup, width, height)
+
+ popup.win.refresh()
+
+ control = cli.controller.getController()
+ key = control.getScreen().getch()
+
+ if key == curses.KEY_RIGHT:
+ if len(self._selection) == 1:
+ # selection is on top menu
+ self._selection[0] = (self._selection[0] + 1) % len(self._rootEntry.children)
+ elif key == curses.KEY_LEFT:
+ if len(self._selection) == 1:
+ # selection is on top menu
+ self._selection[0] = (self._selection[0] - 1) % len(self._rootEntry.children)
+ elif uiTools.isSelectionKey(key):
+ self._handleEvent()
+ break
+
+ finally:
+ popups.finalize()
+
+ def _drawTopLevel(self, popup, width, height):
+ titles = map(attrgetter('title'), self._rootEntry.children)
+
+ # width per title is set according to the longest title
+ titlewidth = max(map(lambda title: len(title), titles)) + 2
+
+ # total number of titles that can be printed in current width
+ printable = (width - 2) / titlewidth
+
+ top = 1
+ left = 1
+ for (index, entry) in enumerate(self._rootEntry.children[:printable]):
+ titleformat = curses.A_NORMAL
+
+ if index == self._selection[0]:
+ titleformat = curses.A_STANDOUT
+
+ popup.win.addch(top, left, curses.ACS_VLINE)
+ left = left + 1
+ popup.win.addstr(top, left, entry.title.center(titlewidth), titleformat)
+ left = left + titlewidth
+
+ popup.win.addch(top, left, curses.ACS_VLINE)
+ left = left + 1
+
+ def _handleEvent(self):
+ entry = self._rootEntry
+
+ for index in self._selection:
+ if isinstance(entry, ParentEntry):
+ entry = entry.children[index]
+ else:
+ break
+
+ if isinstance(entry, LeafEntry):
+ entry.callback(entry)
+
+ def _callbackDefault(self, entry):
+ log.log(log.NOTICE, "%s selected" % entry.title)
+
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits