[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnue] r9378 - trunk/gnue-forms/src/uidrivers/curses/widgets
From: |
johannes |
Subject: |
[gnue] r9378 - trunk/gnue-forms/src/uidrivers/curses/widgets |
Date: |
Tue, 13 Feb 2007 10:02:15 -0600 (CST) |
Author: johannes
Date: 2007-02-13 10:02:14 -0600 (Tue, 13 Feb 2007)
New Revision: 9378
Added:
trunk/gnue-forms/src/uidrivers/curses/widgets/menu.py
trunk/gnue-forms/src/uidrivers/curses/widgets/menuitem.py
Modified:
trunk/gnue-forms/src/uidrivers/curses/widgets/form.py
trunk/gnue-forms/src/uidrivers/curses/widgets/page.py
Log:
Startet menu support for curses
Modified: trunk/gnue-forms/src/uidrivers/curses/widgets/form.py
===================================================================
--- trunk/gnue-forms/src/uidrivers/curses/widgets/form.py 2007-02-13
08:20:06 UTC (rev 9377)
+++ trunk/gnue-forms/src/uidrivers/curses/widgets/form.py 2007-02-13
16:02:14 UTC (rev 9378)
@@ -45,6 +45,8 @@
self.__pages = []
self.__currentPage = None
+ self.__main_menu = None
+ self.__close_in_progress = False
# Status bar values
self.__tip = ''
@@ -74,7 +76,15 @@
return self.__window is not None
+ # -------------------------------------------------------------------------
+ # Register an UIMenu instance as main menu
+ # -------------------------------------------------------------------------
+ def register_main_menu(self, menu):
+
+ self.__main_menu = menu
+
+
# -------------------------------------------------------------------------
# Set form title
# -------------------------------------------------------------------------
@@ -184,8 +194,19 @@
# -------------------------------------------------------------------------
def wait(self):
- return self.__currentPage.wait()
+ result = None
+ while result is None:
+ result = self.__currentPage.wait()
+ if result == curses.KEY_F10 and self.__main_menu is not None:
+ self.__main_menu.show(self.__currentPage)
+ result = None
+
+ if self.__close_in_progress:
+ break
+
+ return result
+
# -------------------------------------------------------------------------
# Get free area in the window
# -------------------------------------------------------------------------
@@ -270,7 +291,7 @@
def _ui_close_(self):
- pass
+ self.__close_in_progress = True
# -------------------------------------------------------------------------
# Create the window and fit all widgets into the available space
Added: trunk/gnue-forms/src/uidrivers/curses/widgets/menu.py
===================================================================
--- trunk/gnue-forms/src/uidrivers/curses/widgets/menu.py 2007-02-13
08:20:06 UTC (rev 9377)
+++ trunk/gnue-forms/src/uidrivers/curses/widgets/menu.py 2007-02-13
16:02:14 UTC (rev 9378)
@@ -0,0 +1,351 @@
+# GNU Enterprise Forms - Curses UI Driver - Menu Widget
+#
+# Copyright 2001-2007 Free Software Foundation
+#
+# This file is part of GNU Enterprise
+#
+# GNU Enterprise is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation; either
+# version 2, or (at your option) any later version.
+#
+# GNU Enterprise is distributed in the hope that it will be
+# useful, but WITHOUT ANY WARRANTY; without even the implied
+# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+# PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public
+# License along with program; see the file COPYING. If not,
+# write to the Free Software Foundation, Inc., 59 Temple Place
+# - Suite 330, Boston, MA 02111-1307, USA.
+#
+# $Id$
+
+import curses
+
+from gnue.forms.uidrivers.curses.widgets._base import UIHelper
+
+
+# =============================================================================
+# Wrap an UI layer around a wxMenu widget
+# =============================================================================
+
+class UIMenu(UIHelper):
+ """
+ Implements a menu object.
+ """
+
+ enough_space = True
+
+ # -------------------------------------------------------------------------
+ # Create a menu widget
+ # -------------------------------------------------------------------------
+
+ def _create_widget_(self, event, spacer):
+ """
+ Creates a new Menu widget.
+ """
+
+ if self._gfObject.name == '__main_menu__' \
+ and not self._form._features['GUI:MENUBAR:SUPPRESS']:
+ # Menu bar of the form
+ self._uiForm.register_main_menu(self)
+ else:
+ # Submenu or popup menu
+ if isinstance (event.container, UIMenu):
+ event.container.add_subitem(self)
+
+ self._container = self
+ self.__menu_items = []
+
+ return None
+
+
+ # -------------------------------------------------------------------------
+ # Add a sub item to the menu
+ # -------------------------------------------------------------------------
+
+ def add_subitem(self, item):
+
+ self.__menu_items.append(item)
+
+
+ # -------------------------------------------------------------------------
+ # Show this menu
+ # -------------------------------------------------------------------------
+
+ def show(self, page, offsx=0, offsy=0, run=True):
+
+ self.__page = page
+ self.__pattern = self.__get_pattern()
+ self.__sep_len = len(self.__pattern % {'text': '-', 'hotk': '-'})
+ self.__separator = curses.ACS_HLINE
+
+ self.__data = []
+ for item in self.__menu_items:
+ if item._gfObject.label:
+ add = self.__pattern % {'text': item._gfObject.label,
+ 'hotk': getattr(item._gfObject, 'hotkey', '')}
+ self.__data.append(' %s ' % add)
+ else:
+ self.__data.append(self.__separator)
+
+ # Figure out where to position the menu
+ ca_left, ca_top, ca_right, ca_bottom = self._uiForm.get_canvas()
+ if not offsx:
+ offsx = ca_left
+ if not offsy:
+ offsy = ca_top
+
+ maxy, maxx = ca_bottom, ca_right
+ if offsx + self.__sep_len + 4 < maxx:
+ self.left = offsx
+
+ elif offsx - self.__sep_len - 4 > 0:
+ self.left = offsx - self.__sep_len - 4
+
+ else:
+ self.left = 0
+
+ if offsy + len(self.__data) + 2 < maxy:
+ self.top = offsy
+
+ elif offsy - len(self.__data) - 2 > 0:
+ self.top = offsy - len(self.__data) - 2
+ else:
+ self.top = 0
+
+ self.width = min((self.__sep_len + 4), maxx - self.left)
+ self.height = min(len(self.__data) + 2, maxy - self.top)
+
+ self.offset = 0
+ self.selected = 0
+ self.display = 0
+
+ self.__draw_menu(run)
+
+ if run:
+ result = self.run()
+ else:
+ result = False
+
+ return result
+
+
+ # -------------------------------------------------------------------------
+
+ def __get_pattern(self):
+
+ ca_left, ca_top, ca_right, ca_bottom = self._uiForm.get_canvas()
+ # Take away the decoration of the menu
+ av_width = ca_right - ca_left - 4
+
+ text = []
+ hotk = []
+
+ for item in self.__menu_items:
+ add = item._gfObject.label or ''
+ text.append(add)
+ hotk.append(getattr(item._gfObject, 'hotkey', '') or '')
+
+ max_text = max([len(i) for i in text])
+ max_hotk = max([len(i) for i in hotk])
+
+ # Get the best width for this menu
+ best = max_text
+ if max_hotk:
+ best += 3 + max_hotk
+ patt = "%%(text)-%ds%%(hotk)%ds" % (max_text, max_hotk + 3)
+ else:
+ patt = "%%(text)-%ds" % max_text
+
+ if best <= av_width:
+ result = patt
+
+ # Does it help to reduce the gap between text and hotkey
+ elif max_hotk and best <= av_width - 2:
+ result = "%%(text)-%ds%%(hotk)%ds" % (max_text, max_hotk + 1)
+
+ # And if we use the text only
+ elif max_text <= av_width:
+ result = "%%(text)-%ds" % max_text
+
+ else:
+ result = "%%(text)-%ds" % av_width
+
+ return result
+
+
+ # -------------------------------------------------------------------------
+ # Draw the menu
+ # -------------------------------------------------------------------------
+
+ def __draw_menu(self, highlight):
+
+ self.__window = curses.newwin(self.height, self.width, self.top,
+ self.left)
+ self.__window.keypad(1)
+ self.__window.box()
+
+ self.__normal = self._uiDriver.attr['window 1']
+ self.__reverse = self._uiDriver.attr['focusentry']
+
+ count = self.height - 2
+ data = self.__data[self.offset:self.offset+count]
+ if len(data) < count:
+ data.extend([''] * (count - len(data)))
+
+ for row, value in enumerate(data):
+ if isinstance(value, basestring):
+ text = value.ljust(self.width - 2)[:self.width - 2]
+ attr = self.__normal
+ if highlight and row == self.display:
+ attr = self.__reverse
+ self.__window.addstr(1 + row, 1, o(text), attr)
+ else:
+ self.__window.hline(1 + row, 2, curses.ACS_HLINE, self.width-4)
+
+ self.__window.refresh()
+
+
+ # -------------------------------------------------------------------------
+ # Start an input loop for the menu
+ # -------------------------------------------------------------------------
+
+ def run(self):
+
+ old = curses.curs_set(0)
+ previous = None
+
+ try:
+ while True:
+ result = True
+ if isinstance(self.__menu_items[self.selected], UIMenu):
+ previous = self.__menu_items[self.selected]
+ self.__step_down(previous, False)
+
+ key = self.__window.getch()
+ current = self.__menu_items[self.selected]
+
+ if key == 27:
+ break
+
+ if key in [curses.KEY_UP, curses.KEY_DOWN]:
+ if previous is not None:
+ self.__update_to_current()
+
+ self.__move([1, -1][key == curses.KEY_UP])
+ key = None
+
+ elif key in [curses.KEY_RIGHT, curses.KEY_ENTER, 10]:
+
+ if isinstance(current, UIMenu):
+ quit = self.__step_down(current, True)
+ if quit:
+ break
+
+ elif key != curses.KEY_RIGHT:
+ current._gfObject._event_fire()
+ break
+
+ elif key == curses.KEY_LEFT:
+ result = False
+ break
+
+ self.__draw_menu(True)
+
+ finally:
+ curses.curs_set(old)
+ return result
+
+
+
+ # -------------------------------------------------------------------------
+ # Repaint all parent menus
+ # -------------------------------------------------------------------------
+
+ def __update_to_current(self):
+
+ self.__page.repaint(False)
+
+ level = self
+ while isinstance(level, UIMenu):
+ level.repaint()
+ level = level.getParent()
+
+ curses.doupdate()
+
+
+ # -------------------------------------------------------------------------
+ # Show and optionally run a submenu
+ # -------------------------------------------------------------------------
+
+ def __step_down(self, destination, run):
+
+ offsx = self.left + self.width - 1
+ offsy = self.top + self.selected + 1
+ return destination.show(self.__page, offsx, offsy, run)
+
+
+ # -------------------------------------------------------------------------
+ # Move the selected item
+ # -------------------------------------------------------------------------
+
+ def __move(self, direction):
+
+ movement = self.__get_next(direction)
+ self.display += movement
+ self.selected += movement
+
+ if self.display >= self.height - 2:
+ if self.selected < len(self.__data):
+ self.offset += movement
+
+ elif self.display < 0:
+ self.offset = max(0, self.offset - 1)
+
+ self.selected = max(0, self.selected)
+ self.selected = min(len(self.__data) - 1, self.selected)
+
+ self.display = max(0, self.display)
+ self.display = min(self.display, self.height-3)
+
+
+ # -------------------------------------------------------------------------
+ # Get the next usable menu-item (skipping separators)
+ # -------------------------------------------------------------------------
+
+ def __get_next(self, direction):
+
+ if direction > 0:
+ next = self.__data[self.selected+1:]
+ else:
+ next = self.__data[:self.selected]
+ next.reverse()
+
+ for add, item in enumerate(next):
+ if item != self.__separator:
+ res = direction * (add + 1)
+ return res
+
+ return 0
+
+
+ # -------------------------------------------------------------------------
+ # Repaint the menu
+ # -------------------------------------------------------------------------
+
+ def repaint(self):
+
+ self.__draw_menu(False)
+
+
+# =============================================================================
+# Configuration data
+# =============================================================================
+
+configuration = {
+ 'baseClass': UIMenu,
+ 'provides' : 'GFMenu',
+ 'container': 1,
+}
Property changes on: trunk/gnue-forms/src/uidrivers/curses/widgets/menu.py
___________________________________________________________________
Name: svn:keywords
+ Id
Added: trunk/gnue-forms/src/uidrivers/curses/widgets/menuitem.py
===================================================================
--- trunk/gnue-forms/src/uidrivers/curses/widgets/menuitem.py 2007-02-13
08:20:06 UTC (rev 9377)
+++ trunk/gnue-forms/src/uidrivers/curses/widgets/menuitem.py 2007-02-13
16:02:14 UTC (rev 9378)
@@ -0,0 +1,99 @@
+# GNU Enterprise Forms - Curses UI Driver - MenuItem Widget
+#
+# Copyright 2001-2007 Free Software Foundation
+#
+# This file is part of GNU Enterprise
+#
+# GNU Enterprise is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation; either
+# version 2, or (at your option) any later version.
+#
+# GNU Enterprise is distributed in the hope that it will be
+# useful, but WITHOUT ANY WARRANTY; without even the implied
+# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+# PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public
+# License along with program; see the file COPYING. If not,
+# write to the Free Software Foundation, Inc., 59 Temple Place
+# - Suite 330, Boston, MA 02111-1307, USA.
+#
+# $Id$
+
+from gnue.forms.uidrivers.curses.widgets._base import UIHelper
+
+
+# =============================================================================
+# Wrap an UI layer around a wxMenu widget
+# =============================================================================
+
+class UIMenuItem(UIHelper):
+ """
+ Implements a menu item object.
+ """
+
+ # -------------------------------------------------------------------------
+ # Create a menu item widget
+ # -------------------------------------------------------------------------
+
+ def _create_widget_(self, event, spacer):
+ """
+ Creates a new MenuItem widget.
+ """
+
+ # These are the relevant parameters
+ label = self._gfObject.label
+ description = self._gfObject.description
+ hotkey = self._gfObject.hotkey
+ check = (self._gfObject.action_off is not None)
+
+ if label is not None:
+ if hotkey is not None:
+ text = label + u"\t" + hotkey
+ else:
+ text = label
+
+ event.container.add_subitem(self)
+
+ return None
+
+
+ # -------------------------------------------------------------------------
+ # Check/uncheck menu item
+ # -------------------------------------------------------------------------
+
+ def _ui_switch_on_(self):
+ # TODO: need implementation
+ return
+
+ # -------------------------------------------------------------------------
+
+ def _ui_switch_off_(self):
+ # TODO: need implementation
+ return
+
+ # -------------------------------------------------------------------------
+ # Enable/disable menu item
+ # -------------------------------------------------------------------------
+
+ def _ui_enable_(self):
+ # TODO: need implementation
+ return
+
+ # -------------------------------------------------------------------------
+
+ def _ui_disable_(self):
+ # TODO: need implmementation
+ return
+
+
+# =============================================================================
+# Configuration data
+# =============================================================================
+
+configuration = {
+ 'baseClass': UIMenuItem,
+ 'provides' : 'GFMenuItem',
+ 'container': False
+}
Property changes on: trunk/gnue-forms/src/uidrivers/curses/widgets/menuitem.py
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: trunk/gnue-forms/src/uidrivers/curses/widgets/page.py
===================================================================
--- trunk/gnue-forms/src/uidrivers/curses/widgets/page.py 2007-02-13
08:20:06 UTC (rev 9377)
+++ trunk/gnue-forms/src/uidrivers/curses/widgets/page.py 2007-02-13
16:02:14 UTC (rev 9378)
@@ -160,8 +160,27 @@
return self.__get_key()
+
# -------------------------------------------------------------------------
+ # Repaint this page
+ # -------------------------------------------------------------------------
+ def repaint(self, immediate=True):
+
+ try:
+ if immediate:
+ self.__window.refresh(0, 0, self.top, self.left, self.bottom,
+ self.right)
+ else:
+ self.__window.noutrefresh(0, 0, self.top, self.left,
+ self.bottom, self.right)
+
+ except curses.error:
+ pass
+
+
+ # -------------------------------------------------------------------------
+
def __get_next_key(self):
# In nodelay mode the result of getch() is -1 if there is no input.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnue] r9378 - trunk/gnue-forms/src/uidrivers/curses/widgets,
johannes <=