Make holding Shift+Up/Down behave better

This commit is contained in:
Přemysl Eric Janouch 2018-10-29 13:33:00 +01:00
parent 0691c533b4
commit 44ebc3591e
Signed by: p
GPG Key ID: A0420B94F92B9493
1 changed files with 42 additions and 30 deletions

View File

@ -2209,52 +2209,65 @@ current_tab_on_item_draw (size_t item_index, struct row_buffer *buffer,
free (s); free (s);
} }
static bool static void
current_tab_move_song (const char *id, int diff) mpd_on_move_response (const struct mpd_response *response,
const struct strv *data, void *user_data)
{ {
struct mpd_client *c = &g.client; (void) data;
int target = g_current_tab.item_selected + diff;
if (c->state != MPD_CONNECTED || target < 0)
return false;
char *target_str = xstrdup_printf ("%d", target); *(bool *) user_data = false;
mpd_client_send_command (c, "moveid", id, target_str, NULL); if (!response->success)
free (target_str); print_error ("%s: %s", "command failed", response->message_text);
// TODO: we should create a cancellable action waiting for the move to
// finish, so that holding Shift-arrows works as expected.
mpd_client_add_task (c, mpd_on_simple_response, NULL);
mpd_client_idle (c, 0);
// XXX: this behaves a bit erratically, as even if we waited for
// a confirmation from the daemon, it would precede the playlist update
g_current_tab.item_selected = target;
app_move_selection (0);
return true;
} }
static bool static bool
current_tab_on_action (enum action action) current_tab_move_selection (int diff)
{ {
struct tab *self = g.active_tab; static bool already_moving;
struct tab_range range = tab_selection_range (self); if (already_moving)
return true;
// TODO: handle multiselect properly
struct tab *self = &g_current_tab;
struct mpd_client *c = &g.client;
compact_map_t map = item_list_get (&g.playlist, self->item_selected); compact_map_t map = item_list_get (&g.playlist, self->item_selected);
const char *id; const char *id;
if (!map || !(id = compact_map_find (map, "id"))) if (!map || !(id = compact_map_find (map, "id")))
return false; return false;
int target = self->item_selected + diff;
if (c->state != MPD_CONNECTED || target < 0)
return false;
char *target_str = xstrdup_printf ("%d", target);
mpd_client_send_command (c, "moveid", id, target_str, NULL);
free (target_str);
mpd_client_add_task (c, mpd_on_move_response, &already_moving);
mpd_client_idle (c, 0);
return already_moving = true;
}
static bool
current_tab_on_action (enum action action)
{
struct tab *self = &g_current_tab;
compact_map_t map = item_list_get (&g.playlist, self->item_selected);
switch (action) switch (action)
{ {
// TODO: make this block more than just multiselect-tolerant const char *id;
case ACTION_MOVE_UP: return current_tab_move_song (id, -1); case ACTION_MOVE_UP:
case ACTION_MOVE_DOWN: return current_tab_move_song (id, 1); return current_tab_move_selection (-1);
case ACTION_MOVE_DOWN:
return current_tab_move_selection (+1);
case ACTION_CHOOSE: case ACTION_CHOOSE:
return MPD_SIMPLE ("playid", id); return map && (id = compact_map_find (map, "id"))
&& MPD_SIMPLE ("playid", id);
case ACTION_DELETE: case ACTION_DELETE:
{ {
struct mpd_client *c = &g.client; struct mpd_client *c = &g.client;
struct tab_range range = tab_selection_range (self);
if (range.from < 0 || c->state != MPD_CONNECTED) if (range.from < 0 || c->state != MPD_CONNECTED)
return false; return false;
@ -2271,9 +2284,8 @@ current_tab_on_action (enum action action)
return true; return true;
} }
default: default:
break; return false;
} }
return false;
} }
static void static void