I am having a difficulty figuring out how to swap two items in a GList
. I need to swap two items in the list so that their order change when rendering. How can I do that?
How can I do that to move up and move down items in this list ?
For example I want to make a function to move up or down items in GtkTreeView
. I try this for moving up:
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);
.......................................
}
How to simplify this without using the GList
remove and insert functions?
Thanks
I assume you're talking about consecutive elements in the list.
In that case, let A and B represent the two elements (in that order) you wish to swap. Then you need to make sure that
Try this:
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;
Edit: Given the code you've added to your question try this instead, which manipulates the list elements' pointers instead of using g_list_remove
and 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;
}