summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 4094d7b)
raw | patch | inline | side by side (parent: 4094d7b)
author | Max Kellermann <max@duempel.org> | |
Sat, 10 Oct 2009 17:36:13 +0000 (19:36 +0200) | ||
committer | Max 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.
code, and saves some memory and CPU cycles.
diff --git a/src/list_window.c b/src/list_window.c
index 35522d53f1c4d1af62f68ca46a832d3284f7ba0d..9e67f9f87a61b1bd257271d98e327794ba2e3250 100644 (file)
--- a/src/list_window.c
+++ b/src/list_window.c
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;
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;
- }
}
/**
{
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);
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);
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)
{
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;
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 eef6b9a7c43c1d8739971bfe3470e8041f65056a..98fcfbef7fc44327cd7ab07f704f51154b2b5d06 100644 (file)
--- a/src/list_window.h
+++ b/src/list_window.h
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);
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 3278f8fbf63926b98432dbb97388e6d58133ff14..a135f9192bbef84357dccce66685ae4aa6e1e451 100644 (file)
--- a/src/screen_artist.c
+++ b/src/screen_artist.c
static bool
screen_artist_cmd(struct mpdclient *c, command_t cmd)
{
+ struct list_window_range range;
char *selected;
char *old;
int idx;
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... */
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 a19fa84f40c7bcfa7e7f927e78150505d7e1be20..c795414ba916cf4b3187928d324581618cb0d5fd 100644 (file)
--- a/src/screen_browser.c
+++ b/src/screen_browser.c
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 *
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 7fae5f202e11b32a84d62dfdf451365c6aede245..f7b3b567e4110a750c6ffb123e7211cc079ff73c 100644 (file)
--- a/src/screen_file.c
+++ b/src/screen_file.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) {
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 66649b256ca37d82939945ca276d1ba788cb0469..d1261c66ee418d7210c76c06cdead50b9dafe50c 100644 (file)
--- a/src/screen_play.c
+++ b/src/screen_play.c
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;
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:
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;