From d0f6719e5016d784308dcd9bfb54994f56b00ac3 Mon Sep 17 00:00:00 2001 From: rakshasa Date: Sun, 4 Jun 2006 23:37:39 +0000 Subject: [PATCH] * Added pageup/down to chunks seen and file list. Patch by Josef Drexler, all future patches to lib/rtorrent will be under public domain. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@712 e378c898-3ddf-0310-93e7-cc216c733640 --- src/display/window.h | 4 +- src/display/window_download_chunks_seen.cc | 35 +++++++---- src/display/window_download_chunks_seen.h | 9 ++- src/ui/element_chunks_seen.cc | 71 ++++++++++++++++++++-- src/ui/element_chunks_seen.h | 7 +++ src/ui/element_file_list.cc | 41 +++++++++++++ src/ui/element_file_list.h | 2 + 7 files changed, 151 insertions(+), 18 deletions(-) diff --git a/src/display/window.h b/src/display/window.h index 25fef7b3..a6f6c9bb 100644 --- a/src/display/window.h +++ b/src/display/window.h @@ -62,7 +62,7 @@ public: bool is_dynamic() { return m_dynamic; } bool is_dirty() { return m_taskUpdate.is_queued(); } - int get_min_height() { return m_minHeight; } + int get_min_height() const { return m_minHeight; } bool get_active() { return m_active; } void set_active(bool a); @@ -70,6 +70,8 @@ public: void refresh() { m_canvas->refresh(); } void resize(int x, int y, int w, int h); + int get_height() const { return m_canvas->get_height(); } + void mark_dirty() { m_slotSchedule(this, cachedTime + 1); } virtual void redraw() = 0; diff --git a/src/display/window_download_chunks_seen.cc b/src/display/window_download_chunks_seen.cc index 8512f5c1..015d2e45 100644 --- a/src/display/window_download_chunks_seen.cc +++ b/src/display/window_download_chunks_seen.cc @@ -47,9 +47,10 @@ namespace display { -WindowDownloadChunksSeen::WindowDownloadChunksSeen(core::Download* d) : +WindowDownloadChunksSeen::WindowDownloadChunksSeen(core::Download* d, unsigned int *focus) : Window(new Canvas, true), - m_download(d) { + m_download(d), + m_focus(focus) { } void @@ -62,9 +63,9 @@ WindowDownloadChunksSeen::redraw() { return; m_canvas->print(2, 0, "Chunks seen: [C/A/D %i/%i/%.2f]", - (int)m_download->download()->peers_complete(), - (int)m_download->download()->peers_accounted(), - std::floor(m_download->distributed_copies() * 100.0f) / 100.0f); + (int)m_download->download()->peers_complete(), + (int)m_download->download()->peers_accounted(), + std::floor(m_download->distributed_copies() * 100.0f) / 100.0f); const uint8_t* seen = m_download->download()->chunks_seen(); @@ -73,7 +74,9 @@ WindowDownloadChunksSeen::redraw() { return; } - const uint8_t* chunk = seen; + *m_focus = std::min(*m_focus, max_focus()); + + const uint8_t* chunk = seen + *m_focus * chunks_per_row(); const uint8_t* last = seen + m_download->download()->chunks_total(); const torrent::Bitfield* bitfield = m_download->download()->bitfield(); @@ -85,23 +88,31 @@ WindowDownloadChunksSeen::redraw() { chtype attr; if (bitfield->get(chunk - seen)) - attr = A_NORMAL; + attr = A_NORMAL; // else if (foo->is_downloading(chunk - seen)) -// attr = A_UNDERLINE; +// attr = A_UNDERLINE; else - attr = A_BOLD; + attr = A_BOLD; m_canvas->print_char(attr | rak::value_to_hexchar<0>(std::min(*chunk, 0xF))); chunk++; if ((chunk - seen) % 10 == 0) { - if (m_canvas->get_x() + 12 > m_canvas->get_width()) - break; + if (m_canvas->get_x() + 12 > m_canvas->get_width()) + break; - m_canvas->print_char(' '); + m_canvas->print_char(' '); } } } } +unsigned int +WindowDownloadChunksSeen::rows() const { + if (m_canvas->get_width() < 18) + return 0; + + return (m_download->download()->chunks_total() + chunks_per_row() - 1) / chunks_per_row(); +} + } diff --git a/src/display/window_download_chunks_seen.h b/src/display/window_download_chunks_seen.h index f4635a42..92a95c04 100644 --- a/src/display/window_download_chunks_seen.h +++ b/src/display/window_download_chunks_seen.h @@ -49,12 +49,19 @@ namespace display { class WindowDownloadChunksSeen : public Window { public: - WindowDownloadChunksSeen(core::Download* d); + WindowDownloadChunksSeen(core::Download* d, unsigned int* focus); virtual void redraw(); + unsigned int rows() const; + unsigned int chunks_per_row() const { return (m_canvas->get_width() - 6) / 11 * 10; } + + unsigned int max_focus() const { return std::max(rows() - get_height() + 1, 0); } + private: core::Download* m_download; + + unsigned int* m_focus; }; } diff --git a/src/ui/element_chunks_seen.cc b/src/ui/element_chunks_seen.cc index 64513f6e..831d6e3c 100644 --- a/src/ui/element_chunks_seen.cc +++ b/src/ui/element_chunks_seen.cc @@ -48,10 +48,13 @@ namespace ui { ElementChunksSeen::ElementChunksSeen(core::Download* d) : m_download(d), - m_window(NULL) { + m_window(NULL), + m_focus(0) { -// m_bindings[KEY_DOWN] = sigc::mem_fun(*this, &ElementChunksSeen::receive_next); -// m_bindings[KEY_UP] = sigc::mem_fun(*this, &ElementChunksSeen::receive_prev); + m_bindings[KEY_DOWN] = sigc::mem_fun(*this, &ElementChunksSeen::receive_next); + m_bindings[KEY_UP] = sigc::mem_fun(*this, &ElementChunksSeen::receive_prev); + m_bindings[KEY_NPAGE] = sigc::mem_fun(*this, &ElementChunksSeen::receive_pagenext); + m_bindings[KEY_PPAGE] = sigc::mem_fun(*this, &ElementChunksSeen::receive_pageprev); // m_bindings[' '] = sigc::mem_fun(*this, &ElementChunksSeen::receive_cycle_group); // m_bindings['*'] = sigc::mem_fun(*this, &ElementChunksSeen::receive_disable); } @@ -63,7 +66,7 @@ ElementChunksSeen::activate(Control* c, MItr mItr) { c->input()->push_front(&m_bindings); - *mItr = m_window = new WChunksSeen(m_download); + *mItr = m_window = new WChunksSeen(m_download, &m_focus); } void @@ -90,4 +93,64 @@ ElementChunksSeen::disable(Control* c) { // m_window->mark_dirty(); // } +void +ElementChunksSeen::receive_next() { + if (m_window == NULL) + throw torrent::client_error("ui::ElementChunksSeen::receive_next(...) called on a disabled object"); + + if (++m_focus > m_window->max_focus()) + m_focus = 0; + + m_window->mark_dirty(); +} + +void +ElementChunksSeen::receive_prev() { + if (m_window == NULL) + throw torrent::client_error("ui::ElementChunksSeen::receive_prev(...) called on a disabled object"); + + if (m_focus > 0) + --m_focus; + else + m_focus = m_window->max_focus(); + + m_window->mark_dirty(); +} + +void +ElementChunksSeen::receive_pagenext() { + if (m_window == NULL) + throw torrent::client_error("ui::ElementChunksSeen::receive_pagenext(...) called on a disabled object"); + + unsigned int visible = m_window->get_height() - 1; + unsigned int scrollable = std::max(m_window->rows() - visible, 0); + + if (scrollable == 0 || m_focus == scrollable) + m_focus = 0; + else if (m_focus + visible / 2 < scrollable) + m_focus += visible / 2; + else + m_focus = scrollable; + + m_window->mark_dirty(); +} + +void +ElementChunksSeen::receive_pageprev() { + if (m_window == NULL) + throw torrent::client_error("ui::ElementChunksSeen::receive_pageprev(...) called on a disabled object"); + + unsigned int visible = m_window->get_height() - 1; + unsigned int scrollable = std::max(m_window->rows() - visible, 0); + + if (m_focus > visible / 2) + m_focus -= visible / 2; + else if (scrollable > 0 && m_focus == 0) + m_focus = scrollable; + else + m_focus = 0; + + m_window->mark_dirty(); +} + } diff --git a/src/ui/element_chunks_seen.h b/src/ui/element_chunks_seen.h index aeda92b9..5e24349c 100644 --- a/src/ui/element_chunks_seen.h +++ b/src/ui/element_chunks_seen.h @@ -60,9 +60,16 @@ public: private: // void receive_disable(); + void receive_next(); + void receive_prev(); + void receive_pagenext(); + void receive_pageprev(); core::Download* m_download; WChunksSeen* m_window; + + unsigned int m_focus; + }; } diff --git a/src/ui/element_file_list.cc b/src/ui/element_file_list.cc index e0ca5181..2fc5d675 100644 --- a/src/ui/element_file_list.cc +++ b/src/ui/element_file_list.cc @@ -56,6 +56,8 @@ ElementFileList::ElementFileList(core::Download* d) : m_bindings['*'] = sigc::mem_fun(*this, &ElementFileList::receive_change_all); m_bindings[KEY_DOWN] = sigc::mem_fun(*this, &ElementFileList::receive_next); m_bindings[KEY_UP] = sigc::mem_fun(*this, &ElementFileList::receive_prev); + m_bindings[KEY_NPAGE] = sigc::mem_fun(*this, &ElementFileList::receive_pagenext); + m_bindings[KEY_PPAGE] = sigc::mem_fun(*this, &ElementFileList::receive_pageprev); } void @@ -108,6 +110,45 @@ ElementFileList::receive_prev() { m_window->mark_dirty(); } +void +ElementFileList::receive_pagenext() { + if (m_window == NULL) + throw torrent::client_error("ui::ElementFileList::receive_pagenext(...) called on a disabled object"); + + unsigned int count = (m_window->get_height() - 1) / 2; + + if (m_focus + count < m_download->download()->file_list().size()) + m_focus += count; + else if (m_focus == m_download->download()->file_list().size() - 1) + m_focus = 0; + else + m_focus = m_download->download()->file_list().size() - 1; + + m_window->mark_dirty(); +} + +void +ElementFileList::receive_pageprev() { + if (m_window == NULL) + throw torrent::client_error("ui::ElementFileList::receive_pageprev(...) called on a disabled object"); + + torrent::FileList fl = m_download->download()->file_list(); + + if (fl.size() == 0) + return; + + unsigned int count = (m_window->get_height() - 1) / 2; + + if (m_focus > count) + m_focus -= count; + else if (m_focus == 0) + m_focus = fl.size() - 1; + else + m_focus = 0; + + m_window->mark_dirty(); +} + void ElementFileList::receive_priority() { if (m_window == NULL) diff --git a/src/ui/element_file_list.h b/src/ui/element_file_list.h index 70bc130a..e8112033 100644 --- a/src/ui/element_file_list.h +++ b/src/ui/element_file_list.h @@ -64,6 +64,8 @@ public: private: void receive_next(); void receive_prev(); + void receive_pagenext(); + void receive_pageprev(); void receive_priority(); void receive_change_all();