Code

list_window: removed selected_start, selected_end
authorMax Kellermann <max@duempel.org>
Sat, 10 Oct 2009 17:36:13 +0000 (19:36 +0200)
committerMax Kellermann <max@duempel.org>
Sat, 10 Oct 2009 17:36:13 +0000 (19:36 +0200)
Calculate those two variables on demand.  This simplifies a lot of
code, and saves some memory and CPU cycles.

src/list_window.c
src/list_window.h
src/screen_artist.c
src/screen_browser.c
src/screen_file.c
src/screen_play.c

index 35522d53f1c4d1af62f68ca46a832d3284f7ba0d..9e67f9f87a61b1bd257271d98e327794ba2e3250 100644 (file)
@@ -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);
 
index eef6b9a7c43c1d8739971bfe3470e8041f65056a..98fcfbef7fc44327cd7ab07f704f51154b2b5d06 100644 (file)
@@ -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,
index 3278f8fbf63926b98432dbb97388e6d58133ff14..a135f9192bbef84357dccce66685ae4aa6e1e451 100644 (file)
@@ -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)
index a19fa84f40c7bcfa7e7f927e78150505d7e1be20..c795414ba916cf4b3187928d324581618cb0d5fd 100644 (file)
@@ -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
index 7fae5f202e11b32a84d62dfdf451365c6aede245..f7b3b567e4110a750c6ffb123e7211cc079ff73c 100644 (file)
@@ -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;
 
index 66649b256ca37d82939945ca276d1ba788cb0469..d1261c66ee418d7210c76c06cdead50b9dafe50c 100644 (file)
@@ -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;