def on_view_loaded( self, module: AbstractModule, controller: AbstractController, item_id: int ): """A new module view was loaded! Present it!""" assert current_thread() == main_thread # Check if current view still matches expected logger.debug('View loaded.') try: view = controller.get_view() except Exception as err: logger.debug("Error retreiving the loaded view") self.on_view_loaded_error(err) return if self._current_view_module != module or self._current_view_controller_class != controller.__class__ or self._current_view_item_id != item_id: logger.warning('Loaded view not matching selection.') view.destroy() return # Insert the view at page 3 [0,1,2,3] of the stack. If there is already a page, remove it. old_view = self._editor_stack.get_child_by_name('es__loaded_view') if old_view: logger.debug('Destroying old view...') self._editor_stack.remove(old_view) old_view.destroy() logger.debug('Adding and showing new view...') self._editor_stack.add_named(view, 'es__loaded_view') view.show_all() self._editor_stack.set_visible_child(view) logger.debug('Unlocking view trees.') self._unlock_trees() EventManager.instance().trigger(EVT_VIEW_SWITCH, module=module, controller=controller, breadcrumbs=self._current_breadcrumbs)
def on_main_window_state_event(self, w: Gtk.Window, evt: Gdk.EventWindowState): if evt.changed_mask & Gdk.WindowState.FOCUSED: if evt.new_window_state & Gdk.WindowState.FOCUSED: EventManager.instance().main_window_has_focus() else: EventManager.instance().main_window_lost_focus()
def on_file_opened(self): """Update the UI after a ROM file has been opened.""" assert current_thread() == main_thread logger.debug('File opened.') # Init the sprite provider RomProject.get_current().get_sprite_provider().init_loader( self.window.get_screen()) self._init_window_after_rom_load( os.path.basename(RomProject.get_current().filename)) try: # Load root node, ROM project = RomProject.get_current() rom_module = project.get_rom_module() rom_module.load_rom_data() # Initialize patch-specific properties for this rom project project.init_patch_properties() logger.info( f'Loaded ROM {project.filename} ({rom_module.get_static_data().game_edition})' ) logger.debug(f"Loading ROM module tree items...") rom_module.load_tree_items(self._item_store, None) root_node = rom_module.get_root_node() # Tell the debugger self._debugger_manager.handle_project_change() # Load item tree items for module in sorted(project.get_modules(False), key=lambda m: m.sort_order()): logger.debug( f"Loading {module.__class__.__name__} module tree items..." ) module.load_tree_items(self._item_store, root_node) if module.__class__.__name__ == 'MapBgModule': self._loaded_map_bg_module = module # TODO: Load settings from ROM for history, bookmarks, etc? - separate module? logger.debug(f"Loaded all modules.") # Trigger event EventManager.instance().trigger(EVT_PROJECT_OPEN, project=project) # Select & load main ROM item by default selection: TreeSelection = self._main_item_list.get_selection() selection.select_path(self._item_store.get_path(root_node)) self.load_view(self._item_store, root_node, self._main_item_list) except BaseException as ex: self.on_file_opened_error(sys.exc_info(), ex) return if self._loading_dialog is not None: self._loading_dialog.hide() self._loading_dialog = None # Show the initial assistant window if not self.settings.get_assistant_shown(): self.on_settings_show_assistant_clicked()
def load(cls): try: # Start the server server = WebsocketServer(port=DEFAULT_PORT, loglevel=SKYTEMPLE_LOGLEVEL) EventThread(server).start() # Register the event handler to the event manager EventManager.instance().register_listener(EventHandler(server)) except BaseException as e: logger.error(f"Failed loading websocket eventserver", exc_info=e)
def run_main(cls, main: Callable, *main_args, **main_kwargs): try: main(*main_args, **main_kwargs) if cls.config_type( ).event_loop_type == AsyncEventLoopType.GLIB_ONLY: Gtk.main() elif cls.config_type().event_loop_type == AsyncEventLoopType.GBULB: gbulb.install(gtk=True) gbulb.get_event_loop().set_exception_handler( async_handle_exeception) from skytemple.core.events.manager import EventManager GLib.idle_add(EventManager.instance().async_init) asyncio.get_event_loop().run_forever() else: raise RuntimeError("Invalid async configuration") except OSError as ex: if hasattr(ex, 'winerror') and ex.winerror == 6: # type: ignore # [WinError 6] The handle is invalid # Originates in gi/_ossighelper.py - Some issues with socket cleanup. We will ignore that. pass else: raise except (SystemExit, KeyboardInterrupt): pass finally: # TODO: Currently always required for Debugger compatibility # (since that ALWAYS uses this async implementation) AsyncTaskRunner.end()
def _tick(self): if self._draw_area is None: return False if self._draw_area is not None and self._draw_area.get_parent() is None: # XXX: Gtk doesn't remove the widget on switch sometimes... self._draw_area.destroy() return False if EventManager.instance().get_if_main_window_has_fous(): self._draw_area.queue_draw() self._frame_counter += 1 return self._drawing_is_active
def on_selected_string_changed(self, string: str): EventManager.instance().trigger(EVT_DEBUGGER_SELECTED_STRING_CHANGED, string)
def on_blur(self): EventManager.instance().debugger_window_lost_focus()
def on_focus(self): EventManager.instance().debugger_window_has_focus()
def on_script_edit(self, filename): EventManager.instance().trigger(EVT_DEBUGGER_SCRIPT_OPEN, filename)
def main(): # TODO: Gtk.Application: https://python-gtk-3-tutorial.readthedocs.io/en/latest/application.html path = os.path.abspath(os.path.dirname(__file__)) # Load settings settings = SkyTempleSettingsStore() if sys.platform.startswith('win'): # Load theming under Windows _load_theme(settings) # Solve issue #12 try: from skytemple_files.common.platform_utils.win import win_set_error_mode win_set_error_mode() except BaseException: # This really shouldn't fail, but it's not important enough to crash over pass if sys.platform.startswith('darwin'): # Load theming under macOS _load_theme(settings) # The search path is wrong if SkyTemple is executed as an .app bundle if getattr(sys, 'frozen', False): path = os.path.dirname(sys.executable) if sys.platform.startswith('linux') and gdk_backend() == GDK_BACKEND_BROADWAY: gtk_settings = Gtk.Settings.get_default() gtk_settings.set_property("gtk-theme-name", 'Arc-Dark') gtk_settings.set_property("gtk-application-prefer-dark-theme", True) itheme: Gtk.IconTheme = Gtk.IconTheme.get_default() itheme.append_search_path(os.path.abspath(icons())) itheme.append_search_path(os.path.abspath(os.path.join(data_dir(), "icons"))) itheme.append_search_path(os.path.abspath(os.path.join(get_debugger_data_dir(), "icons"))) itheme.rescan_if_needed() # Load Builder and Window builder = make_builder(os.path.join(path, "skytemple.glade")) main_window: Window = builder.get_object("main_window") main_window.set_role("SkyTemple") GLib.set_application_name("SkyTemple") GLib.set_prgname("skytemple") # TODO: Deprecated but the only way to set the app title on GNOME...? main_window.set_wmclass("SkyTemple", "SkyTemple") # Load CSS style_provider = Gtk.CssProvider() with open(os.path.join(path, "skytemple.css"), 'rb') as f: css = f.read() style_provider.load_from_data(css) Gtk.StyleContext.add_provider_for_screen( Gdk.Screen.get_default(), style_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION ) # Load async task runner thread AsyncTaskRunner.instance() # Init. core events event_manager = EventManager.instance() if settings.get_integration_discord_enabled(): try: from skytemple.core.events.impl.discord import DiscordPresence discord_listener = DiscordPresence() event_manager.register_listener(discord_listener) except BaseException: pass # Load modules Modules.load() # Load main window + controller MainController(builder, main_window, settings) main_window.present() main_window.set_icon_name('skytemple') try: Gtk.main() except (KeyboardInterrupt, SystemExit): AsyncTaskRunner.end()