Ejemplo n.º 1
0
class AddMissingBonesDialog(wx.Dialog):
    def __init__(self, parent, missing_bones, *args, **kw):
        super().__init__(parent, *args, **kw)

        self.SetTitle("Add Missing Bones")
        self.missing_bones = missing_bones

        self.bone_list = TreeListCtrl(self,
                                      size=(-1, 250),
                                      style=TL_MULTIPLE | TL_CHECKBOX)
        self.bone_list.AppendColumn("Bone")
        root = self.bone_list.GetRootItem()
        for bone in missing_bones:
            item = self.bone_list.AppendItem(root, bone.name, data=bone)
            self.bone_list.CheckItem(item)

        add_button = wx.Button(self, wx.ID_OK, "Add")
        add_button.SetDefault()
        no_add_button = wx.Button(self, wx.ID_CANCEL, "Don't Add")

        button_sizer = wx.BoxSizer(wx.HORIZONTAL)
        button_sizer.Add(add_button, 0, wx.LEFT | wx.RIGHT, 2)
        button_sizer.Add(no_add_button, 0, wx.LEFT | wx.RIGHT, 5)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(
            wx.StaticText(
                self, -1, 'The current EAN is missing the following bones.\n'
                'Do you want to add them?'), 0, wx.ALL, 10)
        sizer.Add(self.bone_list, 1, wx.ALL | wx.EXPAND, 10)
        sizer.Add(wx.StaticLine(self), 0, wx.EXPAND | wx.ALL, 10)
        sizer.Add(button_sizer, 0, wx.ALIGN_CENTER | wx.TOP | wx.BOTTOM, 10)

        self.SetSizer(sizer)
        sizer.Fit(self)
        self.Layout()

    def GetValues(self):
        missing_bones = []
        item = self.bone_list.GetFirstItem()
        while item.IsOk():
            if self.bone_list.GetCheckedState(item) == wx.CHK_CHECKED:
                missing_bones.append(self.bone_list.GetItemData(item))
            item = self.bone_list.GetNextItem(item)
        return missing_bones
Ejemplo n.º 2
0
class MainPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        self.bdm = None
        self.parent = parent

        self.entry_list = TreeListCtrl(self, style=TL_MULTIPLE)
        self.entry_list.AppendColumn("Entry")
        self.entry_list.Bind(EVT_TREELIST_ITEM_CONTEXT_MENU,
                             self.on_right_click)
        self.entry_list.Bind(EVT_TREELIST_SELECTION_CHANGED, self.on_select)
        self.cdo = wx.CustomDataObject("BDMEntry")

        self.Bind(wx.EVT_MENU, self.on_delete, id=wx.ID_DELETE)
        self.Bind(wx.EVT_MENU, self.on_copy, id=wx.ID_COPY)
        self.Bind(wx.EVT_MENU, self.on_paste, id=wx.ID_PASTE)
        self.Bind(wx.EVT_MENU, self.on_new, id=wx.ID_NEW)
        accelerator_table = wx.AcceleratorTable([
            (wx.ACCEL_CTRL, ord('c'), wx.ID_COPY),
            (wx.ACCEL_CTRL, ord('v'), wx.ID_PASTE),
            (wx.ACCEL_NORMAL, wx.WXK_DELETE, wx.ID_DELETE),
        ])
        self.entry_list.SetAcceleratorTable(accelerator_table)

        pub.subscribe(self.on_select, 'on_select')
        pub.subscribe(self.convert_for_skill_creator,
                      'convert_for_skill_creator')

        # Use some sizers to see layout options
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.entry_list, 1, wx.ALL | wx.EXPAND, 10)

        # Layout sizers
        self.SetSizer(sizer)
        self.SetAutoLayout(1)

    def build_tree(self):
        self.entry_list.DeleteAllItems()
        root = self.entry_list.GetRootItem()
        for entry in sorted(self.bdm.entries, key=lambda e: e.id):
            self.entry_list.AppendItem(root, f'{entry.id}: Entry', data=entry)

    def get_current_entry_ids(self):
        entry_ids = []
        item = self.entry_list.GetFirstItem()
        while item.IsOk():
            data = self.entry_list.GetItemData(item)
            entry_ids.append(data.id)
            item = self.entry_list.GetNextItem(item)
        return entry_ids

    def get_previous_entry(self, entry_id):
        item = self.entry_list.GetFirstItem()
        prev = TLI_FIRST
        while item.IsOk():
            data = self.entry_list.GetItemData(item)
            if data.id > entry_id:
                break
            prev, item = item, self.entry_list.GetNextItem(item)
        return prev

    def on_right_click(self, _):
        selected = self.entry_list.GetSelections()
        if not selected:
            return
        menu = wx.Menu()
        menu.Append(wx.ID_NEW)
        menu.Append(wx.ID_DELETE)
        menu.Append(wx.ID_COPY)
        paste = menu.Append(wx.ID_PASTE)
        add = menu.Append(wx.ID_ADD, '&Add Copied Entry')
        success = False

        # Check Clipboard
        if wx.TheClipboard.Open():
            success = wx.TheClipboard.IsSupported(wx.DataFormat("BDMEntry"))
            wx.TheClipboard.Close()
        add.Enable(success)
        paste.Enable(success)
        self.PopupMenu(menu)
        menu.Destroy()

    def on_select(self, _):
        selected = self.entry_list.GetSelections()
        if len(selected) != 1:
            pub.sendMessage('disable')
            return
        pub.sendMessage('load_entry',
                        entry=self.entry_list.GetItemData(selected[0]))

    def add_entry(self, entry):
        root = self.entry_list.GetRootItem()
        prev = self.get_previous_entry(entry.id)
        item = self.entry_list.InsertItem(root,
                                          prev,
                                          f'{entry.id}: Entry',
                                          data=entry)
        self.entry_list.Select(item)
        self.on_select(None)

    def on_new(self, _):
        # Ask for ID
        if self.bdm is None:
            return
        with NewEntryDialog(self, self.get_current_entry_ids()) as dlg:
            if dlg.ShowModal() != wx.ID_OK:
                return
            entry_id = dlg.GetValue()
        self.entry_list.UnselectAll()

        # Add it
        entry = Entry(entry_id=entry_id)
        self.add_entry(entry)
        pub.sendMessage('set_status_bar', text='Added new entry')

    def on_add(self, _):
        if self.bdm is None:
            return
        cdo = wx.CustomDataObject("BDMEntry")
        success = False
        if wx.TheClipboard.Open():
            success = wx.TheClipboard.GetData(cdo)
            wx.TheClipboard.Close()
        if not success:
            with wx.MessageDialog(self, 'Unable to get copied data') as dlg:
                dlg.ShowModal()
                return
        paste_data = pickle.loads(cdo.GetData())

        # Get new Id's
        with NewEntryDialog(self, self.get_current_entry_ids()) as dlg:
            if dlg.ShowModal() != wx.ID_OK:
                return
            entry_id = dlg.GetValue()
        current_entry_ids = self.get_current_entry_ids()
        self.entry_list.UnselectAll()

        # Paste
        for paste in paste_data:
            while entry_id in current_entry_ids:
                entry_id += 1
            entry = Entry(entry_id=entry_id)
            entry.paste(paste)
            self.add_entry(entry)
            entry_id += 1

        self.on_select(None)
        pub.sendMessage(f'Pasted {len(paste_data)} new entry(s)')

    def on_delete(self, _):
        selected = self.entry_list.GetSelections()
        if not selected:
            return

        for item in selected:
            self.entry_list.DeleteItem(item)
        pub.sendMessage('disable')
        pub.sendMessage('set_status_bar',
                        text=f'Deleted {len(selected)} entries')

    def on_copy(self, _):
        selected = self.entry_list.GetSelections()

        self.cdo = wx.CustomDataObject("BDMEntry")
        self.cdo.SetData(
            pickle.dumps(
                [self.entry_list.GetItemData(item) for item in selected]))
        if wx.TheClipboard.Open():
            wx.TheClipboard.SetData(self.cdo)
            wx.TheClipboard.Flush()
            wx.TheClipboard.Close()
        pub.sendMessage('set_status_bar',
                        text=f'Copied {len(selected)} entries')

    def on_paste(self, _):
        selected = self.entry_list.GetSelections()
        if not selected:
            return

        success = False
        cdo = wx.CustomDataObject("BDMEntry")
        if wx.TheClipboard.Open():
            success = wx.TheClipboard.GetData(cdo)
            wx.TheClipboard.Close()
        if success:
            paste_data = pickle.loads(cdo.GetData())
            paste_length = len(paste_data)
            selected_length = len(selected)
            if selected_length > paste_length:
                for item in selected[paste_length:]:
                    self.entry_list.Unselect(item)
                selected = selected[:paste_length]

            item = selected[-1]
            self.entry_list.Select(item)
            for n in range(paste_length - selected_length):
                item = self.entry_list.GetNextItem(item)
                if not item.IsOk():
                    with wx.MessageDialog(
                            self,
                            f'Not enough entries to paste over. Expected {paste_length}'
                    ) as dlg:
                        dlg.ShowModal()
                        return
                self.entry_list.Select(item)
                selected.append(item)

            if len(selected) > 1:
                msg = '\n'.join([
                    f' * {self.entry_list.GetItemData(item).id}: Entry'
                    for item in selected
                ])
                with MultiMessageDialog(
                        self,
                        'Are you sure you want to replace the following entries?',
                        'Warning', msg, wx.YES | wx.NO) as dlg:
                    if dlg.ShowModal() != wx.ID_YES:
                        return

            for n, paste in enumerate(paste_data):
                data = self.entry_list.GetItemData(selected[n])
                data.paste(paste)

            self.on_select(None)
            pub.sendMessage('set_status_bar',
                            text=f'Pasted {len(paste_data)} entry(s)')

    def convert_for_skill_creator(self):
        if not self.bdm:
            with wx.MessageDialog(self, "No BDM loaded!", "Error") as dlg:
                dlg.ShowModal()
            return

        # Get choices
        choices = set()
        item = self.entry_list.GetFirstItem()
        effect_ids = [
            'effect_1_skill_id', 'effect_2_skill_id', 'effect_3_skill_id'
        ]
        while item.IsOk():
            data = self.entry_list.GetItemData(item)
            item = self.entry_list.GetNextItem(item)
            for sub_entry in data.sub_entries:
                for effect_id in effect_ids:
                    try:
                        if sub_entry[effect_id] != 0 and sub_entry[
                                effect_id] != 0xFFFF and sub_entry[
                                    effect_id] != 0xBACA:
                            choices.update([str(sub_entry[effect_id])])
                    except Exception as e:
                        pass

        if not choices:
            with wx.MessageDialog(self, "Cannot find any Skill IDs to convert",
                                  "Error") as dlg:
                dlg.ShowModal()
            return

        # Show Dialog
        with ConvertDialog(self, list(choices)) as dlg:
            if dlg.ShowModal() != wx.ID_OK:
                return
            skill_id = dlg.GetValue()

        # Do Conversion
        item = self.entry_list.GetFirstItem()
        changed = 0
        while item.IsOk():
            data = self.entry_list.GetItemData(item)
            item = self.entry_list.GetNextItem(item)
            for sub_entry in data.sub_entries:
                for effect_id in effect_ids:
                    if sub_entry[effect_id] == skill_id:
                        try:
                            sub_entry[effect_id] = 0xBACA
                            changed += 1
                        except Exception:
                            pass
        self.on_select(None)
        pub.sendMessage('set_status_bar',
                        text=f'Changed {changed} skill ids to 0xBACA')

    def reindex(self):
        selected = self.entry_list.GetSelections()
        if len(selected) != 1:
            return
        item = selected[0]
        entry = self.entry_list.GetItemData(item)
        self.entry_list.DeleteItem(item)
        self.add_entry(entry)
Ejemplo n.º 3
0
class SidePanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        self.code = ''
        self.bac = None
        self.bdm = None
        self.ean = None
        self.cam_ean = None
        self.parent = parent
        self.dirname = ''

        # Name
        self.name = wx.StaticText(self, -1, '(No file loaded)')
        self.font = wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD)
        self.name.SetFont(self.font)

        # Buttons
        self.open = wx.Button(self, wx.ID_OPEN, "Load")
        self.copy = wx.Button(self, wx.ID_COPY, "Copy")
        self.copy.Disable()

        # Entry List
        self.entry_list = TreeListCtrl(self, style=TL_MULTIPLE)
        self.entry_list.AppendColumn("BAC Entry")
        self.entry_list.AppendColumn("Copied", width=64)
        self.entry_list.Bind(EVT_TREELIST_ITEM_CONTEXT_MENU,
                             self.on_right_click)
        # self.cdo = wx.CustomDataObject("BDMEntry")

        self.Bind(wx.EVT_BUTTON, self.on_open, id=wx.ID_OPEN)
        self.Bind(wx.EVT_BUTTON, self.on_copy, id=wx.ID_COPY)
        self.Bind(wx.EVT_MENU, self.on_copy, id=wx.ID_COPY)
        accelerator_table = wx.AcceleratorTable([
            (wx.ACCEL_CTRL, ord('c'), wx.ID_COPY),
        ])
        self.entry_list.SetAcceleratorTable(accelerator_table)
        self.SetDropTarget(FileDropTarget(self, "load_side_moveset"))

        # Button Sizer
        button_sizer = wx.BoxSizer(wx.HORIZONTAL)
        button_sizer.Add(self.open)
        button_sizer.AddSpacer(5)
        button_sizer.Add(self.copy)

        # Use some sizers to see layout options
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.name, 0, wx.CENTER)
        sizer.Add(button_sizer)
        sizer.Add(self.entry_list, 1, wx.ALL | wx.EXPAND, 10)

        # Layout sizers
        self.SetSizer(sizer)
        self.SetAutoLayout(1)

    def on_open(self, _):
        pub.sendMessage('open_side_moveset')

    def build_tree(self):
        self.entry_list.DeleteAllItems()
        root = self.entry_list.GetRootItem()
        for i, entry in enumerate(self.bac.entries):
            if not entry.sub_entries:
                continue
            self.entry_list.AppendItem(
                root,
                f'{entry.index}: {KNOWN_ENTRIES.get(entry.index, "Unknown")}',
                data=entry)
        self.copy.Enable()
        self.parent.copied = None

    def on_right_click(self, _):
        selected = self.entry_list.GetSelections()
        if not selected:
            return
        menu = wx.Menu()
        menu.Append(wx.ID_COPY)
        self.PopupMenu(menu)
        menu.Destroy()

    def on_copy(self, _):
        selected = self.entry_list.GetSelections()
        if not selected:
            return

        # Deselect all
        item = self.entry_list.GetFirstItem()
        while item.IsOk():
            self.entry_list.SetItemText(item, 1, '')
            item = self.entry_list.GetNextItem(item)

        # Check and add to copied
        copied = []
        for item in selected:
            copied.append(self.entry_list.GetItemData(item))
            self.entry_list.SetItemText(item, 1, CHECK)
        self.parent.copied = pickle.dumps(copied)
        pub.sendMessage('set_status_bar',
                        text=f'Copied {len(selected)} entries')