summaryrefslogtreecommitdiff
path: root/examples/pygtk-demo/demos/changedisplay.py
diff options
context:
space:
mode:
Diffstat (limited to 'examples/pygtk-demo/demos/changedisplay.py')
-rw-r--r--examples/pygtk-demo/demos/changedisplay.py413
1 files changed, 0 insertions, 413 deletions
diff --git a/examples/pygtk-demo/demos/changedisplay.py b/examples/pygtk-demo/demos/changedisplay.py
deleted file mode 100644
index e10fcee7..00000000
--- a/examples/pygtk-demo/demos/changedisplay.py
+++ /dev/null
@@ -1,413 +0,0 @@
-#!/usr/bin/env python
-'''Change Display
-
-Demonstrates migrating a window between different displays and
-screens. A display is a mouse and keyboard with some number of
-associated monitors. A screen is a set of monitors grouped
-into a single physical work area. The neat thing about having
-multiple displays is that they can be on a completely separate
-computers, as long as there is a network connection to the
-computer where the application is running.
-
-Only some of the windowing systems where GTK+ runs have the
-concept of multiple displays and screens. (The X Window System
-is the main example.) Other windowing systems can only
-handle one keyboard and mouse, and combine all monitors into
-a single screen.
-
-This is a moderately complex example, and demonstrates:
-
-- Tracking the currently open displays and screens
-- Changing the screen for a window
-- Letting the user choose a window by clicking on it
-- Using GtkListStore and GtkTreeView
-- Using GtkDialog
-'''
-import gtk
-import gobject
-
-# These enumerations provide symbolic names for the columns
-# in the two GtkListStore models.
-#
-(
- DISPLAY_COLUMN_NAME,
- DISPLAY_COLUMN_DISPLAY,
- DISPLAY_NUM_COLUMNS
-) = range(3)
-
-(
- SCREEN_COLUMN_NUMBER,
- SCREEN_COLUMN_SCREEN,
- SCREEN_NUM_COLUMNS
-) = range(3)
-
-def find_toplevel_at_pointer(display):
- ''' Finds the toplevel window under the mouse pointer, if any.
- '''
- pointer_window = display.get_window_at_pointer()[0]
-
- # The user data field of a GdkWindow is used to store a pointer
- # to the widget that created it.
- #
- if pointer_window:
- widget = pointer_window.get_user_data()
-
- return widget and widget.get_toplevel() or None
-
-class QueryForToplevel(gtk.Window):
- ''' Asks the user to click on a window, then waits for them click
- the mouse. When the mouse is released, returns the toplevel
- window under the pointer, or NULL, if there is none.
- '''
-
- def __init__(self, screen, prompt):
- gtk.Window.__init__(self, gtk.WINDOW_POPUP)
- self.set_screen(screen)
- self.set_modal(True)
- self.set_position(gtk.WIN_POS_CENTER)
-
- frame = gtk.Frame()
- frame.set_shadow_type(gtk.SHADOW_OUT)
- self.add(frame)
-
- label = gtk.Label(prompt)
- label.set_padding(10, 10)
- frame.add(label)
-
- self.show_all()
-
- def run(self):
- display = self.get_screen().get_display()
- cursor = gtk.gdk.Cursor(display, gtk.gdk.CROSSHAIR)
-
- main_context = gobject.main_context_default()
- if (gtk.gdk.pointer_grab(self.window, False,
- gtk.gdk.BUTTON_RELEASE_MASK, None, cursor) == gtk.gdk.GRAB_SUCCESS):
- self.query_clicked = False
- self.connect("button-release-event", self.button_release_event_cb)
-
- # Process events until clicked is set by button_release_event_cb.
- # We pass in may_block=True since we want to wait if there
- # are no events currently.
- #
- while self.query_clicked is False:
- main_context.iteration(True)
-
- toplevel = find_toplevel_at_pointer(display)
- if (toplevel == self):
- toplevel = None;
-
- self.destroy()
- gtk.gdk.flush() # Really release the grab
-
- return toplevel
-
- def button_release_event_cb(self, winref, event):
- self.query_clicked = True
- return True
-
-
-class LeftAlignButton(gtk.Button):
- ''' If we have a stack of buttons, it often looks better if their contents
- are left-aligned, rather than centered. This class creates a button
- and left-aligns it contents.
- '''
- def __init__(self, label):
- gtk.Button.__init__(self, label)
- child = self.get_children()[0]
- child.set_alignment(0., 0.5)
-
-
-# Main entry point. If the dialog for this demo doesn't yet exist, creates
-# it.
-#
-class ChangeDisplayDemo(gtk.Dialog):
- size_group = None
- display_model = None
- screen_model = None
- screen_selection = None
- current_display = None
- current_screen = None
-
- def __init__(self, parent=None):
- gtk.Dialog.__init__(self, "Change Screen or display", parent,
- gtk.DIALOG_NO_SEPARATOR,
- (gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE,
- "Change", gtk.RESPONSE_OK))
- self.set_default_size(300, 400)
-
- try:
- self.set_screen(parent.get_screen())
- except AttributeError:
- self.connect('destroy', lambda *w: gtk.main_quit())
- self.connect("response", self.response_cb)
- self.connect("destroy", self.destroy_cb)
-
- vbox = gtk.VBox(False, 5)
- vbox.set_border_width(8)
-
- self.vbox.pack_start(vbox, True, True, 0)
-
- frame = self.__create_display_frame()
- vbox.pack_start(frame, True, True, 0)
-
- frame = self.__create_screen_frame()
- vbox.pack_start(frame, True, True, 0)
-
- self.__initialize_displays()
-
- self.show_all()
-
- def __initialize_displays(self):
- ''' Adds all currently open displays to our list of displays,
- and set up a signal connection so that we'll be notified
- when displays are opened in the future as well.
- '''
- manager = gtk.gdk.display_manager_get()
- displays = manager.list_displays()
-
- for item in displays:
- self.add_display(item)
- id = manager.connect("display_opened", self.display_opened_cb)
- manager.set_data('user-callback', id)
-
- def __create_frame(self, title):
- ''' This function is used both for creating the "Display" and
- "Screen" frames, since they have a similar structure. The
- caller hooks up the right context for the value returned
- in tree_view, and packs any relevant buttons into button_vbox.
- '''
- frame = gtk.Frame(title)
-
- hbox = gtk.HBox(False, 8)
- hbox.set_border_width(8)
- frame.add(hbox)
-
- scrollwin = gtk.ScrolledWindow();
- scrollwin.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
- scrollwin.set_shadow_type (gtk.SHADOW_IN)
- hbox.pack_start(scrollwin, True, True, 0)
-
- tree_view = gtk.TreeView()
- tree_view.set_headers_visible(False)
- scrollwin.add(tree_view)
-
- selection = tree_view.get_selection()
- selection.set_mode(gtk.SELECTION_BROWSE)
-
- button_vbox = gtk.VBox(False, 5)
- hbox.pack_start(button_vbox, False, False, 0)
-
- if self.size_group is None:
- self.size_group = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL)
-
- self.size_group.add_widget(button_vbox)
-
- return (frame, tree_view, button_vbox)
-
-
- def __create_display_frame(self):
- ''' Creates the "Display" frame in the main window.
- '''
- frame, tree_view, button_vbox = self.__create_frame("Display")
-
- button = LeftAlignButton("_Open...")
- button.connect("clicked", self.open_display_cb)
- button_vbox.pack_start(button, False, False, 0)
-
- button = LeftAlignButton("_Close")
- button.connect ("clicked", self.close_display_cb)
- button_vbox.pack_start(button, False, False, 0)
-
- self.display_model = gtk.ListStore(str, object);
- tree_view.set_model(self.display_model)
-
- column = gtk.TreeViewColumn("Name", gtk.CellRendererText(),
- text=DISPLAY_COLUMN_NAME)
- tree_view.append_column(column)
-
- selection = tree_view.get_selection()
- selection.connect("changed", self.display_changed_cb)
-
- return frame
-
- def __create_screen_frame(self):
- ''' Creates the "Screen" frame in the main window.
- '''
- frame, tree_view, button_vbox = self.__create_frame("Screen")
-
- self.screen_model = gtk.ListStore(int, object);
- tree_view.set_model(self.screen_model)
-
- column = gtk.TreeViewColumn("Number", gtk.CellRendererText(),
- text=SCREEN_COLUMN_NUMBER)
- tree_view.append_column(column)
-
- self.screen_selection = tree_view.get_selection()
- self.screen_selection.connect("changed", self.screen_changed_cb)
-
- return frame
-
- def query_change_display(self):
- ''' Prompts the user for a toplevel window to move, and then moves
- that window to the currently selected display
- '''
- screen = self.window.get_screen()
-
- toplevel = QueryForToplevel(screen,
- "Please select the toplevel\nto move to the new screen").run()
-
- if toplevel is not None:
- toplevel.set_screen(self.current_screen)
- else:
- screen.get_display().beep()
-
-
- def response_cb(self, dialog, response_id):
- ''' Called when the user clicks on a button in our dialog or
- closes the dialog through the window manager. Unless the
- "Change" button was clicked, we destroy the dialog.
- '''
- if response_id == gtk.RESPONSE_OK:
- self.query_change_display()
- else:
- dialog.destroy()
-
- def open_display_cb(self, button):
- ''' Called when the user clicks on "Open..." in the display
- frame. Prompts for a new display, and then opens a connection
- to that display.
- '''
- dialog = gtk.Dialog("Open Display", self, gtk.DIALOG_MODAL,
- (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK))
-
- dialog.set_default_response(gtk.RESPONSE_OK)
- display_entry = gtk.Entry()
- display_entry.set_activates_default(True)
- dialog_label = gtk.Label("Please enter the name of\nthe new display\n")
-
- dialog.vbox.add(dialog_label)
- dialog.vbox.add(display_entry)
-
- display_entry.grab_focus()
- dialog.show_all()
-
- result = None
- while result is None:
- response_id = dialog.run()
- if response_id != gtk.RESPONSE_OK:
- break;
- new_screen_name = display_entry.get_chars(0, -1)
- print new_screen_name
- if new_screen_name != "":
- result = gtk.gdk.Display(new_screen_name)
- if result is None:
- error_msg = (
- "Can't open display :\n\t%s\nplease try another one\n" %
- (new_screen_name,))
- dialog_label.set_text(error_msg)
-
- dialog.destroy()
-
- def close_display_cb(self, button):
- ''' Called when the user clicks on the "Close" button in the
- "Display" frame. Closes the selected display.
- '''
- if self.current_display:
- self.current_display.close()
-
-
- def display_changed_cb(self, selection):
- ''' Called when the selected row in the display list changes.
- Updates info.current_display, then refills the list of
- screens.
- '''
- model, iter = selection.get_selected()
- if iter is not None:
- self.current_display = model.get_value(iter, DISPLAY_COLUMN_DISPLAY)
- else:
- self.current_display = None
- self.fill_screens()
-
- def screen_changed_cb(self, selection):
- ''' Called when the selected row in the sceen list changes.
- Updates info->current_screen.
- '''
- model, iter = selection.get_selected()
- if iter:
- self.current_screen = model.get(iter, SCREEN_COLUMN_SCREEN)
- else:
- self.current_screen = None;
-
- def destroy_cb(self, parent):
- self.destroy_info()
- if parent is None:
- gtk.main_quit()
-
-
- def fill_screens(self):
- ''' Fills in the screen list based on the current display
- '''
- self.screen_model.clear()
- if self.current_display is not None:
- n_screens = self.current_display.get_n_screens()
-
- for i in range(n_screens):
- screen = self.current_display.get_screen(i);
- iter = self.screen_model.append()
- self.screen_model.set(iter,
- SCREEN_COLUMN_NUMBER, i, SCREEN_COLUMN_SCREEN, screen)
- if (i == 0):
- self.screen_selection.select_iter(iter)
-
- def display_closed_cb(self, display, is_error, info):
- ''' Called when one of the currently open displays is closed.
- Remove it from our list of displays.
- '''
- iter = self.display_model.get_iter_first()
- while iter:
- tmp_display = self.display_model.get_value(iter, DISPLAY_COLUMN_DISPLAY)
- if (tmp_display == display):
- info.display_model.remove(iter)
- break;
- iter = info.display_model.iter_next()
-
- def add_display(self, display):
- ''' Adds a new display to our list of displays, and connects
- to the "closed" signal so that we can remove it from the
- list of displays again.
- '''
- name = display.get_name()
-
- iter = self.display_model.append()
- self.display_model.set(iter,
- DISPLAY_COLUMN_NAME, name, DISPLAY_COLUMN_DISPLAY, display)
- id = display.connect("closed", self.display_closed_cb)
- display.set_data('user-callback', id)
-
- def display_opened_cb(self, manager, display):
- ''' Called when a new display is opened
- '''
- self.add_display(display)
-
- def destroy_info(self):
- ''' Cleans up when the toplevel is destroyed; we remove the
- connections we use to track currently open displays.
- '''
- manager = gtk.gdk.display_manager_get()
- displays = manager.list_displays()
-
- id = manager.get_data('user-callback')
- manager.disconnect(id)
-
- for tmp_list in displays:
- id = tmp_list.get_data('user-callback')
- tmp_list.disconnect(id)
-
-
-def main():
- ChangeDisplayDemo()
- gtk.main()
-
-if __name__ == '__main__':
- main()