Example #1
0
    def BuildActionDataDict(self, possible_actions: dict) -> dict:
        """
        Compiles a dict clone of the ActionDatabase, limited to a specific subset of categories and actions defined
        in 'possible_actions'
        """
        # Build our action data dict
        compiled_dict = {}
        for category_name, action_list in possible_actions.items():
            # Clone the entire category structure so we don't try and piecemeal it, potentially creating issues
            # in the future if we change the structure
            category_data = copy.deepcopy(
                Settings.getInstance().action_database[category_name])

            # Wipe the available options, as we're going to rebuild the list with only those we can use
            category_data["options"] = []

            # For every action we want, find the matching entry in the database and clone it

            for action_name in action_list:
                for db_action in Settings.getInstance(
                ).action_database[category_name]["options"]:
                    if action_name == db_action["display_name"]:
                        category_data["options"].append(
                            copy.deepcopy(db_action))
                        break

            # Add the completed clone to the main dict
            compiled_dict[category_name] = category_data

        return compiled_dict
Example #2
0
 def MakeUneditable(self):
     self.input_widget.setEnabled(False)
     self.input_widget_alt.setEnabled(False)
     self.input_widget.setStyleSheet(
         Settings.getInstance().read_only_background_color)
     self.input_widget_alt.setStyleSheet(
         Settings.getInstance().read_only_background_color)
Example #3
0
    def CreateGettingStartedDisplay(self):
        """ Creates some temporary UI elements that inform the user how to prepare the editor """
        self.getting_started_container = QtWidgets.QWidget()
        self.getting_started_layout = QtWidgets.QVBoxLayout(
            self.getting_started_container)

        getting_started_title = QtWidgets.QLabel("Getting Started")
        getting_started_title.setFont(
            Settings.getInstance().editor_info_title_font)
        getting_started_title.setStyleSheet(
            Settings.getInstance().editor_info_title_color)

        getting_started_message = QtWidgets.QLabel()
        getting_started_message.setText(
            "To access editor features, please open a Heartbeat project: \n\n"
            "1) Go to 'File' -> 'New Project' to Create a new Heartbeat project\n"
            "2) Go to 'File' -> 'Open Project' to Open an existing Heartbeat project"
        )
        getting_started_message.setFont(
            Settings.getInstance().editor_info_paragraph_font)
        getting_started_message.setStyleSheet(
            Settings.getInstance().editor_info_paragraph_color)

        self.getting_started_layout.setAlignment(Qt.AlignCenter)
        self.getting_started_layout.addWidget(getting_started_title)
        self.getting_started_layout.addWidget(getting_started_message)

        self.main_resize_container.addWidget(self.getting_started_container)
Example #4
0
    def NewFile(self):
        """
        Prompts the user for a type of file to create, and a location & name for the new file. Then creates that
        file, and loads the respective editor
        """
        # Only allow this is there is an active project
        if not Settings.getInstance().user_project_name:
            self.ShowNoActiveProjectPrompt()
        else:
            new_file_prompt = NewFileMenu("Content/Icons/Engine_Logo.png",
                                          "Choose a File Type")

            # Did the user successfully choose something?
            if new_file_prompt.exec():

                selected_type = new_file_prompt.GetSelection()
                prompt = FileSystemPrompt(self.main_window)
                result = prompt.SaveFile(
                    Settings.getInstance().supported_content_types['Data'],
                    Settings.getInstance().GetProjectContentDirectory(),
                    "Save File As")

                # Did the user choose a place and a name for the new file?
                if result:
                    with open(result, 'w') as new_file:
                        pass
                        Logger.getInstance().Log(f"File created - {result}", 2)

                    # Create the editor, then export to initially populate the new file
                    self.OpenEditor(result, selected_type)
                    self.active_editor.Export()
                else:
                    Logger.getInstance().Log(
                        "File information was not provided - Cancelling 'New File' action",
                        3)
Example #5
0
    def __init__(self, action_data, select_func, size_refresh_func):
        super().__init__()

        # Store a func object that is used when this entry is selected
        self.select_func = select_func

        # Store a func object that is used when the row containing this object should be resized based on the
        # subtext data in this object
        self.size_refresh_func = size_refresh_func

        # Store this entries action data
        self.action_data = action_data

        # ****** DISPLAY WIDGETS ******
        self.main_layout = QtWidgets.QVBoxLayout(self)
        self.main_layout.setSpacing(0)
        self.main_layout.setContentsMargins(0, 0, 0, 0)

        # Name
        self.name_widget = QtWidgets.QLabel()
        self.name_widget.setFont(Settings.getInstance().header_2_font)
        self.name_widget.setStyleSheet(Settings.getInstance().header_2_color)
        self.name_widget.setText(self.action_data["display_name"])

        # Details
        self.subtext_widget = QtWidgets.QLabel()
        self.subtext_widget.setFont(Settings.getInstance().subtext_font)
        self.subtext_widget.setStyleSheet(Settings.getInstance().subtext_color)

        # Refresh the subtext
        self.UpdateSubtext()

        # Add everything to the layout
        self.main_layout.addWidget(self.name_widget)
        self.main_layout.addWidget(self.subtext_widget)
Example #6
0
    def SetActiveProject(self, project_name, project_dir):
        """ Sets the active project, pointing the editor to the new location, and refreshing the interface """
        Settings.getInstance().user_project_name = project_name
        Settings.getInstance().user_project_dir = project_dir.replace(
            "\\", "/")
        Settings.getInstance().LoadProjectSettings()

        # If this is the first time a user is loading a project after opening the editor, delete the 'Getting Started'
        # display
        if self.e_ui.getting_started_container:
            target = self.e_ui.main_resize_container.widget(0)
            target.deleteLater()
            self.e_ui.getting_started_container = None

            self.e_ui.CreateMainTabContainer()
            self.e_ui.CreateOutliner()

        # Clear any open editor tabs
        self.e_ui.main_tab_editor.clear()

        # Refresh U.I text using any active translations
        self.e_ui.retranslateUi(self.main_window)

        # Update the outliner with the new project root
        self.outliner.UpdateRoot(
            Settings.getInstance().GetProjectContentDirectory())
Example #7
0
    def __init__(self, details_panel, type_filter, refresh_func=None):
        super().__init__(refresh_func)

        self.details_panel = details_panel

        # Store a type filter to restrict what files can be chosen in the browser
        self.type_filter = type_filter

        self.input_widget = QtWidgets.QLineEdit()
        self.input_widget.setFont(Settings.getInstance().paragraph_font)
        self.input_widget.setStyleSheet(Settings.getInstance().paragraph_color)
        self.input_widget.setText("None")
        self.input_widget.textChanged.connect(self.InputValueUpdated)
        self.input_widget.setEnabled(True)

        # Create the file selector button, and style it accordingly
        self.file_select_button = QtWidgets.QToolButton()
        icon = QtGui.QIcon()
        icon.addPixmap(
            QtGui.QPixmap(Settings.getInstance().ConvertPartialToAbsolutePath(
                "Content/Icons/Open_Folder.png")), QtGui.QIcon.Normal,
            QtGui.QIcon.Off)
        self.file_select_button.setIcon(icon)

        # Add input elements to the layout
        self.main_layout.addWidget(self.input_widget)
        self.main_layout.addWidget(self.file_select_button)

        # Connect Signals
        self.file_select_button.clicked.connect(self.OpenFilePrompt)
Example #8
0
    def SaveAs(self):
        """ Prompts the user for a new location and file name to save the active editor's data """
        # Only allow this is there is an active project
        if not Settings.getInstance().user_project_name:
            self.ShowNoActiveProjectPrompt()
        else:
            # The user is not allowed to rename the project settings file due to the number of dependencies on it
            if self.active_editor.file_type is FileType.Project_Settings:
                Logger.getInstance().Log(
                    "Project Settings can not be renamed or saved to a new location",
                    3)
            else:
                prompt = FileSystemPrompt(self.main_window)
                new_file_path = prompt.SaveFile(
                    Settings.getInstance().supported_content_types['Data'],
                    self.active_editor.GetFilePath(),
                    "Choose a Location to Save the File", True)

                if not new_file_path:
                    Logger.getInstance().Log(
                        "File path was not provided - Cancelling 'SaveAs' action",
                        3)
                else:
                    can_save = self.ValidateNewFileLocation(new_file_path)
                    if can_save:
                        self.active_editor.file_path = new_file_path
                        self.e_ui.main_tab_editor.setTabText(
                            self.e_ui.main_tab_editor.currentIndex(),
                            self.active_editor.GetFileName())
                        self.active_editor.Export()
Example #9
0
 def CreateEntryWidget(self, data, data_type):
     """ Create a specialized entry widget based on the provided ParameterType """
     if data_type == ParameterType.String:
         return InputEntryText(None)
     elif data_type == ParameterType.Bool:
         return InputEntryBool(None)
     elif data_type == ParameterType.Int:
         return InputEntryInt(None)
     elif data_type == ParameterType.Vector2:
         return InputEntryTuple(None)
     elif data_type == ParameterType.Paragraph:
         return InputEntryParagraph(None)
     elif data_type == ParameterType.Color:
         return InputEntryColor(None)
     elif data_type == ParameterType.File:
         return InputEntryFileSelector(self, "", None)
     elif data_type == ParameterType.File_Font:
         return InputEntryFileSelector(
             self,
             Settings.getInstance().supported_content_types['Font'], None)
     elif data_type == ParameterType.File_Image:
         return InputEntryFileSelector(
             self,
             Settings.getInstance().supported_content_types['Image'], None)
     elif data_type == ParameterType.Dropdown:
         return InputEntryDropdown(data, None)
     elif data_type == ParameterType.CUST_Resolution:
         return InputEntryResolution(data, self.core.project_settings)
     else:
         return None
Example #10
0
    def __init__(self, refresh_func=None):
        super().__init__()

        # When the input widget is updated, in case another U.I element needs to refresh, allow us to execute an
        # ambiguous function
        self.refresh_func = refresh_func

        # Details entries have three main widgets: 'name_widget', 'input_widget' and 'global_toggle'.
        # - 'name_widget': A standalone text widget representing the name of the detail
        # - 'input_widget': Kept inside 'input_container' as to allow any number of input_widgets for child classes
        # - 'global_toggle': A checkbox representing whether to use a global value or the value in the 'input_widget'

        # 'name_widget' and 'input_widget' are declared, but not initialized as it is up to the subclass to
        # do that
        self.name_widget = QtWidgets.QLabel()
        self.name_widget.setFont(Settings.getInstance().paragraph_font)
        self.name_widget.setStyleSheet(Settings.getInstance().paragraph_color)

        self.input_widget = None
        self.input_container = QtWidgets.QWidget()

        # 'global_toggle' is not supposed to be shown for all entries. It's only used for entries that need it
        self.show_global_toggle = False
        self.global_toggle = SimpleCheckbox(self.GlobalToggle)
        self.global_toggle.setToolTip(
            "Whether to use the global value specified in the project file for this entry"
        )

        self.main_layout = QtWidgets.QHBoxLayout(self.input_container)
        self.main_layout.setContentsMargins(0, 0, 0, 0)
Example #11
0
    def __init__(self, l_core):
        super().__init__()

        self.l_core = l_core

        font = QtGui.QFont()
        font.setBold(True)
        font.setWeight(75)

        # Main Layout
        self.main_layout = QtWidgets.QVBoxLayout(self)
        self.main_layout.setContentsMargins(4, 2, 4, 2)
        self.main_layout.setSpacing(0)

        # Toolbar
        self.logger_toolbar = QtWidgets.QFrame(self)
        self.logger_toolbar.setAutoFillBackground(False)
        self.logger_toolbar.setStyleSheet(
            "QFrame, QLabel, QToolTip {\n"
            "    border-radius: 4px;\n"
            f"   background-color: rgb({Settings.getInstance().toolbar_background_color});\n"
            "}")
        self.logger_toolbar.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.logger_toolbar.setFrameShadow(QtWidgets.QFrame.Raised)
        self.logger_toolbar_layout = QtWidgets.QHBoxLayout(self.logger_toolbar)
        self.logger_toolbar_layout.setContentsMargins(2, 2, 2, 2)
        self.logger_toolbar_layout.setSpacing(0)

        # Generic Button Settings
        icon = QtGui.QIcon()
        button_style = (
            f"background-color: rgb({Settings.getInstance().toolbar_button_background_color});\n"
        )

        # Clear Log Button
        self.clear_log_button = QtWidgets.QToolButton(self.logger_toolbar)
        self.clear_log_button.setStyleSheet(button_style)
        icon.addPixmap(
            QtGui.QPixmap(Settings.getInstance().ConvertPartialToAbsolutePath("Content/Icons/Trash.png")),
            QtGui.QIcon.Normal,
            QtGui.QIcon.Off
        )
        self.clear_log_button.setIcon(icon)
        self.clear_log_button.clicked.connect(self.l_core.ClearLog)

        # Add buttons to toolbar
        self.logger_toolbar_layout.addWidget(self.clear_log_button)
        toolbar_spacer = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.logger_toolbar_layout.addItem(toolbar_spacer)

        # Logger data list
        self.log_list = QtWidgets.QListWidget(self)
        self.log_list.setFont(Settings.getInstance().paragraph_font)
        self.log_list.setStyleSheet(Settings.getInstance().paragraph_color)
        self.log_list.setAutoScroll(True)

        # Add everything to the main container
        self.main_layout.addWidget(self.logger_toolbar)
        self.main_layout.addWidget(self.log_list)
Example #12
0
 def Clean(self):
     """ Cleans the active project's build folder """
     # Only allow this is there is an active project
     if not Settings.getInstance().user_project_name:
         self.ShowNoActiveProjectPrompt()
     else:
         HBBuilder.Clean(Logger.getInstance(),
                         Settings.getInstance().user_project_dir)
Example #13
0
    def __init__(self, refresh_func=None):
        super().__init__(refresh_func)

        self.input_widget = QtWidgets.QLineEdit()
        self.input_widget.setFont(Settings.getInstance().paragraph_font)
        self.input_widget.setStyleSheet(Settings.getInstance().paragraph_color)
        self.input_widget.textChanged.connect(self.InputValueUpdated)

        # Add input elements to the layout
        self.main_layout.addWidget(self.input_widget)
Example #14
0
 def Build(self):
     """ Launches the HBBuilder in order to generate an executable from the active project """
     # Only allow this is there is an active project
     if not Settings.getInstance().user_project_name:
         self.ShowNoActiveProjectPrompt()
     else:
         HBBuilder.Build(Logger.getInstance(),
                         Settings.getInstance().engine_root,
                         Settings.getInstance().user_project_dir,
                         Settings.getInstance().user_project_name)
Example #15
0
 def Play(self):
     """ Launches the HBEngine, temporarily suspending the HBEditor """
     # Only allow this is there is an active project
     if not Settings.getInstance().user_project_name:
         self.ShowNoActiveProjectPrompt()
     else:
         p_manager = PlayManager()
         p_manager.Play(self.e_ui.central_widget,
                        Settings.getInstance().user_project_dir,
                        Settings.getInstance().root)
Example #16
0
    def GetDetailsWidget(self, data: dict):
        """ Given an action data dict, create and return the relevant details widget """
        #@TODO: Can this be converted to use an enum?

        data_type = data['type']

        if data_type == "str":
            return InputEntryText(self.DetailEntryUpdated)
        elif data_type == "paragraph":
            return InputEntryParagraph(self.DetailEntryUpdated)
        elif data_type == "vector2":
            return InputEntryTuple(self.DetailEntryUpdated)
        elif data_type == "bool":
            return InputEntryBool(self.DetailEntryUpdated)
        elif data_type == "color":
            return InputEntryColor(self.DetailEntryUpdated)
        elif data_type == "int":
            return InputEntryInt(self.DetailEntryUpdated)
        elif data_type == "float":
            return InputEntryFloat(self.DetailEntryUpdated)
        elif data_type == "file":
            return InputEntryFileSelector(self, "", self.DetailEntryUpdated)
        elif data_type == "file_data":
            return InputEntryFileSelector(
                self,
                Settings.getInstance().supported_content_types["Data"],
                self.DetailEntryUpdated)
        elif data_type == "file_image":
            return InputEntryFileSelector(
                self,
                Settings.getInstance().supported_content_types["Image"],
                self.DetailEntryUpdated)
        elif data_type == "file_font":
            return InputEntryFileSelector(
                self,
                Settings.getInstance().supported_content_types["Font"],
                self.DetailEntryUpdated)
        elif data_type == "file_sound":
            return InputEntryFileSelector(
                self,
                Settings.getInstance().supported_content_types["Sound"],
                self.DetailEntryUpdated)
        elif data_type == "dropdown":
            return InputEntryDropdown(data['options'], self.DetailEntryUpdated)
        elif data_type == "choice":
            return InputEntryChoice(data, self.AddEntry,
                                    self.CreateEntryWidget, self.branch_list,
                                    self.DetailEntryUpdated)
        elif data_type == "container":
            new_entry = InputEntryContainer(data['children'])
            for child in data['children']:
                new_entry.addChild(self.CreateEntryWidget(child))

            return new_entry
Example #17
0
 def OpenProjectSettings(self):
     """ Opens the 'Project Settings' editor """
     # Normally we would have loaded this editor like the others, but since we need to bind loading this to a menu
     # button, we need it in the form of a function
     if not Settings.getInstance().user_project_name:
         self.ShowNoActiveProjectPrompt()
     else:
         self.OpenEditor(
             Settings.getInstance().user_project_dir + "/" +
             Settings.getInstance().project_default_files['Config'],
             FileType.Project_Settings, True)
Example #18
0
    def __init__(self, window_icon_path, window_name):
        super().__init__(window_icon_path, window_name)

        self.resize(400, 300)
        self.main_layout = QtWidgets.QVBoxLayout(self)
        self.options_layout = QtWidgets.QHBoxLayout(self)
        self.description_layout = QtWidgets.QVBoxLayout(self)
        self.buttons_layout = QtWidgets.QHBoxLayout(self)

        self.options_list = QtWidgets.QListWidget()
        icon = QtGui.QIcon()
        icon.addPixmap(
            QtGui.QPixmap(Settings.getInstance().ConvertPartialToAbsolutePath(
                "Content/Icons/Engine_Logo.png")), QtGui.QIcon.Normal,
            QtGui.QIcon.Off)
        FileOption(
            icon, FileType.Scene_Dialogue, "Scene (Dialogue)",
            "A scene containing a sequence of dialogue between characters. These files may contain additional branches",
            self.options_list)
        FileOption(
            icon, FileType.Scene_Point_And_Click, "Scene (Point & Click)",
            "A scene with interactable objects. Perfect for designing Point & Click scenes, or interactive maps",
            self.options_list)
        #FileOption(
        #    settings,
        #    icon,
        #    FileType.Character,
        #    "Character",
        #    "A file containing details on a character, such as a special font for their name, their unique color, or various sprites representing their moods",
        #    self.options_list
        #)

        self.description = QtWidgets.QLabel()
        self.description.setWordWrap(True)
        self.description.setFont(Settings.getInstance().paragraph_font)

        self.options_layout.addWidget(self.options_list, 2)
        self.options_layout.addWidget(self.description, 1, Qt.AlignTop)

        self.button_box = QtWidgets.QDialogButtonBox(
            QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel)
        self.buttons_layout.addWidget(self.button_box)

        self.main_layout.addLayout(self.options_layout)
        self.main_layout.addLayout(self.buttons_layout)

        # Signals
        self.options_list.currentItemChanged.connect(self.UpdateDescription)
        self.button_box.accepted.connect(self.accept)
        self.button_box.rejected.connect(self.reject)

        # Weird fix: For some reason, QListWidgets don't "select" the first entry by default despite it being
        # considered the "currentitem". This makes for a weird visual bug, so let's forcefully select it
        self.options_list.setCurrentRow(0)
Example #19
0
 def icon(self, fileInfo):
     # Override the icon function which returns the icon to use for each item in a QTree
     if fileInfo.isDir():
         return QtGui.QIcon(
             Settings.getInstance().ConvertPartialToAbsolutePath(
                 "Content/Icons/Folder.png"))
     elif fileInfo.suffix() in self.recognized_image_extensions:
         return QtGui.QIcon(
             Settings.getInstance().ConvertPartialToAbsolutePath(
                 "Content/Icons/File_Image.png"))
     return QtGui.QIcon(Settings.getInstance().ConvertPartialToAbsolutePath(
         "Content/Icons/File.png"))
Example #20
0
    def __init__(self, refresh_func=None):
        super().__init__(refresh_func)
        # NOTE FOR THE LOGIC IN THIS FILE
        # So for some unholy reason, Qt doesn't really have a great way of changing widget colors. While stylesheets
        # are nice, retrieving data from a stylesheet is a lesson in pain (You get ALL of the data, not just a part
        # you actually want

        # Additionally, to my knowledge, changing stylesheets don't cause a signal change unless you hook onto the
        # underlying events. I try to avoid this complexity, so the way this file handles detecting changes is different
        # than other detail types

        self.input_widget = QtWidgets.QFrame()
        self.input_widget.setFrameStyle(QtWidgets.QFrame.Panel)
        self.input_widget.setStyleSheet(
            "border: 1px solid rgb(122,122,122);background-color: rgb(255,255,255)"
        )

        # @TODO: Replace style sheet assignment with a QPalette to retain button state styles
        # Create the color selector button, and style it accordingly
        self.color_select_button = QtWidgets.QToolButton()
        icon = QtGui.QIcon()
        icon.addPixmap(
            QtGui.QPixmap(Settings.getInstance().ConvertPartialToAbsolutePath(
                "Content/Icons/Color_Wheel.png")), QtGui.QIcon.Normal,
            QtGui.QIcon.Off)
        self.color_select_button.setIcon(icon)
        self.color_select_button.clicked.connect(self.OpenColorPrompt)

        # Add input elements to the layout
        self.main_layout.addWidget(self.input_widget)
        self.main_layout.addWidget(self.color_select_button)
Example #21
0
    def CreateFile(self, path: str, file_type) -> str:
        """
        Create a file of the given file type, initially assigning it a temp name. Returns whether the action was
        successful
        """
        file_name_exists = True

        # Keep trying to create the file using a simple iterator. At some point, don't allow creating if the user has
        # somehow created enough files to max this...I really hope they don't
        for num in range(0, 100):
            full_file_path = path + f"/New_{file_type}_{num}.yaml"
            if not os.path.exists(full_file_path):

                # Doesn't exist. Create it!
                Writer.WriteFile(
                    "", full_file_path,
                    Settings.getInstance().GetMetadataString(
                        FileType[file_type]))
                return full_file_path

        # Somehow the user has all versions of the default name covered...Inform the user
        Logger.getInstance().Log(
            "Unable to create file as all default name iterations are taken",
            4)
        return None
Example #22
0
    def GetFile(self,
                starting_dir,
                type_filter,
                prompt_title="Choose a File",
                project_only=True) -> str:
        """ Opens up a prompt for choosing an existing file. If nothing is selected, return an empty string"""
        Logger.getInstance().Log("Requesting file path...")

        file_path = self.getOpenFileName(self.parent(), prompt_title,
                                         starting_dir, type_filter)

        # Did the user choose a value?
        if file_path[0]:
            selected_dir = file_path[0]

            if project_only:
                if Settings.getInstance().user_project_dir in selected_dir:
                    Logger.getInstance().Log("Valid file chosen")
                    return selected_dir
                else:
                    self.ShowPathOutsideProjectMessage()
                    return ""
            else:
                Logger.getInstance().Log("Valid file chosen")
                return selected_dir
        else:
            Logger.getInstance().Log("File name and path not provided", 3)
            return ""
Example #23
0
    def SaveFile(self,
                 type_filter,
                 starting_dir,
                 prompt_title="Save File",
                 project_only=True) -> str:
        """
        Prompts the user with a filedialog which has them specify a file to create or write to. If nothing
        is selected, return an empty string
        """

        file_path = self.getSaveFileName(self.parent(), prompt_title,
                                         starting_dir, type_filter)

        # Did the user choose a value?
        if file_path[0]:
            selected_dir = file_path[0]

            if project_only:
                if Settings.getInstance().user_project_dir in selected_dir:
                    Logger.getInstance().Log("Valid file chosen")
                    return selected_dir
                else:
                    self.ShowPathOutsideProjectMessage()
                    return ""
            else:
                Logger.getInstance().Log("Valid file chosen")
                return selected_dir
        else:
            Logger.getInstance().Log("File name and path not provided", 3)
            return ""
Example #24
0
    def OpenEditor(self, target_file_path, editor_type, import_file=False):
        """ Creates an editor tab based on the provided file information """
        if not Settings.getInstance().editor_data["EditorSettings"][
                "max_tabs"] <= self.e_ui.main_tab_editor.count():
            editor_classes = {
                FileType.Scene_Dialogue: EditorDialogue,
                FileType.Scene_Point_And_Click: EditorPointAndClick,
                FileType.Project_Settings: EditorProjectSettings
            }

            # Let's check if we already have an editor open for this file
            result = self.CheckIfFileOpen(target_file_path)
            if result:
                #@TODO: Should there be a reimport if the user tries to open an opened file? Or maybe a refesh button?
                Logger.getInstance().Log(
                    "An editor for the selected file is already open - Switching to the open editor ",
                    3)
                self.e_ui.main_tab_editor.setCurrentWidget(result)
            else:
                # Initialize the Editor
                self.active_editor = editor_classes[editor_type](
                    target_file_path)

                # Allow the caller to load the provided file instead of just marking it as the export target
                if import_file:
                    self.active_editor.Import()

                self.e_ui.AddTab(self.active_editor.GetUI(),
                                 os.path.basename(target_file_path),
                                 self.e_ui.main_tab_editor)
        else:
            QtWidgets.QMessageBox.about(
                self.e_ui.central_widget, "Tab Limit Reached!",
                "You have reached the maximum number of open tabs. Please close "
                "a tab before attempting to open another")
Example #25
0
    def ConvertDialogueFileToEditorFormat(self, action_data):
        """
        Given a full dict of dialogue file data in engine format (branches and all), convert it to the editor format by
        rebuilding the structure based on lookups in the ActionDatabase
        """
        #@TODO: Investigate how to speed this up. The volume of O(n) searching is worrying
        new_dialogue_data = {}

        for branch_name, branch_data in action_data.items():
            converted_entries = []
            for action in branch_data["entries"]:
                action_name = action["action"]

                # Using the name of the action, look it up in the ActionDatabase. From there, we can build the new
                # structure
                database_entry = None
                for cat_name, cat_data in Settings.getInstance(
                ).action_database.items():
                    for option in cat_data["options"]:
                        if action_name == option['action_name']:
                            database_entry = copy.deepcopy(option)
                            break

                    if database_entry:
                        break
                # Pass the entry by ref, and let the convert func edit it directly
                self.ConvertActionRequirementsToEditorFormat(
                    database_entry, action)
                converted_entries.append(database_entry)

            branch_data["entries"] = converted_entries
            new_dialogue_data[branch_name] = branch_data

        return new_dialogue_data
Example #26
0
    def OpenProject(self):
        """ Prompts the user for a project directory, then loads that file in the respective editor """
        Logger.getInstance().Log("Requesting path to project root...")
        prompt = FileSystemPrompt(self.main_window)
        existing_project_dir = prompt.GetDirectory(
            self.GetLastSearchPath(), "Choose a Project Directory", False)
        self.UpdateSearchHistory(existing_project_dir)

        if not existing_project_dir:
            Logger.getInstance().Log(
                "Project directory was not provided - Cancelling 'Open Project' action",
                3)
        else:
            # Does the directory already have a project in it (Denoted by the admin folder's existence)
            if os.path.exists(existing_project_dir + "/" +
                              Settings.getInstance().project_file):
                Logger.getInstance().Log(
                    "Valid project selected - Setting as Active Project...")

                # Since we aren't asking for the project name, let's infer it from the path
                project_name = os.path.basename(existing_project_dir)
                self.SetActiveProject(project_name, existing_project_dir)
            else:
                Logger.getInstance().Log(
                    "An invalid Heartbeat project was selected - Cancelling 'Open Project' action",
                    4)
                QtWidgets.QMessageBox.about(
                    self.e_ui.central_widget, "Not a Valid Project Directory!",
                    "The chosen directory is not a valid Heartbeat project.\n"
                    "Please either choose a different project, or create a new project."
                )
Example #27
0
    def OpenFilePrompt(self) -> str:
        #@TODO: Replace file browser will popup list of files available in the project
        """ Prompts the user with a filedialog, accepting an existing file """
        prompt = FileSystemPrompt(self.details_panel)
        existing_file = prompt.GetFile(
            Settings.getInstance().GetProjectContentDirectory(),
            self.type_filter, "Choose a File to Open")

        # Did the user choose a value?
        if existing_file:
            selected_dir = existing_file

            # Remove the project dir from the path, so that the selected dir only contains a relative path
            selected_dir = selected_dir.replace(
                Settings.getInstance().user_project_dir + "/", "")
            self.input_widget.setText(selected_dir)
Example #28
0
 def GetLastSearchPath(self):
     """ Returns the current search path record, or if there is none, return the system home"""
     search_dir = self.ReadFromTemp(
         Settings.getInstance().temp_history_path, "search_dir")
     if search_dir:
         return search_dir
     else:
         return str(Path.home())
Example #29
0
    def __init__(self, refresh_func=None):
        super().__init__(refresh_func)

        self.input_widget = QtWidgets.QLineEdit()
        self.input_widget.setFont(Settings.getInstance().paragraph_font)
        self.input_widget.setStyleSheet(Settings.getInstance().paragraph_color)
        self.input_widget.textChanged.connect(self.InputValueUpdated)

        # Limit entered values to int only
        self.validator = QtGui.QIntValidator()
        self.input_widget.setValidator(self.validator)

        # Assign default value
        self.input_widget.setText("0")

        # Add input elements to the layout
        self.main_layout.addWidget(self.input_widget)
Example #30
0
    def __init__(self, icon, file_type, display_text, description_text,
                 parent):
        super().__init__(icon, display_text, parent)

        self.setFont(Settings.getInstance().paragraph_font)

        self.file_type = file_type
        self.description_text = description_text