Lightningbeam/PyGUI-2.5.3/build/lib/GUI/GWindows.py

258 lines
7.0 KiB
Python

#
# Python GUI - Windows - Generic
#
import Exceptions
from GUI.Properties import overridable_property
from GUI import Container
from GUI import application
class Window(Container):
"""Top-level Container."""
menus = overridable_property('menus', "Menus to be available when this window is active.")
document = overridable_property('document', "Document with which this window is associated.")
title = overridable_property('title', "Title of the window.")
auto_position = overridable_property('auto_position', "Whether to position automatically when first shown.")
target = overridable_property('target', "Current target for key events and menu messages.")
tab_chain = overridable_property('tab_chain', "List of subcomponents in tabbing order.")
visible = overridable_property('visible', "Whether the window is currently shown.")
keeps_document_open = True
_default_width = 200
_default_height = 200
_modal_styles = ('modal_dialog', 'alert')
_dialog_styles = ('nonmodal_dialog', 'modal_dialog', 'alert')
_menus = []
_document = None
_closable = 0
_auto_position = True
_tab_chain = None
def __init__(self, style = 'standard', closable = None, **kwds):
if closable is None:
raise Exceptions.InternalError(
"'closable' parameter unspecified in call to generic Window.__init__")
Container.__init__(self, **kwds)
self._style = style
self._dialog_style = style.find('dialog') >= 0
self._closable = closable
application()._add_window(self)
def destroy(self):
"""Detaches the window from document and application and removes it
from the screen."""
self.set_document(None)
application()._remove_window(self)
Container.destroy(self)
#
# Message handling
#
def next_handler(self):
if self._document:
return self._document
else:
return application()
def dispatch(self, message, *args):
self.target.handle(message, *args)
#
# Menus
#
def get_menus(self):
return self._menus
def set_menus(self, x):
self._menus = x
#
# Document association
#
def get_document(self):
return self._document
def set_document(self, x):
if self._document != x:
if self._document:
self._document._windows.remove(self)
self._document = x
if self._document:
self._document._windows.append(self)
self.update_title()
#
# Title
#
def update_title(self):
"""Update the window's title after a change in its document's title."""
doc = self._document
if doc:
self.set_title(doc.title)
#
# Showing and Positioning
#
def get_auto_position(self):
return self._auto_position
def set_auto_position(self, v):
self._auto_position = v
def center(self):
"""Position the window in the centre of the screen."""
print "GWindow.center" ###
sl, st, sr, sb = self._screen_rect()
w, h = self.size
l = (sr - sl - w) // 2
t = (sb - st - h) // 2
self.position = (l, t)
def centre(self):
self.center()
def show(self):
if self._auto_position:
if self._style == 'standard':
self._stagger()
else:
self.center()
self._auto_position = False
self._show()
def _stagger(self):
pass
def _show(self):
self.visible = True
def hide(self):
self.visible = False
#
# Menu commands
#
def setup_menus(self, m):
Container.setup_menus(self, m)
app = application()
if self._closable:
m.close_cmd.enabled = 1
def close_cmd(self):
"""If this window is the only window belonging to a document
whose keeps_document_open attribute is true, then close the
document, else destroy the window."""
# app = application()
# if not app._may_close_a_window():
# #print "GWindow.close_cmd: Quitting the application" ###
# app.quit_cmd()
# else:
doc = self._document
n = 0
if doc:
for win in doc._windows:
if win is not self and win.keeps_document_open:
n += 1
if doc and n == 0:
doc.close_cmd()
else:
self.destroy()
#
# Tabbing
#
def get_tab_chain(self):
chain = self._tab_chain
if chain is None:
chain = []
self._build_tab_chain(chain)
self._tab_chain = chain
#print "Window.get_tab_chain:", chain ###
return chain
def _invalidate_tab_chain(self):
self._tab_chain = None
def _tab_to_next(self):
self._tab_to(1)
def _tab_to_prev(self):
self._tab_to(-1)
def _tab_to(self, direction):
#print "GWindow._tab_to:", direction ###
chain = self.tab_chain
if chain:
old_target = application().target
new_target = None
n = len(chain)
try:
i = chain.index(old_target)
except ValueError:
if direction > 0:
i = -1
else:
i = n
k = n
while k:
k -= 1
i = (i + direction) % n
comp = chain[i]
if comp._is_targetable():
new_target = comp
break
if new_target:
if old_target:
old_target._tab_out()
new_target._tab_in()
def key_down(self, event):
#print "GWindow.key_down:", event ###
if self._generic_tabbing and event.char == '\t':
#print "GWindow.key_down: doing generic tabbing" ###
if event.shift:
self._tab_to_prev()
else:
self._tab_to_next()
else:
Container.key_down(self, event)
# def _default_key_event(self, event):
# #print "GWindow._default_key_event" ###
# self.pass_event_to_next_handler(event)
#
# Other
#
def get_window(self):
return self
def first_dispatcher(self):
return self
def _document_needs_saving(self, state):
pass
def modal_event_loop(self):
"""Loop reading and handling events for the given window until
exit_event_loop() is called. Interaction with other windows is prevented
(although enabled application-wide menu commands can be used)."""
# Implementations can override this together with exit_modal_event_loop()
# to implement modal event loops in a different way.
application()._event_loop(self)
def exit_modal_event_loop(self):
# Cause the current call to modal_event_loop() to exit.
application()._exit_event_loop()