def demo_docking_widgets():
    """
    Demonstrates how to create a QWidget with PySide2 and attach it to the 3dsmax main window.
    Creates two types of dockable widgets, a QDockWidget and a QToolbar
    """
    # Retrieve 3ds Max Main Window QWdiget
    main_window = GetQMaxMainWindow()

    # QAction reused by both dockable widgets.
    cylinder_icon_path = os.path.dirname(os.path.realpath(__file__)) + "\\cylinder_icon_48.png"
    cylinder_icon = QtGui.QIcon(cylinder_icon_path)
    create_cyl_action = QAction(cylinder_icon, u"Create Cylinder", main_window)
    create_cyl_action.triggered.connect(create_cylinder)

    # QDockWidget construction and placement over the main window
    dock_widget = QDockWidget(main_window)

    # Set for position persistence
    dock_widget.setObjectName("Creators")
    # Set to see dock widget name in toolbar customize popup
    dock_widget.setWindowTitle("Creators")
    dock_tool_button = QToolButton()
    dock_tool_button.setAutoRaise(True)
    dock_tool_button.setDefaultAction(create_cyl_action)
    dock_tool_button.setToolButtonStyle(QtCore.Qt.ToolButtonTextOnly)
    dock_widget.setWidget(dock_tool_button)

    main_window.addDockWidget(QtCore.Qt.LeftDockWidgetArea, dock_widget)
    dock_widget.setFloating(True)
    dock_widget.show()

    # QToolBar construction and attachement to main window
    toolbar_widget = QToolBar(main_window)

    # Set for position persistence
    toolbar_widget.setObjectName("Creators TB")
    # Set to see dock widget name in toolbar customize popup
    toolbar_widget.setWindowTitle("Creators TB")
    toolbar_widget.setFloatable(True)
    toolbar_widget.addAction(create_cyl_action)

    main_window.addToolBar(QtCore.Qt.BottomToolBarArea, toolbar_widget)
    toolbar_widget.show()

    toolbar_position = get_pos_to_dock_toolbar(dock_widget)
    make_toolbar_floating(toolbar_widget, toolbar_position)
Ejemplo n.º 2
0
    def __init__(self, path_to_rom=""):
        super(MainWindow, self).__init__()

        self.setWindowIcon(icon("foundry.ico"))

        file_menu = QMenu("File")

        open_rom_action = file_menu.addAction("&Open ROM")
        open_rom_action.triggered.connect(self.on_open_rom)
        self.open_m3l_action = file_menu.addAction("&Open M3L")
        self.open_m3l_action.triggered.connect(self.on_open_m3l)

        file_menu.addSeparator()

        self.save_rom_action = file_menu.addAction("&Save ROM")
        self.save_rom_action.triggered.connect(self.on_save_rom)
        self.save_rom_as_action = file_menu.addAction("&Save ROM as ...")
        self.save_rom_as_action.triggered.connect(self.on_save_rom_as)
        """
        file_menu.AppendSeparator()
        """
        self.save_m3l_action = file_menu.addAction("&Save M3L")
        self.save_m3l_action.triggered.connect(self.on_save_m3l)
        """
        file_menu.Append(ID_SAVE_LEVEL_TO, "&Save Level to", "")
        file_menu.AppendSeparator()
        file_menu.Append(ID_APPLY_IPS_PATCH, "&Apply IPS Patch", "")
        file_menu.AppendSeparator()
        file_menu.Append(ID_ROM_PRESET, "&ROM Preset", "")
        """
        file_menu.addSeparator()
        settings_action = file_menu.addAction("&Settings")
        settings_action.triggered.connect(show_settings)
        file_menu.addSeparator()
        exit_action = file_menu.addAction("&Exit")
        exit_action.triggered.connect(lambda _: self.close())

        self.menuBar().addMenu(file_menu)
        """
        edit_menu = wx.Menu()

        edit_menu.Append(ID_EDIT_LEVEL, "&Edit Level", "")
        edit_menu.Append(ID_EDIT_OBJ_DEFS, "&Edit Object Definitions", "")
        edit_menu.Append(ID_EDIT_PALETTE, "&Edit Palette", "")
        edit_menu.Append(ID_EDIT_GRAPHICS, "&Edit Graphics", "")
        edit_menu.Append(ID_EDIT_MISC, "&Edit Miscellaneous", "")
        edit_menu.AppendSeparator()
        edit_menu.Append(ID_FREE_FORM_MODE, "&Free form Mode", "")
        edit_menu.Append(ID_LIMIT_SIZE, "&Limit Size", "")
        """

        self.level_menu = QMenu("Level")

        self.select_level_action = self.level_menu.addAction("&Select Level")
        self.select_level_action.triggered.connect(self.open_level_selector)

        self.reload_action = self.level_menu.addAction("&Reload Level")
        self.reload_action.triggered.connect(self.reload_level)
        self.level_menu.addSeparator()
        self.edit_header_action = self.level_menu.addAction("&Edit Header")
        self.edit_header_action.triggered.connect(self.on_header_editor)
        self.edit_autoscroll = self.level_menu.addAction("Edit Autoscrolling")
        self.edit_autoscroll.triggered.connect(self.on_edit_autoscroll)

        self.menuBar().addMenu(self.level_menu)

        self.object_menu = QMenu("Objects")

        view_blocks_action = self.object_menu.addAction("&View Blocks")
        view_blocks_action.triggered.connect(self.on_block_viewer)
        view_objects_action = self.object_menu.addAction("&View Objects")
        view_objects_action.triggered.connect(self.on_object_viewer)
        self.object_menu.addSeparator()
        view_palettes_action = self.object_menu.addAction(
            "View Object Palettes")
        view_palettes_action.triggered.connect(self.on_palette_viewer)

        self.menuBar().addMenu(self.object_menu)

        self.view_menu = QMenu("View")
        self.view_menu.triggered.connect(self.on_menu)

        action = self.view_menu.addAction("Mario")
        action.setProperty(ID_PROP, ID_MARIO)
        action.setCheckable(True)
        action.setChecked(SETTINGS["draw_mario"])

        action = self.view_menu.addAction("&Jumps on objects")
        action.setProperty(ID_PROP, ID_JUMP_OBJECTS)
        action.setCheckable(True)
        action.setChecked(SETTINGS["draw_jump_on_objects"])

        action = self.view_menu.addAction("Items in blocks")
        action.setProperty(ID_PROP, ID_ITEM_BLOCKS)
        action.setCheckable(True)
        action.setChecked(SETTINGS["draw_items_in_blocks"])

        action = self.view_menu.addAction("Invisible items")
        action.setProperty(ID_PROP, ID_INVISIBLE_ITEMS)
        action.setCheckable(True)
        action.setChecked(SETTINGS["draw_invisible_items"])

        action = self.view_menu.addAction("Autoscroll Path")
        action.setProperty(ID_PROP, ID_AUTOSCROLL)
        action.setCheckable(True)
        action.setChecked(SETTINGS["draw_autoscroll"])

        self.view_menu.addSeparator()

        action = self.view_menu.addAction("Jump Zones")
        action.setProperty(ID_PROP, ID_JUMPS)
        action.setCheckable(True)
        action.setChecked(SETTINGS["draw_jumps"])

        action = self.view_menu.addAction("&Grid lines")
        action.setProperty(ID_PROP, ID_GRID_LINES)
        action.setCheckable(True)
        action.setChecked(SETTINGS["draw_grid"])

        action = self.view_menu.addAction("Resize Type")
        action.setProperty(ID_PROP, ID_RESIZE_TYPE)
        action.setCheckable(True)
        action.setChecked(SETTINGS["draw_expansion"])

        self.view_menu.addSeparator()

        action = self.view_menu.addAction("&Block Transparency")
        action.setProperty(ID_PROP, ID_TRANSPARENCY)
        action.setCheckable(True)
        action.setChecked(SETTINGS["block_transparency"])

        self.view_menu.addSeparator()
        self.view_menu.addAction(
            "&Save Screenshot of Level").triggered.connect(self.on_screenshot)
        """
        self.view_menu.Append(ID_BACKGROUND_FLOOR, "&Background & Floor", "")
        self.view_menu.Append(ID_TOOLBAR, "&Toolbar", "")
        self.view_menu.AppendSeparator()
        self.view_menu.Append(ID_ZOOM, "&Zoom", "")
        self.view_menu.AppendSeparator()
        self.view_menu.Append(ID_USE_ROM_GRAPHICS, "&Use ROM Graphics", "")
        self.view_menu.Append(ID_PALETTE, "&Palette", "")
        self.view_menu.AppendSeparator()
        self.view_menu.Append(ID_MORE, "&More", "")
        """

        self.menuBar().addMenu(self.view_menu)

        help_menu = QMenu("Help")
        """
        help_menu.Append(ID_ENEMY_COMPATIBILITY, "&Enemy Compatibility", "")
        help_menu.Append(ID_TROUBLESHOOTING, "&Troubleshooting", "")
        help_menu.AppendSeparator()
        help_menu.Append(ID_PROGRAM_WEBSITE, "&Program Website", "")
        help_menu.Append(ID_MAKE_A_DONATION, "&Make a Donation", "")
        help_menu.AppendSeparator()
        """
        update_action = help_menu.addAction("Check for updates")
        update_action.triggered.connect(self.on_check_for_update)

        help_menu.addSeparator()

        video_action = help_menu.addAction("Feature Video on YouTube")
        video_action.triggered.connect(lambda: open_url(feature_video_link))

        github_action = help_menu.addAction("Github Repository")
        github_action.triggered.connect(lambda: open_url(github_link))

        discord_action = help_menu.addAction("SMB3 Rom Hacking Discord")
        discord_action.triggered.connect(lambda: open_url(discord_link))

        help_menu.addSeparator()

        about_action = help_menu.addAction("&About")
        about_action.triggered.connect(self.on_about)

        self.menuBar().addMenu(help_menu)

        self.block_viewer = None
        self.object_viewer = None

        self.level_ref = LevelRef()
        self.level_ref.data_changed.connect(self._on_level_data_changed)

        self.context_menu = ContextMenu(self.level_ref)
        self.context_menu.triggered.connect(self.on_menu)

        self.level_view = LevelView(self, self.level_ref, self.context_menu)

        self.scroll_panel = QScrollArea()
        self.scroll_panel.setWidgetResizable(True)
        self.scroll_panel.setWidget(self.level_view)

        self.setCentralWidget(self.scroll_panel)

        self.spinner_panel = SpinnerPanel(self, self.level_ref)
        self.spinner_panel.zoom_in_triggered.connect(self.level_view.zoom_in)
        self.spinner_panel.zoom_out_triggered.connect(self.level_view.zoom_out)
        self.spinner_panel.object_change.connect(self.on_spin)

        self.object_list = ObjectList(self, self.level_ref, self.context_menu)

        self.object_dropdown = ObjectDropdown(self)
        self.object_dropdown.object_selected.connect(
            self._on_placeable_object_selected)

        self.level_size_bar = LevelSizeBar(self, self.level_ref)
        self.enemy_size_bar = EnemySizeBar(self, self.level_ref)

        self.jump_list = JumpList(self, self.level_ref)
        self.jump_list.add_jump.connect(self.on_jump_added)
        self.jump_list.edit_jump.connect(self.on_jump_edit)
        self.jump_list.remove_jump.connect(self.on_jump_removed)

        splitter = QSplitter(self)
        splitter.setOrientation(Qt.Vertical)

        splitter.addWidget(self.object_list)
        splitter.setStretchFactor(0, 1)
        splitter.addWidget(self.jump_list)

        splitter.setChildrenCollapsible(False)

        level_toolbar = QToolBar("Level Info Toolbar", self)
        level_toolbar.setContextMenuPolicy(Qt.PreventContextMenu)
        level_toolbar.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)
        level_toolbar.setOrientation(Qt.Horizontal)
        level_toolbar.setFloatable(False)

        level_toolbar.addWidget(self.spinner_panel)
        level_toolbar.addWidget(self.object_dropdown)
        level_toolbar.addWidget(self.level_size_bar)
        level_toolbar.addWidget(self.enemy_size_bar)
        level_toolbar.addWidget(splitter)

        level_toolbar.setAllowedAreas(Qt.LeftToolBarArea | Qt.RightToolBarArea)

        self.addToolBar(Qt.RightToolBarArea, level_toolbar)

        self.object_toolbar = ObjectToolBar(self)
        self.object_toolbar.object_selected.connect(
            self._on_placeable_object_selected)

        object_toolbar = QToolBar("Object Toolbar", self)
        object_toolbar.setContextMenuPolicy(Qt.PreventContextMenu)
        object_toolbar.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)
        object_toolbar.setFloatable(False)

        object_toolbar.addWidget(self.object_toolbar)
        object_toolbar.setAllowedAreas(Qt.LeftToolBarArea
                                       | Qt.RightToolBarArea)

        self.addToolBar(Qt.LeftToolBarArea, object_toolbar)

        self.menu_toolbar = QToolBar("Menu Toolbar", self)
        self.menu_toolbar.setOrientation(Qt.Horizontal)
        self.menu_toolbar.setIconSize(QSize(20, 20))

        self.menu_toolbar.addAction(
            icon("settings.svg"),
            "Editor Settings").triggered.connect(show_settings)
        self.menu_toolbar.addSeparator()
        self.menu_toolbar.addAction(
            icon("folder.svg"), "Open ROM").triggered.connect(self.on_open_rom)
        self.menu_toolbar.addAction(
            icon("save.svg"), "Save Level").triggered.connect(self.on_save_rom)
        self.menu_toolbar.addSeparator()

        self.undo_action = self.menu_toolbar.addAction(icon("rotate-ccw.svg"),
                                                       "Undo Action")
        self.undo_action.triggered.connect(self.level_ref.undo)
        self.undo_action.setEnabled(False)
        self.redo_action = self.menu_toolbar.addAction(icon("rotate-cw.svg"),
                                                       "Redo Action")
        self.redo_action.triggered.connect(self.level_ref.redo)
        self.redo_action.setEnabled(False)

        self.menu_toolbar.addSeparator()
        play_action = self.menu_toolbar.addAction(icon("play-circle.svg"),
                                                  "Play Level")
        play_action.triggered.connect(self.on_play)
        play_action.setWhatsThis(
            "Opens an emulator with the current Level set to 1-1.\nSee Settings."
        )
        self.menu_toolbar.addSeparator()
        self.menu_toolbar.addAction(icon("zoom-out.svg"),
                                    "Zoom Out").triggered.connect(
                                        self.level_view.zoom_out)
        self.menu_toolbar.addAction(icon("zoom-in.svg"),
                                    "Zoom In").triggered.connect(
                                        self.level_view.zoom_in)
        self.menu_toolbar.addSeparator()
        header_action = self.menu_toolbar.addAction(icon("tool.svg"),
                                                    "Edit Level Header")
        header_action.triggered.connect(self.on_header_editor)
        header_action.setWhatsThis(
            "<b>Header Editor</b><br/>"
            "Many configurations regarding the level are done in its header, like the length of "
            "the timer, or where and how Mario enters the level.<br/>")

        self.jump_destination_action = self.menu_toolbar.addAction(
            icon("arrow-right-circle.svg"), "Go to Jump Destination")
        self.jump_destination_action.triggered.connect(
            self._go_to_jump_destination)
        self.jump_destination_action.setWhatsThis(
            "Opens the level, that can be reached from this one, e.g. by entering a pipe."
        )

        self.menu_toolbar.addSeparator()

        whats_this_action = QWhatsThis.createAction()
        whats_this_action.setWhatsThis(
            "Click on parts of the editor, to receive help information.")
        whats_this_action.setIcon(icon("help-circle.svg"))
        whats_this_action.setText("Starts 'What's this?' mode")
        self.menu_toolbar.addAction(whats_this_action)

        self.menu_toolbar.addSeparator()
        self.warning_list = WarningList(self, self.level_ref)

        warning_action = self.menu_toolbar.addAction(
            icon("alert-triangle.svg"), "Warning Panel")
        warning_action.setWhatsThis("Shows a list of warnings.")
        warning_action.triggered.connect(self.warning_list.show)
        warning_action.setDisabled(True)

        self.warning_list.warnings_updated.connect(warning_action.setEnabled)

        self.addToolBar(Qt.TopToolBarArea, self.menu_toolbar)

        self.status_bar = ObjectStatusBar(self, self.level_ref)
        self.setStatusBar(self.status_bar)

        self.delete_shortcut = QShortcut(QKeySequence(Qt.Key_Delete), self,
                                         self.remove_selected_objects)

        QShortcut(QKeySequence(Qt.CTRL + Qt.Key_X), self, self._cut_objects)
        QShortcut(QKeySequence(Qt.CTRL + Qt.Key_C), self, self._copy_objects)
        QShortcut(QKeySequence(Qt.CTRL + Qt.Key_V), self, self._paste_objects)

        QShortcut(QKeySequence(Qt.CTRL + Qt.Key_Z), self, self.level_ref.undo)
        QShortcut(QKeySequence(Qt.CTRL + Qt.Key_Y), self, self.level_ref.redo)
        QShortcut(QKeySequence(Qt.CTRL + Qt.SHIFT + Qt.Key_Z), self,
                  self.level_ref.redo)

        QShortcut(QKeySequence(Qt.CTRL + Qt.Key_Plus), self,
                  self.level_view.zoom_in)
        QShortcut(QKeySequence(Qt.CTRL + Qt.Key_Minus), self,
                  self.level_view.zoom_out)

        QShortcut(QKeySequence(Qt.CTRL + Qt.Key_A), self,
                  self.level_view.select_all)

        self.on_open_rom(path_to_rom)

        self.showMaximized()
Ejemplo n.º 3
0
    def __init__(self, path_to_rom=""):
        super(MainWindow, self).__init__()

        self.setWindowIcon(icon("foundry.ico"))

        file_menu = QMenu("File")

        open_rom_action = file_menu.addAction("&Open ROM")
        open_rom_action.triggered.connect(self.on_open_rom)
        self.open_m3l_action = file_menu.addAction("&Open M3L")
        self.open_m3l_action.triggered.connect(self.on_open_m3l)

        file_menu.addSeparator()

        save_rom_action = file_menu.addAction("&Save ROM")
        save_rom_action.triggered.connect(self.on_save_rom)
        save_rom_as_action = file_menu.addAction("&Save ROM as ...")
        save_rom_as_action.triggered.connect(self.on_save_rom_as)
        """
        file_menu.AppendSeparator()
        """
        self.save_m3l_action = file_menu.addAction("&Save M3L")
        self.save_m3l_action.triggered.connect(self.on_save_m3l)
        """
        file_menu.Append(ID_SAVE_LEVEL_TO, "&Save Level to", "")
        file_menu.AppendSeparator()
        file_menu.Append(ID_APPLY_IPS_PATCH, "&Apply IPS Patch", "")
        file_menu.AppendSeparator()
        file_menu.Append(ID_ROM_PRESET, "&ROM Preset", "")
        """
        file_menu.addSeparator()
        settings_action = file_menu.addAction("&Settings")
        settings_action.triggered.connect(show_settings)
        file_menu.addSeparator()
        exit_action = file_menu.addAction("&Exit")
        exit_action.triggered.connect(lambda _: self.close())

        self.menuBar().addMenu(file_menu)
        """
        edit_menu = wx.Menu()

        edit_menu.Append(ID_EDIT_LEVEL, "&Edit Level", "")
        edit_menu.Append(ID_EDIT_OBJ_DEFS, "&Edit Object Definitions", "")
        edit_menu.Append(ID_EDIT_PALETTE, "&Edit Palette", "")
        edit_menu.Append(ID_EDIT_GRAPHICS, "&Edit Graphics", "")
        edit_menu.Append(ID_EDIT_MISC, "&Edit Miscellaneous", "")
        edit_menu.AppendSeparator()
        edit_menu.Append(ID_FREE_FORM_MODE, "&Free form Mode", "")
        edit_menu.Append(ID_LIMIT_SIZE, "&Limit Size", "")
        """

        level_menu = QMenu("Level")

        select_level_action = level_menu.addAction("&Select Level")
        select_level_action.triggered.connect(self.open_level_selector)
        """
        level_menu.Append(ID_GOTO_NEXT_AREA, "&Go to next Area", "")
        level_menu.AppendSeparator()
        """
        self.reload_action = level_menu.addAction("&Reload Level")
        self.reload_action.triggered.connect(self.reload_level)
        level_menu.addSeparator()
        self.edit_header_action = level_menu.addAction("&Edit Header")
        self.edit_header_action.triggered.connect(self.on_header_editor)
        """
        level_menu.Append(ID_EDIT_POINTERS, "&Edit Pointers", "")
        """

        self.menuBar().addMenu(level_menu)

        object_menu = QMenu("Objects")

        view_blocks_action = object_menu.addAction("&View Blocks")
        view_blocks_action.triggered.connect(self.on_block_viewer)
        view_objects_action = object_menu.addAction("&View Objects")
        view_objects_action.triggered.connect(self.on_object_viewer)
        """
        object_menu.AppendSeparator()
        object_menu.Append(ID_CLONE_OBJECT_ENEMY, "&Clone Object/Enemy", "")
        object_menu.AppendSeparator()
        object_menu.Append(ID_ADD_3_BYTE_OBJECT, "&Add 3 Byte Object", "")
        object_menu.Append(ID_ADD_4_BYTE_OBJECT, "&Add 4 Byte Object", "")
        object_menu.Append(ID_ADD_ENEMY, "&Add Enemy", "")
        object_menu.AppendSeparator()
        object_menu.Append(ID_DELETE_OBJECT_ENEMY, "&Delete Object/Enemy", "")
        object_menu.Append(ID_DELETE_ALL, "&Delete All", "")
        """

        self.menuBar().addMenu(object_menu)

        view_menu = QMenu("View")
        view_menu.triggered.connect(self.on_menu)

        action = view_menu.addAction("Mario")
        action.setProperty(ID_PROP, ID_MARIO)
        action.setCheckable(True)
        action.setChecked(SETTINGS["draw_mario"])

        action = view_menu.addAction("&Jumps on objects")
        action.setProperty(ID_PROP, ID_JUMP_OBJECTS)
        action.setCheckable(True)
        action.setChecked(SETTINGS["draw_jump_on_objects"])

        action = view_menu.addAction("Items in blocks")
        action.setProperty(ID_PROP, ID_ITEM_BLOCKS)
        action.setCheckable(True)
        action.setChecked(SETTINGS["draw_items_in_blocks"])

        action = view_menu.addAction("Invisible items")
        action.setProperty(ID_PROP, ID_INVISIBLE_ITEMS)
        action.setCheckable(True)
        action.setChecked(SETTINGS["draw_invisible_items"])

        view_menu.addSeparator()

        action = view_menu.addAction("Jump Zones")
        action.setProperty(ID_PROP, ID_JUMPS)
        action.setCheckable(True)
        action.setChecked(SETTINGS["draw_jumps"])

        action = view_menu.addAction("&Grid lines")
        action.setProperty(ID_PROP, ID_GRID_LINES)
        action.setCheckable(True)
        action.setChecked(SETTINGS["draw_grid"])

        action = view_menu.addAction("Resize Type")
        action.setProperty(ID_PROP, ID_RESIZE_TYPE)
        action.setCheckable(True)
        action.setChecked(SETTINGS["draw_expansion"])

        view_menu.addSeparator()

        action = view_menu.addAction("&Block Transparency")
        action.setProperty(ID_PROP, ID_TRANSPARENCY)
        action.setCheckable(True)
        action.setChecked(SETTINGS["block_transparency"])

        view_menu.addSeparator()
        view_menu.addAction("&Save Screenshot of Level").triggered.connect(
            self.on_screenshot)
        """
        view_menu.Append(ID_BACKGROUND_FLOOR, "&Background & Floor", "")
        view_menu.Append(ID_TOOLBAR, "&Toolbar", "")
        view_menu.AppendSeparator()
        view_menu.Append(ID_ZOOM, "&Zoom", "")
        view_menu.AppendSeparator()
        view_menu.Append(ID_USE_ROM_GRAPHICS, "&Use ROM Graphics", "")
        view_menu.Append(ID_PALETTE, "&Palette", "")
        view_menu.AppendSeparator()
        view_menu.Append(ID_MORE, "&More", "")
        """

        self.menuBar().addMenu(view_menu)

        help_menu = QMenu("Help")
        """
        help_menu.Append(ID_ENEMY_COMPATIBILITY, "&Enemy Compatibility", "")
        help_menu.Append(ID_TROUBLESHOOTING, "&Troubleshooting", "")
        help_menu.AppendSeparator()
        help_menu.Append(ID_PROGRAM_WEBSITE, "&Program Website", "")
        help_menu.Append(ID_MAKE_A_DONATION, "&Make a Donation", "")
        help_menu.AppendSeparator()
        """
        update_action = help_menu.addAction("Check for updates")
        update_action.triggered.connect(self.on_check_for_update)

        help_menu.addSeparator()

        video_action = help_menu.addAction("Feature Video on YouTube")
        video_action.triggered.connect(lambda: open_url(feature_video_link))

        discord_action = help_menu.addAction("SMB3 Rom Hacking Discord")
        discord_action.triggered.connect(lambda: open_url(discord_link))

        help_menu.addSeparator()

        about_action = help_menu.addAction("&About")
        about_action.triggered.connect(self.on_about)

        self.menuBar().addMenu(help_menu)

        self.level_selector = LevelSelector(parent=self)

        self.block_viewer = None
        self.object_viewer = None

        self.level_ref = LevelRef()
        self.level_ref.data_changed.connect(self._on_level_data_changed)

        self.context_menu = ContextMenu(self.level_ref)
        self.context_menu.triggered.connect(self.on_menu)

        self.level_view = LevelView(self, self.level_ref, self.context_menu)

        self.scroll_panel = QScrollArea()
        self.scroll_panel.setWidgetResizable(True)
        self.scroll_panel.setWidget(self.level_view)

        self.setCentralWidget(self.scroll_panel)

        self.spinner_panel = SpinnerPanel(self, self.level_ref)
        self.spinner_panel.zoom_in_triggered.connect(self.level_view.zoom_in)
        self.spinner_panel.zoom_out_triggered.connect(self.level_view.zoom_out)
        self.spinner_panel.object_change.connect(self.on_spin)

        self.object_list = ObjectList(self, self.level_ref, self.context_menu)

        self.object_dropdown = ObjectDropdown(self)
        self.object_dropdown.object_selected.connect(
            self._on_placeable_object_selected)

        self.level_size_bar = LevelSizeBar(self, self.level_ref)
        self.enemy_size_bar = EnemySizeBar(self, self.level_ref)

        self.jump_list = JumpList(self, self.level_ref)
        self.jump_list.add_jump.connect(self.on_jump_added)
        self.jump_list.edit_jump.connect(self.on_jump_edit)
        self.jump_list.remove_jump.connect(self.on_jump_removed)

        splitter = QSplitter(self)
        splitter.setOrientation(Qt.Vertical)

        splitter.addWidget(self.object_list)
        splitter.setStretchFactor(0, 1)
        splitter.addWidget(self.jump_list)

        splitter.setChildrenCollapsible(False)

        level_toolbar = QToolBar("Level Info Toolbar", self)
        level_toolbar.setContextMenuPolicy(Qt.PreventContextMenu)
        level_toolbar.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)
        level_toolbar.setOrientation(Qt.Horizontal)
        level_toolbar.setFloatable(False)

        level_toolbar.addWidget(self.spinner_panel)
        level_toolbar.addWidget(self.object_dropdown)
        level_toolbar.addWidget(self.level_size_bar)
        level_toolbar.addWidget(self.enemy_size_bar)
        level_toolbar.addWidget(splitter)

        level_toolbar.setAllowedAreas(Qt.LeftToolBarArea | Qt.RightToolBarArea)

        self.addToolBar(Qt.RightToolBarArea, level_toolbar)

        self.object_toolbar = ObjectToolBar(self)
        self.object_toolbar.object_selected.connect(
            self._on_placeable_object_selected)

        object_toolbar = QToolBar("Object Toolbar", self)
        object_toolbar.setContextMenuPolicy(Qt.PreventContextMenu)
        object_toolbar.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)
        object_toolbar.setFloatable(False)

        object_toolbar.addWidget(self.object_toolbar)
        object_toolbar.setAllowedAreas(Qt.LeftToolBarArea
                                       | Qt.RightToolBarArea)

        self.addToolBar(Qt.LeftToolBarArea, object_toolbar)

        menu_toolbar = QToolBar("Menu Toolbar", self)
        menu_toolbar.setOrientation(Qt.Horizontal)
        menu_toolbar.setIconSize(QSize(20, 20))

        menu_toolbar.addAction(
            icon("settings.svg"),
            "Editor Settings").triggered.connect(show_settings)
        menu_toolbar.addSeparator()
        menu_toolbar.addAction(icon("folder.svg"),
                               "Open ROM").triggered.connect(self.on_open_rom)
        menu_toolbar.addAction(
            icon("save.svg"), "Save Level").triggered.connect(self.on_save_rom)
        menu_toolbar.addSeparator()

        self.undo_action = menu_toolbar.addAction(icon("rotate-ccw.svg"),
                                                  "Undo Action")
        self.undo_action.triggered.connect(self.level_ref.undo)
        self.undo_action.setEnabled(False)
        self.redo_action = menu_toolbar.addAction(icon("rotate-cw.svg"),
                                                  "Redo Action")
        self.redo_action.triggered.connect(self.level_ref.redo)
        self.redo_action.setEnabled(False)

        menu_toolbar.addSeparator()
        menu_toolbar.addAction(icon("play-circle.svg"),
                               "Play Level").triggered.connect(self.on_play)
        menu_toolbar.addSeparator()
        menu_toolbar.addAction(icon("zoom-out.svg"),
                               "Zoom Out").triggered.connect(
                                   self.level_view.zoom_out)
        menu_toolbar.addAction(icon("zoom-in.svg"),
                               "Zoom In").triggered.connect(
                                   self.level_view.zoom_in)
        menu_toolbar.addSeparator()
        menu_toolbar.addAction(icon("tool.svg"),
                               "Edit Level Header").triggered.connect(
                                   self.on_header_editor)
        self.jump_destination_action = menu_toolbar.addAction(
            icon("arrow-right-circle.svg"), "Go to Jump Destination")
        self.jump_destination_action.triggered.connect(
            self._go_to_jump_destination)
        menu_toolbar.addSeparator()
        # menu_toolbar.addAction(icon("help-circle.svg"), "What's this?")

        self.addToolBar(Qt.TopToolBarArea, menu_toolbar)

        self.status_bar = ObjectStatusBar(self, self.level_ref)
        self.setStatusBar(self.status_bar)

        self.delete_shortcut = QShortcut(QKeySequence(Qt.Key_Delete), self,
                                         self.remove_selected_objects)

        QShortcut(QKeySequence(Qt.CTRL + Qt.Key_X), self, self._cut_objects)
        QShortcut(QKeySequence(Qt.CTRL + Qt.Key_C), self, self._copy_objects)
        QShortcut(QKeySequence(Qt.CTRL + Qt.Key_V), self, self._paste_objects)

        QShortcut(QKeySequence(Qt.CTRL + Qt.Key_Z), self, self.level_ref.undo)
        QShortcut(QKeySequence(Qt.CTRL + Qt.Key_Y), self, self.level_ref.redo)
        QShortcut(QKeySequence(Qt.CTRL + Qt.SHIFT + Qt.Key_Z), self,
                  self.level_ref.redo)

        QShortcut(QKeySequence(Qt.CTRL + Qt.Key_Plus), self,
                  self.level_view.zoom_in)
        QShortcut(QKeySequence(Qt.CTRL + Qt.Key_Minus), self,
                  self.level_view.zoom_out)

        QShortcut(QKeySequence(Qt.CTRL + Qt.Key_A), self,
                  self.level_view.select_all)

        if not self.on_open_rom(path_to_rom):
            self.deleteLater()

        self.showMaximized()
Ejemplo n.º 4
0
class PlotPieWindow(QMainWindow):
    def __init__(self, title, labels=[], data=[], table_name="", field_name="", random_colors=False, has_explode=True, parent=None):
        super().__init__(parent)
        self._main_widget = QWidget(self)
        self._layout = QVBoxLayout(self._main_widget)
        self._title = title 
        self._data = data
        self._df_data = {k:v for (k,v) in zip(labels, data)} 
        
        self.setWindowTitle(title)
        # Pie chart, where the slices will be ordered and plotted counter-clockwise:
        self._labels = labels 
        self._sizes = data 
        self._legend_labels = [label+" - "+"{:.1f}".format(value)+"%" for label, value in zip(self._labels, self._sizes)]
        self._last_column = excelColumnFromNumber(len(self._labels))
        self._plot_location = excelColumnFromNumber(len(self._data)+2)
        explode = [0 for value in data]
        explode[1] = 0.1
        explode = tuple(explode)

        self._figure = plt.figure(figsize=(5, 4), dpi=100, facecolor=(1,1,1), edgecolor=(0,0,0))
        self.ax = self._figure.add_subplot()
        self._canvas = FigureCanvas(self._figure)
        colors = ['yellowgreen', 'lightskyblue']
        self._navigation_toolbar = NavigationToolbar(self._canvas, None)
        self.addToolBar(self._navigation_toolbar)
        if random_colors:
            if has_explode:
                self.ax.pie(self._sizes, explode=explode, autopct = "%1.1f%%", shadow=True, startangle=int(90))
            else:
                self.ax.pie(self._sizes, autopct = "%1.1f%%", shadow=True, startangle=int(90))
        else:
            if has_explode:
                self.ax.pie(self._sizes, explode=explode, colors=colors, autopct = "%1.1f%%", shadow=True, startangle=int(90))
            else:
                self.ax.pie(self._sizes, colors=colors, autopct = "%1.1f%%", shadow=True, startangle=int(90))
        self.ax.legend(labels=self._legend_labels, loc="best")
        # Equal aspect ratio ensures that pie is drawn as a circle.
        self.ax.axis("equal")
        self.ax.set_title(title)

        self._bottom_toolbar = QToolBar(self)
        self._bottom_toolbar.setMovable(False)
        self._bottom_toolbar.setFloatable(False)
        self._bottom_toolbar.setStyleSheet("QToolBar {border-bottom: None; border-top: 1px solid #BBBBBB;}")
        self._table_name_label = QLabel(" Table:")
        self._field_name_label = QLabel(" Field:")
        self._table_name = FormEntry(self)
        self._table_name.setMaximumHeight(20)
        self._field_name = FormEntry(self)
        self._field_name.setMaximumHeight(20)
        self._table_name.setReadOnly(True)
        self._field_name.setReadOnly(True)
        self._table_name.setText(table_name)
        self._field_name.setText(field_name)
        self._bottom_toolbar.addWidget(self._table_name_label)
        self._bottom_toolbar.addWidget(self._table_name)
        self._bottom_toolbar.addWidget(self._field_name_label)
        self._bottom_toolbar.addWidget(self._field_name)
        
        self._export_chart_button = QPushButton("Export")
        self._export_chart_button.setIcon(QIcon(QPixmap("export.png")))
        self._export_chart_button.clicked.connect(self.exportChart)
        
        self._bottom_toolbar.addWidget(HorizontalFiller(self))
        self._bottom_toolbar.addWidget(self._export_chart_button)
        self.addToolBar(Qt.BottomToolBarArea, self._bottom_toolbar)
        self.setCentralWidget(self._canvas)
 
    def exportChartFileDialog(self):
        file_dialog = QFileDialog()
        file_dialog.setNameFilters(["*. xlsx"])
        file_name, ext = file_dialog.getSaveFileName(self, 'Export File', "", "Excel (*.xlsx)")
            
        if file_name and ext == "Excel (*.xlsx)":
            return file_name 
        return ""

    def exportChart(self):
        file_name = self.exportChartFileDialog()
        if file_name != "":
            title = self.ax.title.get_text()
            df = pd.DataFrame(data=[self._df_data])
            writer = pd.ExcelWriter(file_name, engine='xlsxwriter')
            df.to_excel(writer, sheet_name='Pie_Chart', index=False)
            workbook = writer.book
            worksheet = writer.sheets["Pie_Chart"]
            chart = workbook.add_chart({"type": 'pie'})
            chart.set_title({"name": title})
            chart.add_series({"categories": "=Pie_Chart!$A$1:${lc}$1".format(lc = self._last_column), "values": "=Pie_Chart!$A$2:${lc}$2".format(lc = self._last_column)})
            worksheet.insert_chart(self._plot_location+"2", chart)
            writer.save()
            writer.close()
Ejemplo n.º 5
0
class PlotBarWindow(QMainWindow):
    def __init__(self, title, labels=[], data=[], table_name="", field_name="", x_label=None, y_label=None, parent=None, already_sorted=False):
        super().__init__(parent)
        self._title = title 
        self._labels = labels 
        self._data = data
        self._last_column = excelColumnFromNumber(len(self._data))
        self._plot_location = excelColumnFromNumber(len(self._data)+2)
        self._x_label = x_label
        self._y_label = y_label
        self._already_sorted = already_sorted

        self.setWindowTitle(self._title)
        self._figure = plt.figure(figsize=(5, 4), dpi=100, facecolor=(1,1,1), edgecolor=(0,0,0))
        self.ax = self._figure.add_subplot()
        self.ax.set_title(self._title)
        self._canvas = FigureCanvas(self._figure)
        self._navigation_toolbar = NavigationToolbar(self._canvas, None)
        self.addToolBar(self._navigation_toolbar)
        self._bottom_toolbar = QToolBar(self)
        self._bottom_toolbar.setMovable(False)
        self._bottom_toolbar.setFloatable(False)
        self._bottom_toolbar.setStyleSheet("QToolBar {border-bottom: None; border-top: 1px solid #BBBBBB;}")
        self._table_name_label = QLabel(" Table:")
        self._field_name_label = QLabel(" Field:")
        self._table_name = FormEntry(self)
        self._table_name.setMaximumHeight(20)
        self._field_name = FormEntry(self)
        self._field_name.setMaximumHeight(20)
        self._table_name.setReadOnly(True)
        self._field_name.setReadOnly(True)
        self._table_name.setText(table_name)
        self._field_name.setText(field_name)
        self._bottom_toolbar.addWidget(self._table_name_label)
        self._bottom_toolbar.addWidget(self._table_name)
        self._bottom_toolbar.addWidget(self._field_name_label)
        self._bottom_toolbar.addWidget(self._field_name)
        self._export_chart_button = QPushButton("Export")
        self._export_chart_button.setIcon(QIcon(QPixmap("export.png")))
        self._export_chart_button.clicked.connect(self.exportChart)
        self._bottom_toolbar.addWidget(HorizontalFiller(self))

        self._bottom_toolbar.addWidget(self._export_chart_button)
        self.addToolBar(Qt.BottomToolBarArea, self._bottom_toolbar)

        self.ax.bar(self._labels, self._data)
        if self._x_label != None:
            self.ax.set_xlabel(self._x_label)
        if self._y_label != None:
            self.ax.set_ylabel(self._y_label)
        self.setCentralWidget(self._canvas)

    def exportChartFileDialog(self):
        file_dialog = QFileDialog()
        file_dialog.setNameFilters(["*. xlsx"])
        file_name, ext = file_dialog.getSaveFileName(self, 'Export File', "", "Excel (*.xlsx)")
            
        if file_name and ext == "Excel (*.xlsx)":
            return file_name 
        return ""

    def exportChart(self):
        file_name = self.exportChartFileDialog()
        field_name = self._field_name.text()
        if file_name != "":
            title = self.ax.title.get_text()
            last_row = len(self._data)+2
            labels = sorted(self._labels)
            if self._already_sorted:
                sorted_data = {label:[self._data[i]] for i, label in enumerate(self._labels)}
            else:
                data = {label:[self._data[i]] for i, label in enumerate(self._labels)}
                sorted_data = {label:data[label] for label in labels}
            df = pd.DataFrame(data=sorted_data)
            
            writer = pd.ExcelWriter(file_name, engine='xlsxwriter')
            df.to_excel(writer, sheet_name=field_name, index=False)
            workbook = writer.book
            worksheet = writer.sheets[field_name]
            chart = workbook.add_chart({"type": 'column'})
            chart.set_title({"name": title})
            if self._x_label != None:
                chart.set_x_axis({'name': self._x_label})
            if self._y_label != None:
                chart.set_y_axis({'name': self._y_label})
            chart.add_series({"categories": "={fn}!$A$1:${lc}$1".format(lc=self._last_column, fn=field_name), 
                              "values": "={fn}!$A$2:${lc}$2".format(lc=self._last_column, fn=field_name), 
                              "fill": {'color': '#0000CC'}})
            worksheet.insert_chart(self._plot_location+"2", chart)
            writer.save()
            writer.close()
Ejemplo n.º 6
0
class PlotHBarWindow(QMainWindow):
    def __init__(self, title, labels=[], data=[], table_name="", field_name="", parent=None):
        super().__init__(parent)
        self._title = title 
        self._labels = labels 
        self._data = data
        self._last_column = excelColumnFromNumber(len(self._data))
        self._plot_location = excelColumnFromNumber(len(self._data)+2)

        self.setWindowTitle(self._title)
        self._figure = plt.figure(figsize=(5, 4), dpi=100, facecolor=(1,1,1), edgecolor=(0,0,0))
        self.ax = self._figure.add_subplot()
        self.ax.set_title(self._title)
        self._canvas = FigureCanvas(self._figure)
        self._navigation_toolbar = NavigationToolbar(self._canvas, None)
        self.addToolBar(self._navigation_toolbar)
        self._bottom_toolbar = QToolBar(self)
        self._bottom_toolbar.setMovable(False)
        self._bottom_toolbar.setFloatable(False)
        self._bottom_toolbar.setStyleSheet("QToolBar {border-bottom: None; border-top: 1px solid #BBBBBB;}")
        self._table_name_label = QLabel(" Table:")
        self._field_name_label = QLabel(" Field:")
        self._table_name = FormEntry(self)
        self._table_name.setMaximumHeight(20)
        self._field_name = FormEntry(self)
        self._field_name.setMaximumHeight(20)
        self._table_name.setReadOnly(True)
        self._field_name.setReadOnly(True)
        self._table_name.setText(table_name)
        self._field_name.setText(field_name)
        self._bottom_toolbar.addWidget(self._table_name_label)
        self._bottom_toolbar.addWidget(self._table_name)
        self._bottom_toolbar.addWidget(self._field_name_label)
        self._bottom_toolbar.addWidget(self._field_name)
        self._export_chart_button = QPushButton("Export")
        self._export_chart_button.setIcon(QIcon(QPixmap("export.png")))
        self._export_chart_button.clicked.connect(self.exportChart)
        self._bottom_toolbar.addWidget(HorizontalFiller(self))

        self._bottom_toolbar.addWidget(self._export_chart_button)
        self.addToolBar(Qt.BottomToolBarArea, self._bottom_toolbar)

        y_pos = np.arange(len(data))
        self.ax.barh(y_pos, data, align="center", color='lightskyblue', alpha=0.5)
        self.ax.set_xlabel(labels[len(labels)-1])
        #self.ax.set_ylabel(labels[1])
        
        rects = self.ax.patches
        low_rect = rects[0]
        high_rect = rects[len(rects)-1]
        width = low_rect.get_width()
        self.ax.text(low_rect.get_x()+width, low_rect.get_y()+1, "Lowest: $"+str(data[0]))
        width = high_rect.get_width()
        self.ax.text(high_rect.get_x(), high_rect.get_y()+1, "Highest: $"+str(data[len(data)-1]))
        self.setCentralWidget(self._canvas)
    
    def exportChartFileDialog(self):
        file_dialog = QFileDialog()
        file_dialog.setNameFilters(["*. xlsx"])
        file_name, ext = file_dialog.getSaveFileName(self, 'Export File', "", "Excel (*.xlsx)")
            
        if file_name and ext == "Excel (*.xlsx)":
            return file_name 
        return ""

    def exportChart(self):
        file_name = self.exportChartFileDialog()
        field_name = self._field_name.text()
        if file_name != "":
            title = self.ax.title.get_text()
            last_row = len(self._data)+2
            col_1 = ["" for data in self._data]
            col_2 = col_1.copy()
            col_1[0] = self._data[0]
            col_2[0] = self._data[len(self._data)-1]
            data = {
                self._labels[0]: self._data,
                self._labels[1]: col_1,
                self._labels[2]: col_2
            }
            df = pd.DataFrame(data=data)
            
            writer = pd.ExcelWriter(file_name, engine='xlsxwriter')
            df.to_excel(writer, sheet_name=field_name, index=False)
            workbook = writer.book
            worksheet = writer.sheets[field_name]
            chart = workbook.add_chart({"type": 'bar'})
            chart.set_title({"name": title})
            chart.set_x_axis({'name': self._labels[0]})
            chart.add_series({"values": "={fn}!$A$2:$A${lr}".format(lr=last_row, fn=field_name), 'fill': {'color': '#0000CC'}, 'border': {'color': '#0000CC'}})
            worksheet.insert_chart(self._plot_location+"2", chart)
            writer.save()
            writer.close()
class MainUI(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowFlags(Qt.FramelessWindowHint)
        #self.setAttribute(Qt.WA_TranslucentBackground, True)
        self.setFixedSize(601, 401)
        self.toolbar_selected = False

        self.toolbar = QToolBar()
        self.toolbar.setObjectName("toolbar")
        self.toolbar.setMovable(False)
        self.toolbar.setFloatable(False)
        self.toolbar.setContextMenuPolicy(
            Qt.PreventContextMenu)  # no right-click on toolbar
        self.addToolBar(self.toolbar)
        self.toolbar.setStyleSheet("background-color: khaki")

        self.admin_btn = QPushButton("Admin", self)
        self.admin_btn.setObjectName("admin_btn")
        self.admin_btn.setFixedSize(65, 30)

        self.info_btn = QPushButton("Info", self)
        self.info_btn.setObjectName("info_btn")
        self.info_btn.setFixedSize(35, 30)

        self.spacer = QWidget()
        self.spacer.setObjectName("toolbar_spacer")
        self.spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)

        self.toolbar_label = QLabel("")
        self.toolbar_label.setObjectName("toolbar_label")
        self.toolbar_label.setAlignment(Qt.AlignCenter)
        self.toolbar_label.setSizePolicy(QSizePolicy.Expanding,
                                         QSizePolicy.Fixed)

        self.close_btn = QPushButton(" X")
        self.close_btn.setObjectName("close_btn")
        self.close_btn.setFixedSize(30, 30)

        self.toolbar.addWidget(self.admin_btn)
        # self.toolbar.addWidget(self.spacer)
        self.toolbar.addWidget(self.toolbar_label)
        # self.toolbar.addWidget(self.spacer)
        self.toolbar.addWidget(self.info_btn)
        self.toolbar.addWidget(self.close_btn)

        self.toolbar_label.mousePressEvent = self.mousePressEvent  # to move window
        self.mousePressEvent = self.mousePressEvent_  # to check if window content is selected or not
        self.close_btn.pressed.connect(self.close_window)

    def mousePressEvent_(self, e):
        """ to be able to drag window just via toolbar
		I made this custome mousePressEvent to filter any click,
		other than toolbar.
		If we click on any place on the window(except the toolbar),
		this method will be activated and set the toolbar_selected=false,
		so that we won't be able do anything in normal mousePressEvent			
		"""
        self.toolbar_selected = False

    def mousePressEvent(self, e):
        self.toolbar_selected = True
        """ If defiend section is pressed 
		Activate the mouseMoveEvent to
		get the mouse positions
		"""
        self.mouse_pressed = True
        self.old_pos = e.globalPos()

    def mouseMoveEvent(self, e):
        """ move the whole window to mouse position
		"""
        if self.toolbar_selected:
            delta = QPoint(e.globalPos() - self.old_pos)
            self.move(self.x() + delta.x(), self.y() + delta.y())
            self.old_pos = e.globalPos()

    def close_window(self):
        self.close()