From: Max Kellermann Date: Sat, 10 Oct 2009 17:36:13 +0000 (+0200) Subject: list_window: removed selected_start, selected_end X-Git-Tag: release-0.16~123 X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=74c1180360f39199b76b72e7d266372a52ddbbb3;p=ncmpc.git list_window: removed selected_start, selected_end Calculate those two variables on demand. This simplifies a lot of code, and saves some memory and CPU cycles. --- diff --git a/src/list_window.c b/src/list_window.c index 35522d5..9e67f9f 100644 --- a/src/list_window.c +++ b/src/list_window.c @@ -59,8 +59,6 @@ void list_window_reset(struct list_window *lw) { lw->selected = 0; - lw->selected_start = 0; - lw->selected_end = 0; lw->range_selection = false; lw->range_base = 0; lw->start = 0; @@ -83,19 +81,8 @@ list_window_check_selected(struct list_window *lw) lw->selected = list_window_validate_index(lw, lw->selected); if(lw->range_selection) - { - lw->selected_start = - list_window_validate_index(lw, lw->selected_start); - lw->selected_end = - list_window_validate_index(lw, lw->selected_end); lw->range_base = list_window_validate_index(lw, lw->range_base); - } - else - { - lw->selected_start = lw->selected; - lw->selected_end = lw->selected; - } } /** @@ -166,8 +153,6 @@ list_window_set_cursor(struct list_window *lw, unsigned i) { lw->range_selection = false; lw->selected = i; - lw->selected_start = i; - lw->selected_end = i; list_window_check_selected(lw); list_window_check_origin(lw); @@ -177,24 +162,6 @@ void list_window_move_cursor(struct list_window *lw, unsigned n) { lw->selected = n; - if(lw->range_selection) - { - if(n >= lw->range_base) - { - lw->selected_end = n; - lw->selected_start = lw->range_base; - } - if(n <= lw->range_base) - { - lw->selected_start = n; - lw->selected_end = lw->range_base; - } - } - else - { - lw->selected_start = n; - lw->selected_end = n; - } list_window_check_selected(lw); list_window_check_origin(lw); @@ -211,6 +178,30 @@ list_window_fetch_cursor(struct list_window *lw) list_window_move_cursor(lw, lw->start + lw->rows - 1 - options.scroll_offset); } +void +list_window_get_range(const struct list_window *lw, + struct list_window_range *range) +{ + if (lw->length == 0) { + /* empty list - no selection */ + range->start = 0; + range->end = 0; + } else if (lw->range_selection) { + /* a range selection */ + if (lw->range_base < lw->selected) { + range->start = lw->range_base; + range->end = lw->selected + 1; + } else { + range->start = lw->selected; + range->end = lw->range_base + 1; + } + } else { + /* no range, just the cursor */ + range->start = lw->selected; + range->end = lw->selected + 1; + } +} + static void list_window_next(struct list_window *lw) { @@ -389,13 +380,15 @@ list_window_paint(const struct list_window *lw, list_window_callback_fn_t callback, void *callback_data) { - unsigned i; bool show_cursor = !lw->hide_cursor; + struct list_window_range range; show_cursor = show_cursor && (!options.hardware_cursor || lw->range_selection); - for (i = 0; i < lw->rows; i++) { + list_window_get_range(lw, &range); + + for (unsigned i = 0; i < lw->rows; i++) { const char *label; bool highlight = false; char *second_column = NULL; @@ -417,8 +410,8 @@ list_window_paint(const struct list_window *lw, list_window_paint_row(lw->w, i, lw->cols, show_cursor && - lw->start + i >= lw->selected_start && - lw->start + i <= lw->selected_end, + lw->start + i >= range.start && + lw->start + i < range.end, highlight, label, second_column); diff --git a/src/list_window.h b/src/list_window.h index eef6b9a..98fcfbe 100644 --- a/src/list_window.h +++ b/src/list_window.h @@ -48,14 +48,28 @@ struct list_window { unsigned start; unsigned selected; - unsigned selected_start; /* for range selection, first selected item */ - unsigned selected_end; /* for range selection, last selected item */ unsigned range_base; /* represents the base item. */ bool range_selection; /* range selection activated */ bool hide_cursor; }; +/** + * The bounds of a range selection, see list_window_get_range(). + */ +struct list_window_range { + /** + * The index of the first selected item. + */ + unsigned start; + + /** + * The index after the last selected item. The selection is + * empty when this is the same as "start". + */ + unsigned end; +}; + /* create a new list window */ struct list_window *list_window_init(WINDOW *w, unsigned width, unsigned height); @@ -120,6 +134,15 @@ list_window_move_cursor(struct list_window *lw, unsigned n); void list_window_fetch_cursor(struct list_window *lw); +/** + * Determines the lower and upper bound of the range selection. If + * range selection is disabled, it returns the cursor position (range + * length is 1). + */ +void +list_window_get_range(const struct list_window *lw, + struct list_window_range *range); + /* find a string in a list window */ bool list_window_find(struct list_window *lw, diff --git a/src/screen_artist.c b/src/screen_artist.c index 3278f8f..a135f91 100644 --- a/src/screen_artist.c +++ b/src/screen_artist.c @@ -472,6 +472,7 @@ string_array_find(GPtrArray *array, const char *value) static bool screen_artist_cmd(struct mpdclient *c, command_t cmd) { + struct list_window_range range; char *selected; char *old; int idx; @@ -615,8 +616,8 @@ screen_artist_cmd(struct mpdclient *c, command_t cmd) if (browser.lw->selected >= artist_list->len) return true; - for (unsigned i = browser.lw->selected_start; - i <= browser.lw->selected_end; ++i) { + list_window_get_range(browser.lw, &range); + for (unsigned i = range.start; i < range.end; ++i) { selected = g_ptr_array_index(artist_list, i); add_query(c, MPD_TAG_ARTIST, selected); cmd = CMD_LIST_NEXT; /* continue and select next item... */ @@ -624,8 +625,8 @@ screen_artist_cmd(struct mpdclient *c, command_t cmd) break; case LIST_ALBUMS: - for (unsigned i = browser.lw->selected_start; - i <= browser.lw->selected_end; ++i) { + list_window_get_range(browser.lw, &range); + for (unsigned i = range.start; i < range.end; ++i) { if(i == album_list->len + 1) add_query(c, MPD_TAG_ARTIST, artist); else if (i > 0) diff --git a/src/screen_browser.c b/src/screen_browser.c index a19fa84..c795414 100644 --- a/src/screen_browser.c +++ b/src/screen_browser.c @@ -180,12 +180,17 @@ enqueue_and_play(struct mpdclient *c, struct filelist_entry *entry) struct filelist_entry * browser_get_selected_entry(const struct screen_browser *browser) { + struct list_window_range range; + + list_window_get_range(browser->lw, &range); + if (browser->filelist == NULL || - browser->lw->selected_start < browser->lw->selected_end || - browser->lw->selected >= filelist_length(browser->filelist)) + range.end <= range.start || + range.end > range.start + 1 || + range.start >= filelist_length(browser->filelist)) return NULL; - return filelist_get(browser->filelist, browser->lw->selected); + return filelist_get(browser->filelist, range.start); } static const struct mpd_entity * @@ -304,49 +309,37 @@ browser_select_entry(struct mpdclient *c, struct filelist_entry *entry, static bool browser_handle_select(struct screen_browser *browser, struct mpdclient *c) { + struct list_window_range range; struct filelist_entry *entry; + bool success; - if (browser->lw->range_selection) { - for (unsigned i = browser->lw->selected_start; - i <= browser->lw->selected_end; i++) { - entry = browser_get_index(browser, i); + list_window_get_range(browser->lw, &range); + for (unsigned i = range.start; i < range.end; ++i) { + entry = browser_get_index(browser, i); - if (entry != NULL && entry->entity != NULL) - browser_select_entry(c, entry, TRUE); - } - return false; - } else { - entry = browser_get_selected_entry(browser); - - if (entry == NULL || entry->entity == NULL) - return false; - - return browser_select_entry(c, entry, TRUE); + if (entry != NULL && entry->entity != NULL) + success = browser_select_entry(c, entry, TRUE); } + + return range.end == range.start + 1 && success; } static bool browser_handle_add(struct screen_browser *browser, struct mpdclient *c) { + struct list_window_range range; struct filelist_entry *entry; + bool success; - if (browser->lw->range_selection) { - for (unsigned i = browser->lw->selected_start; - i <= browser->lw->selected_end; i++) { - entry = browser_get_index(browser, i); - - if (entry != NULL && entry->entity != NULL) - browser_select_entry(c, entry, FALSE); - } - return false; - } else { - entry = browser_get_selected_entry(browser); + list_window_get_range(browser->lw, &range); + for (unsigned i = range.start; i < range.end; ++i) { + entry = browser_get_index(browser, i); - if (entry == NULL || entry->entity == NULL) - return false; - - return browser_select_entry(c, entry, FALSE); + if (entry != NULL && entry->entity != NULL) + success = browser_select_entry(c, entry, FALSE); } + + return range.end == range.start + 1 && success; } static void diff --git a/src/screen_file.c b/src/screen_file.c index 7fae5f2..f7b3b56 100644 --- a/src/screen_file.c +++ b/src/screen_file.c @@ -167,18 +167,18 @@ screen_file_handle_enter(struct mpdclient *c) static int handle_save(struct mpdclient *c) { - struct filelist_entry *entry; + struct list_window_range range; const char *defaultname = NULL; char *defaultname_utf8 = NULL; int ret; - unsigned selected; - if (browser.lw->selected >= filelist_length(browser.filelist)) + list_window_get_range(browser.lw, &range); + if (range.start == range.end) return -1; - for(selected = browser.lw->selected_start; selected <= browser.lw->selected_end; ++selected) - { - entry = filelist_get(browser.filelist, selected); + for (unsigned i = range.start; i < range.end; ++i) { + struct filelist_entry *entry = + filelist_get(browser.filelist, i); if( entry && entry->entity ) { struct mpd_entity *entity = entry->entity; if (mpd_entity_get_type(entity) == MPD_ENTITY_TYPE_PLAYLIST) { @@ -201,19 +201,16 @@ static int handle_delete(struct mpdclient *c) { struct mpd_connection *connection = mpdclient_get_connection(c); - struct filelist_entry *entry; + struct list_window_range range; struct mpd_entity *entity; const struct mpd_playlist *playlist; char *str, *buf; int key; - unsigned selected; - for(selected = browser.lw->selected_start; selected <= browser.lw->selected_end; ++selected) - { - if (selected >= filelist_length(browser.filelist)) - return -1; - - entry = filelist_get(browser.filelist, selected); + list_window_get_range(browser.lw, &range); + for (unsigned i = range.start; i < range.end; ++i) { + struct filelist_entry *entry = + filelist_get(browser.filelist, i); if( entry==NULL || entry->entity==NULL ) continue; diff --git a/src/screen_play.c b/src/screen_play.c index 66649b2..d1261c6 100644 --- a/src/screen_play.c +++ b/src/screen_play.c @@ -622,6 +622,8 @@ screen_playlist_cmd(struct mpdclient *c, command_t cmd) struct mpd_connection *connection; static command_t cached_cmd = CMD_NONE; command_t prev_cmd = cached_cmd; + struct list_window_range range; + cached_cmd = cmd; lw->hide_cursor = false; @@ -714,14 +716,10 @@ screen_playlist_cmd(struct mpdclient *c, command_t cmd) return true; case CMD_DELETE: - if (lw->range_selection) { - mpdclient_cmd_delete_range(c, lw->selected_start, - lw->selected_end + 1); - } else { - mpdclient_cmd_delete(c, lw->selected); - } + list_window_get_range(lw, &range); + mpdclient_cmd_delete_range(c, range.start, range.end); - list_window_set_cursor(lw, lw->selected_start); + list_window_set_cursor(lw, range.start); return true; case CMD_SAVE_PLAYLIST: @@ -733,64 +731,42 @@ screen_playlist_cmd(struct mpdclient *c, command_t cmd) return true; case CMD_SHUFFLE: - if(!lw->range_selection) + list_window_get_range(lw, &range); + if (range.end < range.start + 1) /* No range selection, shuffle all list. */ break; connection = mpdclient_get_connection(c); - if (mpd_run_shuffle_range(connection, lw->selected_start, - lw->selected_end + 1)) + if (mpd_run_shuffle_range(connection, range.start, range.end)) screen_status_message(_("Shuffled playlist")); else mpdclient_handle_error(c); return true; case CMD_LIST_MOVE_UP: - if(lw->selected_start == 0) + list_window_get_range(lw, &range); + if (range.start == 0 || range.end <= range.start) return false; - if(lw->range_selection) - { - unsigned i = lw->selected_start; - unsigned last_selected = lw->selected; - for(; i <= lw->selected_end; ++i) - mpdclient_cmd_move(c, i, i-1); - lw->selected_start--; - lw->selected_end--; - lw->selected = last_selected - 1; - lw->range_base--; - } - else - { - mpdclient_cmd_move(c, lw->selected, lw->selected-1); - lw->selected--; - lw->selected_start--; - lw->selected_end--; - } + + for (unsigned i = range.start; i < range.end; ++i) + mpdclient_cmd_move(c, i, i - 1); + + lw->selected--; + lw->range_base--; playlist_save_selection(); return true; case CMD_LIST_MOVE_DOWN: - if(lw->selected_end+1 >= playlist_length(&c->playlist)) + list_window_get_range(lw, &range); + if (range.end >= playlist_length(&c->playlist)) return false; - if(lw->range_selection) - { - int i = lw->selected_end; - unsigned last_selected = lw->selected; - for(; i >= (int)lw->selected_start; --i) - mpdclient_cmd_move(c, i, i+1); - lw->selected_start++; - lw->selected_end++; - lw->selected = last_selected + 1; - lw->range_base++; - } - else - { - mpdclient_cmd_move(c, lw->selected, lw->selected+1); - lw->selected++; - lw->selected_start++; - lw->selected_end++; - } + + for (int i = range.end - 1; i >= (int)range.start; --i) + mpdclient_cmd_move(c, i, i + 1); + + lw->selected++; + lw->range_base++; playlist_save_selection(); return true;