我很难弄清楚如何在一个怪物中交换两个项目。我需要交换列表中的两个项目,以便在渲染时更改其顺序。我怎么能这样做?
我该怎么做才能向上移动并向下移动列表中的项目。
例如,我想在gtktreeview中使用向上或向下移动项目的功能。我试着向上移动:
typedef struct Settings settings;
struct Settings
{
GList *l;
};
typedef struct Preset preset;
struct Preset
{
char* title;
float freq;
};
settings sts;
void move_up_button(GtkWidget *widget, gpointer(data))
{
preset *ps;
int *row, pos;
.....................................
row = gtk_tree_path_get_indices(path);
ps = g_list_nth_data(sts.l, *row);
g_assert(ps);
pos = g_list_index(sts.l, (gpointer)ps);
pos--;
sts.l = g_list_remove(sts.l, (gpointer)ps);
sts.l = g_list_insert(sts.l, (gpointer)ps, pos);
.......................................
}
如何在不使用删除和插入Glist函数的情况下简化此操作?
由于
答案 0 :(得分:1)
我假设你在谈论列表中的连续元素。
在这种情况下,让A和B代表您希望交换的两个元素(按此顺序)。然后你需要确保
试试这个:
GList *element_a, *element_b;
...
/* Swap elements A and B */
element_a->prev->next = element_b;
element_b->prev = element_a->prev;
element_a->next = element_b->next;
element_b->next->prev = element_a;
element_b->next = element_a;
element_a->prev = element_b;
修改:鉴于您已添加到问题中的代码,请尝试使用此代码来操作列表元素'指针而非使用g_list_remove
和g_list_insert
:
GList *button_element, *preceding_element;
....
row = gtk_tree_path_get_indices(path);
button_element = g_list_nth(sts.l, *row);
g_assert(button_element->data);
/* Swap the button with its preceding element, if there is one */
preceding_element = button_element->prev;
if(preceding_element) {
if(preceding_element->prev) {
preceding_element->prev->next = button_element;
button_element->prev = preceding_element->prev;
}
else {
/* The preceding element is the head of the list, which we must update */
sts.l = button_element;
button_element->prev = NULL;
}
preceding_element->next = button_element->next;
if(button_element->next) {
button_element->next->prev = preceding_element;
}
button_element->next = preceding_element;
preceding_element->prev = button_element;
}