Lightningbeam/PyGUI-2.5.3/GUI/Gtk/Window.py

264 lines
9.3 KiB
Python

#
# Python GUI - Windows - Gtk version
#
import sys
import gtk
from gtk import gdk
from GUI import export
from GUI import export
from GUI.GGeometry import sub_pt
from GUI import Component
from GUI import Container
from GUI import application
from GUI.GWindows import Window as GWindow
_default_width = 200
_default_height = 200
_modal_styles = ('modal_dialog', 'alert')
_dialog_styles = ('nonmodal_dialog', 'modal_dialog', 'alert')
class Window(GWindow):
#_pass_key_events_to_platform = False
_size = (_default_width, _default_height)
_gtk_menubar = None
_need_menubar_update = 0
_target = None
def __init__(self, style = 'standard', title = "New Window",
movable = 1, closable = 1, hidable = None, resizable = 1,
zoomable = 1, **kwds):
self._all_menus = []
modal = style in _modal_styles
if hidable is None:
hidable = not modal
self._resizable = resizable
gtk_win = gtk.Window(gtk.WINDOW_TOPLEVEL)
gtk_win.set_gravity(gdk.GRAVITY_STATIC)
gtk_win.set_decorated(style <> 'fullscreen'
and (movable or closable or hidable or zoomable))
gtk_win.set_resizable(resizable)
gtk_win.set_modal(style in _modal_styles)
gtk_content = gtk.Layout()
gtk_content.show()
if style in _dialog_styles:
gtk_win.set_type_hint(gdk.WINDOW_TYPE_HINT_DIALOG)
gtk_win.add(gtk_content)
else:
self._gtk_create_menubar()
gtk_box = gtk.VBox()
gtk_box.show()
gtk_box.pack_start(self._gtk_menubar, expand = 0, fill = 0)
gtk_box.pack_end(gtk_content, expand = 1, fill = 1)
gtk_win.add(gtk_box)
self._need_menubar_update = 1
self._gtk_connect(gtk_win, 'configure-event', self._gtk_configure_event)
self._gtk_connect(gtk_win, 'key-press-event', self._gtk_key_press_event)
self._gtk_connect(gtk_win, 'delete-event', self._gtk_delete_event)
GWindow.__init__(self, _gtk_outer = gtk_win, _gtk_inner = gtk_content,
_gtk_focus = gtk_content, _gtk_input = gtk_content,
style = style, title = title, closable = closable)
if style == 'fullscreen':
size = (gdk.screen_width(), gdk.screen_height())
else:
size = (_default_width, _default_height)
self.set_size(size)
self.set(**kwds)
self.become_target()
def _gtk_create_menubar(self):
gtk_menubar = gtk.MenuBar()
gtk_dummy_item = gtk.MenuItem("")
gtk_menubar.append(gtk_dummy_item)
gtk_menubar.show_all()
h = gtk_menubar.size_request()[1]
gtk_menubar.set_size_request(-1, h)
gtk_dummy_item.remove_submenu()
self._gtk_menubar = gtk_menubar
self._gtk_connect(gtk_menubar, 'button-press-event',
self._gtk_menubar_button_press_event)
def destroy(self):
self.hide()
GWindow.destroy(self)
def set_menus(self, x):
GWindow.set_menus(self, x)
self._need_menubar_update = 1
if self.visible:
self._gtk_update_menubar()
def get_title(self):
return self._gtk_outer_widget.get_title()
def set_title(self, new_title):
self._gtk_outer_widget.set_title(new_title)
def set_position(self, v):
self._position = v
self._gtk_outer_widget.move(*v)
def set_size(self, new_size):
w, h = new_size
if self._resizable:
h += self._gtk_menubar_height()
gtk_resize = self._gtk_outer_widget.resize
else:
gtk_resize = self._gtk_inner_widget.set_size_request
gtk_resize(max(w, 1), max(h, 1))
self._size = new_size
def _gtk_configure_event(self, gtk_event):
gtk_win = self._gtk_outer_widget
self._position = gtk_win.get_position()
#self._update_size(gtk_win.get_size())
w, h = gtk_win.get_size()
#w, h = self._gtk_inner_widget.get_size()
#w, h = self._gtk_inner_widget.size_request()
old_size = self._size
new_size = (w, h - self._gtk_menubar_height())
#new_size = (w, h)
#print "Window._gtk_configure_event:", old_size, "->", new_size ###
self._size = new_size
if old_size <> new_size:
self._resized(sub_pt(new_size, old_size))
def get_visible(self):
return self._gtk_outer_widget.get_property('visible')
def set_visible(self, new_v):
old_v = self.visible
self._gtk_outer_widget.set_property('visible', new_v)
if new_v and not old_v and self._need_menubar_update:
self._gtk_update_menubar()
def _show(self):
self.set_visible(1)
self._gtk_outer_widget.present()
# def key_down(self, event):
# if event.char == '\t':
# if event.shift:
# self._tab_to_prev()
# else:
# self._tab_to_next()
# else:
# self.pass_to_next_handler('key_down', event)
def get_target(self):
target = Component._gtk_find_component(self._gtk_outer_widget.get_focus())
return target or self
def _screen_rect(self):
w = gdk.screen_width()
h = gdk.screen_height()
return (0, 0, w, h)
def _gtk_menubar_height(self):
mb = self._gtk_menubar
if mb:
h = mb.size_request()[1]
else:
h = 0
#print "Window._gtk_menubar_height -->", h ###
return h
def _gtk_delete_event(self, event):
try:
self.close_cmd()
except:
sys.excepthook(*sys.exc_info())
return 1
def _gtk_update_menubar(self):
#
# Update the contents of the menubar after either the application
# menu list or this window's menu list has changed. We only add
# the menu titles at this stage; the menus themselves are attached
# during menu setup. We also attach the accel groups associated
# with the new menus.
#
# Things would be simpler if we could attach the menus here,
# but attempting to share menus between menubar items provokes
# a warning from Gtk, even though it otherwise appears to work.
#
gtk_menubar = self._gtk_menubar
gtk_window = self._gtk_outer_widget
# Remove old accel groups
for menu in self._all_menus:
gtk_window.remove_accel_group(menu._gtk_accel_group)
# Detach any existing menus and remove old menu titles
if gtk_menubar:
for gtk_menubar_item in gtk_menubar.get_children():
gtk_menubar_item.remove_submenu()
gtk_menubar_item.destroy()
# Install new menu list
#all_menus = application().menus + self.menus
all_menus = application()._effective_menus_for_window(self)
self._all_menus = all_menus
# Create new menu titles and attach accel groups
for menu in all_menus:
if gtk_menubar:
gtk_menubar_item = gtk.MenuItem(menu._title)
gtk_menubar_item.show()
gtk_menubar.append(gtk_menubar_item)
gtk_window.add_accel_group(menu._gtk_accel_group)
self._need_menubar_update = 0
def _gtk_menubar_button_press_event(self, event):
# A button press has occurred in the menu bar. Before pulling
# down the menu, perform menu setup and attach the menus to
# the menubar items.
self._gtk_menu_setup()
for (gtk_menubar_item, menu) in \
zip(self._gtk_menubar.get_children(), self._all_menus):
gtk_menu = menu._gtk_menu
attached_widget = gtk_menu.get_attach_widget()
if attached_widget and attached_widget is not gtk_menubar_item:
attached_widget.remove_submenu()
gtk_menubar_item.set_submenu(gtk_menu)
def _gtk_key_press_event(self, gtk_event):
# Intercept key presses with the Control key down and update
# menus, in case this is a keyboard equivalent for a menu command.
if gtk_event.state & gdk.CONTROL_MASK:
#print "Window._gtk_key_press_event: doing menu setup"
self._gtk_menu_setup()
# It appears that GtkWindow caches accelerators, and updates
# the cache in an idle task after accelerators change. This
# would be too late for us, so we force it to be done now.
self._gtk_outer_widget.emit("keys-changed")
#print "Window._gtk_key_press_event: done menu setup"
def _gtk_menu_setup(self):
application()._perform_menu_setup(self._all_menus)
def _default_key_event(self, event):
self.pass_event_to_next_handler(event)
if event._originator is self:
event._not_handled = True
def dispatch(self, message, *args):
self.target.handle(message, *args)
_gtk_menubar_height = None
def _gtk_find_menubar_height():
global _gtk_menubar_height
if _gtk_menubar_height is None:
print "Windows: Finding menubar height"
item = gtk.MenuItem("X")
bar = gtk.MenuBar()
bar.append(item)
bar.show_all()
w, h = bar.size_request()
_gtk_menubar_height = h
print "...done"
return _gtk_menubar_height
export(Window)