def show_variables_window(self): """ Show the variables window. """ if self.var_window is None and self.bot._vars: self.var_window = VarWindow(self, self.bot, '%s variables' % (self.title or 'Shoebot')) self.var_window.window.connect("destroy", self.var_window_closed)
def show_variables_window(self): ''' If bot has variables and var window not visible then create it ''' if self.var_window is None and self.bot._vars: self.var_window = VarWindow(self, self.bot, '%s variables' % (self.title or 'Shoebot')) self.var_window.window.connect("destroy", self.var_window_closed)
def rendering_finished(self, size, frame, cairo_ctx): ''' Delegates to the ShoebotWidget ''' ## A bit hacky... but makes sure bot has executed once: if self.show_vars and self.var_window is None: self.var_window = VarWindow(self, self.bot) return self.sb_widget.rendering_finished(size, frame, cairo_ctx)
class ShoebotWindow(Gtk.Window, GtkInputDeviceMixin, DrawQueueSink): """ Create a GTK+ window that contains a ShoebotWidget """ # Draw in response to an expose-event def __init__(self, title=None, show_vars=False, menu_enabled=True, server=False, port=7777, fullscreen=False): Gtk.Window.__init__(self) DrawQueueSink.__init__(self) GtkInputDeviceMixin.__init__(self) if os.path.isfile(ICON_FILE): self.set_icon_from_file(ICON_FILE) self.menu_enabled = menu_enabled self.has_server = server self.serverport = port self.show_vars = show_vars self.var_window = None self.is_fullscreen = False sb_widget = ShoebotWidget(input_device=self) self.title = title if title: self.set_title(title) if fullscreen: self.is_fullscreen = True self.fullscreen() self.connect("delete-event", self.do_window_close) self.sb_widget = sb_widget self.attach_gtk(self) self.uimanager = Gtk.UIManager() accelgroup = self.uimanager.get_accel_group() self.add_accel_group(accelgroup) self.action_group = Gtk.ActionGroup('Canvas') self.action_group.add_actions([ ('Save as', None, _('_Save as')), ('svg', 'Save as SVG', _('Save as _SVG'), "<Control>1", None, self.snapshot_svg), ('pdf', 'Save as PDF', _('Save as _PDF'), "<Control>2", None, self.snapshot_pdf), ('ps', 'Save as PS', _('Save as P_S'), "<Control>3", None, self.snapshot_ps), ('png', 'Save as PNG', _('Save as P_NG'), "<Control>4", None, self.snapshot_png), ('close', 'Close window', _('_Close Window'), "<Control>w", None, self.do_window_close) ]) self.action_group.add_toggle_actions([ ('vars', 'Variables Window', _('Va_riables Window'), "<Control>r", None, self.do_toggle_variables, self.show_vars), ('fullscreen', 'Fullscreen', _('_Fullscreen'), "<Control>f", None, self.do_toggle_fullscreen, False), ('play', 'Play', _('_Play'), "<Alt>p", None, self.do_toggle_play, True), ]) menuxml = ''' <popup action="Save as"> <menuitem action="play"/> <menuitem action="vars"/> <menuitem action="fullscreen"/> <separator/> <menuitem action="svg"/> <menuitem action="ps"/> <menuitem action="pdf"/> <menuitem action="png"/> <separator/> <separator/> <menuitem action="close"/> </popup> ''' self.uimanager.insert_action_group(self.action_group, 0) self.uimanager.add_ui_from_string(menuxml) sb_widget.show() self.add(sb_widget) self.present() self.scheduled_snapshots = deque() while Gtk.events_pending(): Gtk.main_iteration() self.window_open = True self.pause_speed = None # TODO - factor out bot controller stuff self.last_draw_ctx = None # Need this to save snapshots after frame is drawn def gtk_mouse_button_down(self, widget, event): ''' Handle right mouse button clicks ''' if self.menu_enabled and event.button == 3: menu = self.uimanager.get_widget('/Save as') menu.popup(None, None, None, None, event.button, event.time) else: super(ShoebotWindow, self).gtk_mouse_button_down(widget, event) def render(self, size, frame, drawqueue): cairo_ctx = super(self.__class__, self).render(size, frame, drawqueue) self.last_draw_ctx = cairo_ctx self.sb_widget.do_drawing(size, frame, cairo_ctx) def create_rcontext(self, size, frame): """ Delegates to the sb_widget """ return self.sb_widget.create_rcontext(size, frame) def show_variables_window(self): """ Show the variables window. """ if self.var_window is None and self.bot._vars: self.var_window = VarWindow( self, self.bot, '%s variables' % (self.title or 'Shoebot')) self.var_window.window.connect("destroy", self.var_window_closed) def hide_variables_window(self): """ Hide the variables window """ if self.var_window is not None: self.var_window.window.destroy() self.var_window = None def var_window_closed(self, widget): """ Called if user clicked close button on var window :param widget: :return: """ # TODO - Clean up the menu handling stuff its a bit spagetti right now self.action_group.get_action('vars').set_active(False) self.show_vars = False self.var_window = None def var_changed(self, name, value): self.bot._namespace[name] = value if self.var_window: return self.var_window.update_var(name, value) else: v = self.bot._vars[name] publish_event(VARIABLE_UPDATED_EVENT, v) return True, value def schedule_snapshot(self, format): """ Tell the canvas to perform a snapshot when it's finished rendering :param format: :return: """ bot = self.bot canvas = self.bot.canvas script = bot._namespace['__file__'] if script: filename = os.path.splitext(script)[0] + '.' + format else: filename = 'output.' + format f = canvas.output_closure(filename, self.bot._frame) self.scheduled_snapshots.append(f) def snapshot_svg(self, widget): """ Save an SVG file after drawing is complete. """ self.schedule_snapshot('svg') def snapshot_ps(self, widget): """ Save an Postscript file after drawing is complete. """ self.schedule_snapshot('ps') def snapshot_pdf(self, widget): """ Save a PDF file after drawing is complete. """ self.schedule_snapshot('pdf') def snapshot_png(self, widget): """ Save an PNG file after drawing is complete. """ self.schedule_snapshot('png') def trigger_fullscreen_action(self, fullscreen): """ Toggle fullscreen from outside the GUI, causes the GUI to updated and run all its actions. """ action = self.action_group.get_action('fullscreen') action.set_active(fullscreen) def do_fullscreen(self, widget): """ Widget Action to Make the window fullscreen and update the bot. """ self.fullscreen() self.is_fullscreen = True # next lines seem to be needed for window switching really to # fullscreen mode before reading it's size values while Gtk.events_pending(): Gtk.main_iteration() # we pass informations on full-screen size to bot self.bot._screen_width = Gdk.Screen.width() self.bot._screen_height = Gdk.Screen.height() self.bot._screen_ratio = self.bot._screen_width / self.bot._screen_height def do_unfullscreen(self, widget): """ Widget Action to set Windowed Mode. """ self.unfullscreen() self.is_fullscreen = False self.bot._screen_ratio = None def do_window_close(self, widget, data=None): """ Widget Action to Close the window, triggering the quit event. """ publish_event(QUIT_EVENT) if self.has_server: self.sock.close() self.hide_variables_window() self.destroy() self.window_open = False def do_toggle_fullscreen(self, action): """ Widget Action to Toggle fullscreen from the GUI """ is_fullscreen = action.get_active() if is_fullscreen: self.fullscreen() else: self.unfullscreen() def do_toggle_play(self, action): """ Widget Action to toggle play / pause. """ # TODO - move this into bot controller # along with stuff in socketserver and shell if self.pause_speed is None and not action.get_active(): self.pause_speed = self.bot._speed self.bot._speed = 0 else: self.bot._speed = self.pause_speed self.pause_speed = None def do_toggle_variables(self, action): """ Widget Action to toggle showing the variables window. """ self.show_vars = action.get_active() if self.show_vars: self.show_variables_window() else: self.hide_variables_window() def main_iteration(self): """ Called from main loop, if your sink needs to handle GUI events do it here. Check any GUI flags then call Gtk.main_iteration to update things. """ if self.show_vars: self.show_variables_window() else: self.hide_variables_window() for snapshot_f in self.scheduled_snapshots: fn = snapshot_f(self.last_draw_ctx) print(("Saved snapshot: %s" % fn)) else: self.scheduled_snapshots = deque() while Gtk.events_pending(): Gtk.main_iteration()
class ShoebotWindow(Gtk.Window, GtkInputDeviceMixin, DrawQueueSink): """ Create a GTK+ window that contains a ShoebotWidget """ # Draw in response to an expose-event def __init__( self, title=None, show_vars=False, menu_enabled=True, server=False, port=7777, fullscreen=False, outputfile=None, ): Gtk.Window.__init__(self) DrawQueueSink.__init__(self) GtkInputDeviceMixin.__init__(self) if os.path.isfile(ICON_FILE): self.set_icon_from_file(ICON_FILE) self.menu_enabled = menu_enabled self.has_server = server self.serverport = port self.show_vars = show_vars self.var_window = None self.is_fullscreen = False sb_widget = ShoebotWidget(input_device=self) self.title = title if title: self.set_title(title) if fullscreen: self.is_fullscreen = True self.fullscreen() self.connect("delete-event", self.do_window_close) self.sb_widget = sb_widget self.attach_gtk(self) self.uimanager = Gtk.UIManager() accelgroup = self.uimanager.get_accel_group() self.add_accel_group(accelgroup) self.action_group = Gtk.ActionGroup(name="Canvas") self.action_group.add_actions([ ("Save as", None, _("_Save as")), ( "svg", "Save as SVG", _("Save as _SVG"), "<Control>1", None, self.snapshot_svg, ), ( "pdf", "Save as PDF", _("Save as _PDF"), "<Control>2", None, self.snapshot_pdf, ), ( "ps", "Save as PS", _("Save as P_S"), "<Control>3", None, self.snapshot_ps, ), ( "png", "Save as PNG", _("Save as P_NG"), "<Control>4", None, self.snapshot_png, ), ( "close", "Close window", _("_Close Window"), "<Control>w", None, self.do_window_close, ), ]) self.action_group.add_toggle_actions([ ( "vars", "Variables Window", _("Va_riables Window"), "<Control>r", None, self.do_toggle_variables, self.show_vars, ), ( "fullscreen", "Fullscreen", _("_Fullscreen"), "<Control>f", None, self.do_toggle_fullscreen, False, ), ("play", "Play", _("_Play"), "<Alt>p", None, self.do_toggle_play, True), ]) menuxml = """ <popup action="Save as"> <menuitem action="play"/> <menuitem action="vars"/> <menuitem action="fullscreen"/> <separator/> <menuitem action="svg"/> <menuitem action="ps"/> <menuitem action="pdf"/> <menuitem action="png"/> <separator/> <separator/> <menuitem action="close"/> </popup> """ self.uimanager.insert_action_group(self.action_group, 0) self.uimanager.add_ui_from_string(menuxml) sb_widget.show() self.add(sb_widget) self.present() self.pending_snapshots = [ ] # list of filenames to save after rendering. if outputfile: # The test harness uses this to get the gui to output an image, otherwise it may not make much sense # to have an output file with a GUI window ? self.pending_snapshots.append(outputfile) while Gtk.events_pending(): Gtk.main_iteration() self.window_open = True self.pause_speed = None # TODO - factor out bot controller stuff def gtk_mouse_button_down(self, widget, event): """ Handle right mouse button clicks """ if self.menu_enabled and event.button == 3: menu = self.uimanager.get_widget("/Save as") menu.popup(None, None, None, None, event.button, event.time) else: super(ShoebotWindow, self).gtk_mouse_button_down(widget, event) def render(self, size, frame, drawqueue): cairo_ctx = super(self.__class__, self).render(size, frame, drawqueue) self.sb_widget.do_drawing(size, frame, cairo_ctx) def rendering_finished(self, size, frame, r_context): """ Save any snapshots that were scheduled from the GUI :param size: width, height :param frame: frame number :param r_context: cairo context """ canvas = self.bot.canvas pending_snapshots = self.pending_snapshots for filename in pending_snapshots: # TODO, show filename in the GUI. print(f"Save snapshot: {filename}", file=sys.stderr) # TODO - remove many of these closures. f = canvas.output_closure(filename) f(r_context) super().rendering_finished(size, frame, r_context) self.pending_snapshots = [] def create_rcontext(self, size, frame): """ Delegates to the sb_widget """ return self.sb_widget.create_rcontext(size, frame) def show_variables_window(self): """ Show the variables window. """ if self.var_window is None and self.bot._vars: self.var_window = VarWindow( self, self.bot, "%s variables" % (self.title or "Shoebot")) self.var_window.window.connect("destroy", self.var_window_closed) def hide_variables_window(self): """ Hide the variables window """ if self.var_window is not None: self.var_window.window.destroy() self.var_window = None def var_window_closed(self, widget): """ Called if user clicked close button on var window :param widget: :return: """ # TODO - Clean up the menu handling stuff its a bit spaghetti right now self.action_group.get_action("vars").set_active(False) self.show_vars = False self.var_window = None def var_changed(self, name, value): self.bot._namespace[name] = value if self.var_window: return self.var_window.update_var(name, value) else: v = self.bot._vars[name] publish_event(VARIABLE_CHANGED_EVENT, v) return True, value def output_image_filename(self, format): """ :param format: Format, e.g. svg, pdf, png :return: Full image filename, based on bot name """ script = self.bot._namespace["__file__"] frame = self.bot._namespace["ITERATION"] if script: return f"{Path(script).stem}-{frame:04}.{format}" return f"output.{format}" def snapshot_svg(self, widget): """ Request to save an SVG file after drawing is complete. """ self.pending_snapshots.append(self.output_image_filename("svg")) publish_event(REDRAW_EVENT, data=(None, None)) # TODO - this probably wants its own event def snapshot_ps(self, widget): """ Request to save a Postscript file after drawing is complete. """ self.pending_snapshots.append(self.output_image_filename("ps")) publish_event(REDRAW_EVENT, data=(None, None)) # TODO - this probably wants its own event def snapshot_pdf(self, widget): """ Request to save a PDF file after drawing is complete. """ self.pending_snapshots.append(self.output_image_filename("pdf")) publish_event(REDRAW_EVENT, data=(None, None)) # TODO - this probably wants its own event def snapshot_png(self, widget): """ Request to save a PNG file after drawing is complete. """ self.pending_snapshots.append(self.output_image_filename("png")) publish_event(REDRAW_EVENT, data=(None, None)) # TODO - this probably wants its own event def trigger_fullscreen_action(self, fullscreen): """ Toggle fullscreen from outside the GUI, causes the GUI to updated and run all its actions. """ action = self.action_group.get_action("fullscreen") action.set_active(fullscreen) def do_fullscreen(self, widget): """ Widget Action to Make the window fullscreen and update the bot. """ self.fullscreen() self.is_fullscreen = True # next lines seem to be needed for window switching really to # fullscreen mode before reading it's size values while Gtk.events_pending(): Gtk.main_iteration() # we pass the full-screen size to bot self.bot._screen_width = Gdk.Screen.width() self.bot._screen_height = Gdk.Screen.height() self.bot._screen_ratio = self.bot._screen_width / self.bot._screen_height def do_unfullscreen(self, widget): """ Widget Action to set Windowed Mode. """ self.unfullscreen() self.is_fullscreen = False self.bot._screen_ratio = None def do_window_close(self, widget, data=None): """ Widget Action to Close the window, triggering the quit event. """ publish_event(QUIT_EVENT) if self.has_server: self.sock.close() self.hide_variables_window() self.destroy() self.window_open = False def do_toggle_fullscreen(self, action): """ Widget Action to Toggle fullscreen from the GUI """ is_fullscreen = action.get_active() if is_fullscreen: self.fullscreen() else: self.unfullscreen() def do_toggle_play(self, action): """ Widget Action to toggle play / pause. """ # TODO - move this into bot controller # along with stuff in socketserver and shell if self.pause_speed is None and not action.get_active(): self.pause_speed = self.bot._speed self.bot._speed = 0 else: self.bot._speed = self.pause_speed self.pause_speed = None def do_toggle_variables(self, action): """ Widget Action to toggle showing the variables window. """ self.show_vars = action.get_active() if self.show_vars: self.show_variables_window() else: self.hide_variables_window() def main_iteration(self): """ Called from main loop, if your sink needs to handle GUI events do it here. Check any GUI flags then call Gtk.main_iteration to update things. """ if self.show_vars: self.show_variables_window() else: self.hide_variables_window() while Gtk.events_pending(): Gtk.main_iteration()
class ShoebotWindow(gtk.Window, GtkInputDeviceMixin, DrawQueueSink, SocketServerMixin): '''Create a GTK+ window that contains a ShoebotWidget''' # Draw in response to an expose-event __gsignals__ = { "expose-event": "override" } def __init__(self, title = None, show_vars = False, menu_enabled = True, server=False, port=7777, fullscreen=False): gtk.Window.__init__(self) DrawQueueSink.__init__(self) GtkInputDeviceMixin.__init__(self) self.menu_enabled = menu_enabled self.has_server = server self.serverport = port self.show_vars = show_vars self.var_window = None self.is_fullscreen = False sb_widget = ShoebotWidget(input_device=self) if title: self.set_title(title) if fullscreen: self.is_fullscreen = True self.fullscreen() self.connect("delete-event", self.do_window_close) #self.connect("destroy", ) self.sb_widget = sb_widget self.attach_gtk(self) self.uimanager = gtk.UIManager() accelgroup = self.uimanager.get_accel_group() self.add_accel_group(accelgroup) actiongroup = gtk.ActionGroup('Canvas') actiongroup.add_actions([('Save as', None, _('_Save as')), ('svg', 'Save as SVG', _('Save as _SVG'), "<Control>1", None, self.snapshot_svg), ('pdf', 'Save as PDF', _('Save as _PDF'), "<Control>2", None, self.snapshot_pdf), ('ps', 'Save as PS', _('Save as P_S'), "<Control>3", None, self.snapshot_ps), ('png', 'Save as PNG', _('Save as P_NG'), "<Control>4", None, self.snapshot_png), ('close', 'Close window', _('_Close Window'), "<Control>w", None, self.do_window_close) ]) actiongroup.add_toggle_actions([('vars', 'Variables Window', _('Va_riables Window'), "<Control>r", None, self.do_toggle_variables, self.show_vars), ('fullscreen', 'Fullscreen', _('_Fullscreen'), "<Control>f", None, self.do_toggle_fullscreen, False)]) menuxml = ''' <popup action="Save as"> <menuitem action="vars"/> <menuitem action="fullscreen"/> <separator/> <menuitem action="svg"/> <menuitem action="ps"/> <menuitem action="pdf"/> <menuitem action="png"/> <separator/> <separator/> <menuitem action="close"/> </popup> ''' self.uimanager.insert_action_group(actiongroup, 0) self.uimanager.add_ui_from_string(menuxml) sb_widget.show() self.add(sb_widget) self.present() self.scheduled_snapshots = deque() while gtk.events_pending(): gtk.main_iteration() if server: self.server('', self.serverport) self.window_open = True def gtk_mouse_button_down(self, widget, event): ''' Handle right mouse button clicks ''' if self.menu_enabled and event.button == 3: menu = self.uimanager.get_widget('/Save as') menu.popup(None, None, None, event.button, event.time) else: super(ShoebotWindow, self).gtk_mouse_button_down(widget, event) def create_rcontext(self, size, frame): ''' Delegates to the ShoebotWidget ''' ### Any snapshots that need to be taken for snapshot_func in self.scheduled_snapshots: snapshot_func() else: self.scheduled_snapshots = deque() return self.sb_widget.create_rcontext(size, frame) def rendering_finished(self, size, frame, cairo_ctx): ''' Delegates to the ShoebotWidget ''' # A bit hacky... only show the variable window once bot has # executed once and there are some variables. if self.show_vars: self.show_variables_window() else: self.hide_variables_window() return self.sb_widget.rendering_finished(size, frame, cairo_ctx) def schedule_snapshot(self, format): ''' Since the right click comes in after things have been rendered it's easiest to schedule snapshots for the next render. (There is only a bitmap copy of the screen available at this point...) ''' self.scheduled_snapshots.append(lambda: self.do_snapshot(format)) def show_variables_window(self): ''' If bot has variables and var window not visible then create it ''' if self.var_window is None and self.bot._vars: self.var_window = VarWindow(self, self.bot, '%s variables' % (self.title or 'Shoebot')) def hide_variables_window(self): ''' Hide the var window ''' if self.var_window is not None: self.var_window.window.destroy() self.var_window = None def var_changed(self, name, value): self.bot._namespace[name] = value if self.var_window: return self.var_window.update_var(name, value) def do_snapshot(self, format): bot = self.bot script = bot._namespace['__file__'] if script: filename = os.path.splitext(script)[0] + '.' + format else: filename = 'output.' + format self.bot._canvas.user_snapshot(filename) def snapshot_svg(self, widget): self.schedule_snapshot('svg') def snapshot_ps(self, widget): self.schedule_snapshot('ps') def snapshot_pdf(self, widget): self.schedule_snapshot('pdf') def snapshot_png(self, widget): self.schedule_snapshot('png') def do_fullscreen(self, widget): self.fullscreen() # next lines seem to be needed for window switching really to # fullscreen mode before reading it's size values while gtk.events_pending(): gtk.main_iteration(block=False) # we pass informations on full-screen size to bot self.bot._screen_width = gtk.gdk.screen_width() self.bot._screen_height = gtk.gdk.screen_height() self.bot._screen_ratio = self.bot._screen_width / self.bot._screen_height def do_unfullscreen(self, widget): self.unfullscreen() self.bot._screen_ratio = None def do_window_close(self, widget,data=None): self.bot._quit = True if self.has_server: self.sock.close() self.hide_variables_window() self.destroy() self.window_open = False def do_toggle_fullscreen(self, action): self.is_fullscreen = action.get_active() if self.is_fullscreen: self.fullscreen() else: self.unfullscreen() def do_toggle_variables(self, action): self.show_vars = action.get_active() if self.show_vars: self.show_variables_window() else: self.hide_variables_window() def finish(self): while self.bot._quit == False and self.window_open == True: gtk.main_iteration()
class ShoebotWindow(Gtk.Window, GtkInputDeviceMixin, DrawQueueSink): '''Create a GTK+ window that contains a ShoebotWidget''' # Draw in response to an expose-event def __init__(self, title = None, show_vars = False, menu_enabled = True, server=False, port=7777, fullscreen=False): Gtk.Window.__init__(self) DrawQueueSink.__init__(self) GtkInputDeviceMixin.__init__(self) if os.path.isfile(ICON_FILE): self.set_icon_from_file( ICON_FILE ) self.menu_enabled = menu_enabled self.has_server = server self.serverport = port self.show_vars = show_vars self.var_window = None self.is_fullscreen = False sb_widget = ShoebotWidget(input_device=self) self.title = title if title: self.set_title(title) if fullscreen: self.is_fullscreen = True self.fullscreen() self.connect("delete-event", self.do_window_close) #self.connect("destroy", ) self.sb_widget = sb_widget self.attach_gtk(self) self.uimanager = Gtk.UIManager() accelgroup = self.uimanager.get_accel_group() self.add_accel_group(accelgroup) self.action_group = Gtk.ActionGroup('Canvas') self.action_group.add_actions([('Save as', None, _('_Save as')), ('svg', 'Save as SVG', _('Save as _SVG'), "<Control>1", None, self.snapshot_svg), ('pdf', 'Save as PDF', _('Save as _PDF'), "<Control>2", None, self.snapshot_pdf), ('ps', 'Save as PS', _('Save as P_S'), "<Control>3", None, self.snapshot_ps), ('png', 'Save as PNG', _('Save as P_NG'), "<Control>4", None, self.snapshot_png), ('close', 'Close window', _('_Close Window'), "<Control>w", None, self.do_window_close) ]) self.action_group.add_toggle_actions([ ('vars', 'Variables Window', _('Va_riables Window'), "<Control>r", None, self.do_toggle_variables, self.show_vars), ('fullscreen', 'Fullscreen', _('_Fullscreen'), "<Control>f", None, self.do_toggle_fullscreen, False), ('play', 'Play', _('_Play'), "<Alt>p", None, self.do_toggle_play, True), ]) menuxml = ''' <popup action="Save as"> <menuitem action="play"/> <menuitem action="vars"/> <menuitem action="fullscreen"/> <separator/> <menuitem action="svg"/> <menuitem action="ps"/> <menuitem action="pdf"/> <menuitem action="png"/> <separator/> <separator/> <menuitem action="close"/> </popup> ''' self.uimanager.insert_action_group(self.action_group, 0) self.uimanager.add_ui_from_string(menuxml) sb_widget.show() self.add(sb_widget) self.present() self.scheduled_snapshots = deque() while Gtk.events_pending(): Gtk.main_iteration() self.window_open = True self.pause_speed = None # TODO - factor out bot controller stuff self.last_draw_ctx = None # Need this to save snapshots after frame is drawn def gtk_mouse_button_down(self, widget, event): ''' Handle right mouse button clicks ''' if self.menu_enabled and event.button == 3: menu = self.uimanager.get_widget('/Save as') menu.popup(None, None, None, None, event.button, event.time) else: super(ShoebotWindow, self).gtk_mouse_button_down(widget, event) def render(self, size, frame, drawqueue): cairo_ctx = super(self.__class__, self).render(size, frame, drawqueue) self.last_draw_ctx = cairo_ctx self.sb_widget.do_drawing(size, frame, cairo_ctx) def create_rcontext(self, size, frame): ''' Delegates to the ShoebotWidget ''' return self.sb_widget.create_rcontext(size, frame) def show_variables_window(self): ''' If bot has variables and var window not visible then create it ''' if self.var_window is None and self.bot._vars: self.var_window = VarWindow(self, self.bot, '%s variables' % (self.title or 'Shoebot')) self.var_window.window.connect("destroy", self.var_window_closed) def hide_variables_window(self): ''' Hide the var window ''' if self.var_window is not None: self.var_window.window.destroy() self.var_window = None def var_window_closed(self, widget): """ Called if user clicked close button on var window :param widget: :return: """ # TODO - Clean up the menu handling stuff its a bit spagetti right now self.action_group.get_action('vars').set_active(False) self.show_vars = False self.var_window = None def var_changed(self, name, value): self.bot._namespace[name] = value if self.var_window: return self.var_window.update_var(name, value) else: v = self.bot._vars[name] publish_event(EVENT_VARIABLE_UPDATED, v) return True, value def schedule_snapshot(self, format): """ Tell the canvas to perform a snapshot when it's finished rendering :param format: :return: """ bot = self.bot canvas = self.bot.canvas script = bot._namespace['__file__'] if script: filename = os.path.splitext(script)[0] + '.' + format else: filename = 'output.' + format f = canvas.output_closure(filename, self.bot._frame) self.scheduled_snapshots.append(f) def snapshot_svg(self, widget): self.schedule_snapshot('svg') def snapshot_ps(self, widget): self.schedule_snapshot('ps') def snapshot_pdf(self, widget): self.schedule_snapshot('pdf') def snapshot_png(self, widget): self.schedule_snapshot('png') def do_fullscreen(self, widget): self.fullscreen() # next lines seem to be needed for window switching really to # fullscreen mode before reading it's size values while Gtk.events_pending(): Gtk.main_iteration(block=False) # we pass informations on full-screen size to bot self.bot._screen_width = Gdk.Screen.width() self.bot._screen_height = Gdk.Screen.height() self.bot._screen_ratio = self.bot._screen_width / self.bot._screen_height def do_unfullscreen(self, widget): self.unfullscreen() self.bot._screen_ratio = None def do_window_close(self, widget,data=None): publish_event(QUIT_EVENT) if self.has_server: self.sock.close() self.hide_variables_window() self.destroy() self.window_open = False def do_toggle_fullscreen(self, action): self.is_fullscreen = action.get_active() if self.is_fullscreen: self.fullscreen() else: self.unfullscreen() def do_toggle_play(self, action): # TODO - move this into bot controller # along with stuff in socketserver and shell if self.pause_speed is None and not action.get_active(): self.pause_speed = self.bot._speed self.bot._speed = 0 else: self.bot._speed = self.pause_speed self.pause_speed = None def do_toggle_variables(self, action): self.show_vars = action.get_active() if self.show_vars: self.show_variables_window() else: self.hide_variables_window() def main_iteration(self): """ Called from main loop, if your sink needs to handle GUI events do it here. Check any GUI flags then call Gtk.main_iteration to update things. """ if self.show_vars: self.show_variables_window() else: self.hide_variables_window() for snapshot_f in self.scheduled_snapshots: fn = snapshot_f(self.last_draw_ctx) print "Saved snapshot: %s" % fn else: self.scheduled_snapshots = deque() while Gtk.events_pending(): Gtk.main_iteration()