コード例 #1
0
ファイル: main.py プロジェクト: SkyTemple/skytemple
    def on_tree_grouped_drag_data_received(self, w: Gtk.TreeView, context, x, y, selection: Gtk.SelectionData, info, etime):
        model: Gtk.TreeStore = w.get_model()
        dungeon_id_str = str(selection.get_data(), 'utf-8')
        if dungeon_id_str == '':
            return
        dungeon_id = int(dungeon_id_str)
        dungeon_iter = self._find_dungeon_iter(model, dungeon_id)
        assert dungeon_iter is not None

        drop_info = w.get_dest_row_at_pos(x, y)

        if drop_info:
            path, position = drop_info
            iter = model.get_iter(path)
            did_drag = True

            # Did we drag onto a group or a dungeon in a group?
            new_group_iter = self._get_group_iter(model, iter, position)
            old_group_iter = self._get_group_iter(model, dungeon_iter, Gtk.TreeViewDropPosition.INTO_OR_BEFORE)

            if not new_group_iter:
                # After/Before top level:
                # Don't do anything
                if position == Gtk.TreeViewDropPosition.INTO_OR_BEFORE or position == Gtk.TreeViewDropPosition.INTO_OR_AFTER:
                    # Inside top level, dungeon:
                    # Build new group
                    dungeon_id_insert = model[iter][1]
                    before_iter = model.iter_previous(iter)
                    assert iter is not None
                    model.remove(iter)
                    if before_iter is None:
                        new_iter = model.insert(None, 0, self._generate_group_row(
                            dungeon_id_insert
                        ))
                    else:
                        new_iter = model.insert_after(model.iter_parent(before_iter), before_iter, self._generate_group_row(
                            dungeon_id_insert
                        ))
                    model.append(new_iter, self._generate_dungeon_row(dungeon_id_insert))
                    model.append(new_iter, self._generate_dungeon_row(dungeon_id))
                    w.expand_row(model.get_path(new_iter), False)
                elif old_group_iter is not None:
                    self._reinsert(model, dungeon_id, self._generate_dungeon_row(dungeon_id))
                else:
                    did_drag = False
            else:
                if new_group_iter == iter:
                    # Inside top level, group:
                    # Add to end of group
                    assert new_group_iter is not None
                    model.append(new_group_iter, self._generate_dungeon_row(dungeon_id))
                else:
                    # After/Before in group / Inside in group:
                    # Add it to group after/before this element
                    if position == Gtk.TreeViewDropPosition.INTO_OR_BEFORE or position == Gtk.TreeViewDropPosition.BEFORE:
                        assert new_group_iter is not None
                        model.insert_before(new_group_iter, iter, self._generate_dungeon_row(dungeon_id))
                    else:
                        assert new_group_iter is not None
                        model.insert_after(new_group_iter, iter, self._generate_dungeon_row(dungeon_id))

            if did_drag:
                assert dungeon_iter is not None
                # Remove the original iter.
                model.remove(dungeon_iter)

                # Check if group headers (main id) needs to be rewritten:
                if old_group_iter:
                    self._rewrite_group_header_id_and_pos(model, old_group_iter)
                if new_group_iter and new_group_iter != old_group_iter:
                    self._rewrite_group_header_id_and_pos(model, new_group_iter)

                if old_group_iter and old_group_iter != new_group_iter:
                    # If was in group:
                    # Remove from group
                    # (If removing dungeons from a group, recalculate group id, name,
                    # position and if it even still needs to exist)
                    if model.iter_n_children(old_group_iter) < 2:
                        # Remove group
                        dungeon_id_that_was_in_group = model[model.iter_nth_child(old_group_iter, 0)][1]
                        assert old_group_iter is not None
                        model.remove(old_group_iter)
                        self._reinsert(model, dungeon_id_that_was_in_group, self._generate_dungeon_row(dungeon_id_that_was_in_group))

                # Select the newly inserted.
                dungeon_iter = self._find_dungeon_iter(model, dungeon_id)
                w.get_selection().select_iter(dungeon_iter)
                w.scroll_to_cell(model.get_path(dungeon_iter), None, True, 0.5, 0.5)

        if context.get_actions() == Gdk.DragAction.MOVE:
            # We remove the source data manual.
            context.finish(True, False, etime)