diff --git a/src/ui/Makefile.am b/src/ui/Makefile.am index 1446890f..1b7df365 100644 --- a/src/ui/Makefile.am +++ b/src/ui/Makefile.am @@ -1,6 +1,7 @@ noinst_LIBRARIES = libsub_ui.a libsub_ui_a_SOURCES = \ + base_element.h \ control.h \ download.cc \ download.h \ @@ -10,6 +11,8 @@ libsub_ui_a_SOURCES = \ file_list.h \ peer_info.cc \ peer_info.h \ + peer_list.cc \ + peer_list.h \ root.cc \ root.h \ tracker_list.cc \ diff --git a/src/ui/base_element.h b/src/ui/base_element.h new file mode 100644 index 00000000..6c1fd4b4 --- /dev/null +++ b/src/ui/base_element.h @@ -0,0 +1,48 @@ +// rTorrent - BitTorrent client +// Copyright (C) 2005, Jari Sundell +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// Contact: Jari Sundell +// +// Skomakerveien 33 +// 3185 Skoppum, NORWAY + +#ifndef RTORRENT_UI_BASE_ELEMENT_H +#define RTORRENT_UI_BASE_ELEMENT_H + +#include "display/manager.h" +#include "input/bindings.h" + +namespace ui { + +class BaseElement { +public: + typedef display::Manager::iterator MItr; + + virtual ~BaseElement() {} + + virtual void activate(Control* c, MItr mItr) = 0; + virtual void disable(Control* c) = 0; + + input::Bindings& get_bindings() { return m_bindings; } + +protected: + input::Bindings m_bindings; +}; + +} + +#endif diff --git a/src/ui/download.cc b/src/ui/download.cc index fa462c14..2683f1e5 100644 --- a/src/ui/download.cc +++ b/src/ui/download.cc @@ -25,12 +25,11 @@ #include #include #include +#include #include "core/download.h" #include "input/bindings.h" #include "display/window_title.h" -#include "display/window_peer_list.h" -#include "display/window_peer_info.h" #include "display/window_download_statusbar.h" #include "display/window_statusbar.h" @@ -38,17 +37,14 @@ #include "download.h" #include "file_list.h" #include "peer_info.h" +#include "peer_list.h" #include "tracker_list.h" namespace ui { Download::Download(DPtr d, Control* c) : m_download(d), - m_state(DISPLAY_NONE), - - m_uiFileList(new FileList(c, d)), - m_uiPeerInfo(new PeerInfo(d, &m_peers, &m_focus)), - m_uiTrackerList(new TrackerList(c, d)), + m_state(DISPLAY_MAX_SIZE), m_windowTitle(new WTitle(d->get_download().get_name())), m_windowDownloadStatus(new WDownloadStatus(d)), @@ -61,11 +57,16 @@ Download::Download(DPtr d, Control* c) : m_focus = m_peers.end(); + m_uiArray[DISPLAY_PEER_LIST] = new PeerList(d, &m_peers, &m_focus); + m_uiArray[DISPLAY_PEER_INFO] = new PeerInfo(d, &m_peers, &m_focus); + m_uiArray[DISPLAY_FILE_LIST] = new FileList(d); + m_uiArray[DISPLAY_TRACKER_LIST] = new TrackerList(d); + bind_keys(); m_download->get_download().peer_list(m_peers); - m_connPeerConnected = m_download->get_download().signal_peer_connected(sigc::mem_fun(*this, &Download::receive_peer_connected)); + m_connPeerConnected = m_download->get_download().signal_peer_connected(sigc::mem_fun(*this, &Download::receive_peer_connected)); m_connPeerDisconnected = m_download->get_download().signal_peer_disconnected(sigc::mem_fun(*this, &Download::receive_peer_disconnected)); } @@ -73,9 +74,7 @@ Download::~Download() { if (m_window != m_control->get_display().end()) throw std::logic_error("ui::Download::~Download() called on an active object"); - delete m_uiFileList; - delete m_uiPeerInfo; - delete m_uiTrackerList; + std::for_each(m_uiArray, m_uiArray + DISPLAY_MAX_SIZE, rak::call_delete()); delete m_windowTitle; delete m_windowDownloadStatus; @@ -98,7 +97,7 @@ Download::activate() { m_control->get_input().push_front(m_bindings); - activate_display(DISPLAY_MAIN); + activate_display(DISPLAY_PEER_LIST); } void @@ -120,35 +119,14 @@ Download::disable() { void Download::activate_display(Display d) { - WPeerList* wpl; - if (m_window == m_control->get_display().end()) throw std::logic_error("ui::Download::activate_display(...) could not find previous display iterator"); - switch (d) { - case DISPLAY_MAIN: - *m_window = wpl = new WPeerList(m_download, &m_peers, &m_focus); - - (*m_bindings)[KEY_RIGHT] = sigc::bind(sigc::mem_fun(*this, &Download::receive_change), DISPLAY_FILE_LIST); - break; - - case DISPLAY_PEER: - m_uiPeerInfo->activate(m_control, m_window); - break; - - case DISPLAY_FILE_LIST: - m_uiFileList->activate(m_window); - break; - - case DISPLAY_TRACKER_LIST: - m_uiTrackerList->activate(m_window); - break; - - default: - throw std::logic_error("ui::Download::activate_display(...) got wrong state"); - } + if (d >= DISPLAY_MAX_SIZE) + throw std::logic_error("ui::Download::activate_display(...) out of bounds"); m_state = d; + m_uiArray[d]->activate(m_control, m_window); m_control->get_display().adjust_layout(); } @@ -156,37 +134,9 @@ Download::activate_display(Display d) { // Does not delete disabled window. void Download::disable_display() { - switch (m_state) { - case DISPLAY_MAIN: - m_bindings->erase(KEY_RIGHT); - - break; - - case DISPLAY_PEER: - m_uiPeerInfo->disable(m_control); - *m_window = NULL; - - return; - - case DISPLAY_FILE_LIST: - m_uiFileList->disable(); - *m_window = NULL; - - return; - - case DISPLAY_TRACKER_LIST: - m_uiTrackerList->disable(); - *m_window = NULL; - - return; - - default: - throw std::logic_error("ui::Download::disable_display() is in an invalid state"); - } - - // urgh, get ui's for the rest too. - delete *m_window; + m_uiArray[m_state]->disable(m_control); + m_state = DISPLAY_MAX_SIZE; *m_window = NULL; } @@ -284,16 +234,17 @@ Download::bind_keys() { (*m_bindings)['t'] = sigc::bind(sigc::mem_fun(m_download->get_download(), &torrent::Download::set_tracker_timeout), 2 * 1000000); - (*m_bindings)['p'] = sigc::bind(sigc::mem_fun(*this, &Download::receive_change), DISPLAY_PEER); + (*m_bindings)['p'] = sigc::bind(sigc::mem_fun(*this, &Download::receive_change), DISPLAY_PEER_INFO); (*m_bindings)['o'] = sigc::bind(sigc::mem_fun(*this, &Download::receive_change), DISPLAY_TRACKER_LIST); (*m_bindings)[KEY_UP] = sigc::mem_fun(*this, &Download::receive_prev); (*m_bindings)[KEY_DOWN] = sigc::mem_fun(*this, &Download::receive_next); // Key bindings for sub-ui's. - m_uiFileList->get_bindings()[KEY_LEFT] = sigc::bind(sigc::mem_fun(*this, &Download::receive_change), DISPLAY_MAIN); - m_uiPeerInfo->get_bindings()[' '] = sigc::bind(sigc::mem_fun(*this, &Download::receive_change), DISPLAY_MAIN); - m_uiTrackerList->get_bindings()[' '] = sigc::bind(sigc::mem_fun(*this, &Download::receive_change), DISPLAY_MAIN); + m_uiArray[DISPLAY_PEER_LIST]->get_bindings()[KEY_RIGHT] = sigc::bind(sigc::mem_fun(*this, &Download::receive_change), DISPLAY_FILE_LIST); + m_uiArray[DISPLAY_PEER_INFO]->get_bindings()[' '] = sigc::bind(sigc::mem_fun(*this, &Download::receive_change), DISPLAY_PEER_LIST); + m_uiArray[DISPLAY_FILE_LIST]->get_bindings()[KEY_LEFT] = sigc::bind(sigc::mem_fun(*this, &Download::receive_change), DISPLAY_PEER_LIST); + m_uiArray[DISPLAY_TRACKER_LIST]->get_bindings()[' '] = sigc::bind(sigc::mem_fun(*this, &Download::receive_change), DISPLAY_PEER_LIST); } void diff --git a/src/ui/download.h b/src/ui/download.h index eca1ee4b..8f6151e0 100644 --- a/src/ui/download.h +++ b/src/ui/download.h @@ -30,7 +30,6 @@ namespace display { class WindowTitle; class WindowStatusbar; - class WindowPeerList; class WindowDownloadStatusbar; } @@ -41,14 +40,10 @@ namespace core { namespace ui { class Control; -class FileList; -class PeerInfo; -class TrackerList; +class BaseElement; class Download { public: - typedef display::Window Window; - typedef display::WindowPeerList WPeerList; typedef display::WindowTitle WTitle; typedef display::WindowStatusbar WMainStatus; typedef display::WindowDownloadStatusbar WDownloadStatus; @@ -58,11 +53,11 @@ public: typedef display::Manager::iterator MItr; typedef enum { - DISPLAY_NONE, - DISPLAY_MAIN, - DISPLAY_PEER, + DISPLAY_PEER_LIST, + DISPLAY_PEER_INFO, DISPLAY_FILE_LIST, - DISPLAY_TRACKER_LIST + DISPLAY_TRACKER_LIST, + DISPLAY_MAX_SIZE } Display; // We own 'window'. @@ -103,9 +98,7 @@ private: Display m_state; - FileList* m_uiFileList; - PeerInfo* m_uiPeerInfo; - TrackerList* m_uiTrackerList; + BaseElement* m_uiArray[DISPLAY_MAX_SIZE]; WTitle* m_windowTitle; WDownloadStatus* m_windowDownloadStatus; diff --git a/src/ui/file_list.cc b/src/ui/file_list.cc index 71c6a4e5..f54debc1 100644 --- a/src/ui/file_list.cc +++ b/src/ui/file_list.cc @@ -31,10 +31,9 @@ namespace ui { -FileList::FileList(Control* c, core::Download* d) : +FileList::FileList(core::Download* d) : m_download(d), m_window(NULL), - m_control(c), m_focus(0) { m_bindings[' '] = sigc::mem_fun(*this, &FileList::receive_priority); @@ -43,21 +42,21 @@ FileList::FileList(Control* c, core::Download* d) : } void -FileList::activate(MItr mItr) { +FileList::activate(Control* c, MItr mItr) { if (m_window != NULL) throw std::logic_error("ui::FileList::activate(...) called on an object in the wrong state"); - m_control->get_input().push_front(&m_bindings); + c->get_input().push_front(&m_bindings); *mItr = m_window = new WFileList(m_download, &m_focus); } void -FileList::disable() { +FileList::disable(Control* c) { if (m_window == NULL) throw std::logic_error("ui::FileList::disable(...) called on an object in the wrong state"); - m_control->get_input().erase(&m_bindings); + c->get_input().erase(&m_bindings); delete m_window; m_window = NULL; diff --git a/src/ui/file_list.h b/src/ui/file_list.h index 0f695414..39dff537 100644 --- a/src/ui/file_list.h +++ b/src/ui/file_list.h @@ -24,8 +24,8 @@ #define RTORRENT_UI_FILE_LIST_H #include "core/download.h" -#include "display/manager.h" -#include "input/bindings.h" + +#include "base_element.h" namespace display { class WindowFileList; @@ -35,17 +35,14 @@ namespace ui { class Control; -class FileList { +class FileList : public BaseElement { public: typedef display::WindowFileList WFileList; - typedef display::Manager::iterator MItr; - FileList(Control* c, core::Download* d); + FileList(core::Download* d); - void activate(MItr mItr); - void disable(); - - input::Bindings& get_bindings() { return m_bindings; } + void activate(Control* c, MItr mItr); + void disable(Control* c); private: void receive_next(); @@ -56,9 +53,6 @@ private: core::Download* m_download; WFileList* m_window; - Control* m_control; - input::Bindings m_bindings; - // Change to unsigned, please. unsigned int m_focus; }; diff --git a/src/ui/peer_info.h b/src/ui/peer_info.h index 05720f64..d5f1f086 100644 --- a/src/ui/peer_info.h +++ b/src/ui/peer_info.h @@ -24,8 +24,8 @@ #define RTORRENT_UI_PEER_INFO_H #include "core/download.h" -#include "display/manager.h" -#include "input/bindings.h" + +#include "base_element.h" namespace display { class WindowPeerInfo; @@ -35,10 +35,9 @@ namespace ui { class Control; -class PeerInfo { +class PeerInfo : public BaseElement { public: typedef display::WindowPeerInfo WPeerInfo; - typedef display::Manager::iterator MItr; typedef std::list PList; PeerInfo(core::Download* d, PList* l, PList::iterator* f); @@ -46,14 +45,10 @@ public: void activate(Control* c, MItr mItr); void disable(Control* c); - input::Bindings& get_bindings() { return m_bindings; } - private: core::Download* m_download; WPeerInfo* m_window; - input::Bindings m_bindings; - PList* m_list; PList::iterator* m_focus; }; diff --git a/src/ui/peer_list.cc b/src/ui/peer_list.cc new file mode 100644 index 00000000..aa6e9d8a --- /dev/null +++ b/src/ui/peer_list.cc @@ -0,0 +1,63 @@ +// rTorrent - BitTorrent client +// Copyright (C) 2005, Jari Sundell +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// Contact: Jari Sundell +// +// Skomakerveien 33 +// 3185 Skoppum, NORWAY + +#include "config.h" + +#include + +#include "display/window_peer_list.h" + +#include "control.h" +#include "peer_list.h" + +namespace ui { + +PeerList::PeerList(core::Download* d, PList* l, PList::iterator* f) : + m_download(d), + m_window(NULL), + m_list(l), + m_focus(f) { + +} + +void +PeerList::activate(Control* c, MItr mItr) { + if (m_window != NULL) + throw std::logic_error("ui::PeerList::activate(...) called on an object in the wrong state"); + + c->get_input().push_front(&m_bindings); + + *mItr = m_window = new WPeerList(m_download, m_list, m_focus); +} + +void +PeerList::disable(Control* c) { + if (m_window == NULL) + throw std::logic_error("ui::PeerList::disable(...) called on an object in the wrong state"); + + c->get_input().erase(&m_bindings); + + delete m_window; + m_window = NULL; +} + +} diff --git a/src/ui/peer_list.h b/src/ui/peer_list.h new file mode 100644 index 00000000..8b54ff1d --- /dev/null +++ b/src/ui/peer_list.h @@ -0,0 +1,58 @@ +// rTorrent - BitTorrent client +// Copyright (C) 2005, Jari Sundell +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// Contact: Jari Sundell +// +// Skomakerveien 33 +// 3185 Skoppum, NORWAY + +#ifndef RTORRENT_UI_PEER_LIST_H +#define RTORRENT_UI_PEER_LIST_H + +#include "core/download.h" + +#include "base_element.h" + +namespace display { + class WindowPeerList; +} + +namespace ui { + +class Control; + +class PeerList : public BaseElement { +public: + typedef display::WindowPeerList WPeerList; + typedef std::list PList; + + PeerList(core::Download* d, PList* l, PList::iterator* f); + + void activate(Control* c, MItr mItr); + void disable(Control* c); + +private: + core::Download* m_download; + WPeerList* m_window; + + PList* m_list; + PList::iterator* m_focus; +}; + +} + +#endif diff --git a/src/ui/tracker_list.cc b/src/ui/tracker_list.cc index b0b506a5..7df1e7f1 100644 --- a/src/ui/tracker_list.cc +++ b/src/ui/tracker_list.cc @@ -31,10 +31,9 @@ namespace ui { -TrackerList::TrackerList(Control* c, core::Download* d) : +TrackerList::TrackerList(core::Download* d) : m_download(d), m_window(NULL), - m_control(c), m_focus(0) { m_bindings[KEY_DOWN] = sigc::mem_fun(*this, &TrackerList::receive_next); @@ -42,21 +41,21 @@ TrackerList::TrackerList(Control* c, core::Download* d) : } void -TrackerList::activate(MItr mItr) { +TrackerList::activate(Control* c, MItr mItr) { if (m_window != NULL) throw std::logic_error("ui::TrackerList::activate(...) called on an object in the wrong state"); - m_control->get_input().push_front(&m_bindings); + c->get_input().push_front(&m_bindings); *mItr = m_window = new WTrackerList(m_download, &m_focus); } void -TrackerList::disable() { +TrackerList::disable(Control* c) { if (m_window == NULL) throw std::logic_error("ui::TrackerList::disable(...) called on an object in the wrong state"); - m_control->get_input().erase(&m_bindings); + c->get_input().erase(&m_bindings); delete m_window; m_window = NULL; diff --git a/src/ui/tracker_list.h b/src/ui/tracker_list.h index 74e6375d..fbb5df6a 100644 --- a/src/ui/tracker_list.h +++ b/src/ui/tracker_list.h @@ -24,8 +24,8 @@ #define RTORRENT_UI_TRACKER_LIST_H #include "core/download.h" -#include "display/manager.h" -#include "input/bindings.h" + +#include "base_element.h" namespace display { class WindowTrackerList; @@ -35,17 +35,14 @@ namespace ui { class Control; -class TrackerList { +class TrackerList : public BaseElement { public: typedef display::WindowTrackerList WTrackerList; - typedef display::Manager::iterator MItr; - TrackerList(Control* c, core::Download* d); + TrackerList(core::Download* d); - void activate(MItr mItr); - void disable(); - - input::Bindings& get_bindings() { return m_bindings; } + void activate(Control* c, MItr mItr); + void disable(Control* c); private: void receive_next(); @@ -54,9 +51,6 @@ private: core::Download* m_download; WTrackerList* m_window; - Control* m_control; - input::Bindings m_bindings; - // Change to unsigned, please. unsigned int m_focus; };