Example #1
0
    def __init__(self, parent=None):
        super(FontGenMenu, self).__init__(parent)

        self.ui = Ui_FontGenerator()
        self.ui.setupUi(self)
        # self.setAttribute(QtCore.Qt.WA_DeleteOnClose)

        self.ui.tabFonts.tabBar().tabMoved.connect(self.export_changed)

        self.filename = None
        self.loading = False

        self.load_last()
 def __init__(self, parent=None):
   super(FontGenMenu, self).__init__(parent)
   
   self.ui = Ui_FontGenerator()
   self.ui.setupUi(self)
   # self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
   
   self.ui.tabFonts.tabBar().tabMoved.connect(self.export_changed)
   
   self.filename = None
   self.loading = False
   
   self.load_last()
Example #3
0
class FontGenMenu(QtGui.QDialog):
    def __init__(self, parent=None):
        super(FontGenMenu, self).__init__(parent)

        self.ui = Ui_FontGenerator()
        self.ui.setupUi(self)
        # self.setAttribute(QtCore.Qt.WA_DeleteOnClose)

        self.ui.tabFonts.tabBar().tabMoved.connect(self.export_changed)

        self.filename = None
        self.loading = False

        self.load_last()

    def set_title(self):
        title = "Font Generator - %s[*]"
        if self.filename == None:
            title = title % "untitled"
        else:
            title = title % self.filename

        self.setWindowTitle(title)

    def ask_unsaved(self):
        if not self.isWindowModified():
            return True

        answer = QtGui.QMessageBox.question(
            self,
            "Unsaved Changes",
            "Would you like to save your changes?",
            buttons=QtGui.QMessageBox.Save | QtGui.QMessageBox.Discard
            | QtGui.QMessageBox.Cancel,
            defaultButton=QtGui.QMessageBox.Cancel)

        if answer == QtGui.QMessageBox.Cancel:
            return False
        elif answer == QtGui.QMessageBox.Discard:
            return True
        elif answer == QtGui.QMessageBox.Save:
            self.save(filename=self.filename)
            return True

    def update_config(self):
        common.editor_config.last_font = self.filename
        common.editor_config.save_config()

    ##############################################################################
    ### NEW FUNCTIONS
    ##############################################################################
    def new(self):
        self.filename = None
        self.set_title()

        self.ui.tabFonts.clear()
        self.add_tab()

        self.setWindowModified(False)

    def new_clicked(self):
        if not self.ask_unsaved():
            return

        self.new()

    ##############################################################################
    ### SAVE FUNCTIONS
    ##############################################################################
    def save(self, filename=None):
        if not filename:
            # Ask for a filename.
            filename = get_save_file(self,
                                     os.path.dirname(
                                         common.editor_config.last_font),
                                     filter="SDSE font files (*.sdse-font)")

            # And if that failed...
            if not filename:
                return False

        # Save shit.
        font_settings = FontSettings()

        font_settings.font_data = self.get_font_data()
        font_settings.gen_for_game = self.ui.chkGenForGame.isChecked()
        font_settings.gen_for_editor = self.ui.chkGenForEditor.isChecked()
        font_settings.left_to_right = self.ui.rdoLeftToRight.isChecked()
        if self.ui.rdoGenFont1.isChecked():
            font_settings.font_type = FONT1
        else:
            font_settings.font_type = FONT2

        with open(filename, "wb") as f:
            pickle.dump(font_settings, f, pickle.HIGHEST_PROTOCOL)

        self.filename = filename
        self.set_title()
        self.setWindowModified(False)

        self.update_config()

    def save_clicked(self):
        self.save(filename=self.filename)

    def save_as_clicked(self):
        self.save(filename=None)

    ##############################################################################
    ### LOAD FUNCTIONS
    ##############################################################################
    def load(self, filename=None):
        if not filename or not os.path.isfile(filename):
            # Ask for a filename.
            filename = get_open_file(self,
                                     os.path.dirname(
                                         common.editor_config.last_font),
                                     filter="SDSE font files (*.sdse-font)")

            # And if that failed...
            if not filename or not os.path.isfile(filename):
                return False

        self.loading = True

        # Load shit.
        with open(filename, "rb") as f:
            try:
                temp_settings = pickle.load(f)
            except:
                return False

        # In case we're coming from pickled data that might
        # not have all the members we need.
        font_settings = FontSettings()
        font_settings.__dict__.update(temp_settings.__dict__)

        self.ui.tabFonts.clear()

        for font_data in font_settings.font_data:
            tab = self.add_tab()
            self.ui.tabFonts.widget(tab).import_data(font_data)

        self.ui.chkGenForGame.setChecked(font_settings.gen_for_game)
        self.ui.chkGenForEditor.setChecked(font_settings.gen_for_editor)

        if font_settings.font_type == FONT1:
            self.ui.rdoGenFont1.setChecked(True)
            self.ui.rdoGenFont2.setChecked(False)
        else:
            self.ui.rdoGenFont1.setChecked(False)
            self.ui.rdoGenFont2.setChecked(True)

        if font_settings.left_to_right:
            self.ui.rdoLeftToRight.setChecked(True)
            self.ui.rdoRightToLeft.setChecked(False)
        else:
            self.ui.rdoLeftToRight.setChecked(False)
            self.ui.rdoRightToLeft.setChecked(True)

        self.filename = filename
        self.set_title()
        self.setWindowModified(False)

        self.update_config()

        self.loading = False

    def load_last(self):
        last_font = common.editor_config.last_font

        if os.path.isfile(last_font):
            self.load(filename=last_font)
        else:
            self.new()

    def load_clicked(self):
        if not self.ask_unsaved():
            return

        self.load()

    ##############################################################################
    ### TAB FUNCTIONS
    ##############################################################################
    def __tab_title(self, widget):
        return "%s [%d]" % (widget.font_name(), widget.font_size())

    @QtCore.pyqtSlot()
    def tab_modified(self):
        widget = self.sender()
        tab = self.ui.tabFonts.indexOf(widget)
        tab_title = self.__tab_title(widget)
        self.ui.tabFonts.setTabText(tab, tab_title)

        if not self.loading:
            self.setWindowModified(True)

    def add_tab(self):
        font_widget = FontGenWidget()
        font_widget.font_type = self.font_type()
        font_widget.modified.connect(self.tab_modified)
        tab = self.ui.tabFonts.addTab(font_widget,
                                      self.__tab_title(font_widget))

        if not self.loading:
            self.setWindowModified(True)

        return tab

    def remove_tab(self):
        answer = QtGui.QMessageBox.warning(
            self,
            "Remove Tab",
            "Are you sure you want to remove this tab?\n\n" +
            "This action cannot be undone. Proceed?",
            buttons=QtGui.QMessageBox.Yes | QtGui.QMessageBox.No,
            defaultButton=QtGui.QMessageBox.No)

        if answer == QtGui.QMessageBox.No:
            return

        widget = self.ui.tabFonts.currentWidget()
        self.ui.tabFonts.removeTab(self.ui.tabFonts.currentIndex())
        del widget

        self.setWindowModified(True)

    ##############################################################################
    ### FONT GENERATION
    ##############################################################################
    def get_font_data(self):
        font_data = []

        for i in range(self.ui.tabFonts.count()):
            data = self.ui.tabFonts.widget(i).get_data()
            font_data.append(data)

        return font_data

    def generate_font(self):
        progress = QProgressDialog("", QtCore.QString(), 0, 0, self)
        progress.setWindowModality(Qt.Qt.WindowModal)
        progress.setWindowTitle("Generating font...")
        progress.setLabelText("Generating font...")
        progress.setMinimumDuration(0)
        progress.setAutoClose(False)

        # Thread this because it's slow as hell and we don't want to lock up the GUI.
        thread = threading.Thread(target=self.__generate_font__)
        thread.start()

        while thread.isAlive():
            thread.join(THREAD_TIMEOUT)
            # It has to change by some amount or it won't update and the UI will lock up.
            progress.setValue(progress.value() - 1)

        progress.close()

    def __generate_font__(self):
        gen_font1 = self.ui.rdoGenFont1.isChecked()
        temp_dir = tempfile.mkdtemp(prefix="sdse-")
        temp_name = "font"
        font_type = font_generator.FONT_TYPES.font01 if gen_font1 else font_generator.FONT_TYPES.font02
        for_game = self.ui.chkGenForGame.isChecked()
        for_editor = self.ui.chkGenForEditor.isChecked()

        font_data = self.get_font_data()
        if self.ui.rdoRightToLeft.isChecked():
            font_data.reverse()

        # Add the required characters to the end of the lowest-priority font
        # so they're there by default but they don't override any existing
        # settings for them, if they're already there.
        font_data[-1].chars += ''.join(REQUIRED_CHARS)

        font = font_generator.gen_font(font_data,
                                       font_type=font_type,
                                       img_width=1024,
                                       draw_outlines=False)
        font.save(temp_dir,
                  temp_name,
                  for_game,
                  for_editor,
                  font_type,
                  game=font_generator.GAMES.sdr2)

        basename = os.path.join(temp_dir, temp_name)
        font_png = basename + ".png"
        font_bmp = basename + ".bmp"
        font_font = basename + ".font"

        font_dir = os.path.join(common.editor_config.data01_dir, "jp", "font",
                                "font.pak")

        if for_game:
            game_bmp = "0000.bmp" if gen_font1 else "0002.bmp"
            game_font = "0001.font" if gen_font1 else "0003.font"

            backup_files(font_dir, [game_bmp, game_font], suffix="_FONT")
            # backup_time = time.strftime("%Y.%m.%d_%H.%M.%S_FONT")
            # backup_dir = os.path.join(common.editor_config.backup_dir, backup_time, "font.pak")
            # if not os.path.isdir(backup_dir):
            # os.makedirs(backup_dir)

            # Copy our existing data into the backup directory.
            # shutil.copy(game_bmp, backup_dir)
            # shutil.copy(game_font, backup_dir)

            # Then replace it with the one we generated.
            shutil.copy(font_bmp, os.path.join(font_dir, game_bmp))
            shutil.copy(font_font, os.path.join(font_dir, game_font))

        if for_editor:
            editor_png = os.path.join(
                common.editor_config.gfx_dir, "font",
                "Font01.png" if gen_font1 else "Font02.png")
            editor_font = os.path.join(
                common.editor_config.gfx_dir, "font",
                "Font01.font" if gen_font1 else "Font02.font")

            # Copy our files in.
            shutil.copy(font_png, editor_png)
            shutil.copy(font_font, editor_font)

            # Reparse the font for the editor.
            text_printer.load_fonts()

        shutil.rmtree(temp_dir)

    ##############################################################################
    ### MISC FUNCTIONS
    ##############################################################################
    def font_type(self):
        return font_generator.FONT_TYPES.font01 if self.ui.rdoGenFont1.isChecked(
        ) else font_generator.FONT_TYPES.font02

    def export_changed(self):
        font_type = self.font_type()
        for i in range(self.ui.tabFonts.count()):
            self.ui.tabFonts.widget(i).font_type = font_type
            self.ui.tabFonts.widget(i).auto_update()

        if not self.loading:
            self.setWindowModified(True)

    ##############################################################################
    ### @fn   accept()
    ### @desc Overrides the OK button.
    ##############################################################################
    def accept(self):
        if not self.ask_unsaved():
            return

        super(FontGenMenu, self).accept()

    ##############################################################################
    ### @fn   reject()
    ### @desc Overrides the cancel button.
    ##############################################################################
    def reject(self):
        if not self.ask_unsaved():
            return

        super(FontGenMenu, self).reject()
class FontGenMenu(QtGui.QDialog):
  def __init__(self, parent=None):
    super(FontGenMenu, self).__init__(parent)
    
    self.ui = Ui_FontGenerator()
    self.ui.setupUi(self)
    # self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
    
    self.ui.tabFonts.tabBar().tabMoved.connect(self.export_changed)
    
    self.filename = None
    self.loading = False
    
    self.load_last()
  
  def set_title(self):
    title = "Font Generator - %s[*]"
    if self.filename == None:
      title = title % "untitled"
    else:
      title = title % self.filename
    
    self.setWindowTitle(title)
  
  def ask_unsaved(self):
    if not self.isWindowModified():
      return True
    
    answer = QtGui.QMessageBox.question(
      self,
      "Unsaved Changes",
      "Would you like to save your changes?",
      buttons = QtGui.QMessageBox.Save | QtGui.QMessageBox.Discard | QtGui.QMessageBox.Cancel,
      defaultButton = QtGui.QMessageBox.Cancel
    )
    
    if answer == QtGui.QMessageBox.Cancel:
      return False
    elif answer == QtGui.QMessageBox.Discard:
      return True
    elif answer == QtGui.QMessageBox.Save:
      self.save(filename = self.filename)
      return True
  
  def update_config(self):
    common.editor_config.last_font = self.filename
    common.editor_config.save_config()
  
  ##############################################################################
  ### NEW FUNCTIONS
  ##############################################################################
  def new(self):
    self.filename = None
    self.set_title()
    
    self.ui.tabFonts.clear()
    self.add_tab()
    
    self.setWindowModified(False)
  
  def new_clicked(self):
    if not self.ask_unsaved():
      return
    
    self.new()
  
  ##############################################################################
  ### SAVE FUNCTIONS
  ##############################################################################
  def save(self, filename = None):
    if not filename:
      # Ask for a filename.
      filename = get_save_file(self, os.path.dirname(common.editor_config.last_font), filter = "SDSE font files (*.sdse-font)")
    
      # And if that failed...
      if not filename:
        return False
    
    # Save shit.
    font_settings = FontSettings()
    
    font_settings.font_data       = self.get_font_data()
    font_settings.gen_for_game    = self.ui.chkGenForGame.isChecked()
    font_settings.gen_for_editor  = self.ui.chkGenForEditor.isChecked()
    font_settings.left_to_right   = self.ui.rdoLeftToRight.isChecked()
    if self.ui.rdoGenFont1.isChecked():
      font_settings.font_type = FONT1
    else:
      font_settings.font_type = FONT2
    
    with open(filename, "wb") as f:
      pickle.dump(font_settings, f, pickle.HIGHEST_PROTOCOL)
    
    self.filename = filename
    self.set_title()
    self.setWindowModified(False)
    
    self.update_config()
  
  def save_clicked(self):
    self.save(filename = self.filename)
  
  def save_as_clicked(self):
    self.save(filename = None)
  
  ##############################################################################
  ### LOAD FUNCTIONS
  ##############################################################################
  def load(self, filename = None):
    if not filename or not os.path.isfile(filename):
      # Ask for a filename.
      filename = get_open_file(self, os.path.dirname(common.editor_config.last_font), filter = "SDSE font files (*.sdse-font)")
    
      # And if that failed...
      if not filename or not os.path.isfile(filename):
        return False
    
    self.loading = True
    
    # Load shit.
    with open(filename, "rb") as f:
      try:
        temp_settings = pickle.load(f)
      except:
        return False
    
    # In case we're coming from pickled data that might
    # not have all the members we need.
    font_settings = FontSettings()
    font_settings.__dict__.update(temp_settings.__dict__)
    
    self.ui.tabFonts.clear()
    
    for font_data in font_settings.font_data:
      tab = self.add_tab()
      self.ui.tabFonts.widget(tab).import_data(font_data)
    
    self.ui.chkGenForGame.setChecked(font_settings.gen_for_game)
    self.ui.chkGenForEditor.setChecked(font_settings.gen_for_editor)
    
    if font_settings.font_type == FONT1:
      self.ui.rdoGenFont1.setChecked(True)
      self.ui.rdoGenFont2.setChecked(False)
    else:
      self.ui.rdoGenFont1.setChecked(False)
      self.ui.rdoGenFont2.setChecked(True)
    
    if font_settings.left_to_right:
      self.ui.rdoLeftToRight.setChecked(True)
      self.ui.rdoRightToLeft.setChecked(False)
    else:
      self.ui.rdoLeftToRight.setChecked(False)
      self.ui.rdoRightToLeft.setChecked(True)
    
    self.filename = filename
    self.set_title()
    self.setWindowModified(False)
    
    self.update_config()
    
    self.loading = False
  
  def load_last(self):
    last_font = common.editor_config.last_font
    
    if os.path.isfile(last_font):
      self.load(filename = last_font)
    else:
      self.new()
  
  def load_clicked(self):
    if not self.ask_unsaved():
      return
    
    self.load()
  
  ##############################################################################
  ### TAB FUNCTIONS
  ##############################################################################
  def __tab_title(self, widget):
    return "%s [%d]" % (widget.font_name(), widget.font_size())
  
  @QtCore.pyqtSlot()
  def tab_modified(self):
    widget = self.sender()
    tab = self.ui.tabFonts.indexOf(widget)
    tab_title = self.__tab_title(widget)
    self.ui.tabFonts.setTabText(tab, tab_title)
    
    if not self.loading:
      self.setWindowModified(True)
  
  def add_tab(self):
    font_widget = FontGenWidget()
    font_widget.font_type = self.font_type()
    font_widget.modified.connect(self.tab_modified)
    tab = self.ui.tabFonts.addTab(font_widget, self.__tab_title(font_widget))
    
    if not self.loading:
      self.setWindowModified(True)
    
    return tab
  
  def remove_tab(self):
    answer = QtGui.QMessageBox.warning(
      self,
      "Remove Tab",
      "Are you sure you want to remove this tab?\n\n" +
      "This action cannot be undone. Proceed?",
      buttons = QtGui.QMessageBox.Yes | QtGui.QMessageBox.No,
      defaultButton = QtGui.QMessageBox.No
    )
    
    if answer == QtGui.QMessageBox.No:
      return
    
    widget = self.ui.tabFonts.currentWidget()
    self.ui.tabFonts.removeTab(self.ui.tabFonts.currentIndex())
    del widget
    
    self.setWindowModified(True)
  
  ##############################################################################
  ### FONT GENERATION
  ##############################################################################
  def get_font_data(self):
    font_data = []
    
    for i in range(self.ui.tabFonts.count()):
      data = self.ui.tabFonts.widget(i).get_data()
      font_data.append(data)
    
    return font_data
  
  def generate_font(self):
    progress = QProgressDialog("", QtCore.QString(), 0, 0, self)
    progress.setWindowModality(Qt.Qt.WindowModal)
    progress.setWindowTitle("Generating font...")
    progress.setLabelText("Generating font...")
    progress.setMinimumDuration(0)
    progress.setAutoClose(False)
    
    # Thread this because it's slow as hell and we don't want to lock up the GUI.
    thread = threading.Thread(target = self.__generate_font__)
    thread.start()
    
    while thread.isAlive():
      thread.join(THREAD_TIMEOUT)
      # It has to change by some amount or it won't update and the UI will lock up.
      progress.setValue(progress.value() - 1)
    
    progress.close()
    
  def __generate_font__(self):
    gen_font1   = self.ui.rdoGenFont1.isChecked()
    temp_dir    = tempfile.mkdtemp(prefix = "sdse-")
    temp_name   = "font"
    font_type   = font_generator.FONT_TYPES.font01 if gen_font1 else font_generator.FONT_TYPES.font02
    for_game    = self.ui.chkGenForGame.isChecked()
    for_editor  = self.ui.chkGenForEditor.isChecked()
    
    font_data = self.get_font_data()
    if self.ui.rdoRightToLeft.isChecked():
      font_data.reverse()
    
    # Add the required characters to the end of the lowest-priority font
    # so they're there by default but they don't override any existing
    # settings for them, if they're already there.
    font_data[-1].chars += ''.join(REQUIRED_CHARS)
    
    font = font_generator.gen_font(font_data, font_type = font_type, img_width = 1024, draw_outlines = False)
    font.save(temp_dir, temp_name, for_game, for_editor, font_type, game = font_generator.GAMES.sdr2)
    
    basename  = os.path.join(temp_dir, temp_name)
    font_png  = basename + ".png"
    font_bmp  = basename + ".bmp"
    font_font = basename + ".font"
    
    font_dir  = os.path.join(common.editor_config.data01_dir, "jp", "font", "font.pak")
    
    if for_game:
      game_bmp  = "0000.bmp"  if gen_font1 else "0002.bmp"
      game_font = "0001.font" if gen_font1 else "0003.font"
      
      backup_files(font_dir, [game_bmp, game_font], suffix = "_FONT")
      # backup_time = time.strftime("%Y.%m.%d_%H.%M.%S_FONT")
      # backup_dir = os.path.join(common.editor_config.backup_dir, backup_time, "font.pak")
      # if not os.path.isdir(backup_dir):
        # os.makedirs(backup_dir)
      
      # Copy our existing data into the backup directory.
      # shutil.copy(game_bmp, backup_dir)
      # shutil.copy(game_font, backup_dir)
      
      # Then replace it with the one we generated.
      shutil.copy(font_bmp, os.path.join(font_dir, game_bmp))
      shutil.copy(font_font, os.path.join(font_dir, game_font))
    
    if for_editor:
      editor_png  = os.path.join(common.editor_config.gfx_dir, "font", "Font01.png"  if gen_font1 else "Font02.png")
      editor_font = os.path.join(common.editor_config.gfx_dir, "font", "Font01.font" if gen_font1 else "Font02.font")
      
      # Copy our files in.
      shutil.copy(font_png, editor_png)
      shutil.copy(font_font, editor_font)
      
      # Reparse the font for the editor.
      text_printer.load_fonts()
    
    shutil.rmtree(temp_dir)
  
  ##############################################################################
  ### MISC FUNCTIONS
  ##############################################################################
  def font_type(self):
    return font_generator.FONT_TYPES.font01 if self.ui.rdoGenFont1.isChecked() else font_generator.FONT_TYPES.font02
  
  def export_changed(self):
    font_type = self.font_type()
    for i in range(self.ui.tabFonts.count()):
      self.ui.tabFonts.widget(i).font_type = font_type
      self.ui.tabFonts.widget(i).auto_update()
      
    if not self.loading:
      self.setWindowModified(True)
  
  ##############################################################################
  ### @fn   accept()
  ### @desc Overrides the OK button.
  ##############################################################################
  def accept(self):
    if not self.ask_unsaved():
      return
    
    super(FontGenMenu, self).accept()
  
  ##############################################################################
  ### @fn   reject()
  ### @desc Overrides the cancel button.
  ##############################################################################
  def reject(self):
    if not self.ask_unsaved():
      return
    
    super(FontGenMenu, self).reject()