diff --git a/configure.ac b/configure.ac index 1d1cb4ab..67769203 100644 --- a/configure.ac +++ b/configure.ac @@ -50,4 +50,5 @@ AC_OUTPUT([ src/core/Makefile src/display/Makefile src/input/Makefile + src/ui/Makefile ]) diff --git a/src/Makefile.am b/src/Makefile.am index c730a4f6..0638baf7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,11 +1,13 @@ SUBDIRS = \ core \ display \ - input + input \ + ui bin_PROGRAMS = rtorrent rtorrent_LDADD = \ + $(top_srcdir)/src/ui/libsub_ui.a \ $(top_srcdir)/src/core/libsub_core.a \ $(top_srcdir)/src/display/libsub_display.a \ $(top_srcdir)/src/input/libsub_input.a diff --git a/src/core/poll.cc b/src/core/poll.cc index 532bbfae..2f7fd96a 100644 --- a/src/core/poll.cc +++ b/src/core/poll.cc @@ -1,6 +1,7 @@ #include "config.h" #include +#include #include #include #include @@ -34,9 +35,13 @@ Poll::poll() { m_maxFd = select(m_maxFd, &m_readSet, &m_writeSet, &m_exceptSet, &timeout); - if (m_maxFd == EINTR) + if (m_maxFd >= 0) + return; + + else if (errno == EINTR) m_slotSelectInterrupted(); - else if (m_maxFd < 0) + + else if (errno < 0) throw std::runtime_error("Poll::work(): select error"); } diff --git a/src/display/manager.cc b/src/display/manager.cc index 72c0040d..5912ebee 100644 --- a/src/display/manager.cc +++ b/src/display/manager.cc @@ -26,6 +26,16 @@ _accumulate accumulate(Type& t, Ftor f) { return _accumulate(t, f); } +Manager::iterator +Manager::erase(Window* w) { + iterator itr = std::find(begin(), end(), w); + + if (itr == end()) + throw std::logic_error("Manager::erase(...) did not find the window"); + + return Base::erase(itr); +} + void Manager::adjust_layout() { int countDynamic = 0; diff --git a/src/display/manager.h b/src/display/manager.h index 42759a47..b3ba1234 100644 --- a/src/display/manager.h +++ b/src/display/manager.h @@ -1,15 +1,15 @@ #ifndef RTORRENT_DISPLAY_MANAGER_H #define RTORRENT_DISPLAY_MANAGER_H -#include +#include namespace display { class Window; -class Manager : private std::vector { +class Manager : private std::list { public: - typedef std::vector Base; + typedef std::list Base; using Base::iterator; using Base::const_iterator; @@ -23,8 +23,11 @@ public: using Base::insert; using Base::erase; + using Base::push_front; using Base::push_back; + iterator erase(Window* w); + void adjust_layout(); void do_update(); diff --git a/src/display/window_download_list.h b/src/display/window_download_list.h index 8e8c323b..7137a530 100644 --- a/src/display/window_download_list.h +++ b/src/display/window_download_list.h @@ -12,7 +12,9 @@ public: WindowDownloadList(List* d); - List::iterator get_focus() { return m_focus; } + List* get_list() { return m_downloads; } + + List::iterator get_focus() { return m_focus; } void set_focus(core::DownloadList::iterator itr) { m_focus = itr; } virtual void redraw(); diff --git a/src/display/window_title.cc b/src/display/window_title.cc index ff491b37..dfc8b209 100644 --- a/src/display/window_title.cc +++ b/src/display/window_title.cc @@ -8,7 +8,8 @@ namespace display { WindowTitle::WindowTitle() : - Window(new Canvas, false, 1) { + Window(new Canvas, false, 1), + m_counter(0) { m_title += "rtorrent " VERSION " - "; m_title += torrent::get(torrent::LIBRARY_NAME); @@ -16,10 +17,11 @@ WindowTitle::WindowTitle() : void WindowTitle::redraw() { + m_counter++; + m_canvas->erase(); - m_canvas->print(std::max(0, (m_canvas->get_width() - (int)m_title.size()) / 2 - 4), 0, - "*** %s ***", m_title.c_str()); + "*** %s *** %i", m_title.c_str(), m_counter); } } diff --git a/src/display/window_title.h b/src/display/window_title.h index cad88a61..8361ee7e 100644 --- a/src/display/window_title.h +++ b/src/display/window_title.h @@ -1,6 +1,7 @@ #ifndef RTORRENT_DISPLAY_WINDOW_TITLE_H #define RTORRENT_DISPLAY_WINDOW_TITLE_H +#include #include "window.h" namespace display { @@ -13,6 +14,8 @@ public: private: std::string m_title; + + int m_counter; }; } diff --git a/src/input/bindings.cc b/src/input/bindings.cc index 3da21dc9..590c822a 100644 --- a/src/input/bindings.cc +++ b/src/input/bindings.cc @@ -8,6 +8,9 @@ namespace input { bool Bindings::pressed(int key) { + if (!m_active) + return false; + const_iterator itr = find(key); if (itr != end()) diff --git a/src/input/bindings.h b/src/input/bindings.h index 1b4c1927..650f1d13 100644 --- a/src/input/bindings.h +++ b/src/input/bindings.h @@ -2,6 +2,7 @@ #define RTORRENT_INPUT_BINDINGS_H #include +#include #include namespace input { @@ -23,7 +24,15 @@ public: using Base::operator[]; - bool pressed(int key); + Bindings() : m_active(true) {} + + void activate() { m_active = true; } + void disable() { m_active = false; } + + bool pressed(int key); + +private: + bool m_active; }; } diff --git a/src/input/manager.cc b/src/input/manager.cc index 16762290..ec153f7d 100644 --- a/src/input/manager.cc +++ b/src/input/manager.cc @@ -2,12 +2,23 @@ #include #include +#include #include "manager.h" #include "bindings.h" namespace input { +void +Manager::erase(Bindings* b) { + iterator itr = std::find(begin(), end(), b); + + if (itr == end()) + throw std::logic_error("Manager::erase(...) could not find binding"); + + Base::erase(itr); +} + void Manager::pressed(int key) { std::find_if(begin(), end(), std::bind2nd(std::mem_fun(&Bindings::pressed), key)); diff --git a/src/input/manager.h b/src/input/manager.h index 9aeffe02..df6e6c56 100644 --- a/src/input/manager.h +++ b/src/input/manager.h @@ -24,6 +24,8 @@ public: using Base::push_back; using Base::push_front; + void erase(Bindings* b); + void pressed(int key); // Slot for unreacted keys. diff --git a/src/main.cc b/src/main.cc index f9914276..64a2b839 100644 --- a/src/main.cc +++ b/src/main.cc @@ -15,6 +15,8 @@ #include "input/bindings.h" #include "input/manager.h" +#include "ui/control.h" +#include "ui/download_list.h" #include "signal_handler.h" @@ -24,9 +26,6 @@ bool is_shutting_down = false; core::Poll poll; core::DownloadList downloads; -display::Manager displayManager; -input::Manager inputManager; - void set_shutdown() { start_shutdown = true; @@ -51,16 +50,14 @@ main(int argc, char** argv) { display::Canvas::init(); - inputManager.push_back(new input::Bindings); + ui::Control uiControl; + ui::DownloadList uiDownloadList(&downloads, &uiControl); - poll.slot_read_stdin(sigc::mem_fun(inputManager, &input::Manager::pressed)); + uiDownloadList.activate(); + + poll.slot_read_stdin(sigc::mem_fun(uiControl.get_input(), &input::Manager::pressed)); poll.register_http(); - display::WindowDownloadList* wdl = new display::WindowDownloadList(&downloads); - - displayManager.push_back(new display::WindowTitle); - displayManager.push_back(wdl); - torrent::initialize(); torrent::listen_open(6880, 6999); @@ -71,8 +68,6 @@ main(int argc, char** argv) { itr->open(); itr->hash_check(); - - wdl->set_focus(itr); } SignalHandler::set_handler(SIGINT, sigc::ptr_fun(&set_shutdown)); @@ -81,8 +76,8 @@ main(int argc, char** argv) { if (start_shutdown && !is_shutting_down) do_shutdown(); - displayManager.adjust_layout(); - displayManager.do_update(); + uiControl.get_display().adjust_layout(); + uiControl.get_display().do_update(); poll.poll(); poll.work(); diff --git a/src/ui/control.h b/src/ui/control.h new file mode 100644 index 00000000..87170d98 --- /dev/null +++ b/src/ui/control.h @@ -0,0 +1,22 @@ +#ifndef RTORRENT_UI_CONTROL_H +#define RTORRENT_UI_CONTROL_H + +#include "display/manager.h" +#include "input/manager.h" + +namespace ui { + +class Control { +public: + + display::Manager& get_display() { return m_display; } + input::Manager& get_input() { return m_input; } + +private: + display::Manager m_display; + input::Manager m_input; +}; + +} + +#endif