From 62beb9d9ed252523d7e9166c79afda765368135b Mon Sep 17 00:00:00 2001 From: rakshasa Date: Mon, 31 Jul 2006 00:26:58 +0000 Subject: [PATCH] * Moved handling of events from DownloadList into ElementDownloadList and WindowLog. * Added bindings to input::TextInput and disabled other bindings while it is active. * ^K now sets ignore_commands. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@750 e378c898-3ddf-0310-93e7-cc216c733640 --- src/display/canvas.h | 18 +-- src/display/frame.cc | 25 ++++ src/display/frame.h | 2 + src/display/manager.cc | 2 + src/display/window_input.h | 2 +- src/display/window_log.cc | 18 ++- src/display/window_log.h | 12 +- src/input/manager.cc | 8 +- src/input/manager.h | 9 +- src/ui/download.cc | 2 +- src/ui/download_list.cc | 207 +++----------------------------- src/ui/download_list.h | 25 +--- src/ui/element_base.h | 2 - src/ui/element_chunks_seen.cc | 2 +- src/ui/element_download_list.cc | 156 +++++++++++++++++++++++- src/ui/element_download_list.h | 26 +++- src/ui/element_file_list.cc | 2 +- src/ui/element_log_complete.cc | 2 +- src/ui/element_peer_info.cc | 2 +- src/ui/element_peer_list.cc | 2 +- src/ui/element_string_list.cc | 2 +- src/ui/element_tracker_list.cc | 2 +- src/ui/element_transfer_list.cc | 2 +- src/ui/root.cc | 3 + 24 files changed, 272 insertions(+), 261 deletions(-) diff --git a/src/display/canvas.h b/src/display/canvas.h index 9c2ddf67..f71642af 100644 --- a/src/display/canvas.h +++ b/src/display/canvas.h @@ -71,9 +71,9 @@ public: static void erase_std() { werase(stdscr); } void print_border(chtype ls, chtype rs, - chtype ts, chtype bs, - chtype tl, chtype tr, - chtype bl, chtype br) { wborder(m_window, ls, rs, ts, bs, tl, tr, bl, br); } + chtype ts, chtype bs, + chtype tl, chtype tr, + chtype bl, chtype br) { wborder(m_window, ls, rs, ts, bs, tl, tr, bl, br); } // The format string is non-const, but that will not be a problem // since the string shall always be a C string choosen at @@ -89,27 +89,27 @@ public: template void print(int x, int y, char* str, - A1 a1, A2 a2, A3 a3) { mvwprintw(m_window, y, x, str, a1, a2, a3); } + A1 a1, A2 a2, A3 a3) { mvwprintw(m_window, y, x, str, a1, a2, a3); } template void print(int x, int y, char* str, - A1 a1, A2 a2, A3 a3, A4 a4) { mvwprintw(m_window, y, x, str, a1, a2, a3, a4); } + A1 a1, A2 a2, A3 a3, A4 a4) { mvwprintw(m_window, y, x, str, a1, a2, a3, a4); } template void print(int x, int y, char* str, - A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { mvwprintw(m_window, y, x, str, a1, a2, a3, a4, a5); } + A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { mvwprintw(m_window, y, x, str, a1, a2, a3, a4, a5); } template void print(int x, int y, char* str, - A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) { mvwprintw(m_window, y, x, str, a1, a2, a3, a4, a5, a6); } + A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) { mvwprintw(m_window, y, x, str, a1, a2, a3, a4, a5, a6); } template void print(int x, int y, char* str, - A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) { mvwprintw(m_window, y, x, str, a1, a2, a3, a4, a5, a6, a7); } + A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) { mvwprintw(m_window, y, x, str, a1, a2, a3, a4, a5, a6, a7); } template void print(int x, int y, char* str, - A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) { mvwprintw(m_window, y, x, str, a1, a2, a3, a4, a5, a6, a7, a8); } + A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) { mvwprintw(m_window, y, x, str, a1, a2, a3, a4, a5, a6, a7, a8); } void print_char(const chtype ch) { waddch(m_window, ch); } diff --git a/src/display/frame.cc b/src/display/frame.cc index 21cc9f58..7f98cb83 100644 --- a/src/display/frame.cc +++ b/src/display/frame.cc @@ -221,6 +221,27 @@ Frame::refresh() { } } +void +Frame::redraw() { + switch (m_type) { + case TYPE_NONE: + break; + + case TYPE_WINDOW: + if (m_window->is_active() && !m_window->is_offscreen()) + m_window->redraw(); + + break; + + case TYPE_ROW: + case TYPE_COLUMN: + for (Frame **itr = m_container, **last = m_container + m_containerSize; itr != last; ++itr) + (*itr)->redraw(); + + break; + } +} + void Frame::balance(uint32_t x, uint32_t y, uint32_t width, uint32_t height) { m_positionX = x; @@ -289,6 +310,10 @@ Frame::balance(uint32_t x, uint32_t y, uint32_t width, uint32_t height) { (*itr)->m_width = s; } + // Use the pre-calculated frame sizes to balance the sub-frames. If + // the frame is too small, it will set the remaining windows to zero + // extent which will flag them as offscreen. + for (Frame **itr = m_container, **last = m_container + m_containerSize; itr != last; ++itr) { if (m_type == TYPE_ROW) { (*itr)->balance(x, y, m_width, std::min((*itr)->m_height, height)); diff --git a/src/display/frame.h b/src/display/frame.h index 8171dccc..784b3836 100644 --- a/src/display/frame.h +++ b/src/display/frame.h @@ -87,6 +87,8 @@ public: void clear(); void refresh(); + void redraw(); + void balance(uint32_t x, uint32_t y, uint32_t width, uint32_t height); private: diff --git a/src/display/manager.cc b/src/display/manager.cc index f83ea1ae..d686f232 100644 --- a/src/display/manager.cc +++ b/src/display/manager.cc @@ -87,7 +87,9 @@ Manager::receive_update() { display::Canvas::resize_term(display::Canvas::term_size()); Canvas::redraw_std(); + adjust_layout(); + m_rootFrame.redraw(); } Canvas::refresh_std(); diff --git a/src/display/window_input.h b/src/display/window_input.h index bbcedba2..e2a373f3 100644 --- a/src/display/window_input.h +++ b/src/display/window_input.h @@ -61,7 +61,7 @@ public: void set_title(const std::string& str) { m_title = str; } bool focus() const { return m_focus; } - void set_focus(bool f) { mark_dirty(); m_focus = f; } + void set_focus(bool f) { m_focus = f; if (is_active()) mark_dirty(); } virtual void redraw(); diff --git a/src/display/window_log.cc b/src/display/window_log.cc index d1bc77df..023fbccd 100644 --- a/src/display/window_log.cc +++ b/src/display/window_log.cc @@ -48,11 +48,14 @@ WindowLog::WindowLog(core::Log* l) : Window(new Canvas, flag_width_dynamic, 0, 0), m_log(l) { + m_taskUpdate.set_slot(rak::mem_fn(this, &WindowLog::receive_update)), + // We're trying out scheduled tasks instead. m_connUpdate = l->signal_update().connect(sigc::mem_fun(*this, &WindowLog::receive_update)); } WindowLog::~WindowLog() { + priority_queue_erase(&taskScheduler, &m_taskUpdate); m_connUpdate.disconnect(); } @@ -75,19 +78,28 @@ WindowLog::redraw() { } } +// When WindowLog is activated, call receive_update() to ensure it +// gets updated. void WindowLog::receive_update() { + if (!is_active()) + return; + iterator itr = find_older(); extent_type h = std::min(std::distance(m_log->begin(), itr), (std::iterator_traits::difference_type)10); if (h != m_minHeight) { - set_active(h != 0); - m_minHeight = h; m_slotAdjust(); + + } else { + mark_dirty(); } - mark_dirty(); + priority_queue_erase(&taskScheduler, &m_taskUpdate); + + if (h != 0) + priority_queue_insert(&taskScheduler, &m_taskUpdate, (cachedTime + rak::timer::from_seconds(30)).round_seconds()); } } diff --git a/src/display/window_log.h b/src/display/window_log.h index 1ec9ed02..f0d4cbee 100644 --- a/src/display/window_log.h +++ b/src/display/window_log.h @@ -52,15 +52,17 @@ public: WindowLog(core::Log* l); ~WindowLog(); - virtual void redraw(); + virtual void redraw(); - void receive_update(); + void receive_update(); private: - inline iterator find_older(); + inline iterator find_older(); - core::Log* m_log; - sigc::connection m_connUpdate; + core::Log* m_log; + sigc::connection m_connUpdate; + + rak::priority_item m_taskUpdate; }; } diff --git a/src/input/manager.cc b/src/input/manager.cc index edb11055..dbb8f7b2 100644 --- a/src/input/manager.cc +++ b/src/input/manager.cc @@ -61,10 +61,10 @@ Manager::erase(Bindings* b) { void Manager::pressed(int key) { - if (m_textInput != NULL && m_textInput->pressed(key)) - return; - - std::find_if(begin(), end(), std::bind2nd(std::mem_fun(&Bindings::pressed), key)); + if (m_textInput != NULL) + m_textInput->pressed(key); + else + std::find_if(rbegin(), rend(), std::bind2nd(std::mem_fun(&Bindings::pressed), key)); } } diff --git a/src/input/manager.h b/src/input/manager.h index e1f4f10d..a8ba8b79 100644 --- a/src/input/manager.h +++ b/src/input/manager.h @@ -37,16 +37,16 @@ #ifndef RTORRENT_INPUT_MANAGER_H #define RTORRENT_INPUT_MANAGER_H -#include +#include namespace input { class Bindings; class TextInput; -class Manager : private std::list { +class Manager : private std::vector { public: - typedef std::list Base; + typedef std::vector Base; using Base::iterator; using Base::const_iterator; @@ -59,7 +59,6 @@ public: using Base::rend; using Base::push_back; - using Base::push_front; Manager() : m_textInput(NULL) {} @@ -69,8 +68,6 @@ public: void set_text_input(TextInput* input = NULL) { m_textInput = input; } - // Slot for unreacted keys. - private: TextInput* m_textInput; }; diff --git a/src/ui/download.cc b/src/ui/download.cc index 809a01f3..a816108f 100644 --- a/src/ui/download.cc +++ b/src/ui/download.cc @@ -99,7 +99,7 @@ Download::activate(display::Frame* frame) { if (is_active()) throw torrent::client_error("ui::Download::activate() called on an already activated object."); - control->input()->push_front(&m_bindings); + control->input()->push_back(&m_bindings); m_frame = frame; activate_display(DISPLAY_PEER_LIST); diff --git a/src/ui/download_list.cc b/src/ui/download_list.cc index 6f5af8c0..d45a63ff 100644 --- a/src/ui/download_list.cc +++ b/src/ui/download_list.cc @@ -77,13 +77,6 @@ DownloadList::DownloadList() : m_windowLog = new WLog(&control->core()->get_log_important()); - receive_change_view("main"); - - if (m_view == NULL) - throw torrent::client_error("View \"main\" must be present to initialize the main display."); - - m_taskUpdate.set_slot(rak::mem_fn(this, &DownloadList::task_update)), - setup_keys(); } @@ -101,11 +94,9 @@ DownloadList::activate(display::Frame* frame) { if (is_active()) throw torrent::client_error("ui::DownloadList::activate() called on an already activated object"); - priority_queue_insert(&taskScheduler, &m_taskUpdate, cachedTime); - m_frame = frame; - control->input()->push_front(&m_bindings); + control->input()->push_back(&m_bindings); control->core()->download_list()->slot_map_erase()["0_download_list"] = sigc::mem_fun(this, &DownloadList::receive_download_erased); activate_display(DISPLAY_DOWNLOAD_LIST); @@ -121,10 +112,14 @@ DownloadList::disable() { m_frame = NULL; - priority_queue_erase(&taskScheduler, &m_taskUpdate); control->input()->erase(&m_bindings); } +core::View* +DownloadList::current_view() { + return dynamic_cast(m_uiArray[DISPLAY_DOWNLOAD_LIST])->view(); +} + void DownloadList::activate_display(Display displayType) { if (!is_active()) @@ -144,7 +139,6 @@ DownloadList::activate_display(Display displayType) { delete m_uiArray[m_state]; m_uiArray[m_state] = NULL; - control->input()->push_front(&m_bindings); break; case DISPLAY_DOWNLOAD_LIST: @@ -171,16 +165,14 @@ DownloadList::activate_display(Display displayType) { switch (displayType) { case DISPLAY_DOWNLOAD: // If no download has the focus, just return to the download list. - if (m_view->focus() == m_view->end_visible()) { + if (current_view()->focus() == current_view()->end_visible()) { m_state = DISPLAY_MAX_SIZE; activate_display(DISPLAY_DOWNLOAD_LIST); return; } else { - control->input()->erase(&m_bindings); - - Download* download = new Download(*m_view->focus()); + Download* download = new Download(*current_view()->focus()); download->activate(m_frame); download->bindings()[KEY_LEFT] = sigc::bind(sigc::mem_fun(*this, &DownloadList::activate_display), DISPLAY_DOWNLOAD_LIST); @@ -196,6 +188,7 @@ DownloadList::activate_display(Display displayType) { m_frame->frame(1)->initialize_window(m_windowLog); m_windowLog->set_active(true); + m_windowLog->receive_update(); break; case DISPLAY_LOG: @@ -217,108 +210,6 @@ DownloadList::activate_display(Display displayType) { control->display()->adjust_layout(); } -void -DownloadList::receive_next() { - m_view->next_focus(); - m_view->set_last_changed(); -} - -void -DownloadList::receive_prev() { - m_view->prev_focus(); - m_view->set_last_changed(); -} - -void -DownloadList::receive_start_download() { - if (m_view->focus() == m_view->end_visible()) - return; - - control->core()->download_list()->start_normal(*m_view->focus()); - m_view->set_last_changed(); -} - -void -DownloadList::receive_stop_download() { - if (m_view->focus() == m_view->end_visible()) - return; - - if ((*m_view->focus())->variable()->get_value("state") == 1) - control->core()->download_list()->stop_normal(*m_view->focus()); - else - control->core()->download_list()->erase(*m_view->focus()); - - m_view->set_last_changed(); -} - -void -DownloadList::receive_close_download() { - if (m_view->focus() == m_view->end_visible()) - return; - - core::Download* download = *m_view->focus(); - - control->core()->download_list()->stop_normal(download); - control->core()->download_list()->close(download); - m_view->set_last_changed(); -} - -void -DownloadList::receive_next_priority() { - if (m_view->focus() == m_view->end_visible()) - return; - - (*m_view->focus())->set_priority(((*m_view->focus())->priority() + 1) % 4); -// (*m_window)->mark_dirty(); -} - -void -DownloadList::receive_prev_priority() { - if (m_view->focus() == m_view->end_visible()) - return; - - (*m_view->focus())->set_priority(((*m_view->focus())->priority() - 1) % 4); -// (*m_window)->mark_dirty(); -} - -void -DownloadList::receive_check_hash() { - if (m_view->focus() == m_view->end_visible()) - return; - - // Catch here? - control->core()->download_list()->check_hash(*m_view->focus()); -} - -void -DownloadList::receive_ignore_ratio() { - if (m_view->focus() == m_view->end_visible()) - return; - - if ((*m_view->focus())->variable()->get_value("ignore_commands") != 0) { - (*m_view->focus())->variable()->set("ignore_commands", (int64_t)0); - control->core()->push_log("Torrent set to heed commands."); - } else { - (*m_view->focus())->variable()->set("ignore_commands", (int64_t)1); - control->core()->push_log("Torrent set to ignore commands."); - } -} - -void -DownloadList::receive_clear_tied() { - if (m_view->focus() == m_view->end_visible()) - return; - - const std::string& tiedFile = (*m_view->focus())->variable()->get_string("tied_to_file"); - - if (!tiedFile.empty()) { - // Move this into core? - control->core()->delete_tied(*m_view->focus()); - - control->core()->push_log("Cleared tied to file association for download."); - } -} - void DownloadList::receive_view_input(Input type) { if (control->ui()->current_input() != NULL) @@ -365,7 +256,6 @@ DownloadList::receive_view_input(Input type) { input->bindings()[KEY_ENTER] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_exit_input), type); input->bindings()['\x07'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_exit_input), INPUT_NONE); - m_bindings.disable(); control->ui()->enable_input(title, input); } @@ -378,7 +268,6 @@ DownloadList::receive_exit_input(Input type) { return; control->ui()->disable_input(); - m_bindings.enable(); try { @@ -392,11 +281,11 @@ DownloadList::receive_exit_input(Input type) { break; case INPUT_CHANGE_DIRECTORY: - if (m_view->focus() == m_view->end_visible()) + if (current_view()->focus() == current_view()->end_visible()) throw torrent::input_error("No download in focus to change root directory."); - (*m_view->focus())->variable()->set("directory", rak::trim(input->str())); - control->core()->push_log("New root directory \"" + (*m_view->focus())->variable()->get_string("directory") + "\" for torrent."); + (*current_view()->focus())->variable()->set("directory", rak::trim(input->str())); + control->core()->push_log("New root directory \"" + (*current_view()->focus())->variable()->get_string("directory") + "\" for torrent."); break; case INPUT_COMMAND: @@ -418,51 +307,14 @@ DownloadList::receive_exit_input(Input type) { void DownloadList::receive_download_erased(core::Download* d) { - if (m_view->focus() == m_view->end_visible() || *m_view->focus() != d) + if (m_state != DISPLAY_DOWNLOAD || current_view()->focus() == current_view()->end_visible() || *current_view()->focus() != d) return; activate_display(DISPLAY_DOWNLOAD_LIST); - receive_next(); -} - -void -DownloadList::receive_change_view(const std::string& name) { - core::ViewManager::iterator itr = control->view_manager()->find(name); - - if (itr == control->view_manager()->end()) { - control->core()->push_log("Could not find view \"" + name + "\"."); - return; - } - - m_view = *itr; - m_view->sort(); - - ElementDownloadList* ui = dynamic_cast(m_uiArray[DISPLAY_DOWNLOAD_LIST]); - - if (ui == NULL) - throw torrent::client_error("DownloadList::receive_change_view(...) could not cast ui."); - - ui->set_view(m_view); -} - -void -DownloadList::task_update() { - m_windowLog->receive_update(); - - priority_queue_insert(&taskScheduler, &m_taskUpdate, (cachedTime + rak::timer::from_seconds(1)).round_seconds()); } void DownloadList::setup_keys() { - m_bindings['\x13'] = sigc::mem_fun(*this, &DownloadList::receive_start_download); - m_bindings['\x04'] = sigc::mem_fun(*this, &DownloadList::receive_stop_download); - m_bindings['\x0B'] = sigc::mem_fun(*this, &DownloadList::receive_close_download); - m_bindings['\x12'] = sigc::mem_fun(*this, &DownloadList::receive_check_hash); - m_bindings['+'] = sigc::mem_fun(*this, &DownloadList::receive_next_priority); - m_bindings['-'] = sigc::mem_fun(*this, &DownloadList::receive_prev_priority); - m_bindings['I'] = sigc::mem_fun(*this, &DownloadList::receive_ignore_ratio); - m_bindings['U'] = sigc::mem_fun(*this, &DownloadList::receive_clear_tied); - m_bindings['\x7f'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_view_input), INPUT_LOAD_DEFAULT); m_bindings[KEY_BACKSPACE] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_view_input), INPUT_LOAD_DEFAULT); m_bindings['\n'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_view_input), INPUT_LOAD_MODIFIED); @@ -470,36 +322,11 @@ DownloadList::setup_keys() { m_bindings['\x0F'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_view_input), INPUT_CHANGE_DIRECTORY); m_bindings['\x10'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_view_input), INPUT_COMMAND); - m_bindings[KEY_UP] = sigc::mem_fun(*this, &DownloadList::receive_prev); - m_bindings[KEY_DOWN] = sigc::mem_fun(*this, &DownloadList::receive_next); - m_bindings[KEY_RIGHT] = sigc::bind(sigc::mem_fun(*this, &DownloadList::activate_display), DISPLAY_DOWNLOAD); - m_bindings['l'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::activate_display), DISPLAY_LOG); + m_uiArray[DISPLAY_LOG]->bindings()[' '] = sigc::bind(sigc::mem_fun(*this, &DownloadList::activate_display), DISPLAY_DOWNLOAD_LIST); + m_uiArray[DISPLAY_LOG]->bindings()[KEY_LEFT] = sigc::bind(sigc::mem_fun(*this, &DownloadList::activate_display), DISPLAY_DOWNLOAD_LIST); - m_bindings['1'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_change_view), "main"); - m_bindings['2'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_change_view), "name"); - m_bindings['3'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_change_view), "started"); - m_bindings['4'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_change_view), "stopped"); - m_bindings['5'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_change_view), "complete"); - m_bindings['6'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_change_view), "incomplete"); - m_bindings['7'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_change_view), "hashing"); - - m_uiArray[DISPLAY_LOG]->bindings()[' '] = sigc::bind(sigc::mem_fun(*this, &DownloadList::activate_display), DISPLAY_DOWNLOAD_LIST); - m_uiArray[DISPLAY_LOG]->bindings()[KEY_LEFT] = sigc::bind(sigc::mem_fun(*this, &DownloadList::activate_display), DISPLAY_DOWNLOAD_LIST); + m_uiArray[DISPLAY_DOWNLOAD_LIST]->bindings()[KEY_RIGHT] = sigc::bind(sigc::mem_fun(*this, &DownloadList::activate_display), DISPLAY_DOWNLOAD); + m_uiArray[DISPLAY_DOWNLOAD_LIST]->bindings()['l'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::activate_display), DISPLAY_LOG); } -// void -// DownloadList::setup_input() { -// input::PathInput* p = new input::PathInput; -// m_windowTextInput = new WInput(p); - -// p->slot_dirty(sigc::mem_fun(*m_windowTextInput, &WInput::mark_dirty)); - -// p->signal_show_next().connect(sigc::bind(sigc::mem_fun(*this, &DownloadList::activate_display), DISPLAY_STRING_LIST)); -// p->signal_show_next().connect(sigc::mem_fun(*esl, &ElementStringList::next_screen)); - -// p->signal_show_range().connect(sigc::hide(sigc::hide(sigc::bind(sigc::mem_fun(*this, &DownloadList::activate_display), DISPLAY_STRING_LIST)))); -// p->signal_show_range().connect(sigc::mem_fun(*esl, &ElementStringList::set_range)); - -// } - } diff --git a/src/ui/download_list.h b/src/ui/download_list.h index f53a9223..df4a94b8 100644 --- a/src/ui/download_list.h +++ b/src/ui/download_list.h @@ -100,7 +100,7 @@ public: void activate_display(Display d); - display::Window* window() { return NULL; } + core::View* current_view(); void slot_open_uri(SlotOpenUri s) { m_slotOpenUri = s; } @@ -108,30 +108,11 @@ private: DownloadList(const DownloadList&); void operator = (const DownloadList&); - void receive_next(); - void receive_prev(); - - void receive_start_download(); - void receive_stop_download(); - void receive_close_download(); - - void receive_next_priority(); - void receive_prev_priority(); - - void receive_check_hash(); - - void receive_ignore_ratio(); - void receive_clear_tied(); - void receive_view_input(Input type); void receive_exit_input(Input type); void receive_download_erased(core::Download* d); - void receive_change_view(const std::string& name); - - void task_update(); - void setup_keys(); void setup_input(); @@ -140,10 +121,6 @@ private: ElementBase* m_uiArray[DISPLAY_MAX_SIZE]; WLog* m_windowLog; - core::View* m_view; - - rak::priority_item m_taskUpdate; - SlotOpenUri m_slotOpenUri; }; diff --git a/src/ui/element_base.h b/src/ui/element_base.h index d428b5f6..97193194 100644 --- a/src/ui/element_base.h +++ b/src/ui/element_base.h @@ -58,8 +58,6 @@ public: virtual void activate(display::Frame* frame) = 0; virtual void disable() = 0; - virtual display::Window* window() = 0; - protected: display::Frame* m_frame; diff --git a/src/ui/element_chunks_seen.cc b/src/ui/element_chunks_seen.cc index 23f9ff06..b5d50c94 100644 --- a/src/ui/element_chunks_seen.cc +++ b/src/ui/element_chunks_seen.cc @@ -65,7 +65,7 @@ ElementChunksSeen::activate(display::Frame* frame) { if (is_active()) throw torrent::client_error("ui::ElementChunksSeen::activate(...) is_active()."); - control->input()->push_front(&m_bindings); + control->input()->push_back(&m_bindings); m_window = new WChunksSeen(m_download, &m_focus); m_window->set_active(true); diff --git a/src/ui/element_download_list.cc b/src/ui/element_download_list.cc index c1ebf983..11b9e0b4 100644 --- a/src/ui/element_download_list.cc +++ b/src/ui/element_download_list.cc @@ -36,8 +36,13 @@ #include "config.h" +#include #include +#include "core/download.h" +#include "core/manager.h" +#include "core/view.h" +#include "core/view_manager.h" #include "display/frame.h" #include "display/manager.h" #include "input/manager.h" @@ -47,12 +52,42 @@ namespace ui { +ElementDownloadList::ElementDownloadList() : + m_window(NULL), + m_view(NULL) { + + receive_change_view("main"); + + if (m_view == NULL) + throw torrent::client_error("View \"main\" must be present to initialize the main display."); + + m_bindings['\x13'] = sigc::mem_fun(*this, &ElementDownloadList::receive_start_download); + m_bindings['\x04'] = sigc::mem_fun(*this, &ElementDownloadList::receive_stop_download); + m_bindings['\x0B'] = sigc::mem_fun(*this, &ElementDownloadList::receive_close_download); + m_bindings['\x12'] = sigc::mem_fun(*this, &ElementDownloadList::receive_check_hash); + m_bindings['+'] = sigc::mem_fun(*this, &ElementDownloadList::receive_next_priority); + m_bindings['-'] = sigc::mem_fun(*this, &ElementDownloadList::receive_prev_priority); + m_bindings['I'] = sigc::mem_fun(*this, &ElementDownloadList::receive_ignore_ratio); + m_bindings['U'] = sigc::mem_fun(*this, &ElementDownloadList::receive_clear_tied); + + m_bindings['1'] = sigc::bind(sigc::mem_fun(*this, &ElementDownloadList::receive_change_view), "main"); + m_bindings['2'] = sigc::bind(sigc::mem_fun(*this, &ElementDownloadList::receive_change_view), "name"); + m_bindings['3'] = sigc::bind(sigc::mem_fun(*this, &ElementDownloadList::receive_change_view), "started"); + m_bindings['4'] = sigc::bind(sigc::mem_fun(*this, &ElementDownloadList::receive_change_view), "stopped"); + m_bindings['5'] = sigc::bind(sigc::mem_fun(*this, &ElementDownloadList::receive_change_view), "complete"); + m_bindings['6'] = sigc::bind(sigc::mem_fun(*this, &ElementDownloadList::receive_change_view), "incomplete"); + m_bindings['7'] = sigc::bind(sigc::mem_fun(*this, &ElementDownloadList::receive_change_view), "hashing"); + + m_bindings[KEY_UP] = sigc::mem_fun(*this, &ElementDownloadList::receive_prev); + m_bindings[KEY_DOWN] = sigc::mem_fun(*this, &ElementDownloadList::receive_next); +} + void ElementDownloadList::activate(display::Frame* frame) { if (is_active()) throw torrent::client_error("ui::ElementDownloadList::activate(...) is_active()."); - control->input()->push_front(&m_bindings); + control->input()->push_back(&m_bindings); m_window = new WDownloadList(); m_window->set_active(true); @@ -60,8 +95,6 @@ ElementDownloadList::activate(display::Frame* frame) { m_frame = frame; m_frame->initialize_window(m_window); - - control->display()->schedule(m_window, cachedTime); } void @@ -81,6 +114,7 @@ ElementDownloadList::disable() { void ElementDownloadList::set_view(core::View* l) { m_view = l; + m_view->sort(); if (m_window == NULL) return; @@ -89,4 +123,120 @@ ElementDownloadList::set_view(core::View* l) { m_window->mark_dirty(); } +void +ElementDownloadList::receive_next() { + m_view->next_focus(); + m_view->set_last_changed(); +} + +void +ElementDownloadList::receive_prev() { + m_view->prev_focus(); + m_view->set_last_changed(); +} + +void +ElementDownloadList::receive_start_download() { + if (m_view->focus() == m_view->end_visible()) + return; + + control->core()->download_list()->start_normal(*m_view->focus()); + m_view->set_last_changed(); +} + +void +ElementDownloadList::receive_stop_download() { + if (m_view->focus() == m_view->end_visible()) + return; + + if ((*m_view->focus())->variable()->get_value("state") == 1) + control->core()->download_list()->stop_normal(*m_view->focus()); + else + control->core()->download_list()->erase(*m_view->focus()); + + m_view->set_last_changed(); +} + +void +ElementDownloadList::receive_close_download() { + if (m_view->focus() == m_view->end_visible()) + return; + + core::Download* download = *m_view->focus(); + + download->variable()->set("ignore_commands", (int64_t)1); + + control->core()->download_list()->stop_normal(download); + control->core()->download_list()->close(download); + m_view->set_last_changed(); +} + +void +ElementDownloadList::receive_next_priority() { + if (m_view->focus() == m_view->end_visible()) + return; + + (*m_view->focus())->set_priority(((*m_view->focus())->priority() + 1) % 4); + m_window->mark_dirty(); +} + +void +ElementDownloadList::receive_prev_priority() { + if (m_view->focus() == m_view->end_visible()) + return; + + (*m_view->focus())->set_priority(((*m_view->focus())->priority() - 1) % 4); + m_window->mark_dirty(); +} + +void +ElementDownloadList::receive_check_hash() { + if (m_view->focus() == m_view->end_visible()) + return; + + // Catch here? + control->core()->download_list()->check_hash(*m_view->focus()); +} + +void +ElementDownloadList::receive_ignore_ratio() { + if (m_view->focus() == m_view->end_visible()) + return; + + if ((*m_view->focus())->variable()->get_value("ignore_commands") != 0) { + (*m_view->focus())->variable()->set("ignore_commands", (int64_t)0); + control->core()->push_log("Torrent set to heed commands."); + } else { + (*m_view->focus())->variable()->set("ignore_commands", (int64_t)1); + control->core()->push_log("Torrent set to ignore commands."); + } +} + +void +ElementDownloadList::receive_clear_tied() { + if (m_view->focus() == m_view->end_visible()) + return; + + const std::string& tiedFile = (*m_view->focus())->variable()->get_string("tied_to_file"); + + if (!tiedFile.empty()) { + // Move this into core? + control->core()->delete_tied(*m_view->focus()); + + control->core()->push_log("Cleared tied to file association for download."); + } +} + +void +ElementDownloadList::receive_change_view(const std::string& name) { + core::ViewManager::iterator itr = control->view_manager()->find(name); + + if (itr == control->view_manager()->end()) { + control->core()->push_log("Could not find view \"" + name + "\"."); + return; + } + + set_view(*itr); +} + } diff --git a/src/ui/element_download_list.h b/src/ui/element_download_list.h index 2d2cc19f..f8fbe9e5 100644 --- a/src/ui/element_download_list.h +++ b/src/ui/element_download_list.h @@ -54,18 +54,34 @@ class ElementDownloadList : public ElementBase { public: typedef display::WindowDownloadList WDownloadList; - ElementDownloadList() : m_window(NULL), m_view(NULL) {} + ElementDownloadList(); void activate(display::Frame* frame); void disable(); - display::Window* window() { return m_window; } - + core::View* view() { return m_view; } void set_view(core::View* l); + void receive_next(); + void receive_prev(); + + void receive_start_download(); + void receive_stop_download(); + void receive_close_download(); + + void receive_next_priority(); + void receive_prev_priority(); + + void receive_check_hash(); + + void receive_ignore_ratio(); + void receive_clear_tied(); + + void receive_change_view(const std::string& name); + private: - WDownloadList* m_window; - core::View* m_view; + WDownloadList* m_window; + core::View* m_view; }; } diff --git a/src/ui/element_file_list.cc b/src/ui/element_file_list.cc index e1468174..8e57bb15 100644 --- a/src/ui/element_file_list.cc +++ b/src/ui/element_file_list.cc @@ -66,7 +66,7 @@ ElementFileList::activate(display::Frame* frame) { if (m_window != NULL) throw torrent::client_error("ui::ElementFileList::activate(...) is_active()."); - control->input()->push_front(&m_bindings); + control->input()->push_back(&m_bindings); m_window = new WFileList(m_download, &m_focus); m_window->set_active(true); diff --git a/src/ui/element_log_complete.cc b/src/ui/element_log_complete.cc index a8439ddf..bf2075cc 100644 --- a/src/ui/element_log_complete.cc +++ b/src/ui/element_log_complete.cc @@ -58,7 +58,7 @@ ElementLogComplete::activate(display::Frame* frame) { if (is_active()) throw torrent::client_error("ui::ElementLogComplete::activate(...) is_active()."); - control->input()->push_front(&m_bindings); + control->input()->push_back(&m_bindings); m_window = new WLogComplete(m_log); m_window->set_active(true); diff --git a/src/ui/element_peer_info.cc b/src/ui/element_peer_info.cc index ad043b66..d4961c0a 100644 --- a/src/ui/element_peer_info.cc +++ b/src/ui/element_peer_info.cc @@ -60,7 +60,7 @@ ElementPeerInfo::activate(display::Frame* frame) { if (is_active()) throw torrent::client_error("ui::ElementPeerInfo::activate(...) is_active()."); - control->input()->push_front(&m_bindings); + control->input()->push_back(&m_bindings); m_window = new WPeerInfo(m_download, m_list, m_focus); m_window->set_active(true); diff --git a/src/ui/element_peer_list.cc b/src/ui/element_peer_list.cc index bbb430cb..a51085fc 100644 --- a/src/ui/element_peer_list.cc +++ b/src/ui/element_peer_list.cc @@ -59,7 +59,7 @@ ElementPeerList::activate(display::Frame* frame) { if (is_active()) throw torrent::client_error("ui::ElementPeerList::activate(...) is_active()."); - control->input()->push_front(&m_bindings); + control->input()->push_back(&m_bindings); m_window = new WPeerList(m_download, m_list, m_focus); m_window->set_active(true); diff --git a/src/ui/element_string_list.cc b/src/ui/element_string_list.cc index 7f109617..7d4e3899 100644 --- a/src/ui/element_string_list.cc +++ b/src/ui/element_string_list.cc @@ -55,7 +55,7 @@ ElementStringList::activate(display::Frame* frame) { if (is_active()) throw torrent::client_error("ui::ElementStringList::activate(...) is_active()."); - control->input()->push_front(&m_bindings); + control->input()->push_back(&m_bindings); m_window = new WStringList(); m_window->set_active(true); diff --git a/src/ui/element_tracker_list.cc b/src/ui/element_tracker_list.cc index 76fec76f..a708ddf4 100644 --- a/src/ui/element_tracker_list.cc +++ b/src/ui/element_tracker_list.cc @@ -65,7 +65,7 @@ ElementTrackerList::activate(display::Frame* frame) { if (m_window != NULL) throw torrent::client_error("ui::ElementTrackerList::activate(...) is_active()."); - control->input()->push_front(&m_bindings); + control->input()->push_back(&m_bindings); m_window = new WTrackerList(m_download, &m_focus); m_window->set_active(true); diff --git a/src/ui/element_transfer_list.cc b/src/ui/element_transfer_list.cc index e4cef0e0..ff20d6e1 100644 --- a/src/ui/element_transfer_list.cc +++ b/src/ui/element_transfer_list.cc @@ -65,7 +65,7 @@ ElementTransferList::activate(display::Frame* frame) { if (is_active()) throw torrent::client_error("ui::ElementTransferList::activate(...) is_active()."); - control->input()->push_front(&m_bindings); + control->input()->push_back(&m_bindings); m_window = new WTransferList(m_download, &m_focus); m_window->set_active(true); diff --git a/src/ui/root.cc b/src/ui/root.cc index 03ad8d4d..2ce12197 100644 --- a/src/ui/root.cc +++ b/src/ui/root.cc @@ -198,6 +198,9 @@ Root::enable_input(const std::string& title, input::TextInput* input) { m_windowInput->set_title(title); m_windowInput->set_focus(true); + input->bindings()['\x0C'] = sigc::mem_fun(m_control->display(), &display::Manager::force_redraw); // ^L + input->bindings()['\x11'] = sigc::mem_fun(m_control, &Control::receive_normal_shutdown); // ^Q + control->input()->set_text_input(input); control->display()->adjust_layout(); }