From fc76a11d7118888f1eed2029251dd50ad8b64bdc Mon Sep 17 00:00:00 2001 From: rakshasa Date: Wed, 26 Jul 2006 21:41:09 +0000 Subject: [PATCH] * UI refactoring, added display::Frame and started cleaning up the code. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@747 e378c898-3ddf-0310-93e7-cc216c733640 --- rak/algorithm.h | 9 + src/display/Makefile.am | 2 + src/display/frame.cc | 239 +++++++++++++++++++++ src/display/frame.h | 110 ++++++++++ src/display/manager.cc | 64 +----- src/display/manager.h | 31 +-- src/display/window_http_queue.cc | 7 +- src/display/window_input.cc | 8 +- src/display/window_input.h | 15 +- src/display/window_log_complete.cc | 2 +- src/display/window_statusbar.cc | 11 +- src/display/window_statusbar.h | 5 +- src/display/window_title.cc | 7 +- src/display/window_title.h | 9 +- src/input/text_input.cc | 8 +- src/ui/download.cc | 61 +++--- src/ui/download.h | 7 +- src/ui/download_list.cc | 319 ++++++++++++++--------------- src/ui/download_list.h | 33 +-- src/ui/element_base.h | 21 +- src/ui/element_chunks_seen.cc | 26 ++- src/ui/element_chunks_seen.h | 6 +- src/ui/element_download_list.cc | 28 ++- src/ui/element_download_list.h | 6 +- src/ui/element_file_list.cc | 20 +- src/ui/element_file_list.h | 6 +- src/ui/element_log_complete.cc | 35 +++- src/ui/element_log_complete.h | 6 +- src/ui/element_peer_info.cc | 26 ++- src/ui/element_peer_info.h | 6 +- src/ui/element_peer_list.cc | 26 ++- src/ui/element_peer_list.h | 6 +- src/ui/element_string_list.cc | 21 +- src/ui/element_string_list.h | 6 +- src/ui/element_tracker_list.cc | 20 +- src/ui/element_tracker_list.h | 6 +- src/ui/element_transfer_list.cc | 26 ++- src/ui/element_transfer_list.h | 6 +- src/ui/root.cc | 83 +++++++- src/ui/root.h | 23 ++- src/utils/variable_map.cc | 4 +- 41 files changed, 889 insertions(+), 471 deletions(-) create mode 100644 src/display/frame.cc create mode 100644 src/display/frame.h diff --git a/rak/algorithm.h b/rak/algorithm.h index 64528abc..df28d452 100644 --- a/rak/algorithm.h +++ b/rak/algorithm.h @@ -56,6 +56,15 @@ for_each_pre(_InputIter __first, _InputIter __last, _Function __f) { return __f; } +template +Accumulator +accumulate(InputIter first, InputIter last, Function function, Accumulator acc) { + while (first != last) + acc += function(*first++); + + return acc; +} + // Return a range with a distance of no more than __distance and // between __first and __last, centered on __middle1. template diff --git a/src/display/Makefile.am b/src/display/Makefile.am index 0eadd251..70f23f2b 100644 --- a/src/display/Makefile.am +++ b/src/display/Makefile.am @@ -5,6 +5,8 @@ libsub_display_a_SOURCES = \ canvas.h \ client_info.cc \ client_info.h \ + frame.cc \ + frame.h \ manager.cc \ manager.h \ utils.cc \ diff --git a/src/display/frame.cc b/src/display/frame.cc new file mode 100644 index 00000000..84df2897 --- /dev/null +++ b/src/display/frame.cc @@ -0,0 +1,239 @@ +// rTorrent - BitTorrent client +// Copyright (C) 2005-2006, 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 +// +// In addition, as a special exception, the copyright holders give +// permission to link the code of portions of this program with the +// OpenSSL library under certain conditions as described in each +// individual source file, and distribute linked combinations +// including the two. +// +// You must obey the GNU General Public License in all respects for +// all of the code used other than OpenSSL. If you modify file(s) +// with this exception, you may extend this exception to your version +// of the file(s), but you are not obligated to do so. If you do not +// wish to do so, delete this exception statement from your version. +// If you delete this exception statement from all source files in the +// program, then also delete it here. +// +// Contact: Jari Sundell +// +// Skomakerveien 33 +// 3185 Skoppum, NORWAY + +#include "config.h" + +#include +#include +#include +#include + +#include "frame.h" +#include "window.h" + +namespace display { + +Frame::Frame() : + m_type(TYPE_NONE), + + m_positionX(0), + m_positionY(0), + m_width(0), + m_height(0) { +} + +bool +Frame::is_dynamic() const { + switch (m_type) { + case TYPE_NONE: + return false; + + case TYPE_WINDOW: + return m_window->is_active() && m_window->is_dynamic(); + + case TYPE_ROW: + case TYPE_COLUMN: + for (size_type i = 0; i < m_containerSize; ++i) + if (m_container[i]->is_dynamic()) + return true; + + return false; + } + + return false; +} + +Frame::pair_type +Frame::preferred_size() const { + switch (m_type) { + case TYPE_NONE: + return pair_type(0, 0); + + case TYPE_WINDOW: + return m_window->is_active() ? pair_type(0, m_window->get_min_height()) : pair_type(0, 0); + + case TYPE_ROW: + case TYPE_COLUMN: + { + pair_type accum(0, 0); + + for (size_type i = 0; i < m_containerSize; ++i) { + pair_type p = m_container[i]->preferred_size(); + + accum.first += p.first; + accum.second += p.second; + } + + return accum; + } + } + + return pair_type(0, 0); +} + +void +Frame::set_container_size(size_type size) { + if ((m_type != TYPE_ROW && m_type != TYPE_COLUMN) || size >= max_size) + throw torrent::client_error("Frame::set_container_size(...) Bad state."); + + while (m_containerSize > size) { + delete m_container[--m_containerSize]; + m_container[m_containerSize] = NULL; + } + + while (m_containerSize < size) { + m_container[m_containerSize++] = new Frame(); + } +} + +void +Frame::initialize_window(Window* window) { + if (m_type != TYPE_NONE) + throw torrent::client_error("Frame::initialize_window(...) m_type != TYPE_NONE."); + + m_type = TYPE_WINDOW; + m_window = window; +} + +void +Frame::initialize_container(Type containerType, size_type size) { + if (m_type != TYPE_NONE || (containerType != TYPE_ROW && containerType != TYPE_COLUMN)) + throw torrent::client_error("Frame::initialize_container(...) Invalid state."); + + if (size > max_size) + throw torrent::client_error("Frame::initialize_container(...) size >= max_size."); + + m_type = containerType; + m_containerSize = size; + + for (size_type i = 0; i < m_containerSize; ++i) + m_container[i] = new Frame(); +} + +void +Frame::clear() { + switch (m_type) { + case TYPE_ROW: + case TYPE_COLUMN: + for (size_type i = 0; i < m_containerSize; ++i) { + m_container[i]->clear(); + delete m_container[i]; + } + break; + + default: + break; + } + + m_type = TYPE_NONE; +} + +void +Frame::refresh() { + switch (m_type) { + case TYPE_NONE: + break; + + case TYPE_WINDOW: + if (m_window->is_active()) + m_window->refresh(); + + break; + + case TYPE_ROW: + case TYPE_COLUMN: + for (Frame **itr = m_container, **last = m_container + m_containerSize; itr != last; ++itr) + (*itr)->refresh(); + + break; + } +} + +void +Frame::balance(uint32_t x, uint32_t y, uint32_t width, uint32_t height) { + m_positionX = x; + m_positionY = y; + m_width = width; + m_height = height; + + if (m_type == TYPE_NONE) + return; + + if (m_type == TYPE_WINDOW) { + if (m_window->is_active()) + m_window->resize(x, y, width, height); + + return; + } + + uint32_t size; + + if (m_type == TYPE_ROW) + size = height - std::min(height, preferred_size().second); + else + size = width - std::min(width, preferred_size().first); + + uint32_t dynamicCount = std::count_if(m_container, m_container + m_containerSize, std::mem_fun(&Frame::is_dynamic)); + + for (Frame **itr = m_container, **last = m_container + m_containerSize; itr != last; ++itr) { + uint32_t s; + + if ((*itr)->is_dynamic()) { + s = (size + dynamicCount - 1) / dynamicCount; + + size -= s; + dynamicCount--; + + } else { + s = 0; + } + + if (m_type == TYPE_ROW) { + s += (*itr)->preferred_size().second; + + (*itr)->balance(x, y, m_width, s); + y += s; + + } else { + s += (*itr)->preferred_size().first; + + (*itr)->balance(x, y, s, height); + x += s; + } + } +} + +} diff --git a/src/display/frame.h b/src/display/frame.h new file mode 100644 index 00000000..843f9a2e --- /dev/null +++ b/src/display/frame.h @@ -0,0 +1,110 @@ +// rTorrent - BitTorrent client +// Copyright (C) 2005-2006, 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 +// +// In addition, as a special exception, the copyright holders give +// permission to link the code of portions of this program with the +// OpenSSL library under certain conditions as described in each +// individual source file, and distribute linked combinations +// including the two. +// +// You must obey the GNU General Public License in all respects for +// all of the code used other than OpenSSL. If you modify file(s) +// with this exception, you may extend this exception to your version +// of the file(s), but you are not obligated to do so. If you do not +// wish to do so, delete this exception statement from your version. +// If you delete this exception statement from all source files in the +// program, then also delete it here. +// +// Contact: Jari Sundell +// +// Skomakerveien 33 +// 3185 Skoppum, NORWAY + +#ifndef RTORRENT_DISPLAY_FRAME_H +#define RTORRENT_DISPLAY_FRAME_H + +#include + +namespace display { + +class Window; + +class Frame { +public: + enum Type { + TYPE_NONE, + TYPE_WINDOW, + TYPE_ROW, + TYPE_COLUMN + }; + + typedef uint32_t size_type; + typedef std::pair pair_type; + + static const size_type max_size = 5; + + Frame(); + + bool is_dynamic() const; + + pair_type preferred_size() const; + + uint32_t position_x() const { return m_positionX; } + uint32_t position_y() const { return m_positionY; } + + uint32_t width() const { return m_width; } + uint32_t height() const { return m_height; } + + Type get_type() const { return m_type; } + void set_type(Type t); + + Window* window() const { return m_window; } + + Frame* frame(size_type idx) { return m_container[idx]; } + + size_type container_size() const { return m_containerSize; } + void set_container_size(size_type size); + + void initialize_window(Window* window); + void initialize_container(Type containerType, size_type size); + + void clear(); + + void refresh(); + void balance(uint32_t x, uint32_t y, uint32_t width, uint32_t height); + +private: + Type m_type; + + uint32_t m_positionX; + uint32_t m_positionY; + uint32_t m_width; + uint32_t m_height; + + union { + Window* m_window; + + struct { + size_type m_containerSize; + Frame* m_container[max_size]; + }; + }; +}; + +} + +#endif diff --git a/src/display/manager.cc b/src/display/manager.cc index 256073c5..2605e47e 100644 --- a/src/display/manager.cc +++ b/src/display/manager.cc @@ -49,6 +49,7 @@ namespace display { Manager::Manager() : m_forceRedraw(false) { + m_taskUpdate.set_slot(rak::mem_fn(this, &Manager::receive_update)); } @@ -61,36 +62,6 @@ Manager::force_redraw() { m_forceRedraw = true; } - -Manager::iterator -Manager::insert(iterator pos, Window* w) { - return Base::insert(pos, w); -} - -// Swap with the function below. -Manager::iterator -Manager::erase(iterator pos) { - if (pos != end()) - return erase(*pos); - else - return end(); -} - -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); -} - -Manager::iterator -Manager::find(Window* w) { - return std::find(begin(), end(), w); -} - void Manager::schedule(Window* w, rak::timer t) { rak::priority_queue_erase(&m_scheduler, w->task_update()); @@ -106,34 +77,7 @@ Manager::unschedule(Window* w) { void Manager::adjust_layout() { - int staticHeight = std::for_each(begin(), end(), - rak::if_then(std::mem_fun(&Window::is_active), - rak::accumulate(0, std::mem_fun(&Window::get_min_height)))).m_then.result; - int countDynamic = std::for_each(begin(), end(), - rak::if_then(std::mem_fun(&Window::is_active), - rak::accumulate(0, std::mem_fun(&Window::is_dynamic)))).m_then.result; - - int dynamic = std::max(0, Canvas::get_screen_height() - staticHeight); - int height = 0, h; - - for (iterator itr = begin(); itr != end(); ++itr, height += h) { - h = 0; - - if (!(*itr)->is_active()) - continue; - - if ((*itr)->is_dynamic()) { - dynamic -= h = (dynamic + countDynamic - 1) / countDynamic; - countDynamic--; - } else { - h = 0; - } - - h += (*itr)->get_min_height(); - - (*itr)->resize(0, height, Canvas::get_screen_width(), h); - (*itr)->mark_dirty(); - } + m_rootFrame.balance(0, 0, Canvas::get_screen_width(), Canvas::get_screen_height()); } void @@ -149,7 +93,9 @@ Manager::receive_update() { Canvas::refresh_std(); rak::priority_queue_perform(&m_scheduler, cachedTime); - std::for_each(begin(), end(), rak::if_then(std::mem_fun(&Window::is_active), std::mem_fun(&Window::refresh))); + +// std::for_each(begin(), end(), rak::if_then(std::mem_fun(&Window::is_active), std::mem_fun(&Window::refresh))); + m_rootFrame.refresh(); Canvas::do_update(); diff --git a/src/display/manager.h b/src/display/manager.h index 69837e7b..602561d8 100644 --- a/src/display/manager.h +++ b/src/display/manager.h @@ -40,44 +40,28 @@ #include #include +#include "frame.h" + namespace display { class Window; -class Manager : private std::list { +class Manager { public: - typedef std::list Base; - - using Base::iterator; - using Base::const_iterator; - using Base::reverse_iterator; - using Base::const_reverse_iterator; - - using Base::begin; - using Base::end; - using Base::rbegin; - using Base::rend; - - using Base::push_front; - using Base::push_back; - Manager(); ~Manager(); void force_redraw(); - iterator insert(iterator pos, Window* w); - iterator erase(iterator pos); - iterator erase(Window* w); - - iterator find(Window* w); - void schedule(Window* w, rak::timer t); void unschedule(Window* w); void adjust_layout(); void receive_update(); + // New interface. + Frame* root_frame() { return &m_rootFrame; } + private: void schedule_update(); @@ -86,6 +70,9 @@ private: rak::priority_queue_default m_scheduler; rak::priority_item m_taskUpdate; + + // New interface. + Frame m_rootFrame; }; } diff --git a/src/display/window_http_queue.cc b/src/display/window_http_queue.cc index 7b36bf71..f85aab87 100644 --- a/src/display/window_http_queue.cc +++ b/src/display/window_http_queue.cc @@ -83,9 +83,7 @@ WindowHttpQueue::redraw() { m_canvas->print(pos, 0, "%s ---%%", itr->m_name.c_str()); else - m_canvas->print(pos, 0, "%s %3i%%", - itr->m_name.c_str(), - (int)(100.0 * itr->m_http->size_done() / itr->m_http->size_total())); + m_canvas->print(pos, 0, "%s %3i%%", itr->m_name.c_str(), (int)(100.0 * itr->m_http->size_done() / itr->m_http->size_total())); pos += itr->m_name.size() + 6; ++itr; @@ -140,8 +138,7 @@ WindowHttpQueue::receive_insert(core::CurlGet* h) { void WindowHttpQueue::receive_erase(core::CurlGet* h) { - Container::iterator itr = std::find_if(m_container.begin(), m_container.end(), - rak::equal(h, std::mem_fun_ref(&Node::get_http))); + Container::iterator itr = std::find_if(m_container.begin(), m_container.end(), rak::equal(h, std::mem_fun_ref(&Node::get_http))); if (itr == m_container.end()) throw std::logic_error("WindowHttpQueue::receive_erase(...) tried to remove an object we don't have"); diff --git a/src/display/window_input.cc b/src/display/window_input.cc index ac3ebf25..b7c6eede 100644 --- a/src/display/window_input.cc +++ b/src/display/window_input.cc @@ -43,16 +43,10 @@ namespace display { -WindowInput::WindowInput(input::TextInput* input) : - Window(new Canvas, false, 1), - m_input(input), - m_focus(false) { -} - void WindowInput::redraw() { m_canvas->erase(); - m_canvas->print(0, 0, "> %s", m_input->c_str()); + m_canvas->print(0, 0, "> %s", m_input != NULL ? m_input->c_str() : ""); if (m_focus) m_canvas->set_attr(m_input->get_pos() + 2, 0, 1, A_REVERSE, COLOR_PAIR(0)); diff --git a/src/display/window_input.h b/src/display/window_input.h index d014807d..529d1f2c 100644 --- a/src/display/window_input.h +++ b/src/display/window_input.h @@ -47,18 +47,19 @@ namespace display { class WindowInput : public Window { public: - WindowInput(input::TextInput* input); + WindowInput() : Window(new Canvas, false, 1), m_input(NULL), m_focus(false) {} - input::TextInput* get_input() { return m_input; } + input::TextInput* input() { return m_input; } + void set_input(input::TextInput* input) { m_input = input; } - bool get_focus() { return m_focus; } - void set_focus(bool f) { mark_dirty(); m_focus = f; } + bool focus() const { return m_focus; } + void set_focus(bool f) { mark_dirty(); m_focus = f; } - virtual void redraw(); + virtual void redraw(); private: - input::TextInput* m_input; - bool m_focus; + input::TextInput* m_input; + bool m_focus; }; } diff --git a/src/display/window_log_complete.cc b/src/display/window_log_complete.cc index 73c854cb..56b5bf45 100644 --- a/src/display/window_log_complete.cc +++ b/src/display/window_log_complete.cc @@ -67,7 +67,7 @@ WindowLogComplete::redraw() { int pos = 0; - m_canvas->print(std::max(0, (int)m_canvas->get_width() / 2 - 5), pos++, "*** Log ***"); +// m_canvas->print(std::max(0, (int)m_canvas->get_width() / 2 - 5), pos++, "*** Log ***"); for (core::Log::iterator itr = m_log->begin(), e = m_log->end(); itr != e && pos < m_canvas->get_height(); ++itr) { char buffer[16]; diff --git a/src/display/window_statusbar.cc b/src/display/window_statusbar.cc index 824de71d..8bd0531c 100644 --- a/src/display/window_statusbar.cc +++ b/src/display/window_statusbar.cc @@ -46,12 +46,6 @@ namespace display { -WindowStatusbar::WindowStatusbar(Control* c) : - Window(new Canvas, false, 1), - m_lastTick(0), - m_control(c) { -} - void WindowStatusbar::redraw() { m_slotSchedule(this, (cachedTime + rak::timer::from_seconds(1)).round_seconds()); @@ -101,12 +95,11 @@ WindowStatusbar::redraw() { last = last - (position - buffer); if (last > buffer) { - position = print_status_extra(buffer, last, m_control); + position = print_status_extra(buffer, last, control); m_canvas->print(m_canvas->get_width() - (position - buffer), 0, "%s", buffer); } - - m_lastTick = m_control->tick(); + m_lastTick = control->tick(); } } diff --git a/src/display/window_statusbar.h b/src/display/window_statusbar.h index f5c3b2e7..ffa2c638 100644 --- a/src/display/window_statusbar.h +++ b/src/display/window_statusbar.h @@ -41,19 +41,16 @@ #include "window.h" -class Control; - namespace display { class WindowStatusbar : public Window { public: - WindowStatusbar(Control* c); + WindowStatusbar() : Window(new Canvas, false, 1), m_lastTick(0) {} virtual void redraw(); private: uint64_t m_lastTick; - Control* m_control; }; } diff --git a/src/display/window_title.cc b/src/display/window_title.cc index f7334dd4..509a1a77 100644 --- a/src/display/window_title.cc +++ b/src/display/window_title.cc @@ -41,18 +41,13 @@ namespace display { -WindowTitle::WindowTitle(const std::string& s) : - Window(new Canvas, false, 1), - m_title(s) { -} - void WindowTitle::redraw() { m_slotSchedule(this, (cachedTime + rak::timer::from_seconds(1)).round_seconds()); 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 ***", m_title.c_str()); } } diff --git a/src/display/window_title.h b/src/display/window_title.h index 0b796e01..62504ccf 100644 --- a/src/display/window_title.h +++ b/src/display/window_title.h @@ -44,12 +44,15 @@ namespace display { class WindowTitle : public Window { public: - WindowTitle(const std::string& s); + WindowTitle() : Window(new Canvas, false, 1) {} - virtual void redraw(); + const std::string& title() const { return m_title; } + void set_title(const std::string& title) { m_title = title; mark_dirty(); } + + virtual void redraw(); private: - std::string m_title; + std::string m_title; }; } diff --git a/src/input/text_input.cc b/src/input/text_input.cc index 1e1b46d0..f505ed6c 100644 --- a/src/input/text_input.cc +++ b/src/input/text_input.cc @@ -69,27 +69,27 @@ TextInput::pressed(int key) { case 'h' - 'a' + 1: // ^H case KEY_BACKSPACE: if (m_pos != 0) - Base::erase(--m_pos, 1); + Base::erase(--m_pos, 1); break; case KEY_DC: if (m_pos != size()) - Base::erase(m_pos, 1); + Base::erase(m_pos, 1); break; case 0x02: case KEY_LEFT: if (m_pos != 0) - --m_pos; + --m_pos; break; case 0x06: case KEY_RIGHT: if (m_pos != size()) - ++m_pos; + ++m_pos; break; diff --git a/src/ui/download.cc b/src/ui/download.cc index a9f6252c..5337f838 100644 --- a/src/ui/download.cc +++ b/src/ui/download.cc @@ -50,6 +50,7 @@ #include "control.h" #include "download.h" +#include "root.h" #include "element_file_list.h" #include "element_peer_info.h" #include "element_peer_list.h" @@ -63,11 +64,8 @@ Download::Download(DPtr d, Control* c) : m_download(d), m_state(DISPLAY_MAX_SIZE), - m_windowTitle(new WTitle(d->download()->name())), m_windowDownloadStatus(new WDownloadStatus(d)), - m_window(c->display()->end()), - m_control(c), m_bindings(new input::Bindings) { @@ -89,8 +87,8 @@ Download::Download(DPtr d, Control* c) : } Download::~Download() { - if (m_window != m_control->display()->end()) - throw std::logic_error("ui::Download::~Download() called on an active object"); +// if (m_window != m_control->display()->end()) +// throw std::logic_error("ui::Download::~Download() called on an active object"); m_connPeerConnected.disconnect(); m_connPeerDisconnected.disconnect(); @@ -99,18 +97,19 @@ Download::~Download() { std::for_each(m_uiArray, m_uiArray + DISPLAY_MAX_SIZE, rak::call_delete()); - delete m_windowTitle; delete m_windowDownloadStatus; } void Download::activate() { - if (m_window != m_control->display()->end()) - throw std::logic_error("ui::Download::activate() called on an already activated object"); +// if (m_window != m_control->display()->end()) +// throw std::logic_error("ui::Download::activate() called on an already activated object"); - m_control->display()->push_front(m_windowDownloadStatus); - m_window = m_control->display()->insert(m_control->display()->begin(), NULL); - m_control->display()->push_front(m_windowTitle); + m_control->ui()->window_title()->set_title(m_download->download()->name()); + +// m_control->display()->push_front(m_windowDownloadStatus); +// m_window = m_control->display()->insert(m_control->display()->begin(), NULL); +// m_control->display()->push_front(m_control->ui()->window_title()); m_control->input()->push_front(m_bindings); @@ -119,30 +118,30 @@ Download::activate() { void Download::disable() { - if (m_window == m_control->display()->end()) - throw std::logic_error("ui::Download::disable() called on an already disabled object"); +// if (m_window == m_control->display()->end()) +// throw std::logic_error("ui::Download::disable() called on an already disabled object"); disable_display(); - m_control->display()->erase(m_window); - m_control->display()->erase(m_windowTitle); - m_control->display()->erase(m_windowDownloadStatus); +// m_control->display()->erase(m_window); +// m_control->display()->erase(m_control->ui()->window_title()); +// m_control->display()->erase(m_windowDownloadStatus); - m_window = m_control->display()->end(); +// m_window = m_control->display()->end(); m_control->input()->erase(m_bindings); } void Download::activate_display(Display d) { - if (m_window == m_control->display()->end()) - throw std::logic_error("ui::Download::activate_display(...) could not find previous display iterator"); +// if (m_window == m_control->display()->end()) +// throw std::logic_error("ui::Download::activate_display(...) could not find previous display iterator"); 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_uiArray[d]->activate(m_control, m_window); m_control->display()->adjust_layout(); } @@ -150,10 +149,10 @@ Download::activate_display(Display d) { // Does not delete disabled window. void Download::disable_display() { - m_uiArray[m_state]->disable(m_control); + m_uiArray[m_state]->disable(); m_state = DISPLAY_MAX_SIZE; - *m_window = NULL; +// *m_window = NULL; } void @@ -279,21 +278,21 @@ Download::bind_keys() { (*m_bindings)[KEY_DOWN] = sigc::mem_fun(this, &Download::receive_next); // Key bindings for sub-ui's. - 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()[KEY_LEFT] = 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()[KEY_LEFT] = sigc::bind(sigc::mem_fun(this, &Download::receive_change), DISPLAY_PEER_LIST); - m_uiArray[DISPLAY_CHUNKS_SEEN]->get_bindings()[KEY_LEFT] = sigc::bind(sigc::mem_fun(this, &Download::receive_change), DISPLAY_PEER_LIST); - m_uiArray[DISPLAY_TRANSFER_LIST]->get_bindings()[KEY_LEFT]= sigc::bind(sigc::mem_fun(this, &Download::receive_change), DISPLAY_PEER_LIST); + m_uiArray[DISPLAY_PEER_LIST]->bindings()[KEY_RIGHT] = sigc::bind(sigc::mem_fun(this, &Download::receive_change), DISPLAY_FILE_LIST); + m_uiArray[DISPLAY_PEER_INFO]->bindings()[KEY_LEFT] = sigc::bind(sigc::mem_fun(this, &Download::receive_change), DISPLAY_PEER_LIST); + m_uiArray[DISPLAY_FILE_LIST]->bindings()[KEY_LEFT] = sigc::bind(sigc::mem_fun(this, &Download::receive_change), DISPLAY_PEER_LIST); + m_uiArray[DISPLAY_TRACKER_LIST]->bindings()[KEY_LEFT] = sigc::bind(sigc::mem_fun(this, &Download::receive_change), DISPLAY_PEER_LIST); + m_uiArray[DISPLAY_CHUNKS_SEEN]->bindings()[KEY_LEFT] = sigc::bind(sigc::mem_fun(this, &Download::receive_change), DISPLAY_PEER_LIST); + m_uiArray[DISPLAY_TRANSFER_LIST]->bindings()[KEY_LEFT]= sigc::bind(sigc::mem_fun(this, &Download::receive_change), DISPLAY_PEER_LIST); // Doesn't belong here. - m_uiArray[DISPLAY_PEER_LIST]->get_bindings()['*'] = sigc::mem_fun(this, &Download::receive_snub_peer); - m_uiArray[DISPLAY_PEER_INFO]->get_bindings()['*'] = sigc::mem_fun(this, &Download::receive_snub_peer); + m_uiArray[DISPLAY_PEER_LIST]->bindings()['*'] = sigc::mem_fun(this, &Download::receive_snub_peer); + m_uiArray[DISPLAY_PEER_INFO]->bindings()['*'] = sigc::mem_fun(this, &Download::receive_snub_peer); } void Download::mark_dirty() { - (*m_window)->mark_dirty(); +// (*m_window)->mark_dirty(); } } diff --git a/src/ui/download.h b/src/ui/download.h index 133de0fd..75127842 100644 --- a/src/ui/download.h +++ b/src/ui/download.h @@ -47,6 +47,7 @@ class Control; namespace display { + class Frame; class WindowTitle; class WindowStatusbar; class WindowDownloadStatusbar; @@ -62,12 +63,10 @@ class ElementBase; class Download { public: - typedef display::WindowTitle WTitle; typedef display::WindowDownloadStatusbar WDownloadStatus; typedef core::Download* DPtr; typedef std::list PList; - typedef display::Manager::iterator MItr; typedef enum { DISPLAY_PEER_LIST, @@ -122,13 +121,11 @@ private: Display m_state; + display::Frame* m_frame; ElementBase* m_uiArray[DISPLAY_MAX_SIZE]; - WTitle* m_windowTitle; WDownloadStatus* m_windowDownloadStatus; - MItr m_window; - Control* m_control; input::Bindings* m_bindings; diff --git a/src/ui/download_list.cc b/src/ui/download_list.cc index c9590875..dcfaccdf 100644 --- a/src/ui/download_list.cc +++ b/src/ui/download_list.cc @@ -36,7 +36,6 @@ #include "config.h" -#include #include #include #include @@ -54,8 +53,6 @@ #include "input/manager.h" #include "input/path_input.h" -#include "display/window_http_queue.h" -#include "display/window_input.h" #include "display/window_log.h" #include "display/window_title.h" #include "display/window_statusbar.h" @@ -70,22 +67,16 @@ namespace ui { -DownloadList::DownloadList(Control* c) : - m_state(DISPLAY_MAX_SIZE), +DownloadList::DownloadList() : + m_state(DISPLAY_NONE), - m_window(c->display()->end()), + m_uiDownload(NULL) { - m_windowTitle(new WTitle("rTorrent " VERSION " - libTorrent " + std::string(torrent::version()))), - m_windowHttpQueue(new WHttp(c->core()->http_queue())), - - m_uiDownload(NULL), - - m_control(c), - m_bindings(new input::Bindings) -{ m_uiArray[DISPLAY_DOWNLOAD_LIST] = new ElementDownloadList(); - m_uiArray[DISPLAY_LOG] = new ElementLogComplete(&m_control->core()->get_log_complete()); - m_windowLog = new WLog(&m_control->core()->get_log_important()); + m_uiArray[DISPLAY_LOG] = new ElementLogComplete(&control->core()->get_log_complete()); + m_uiArray[DISPLAY_STRING_LIST] = new ElementStringList(); + + m_windowLog = new WLog(&control->core()->get_log_important()); receive_change_view("main"); @@ -95,7 +86,6 @@ DownloadList::DownloadList(Control* c) : m_taskUpdate.set_slot(rak::mem_fn(this, &DownloadList::task_update)), setup_keys(); - setup_input(); } DownloadList::~DownloadList() { @@ -104,33 +94,20 @@ DownloadList::~DownloadList() { std::for_each(m_uiArray, m_uiArray + DISPLAY_MAX_SIZE, rak::call_delete()); - delete m_windowTitle; - delete m_bindings; - delete m_windowLog; - delete m_windowTextInput->get_input(); - delete m_windowTextInput; - delete m_windowHttpQueue; } void -DownloadList::activate() { +DownloadList::activate(display::Frame* frame) { if (is_active()) - throw std::logic_error("ui::Download::activate() called on an already activated object"); + throw torrent::client_error("ui::DownloadList::activate() called on an already activated object"); priority_queue_insert(&taskScheduler, &m_taskUpdate, cachedTime); - m_windowTextInput->set_active(false); + m_frame = frame; - m_control->display()->push_front(m_windowTextInput); - m_control->display()->push_front(m_windowHttpQueue); - m_control->display()->push_front(m_windowLog); - m_window = m_control->display()->insert(m_control->display()->begin(), NULL); - m_control->display()->push_front(m_windowTitle); - - m_control->input()->push_front(m_bindings); - - m_control->core()->download_list()->slot_map_erase()["0_download_list"] = sigc::mem_fun(this, &DownloadList::receive_download_erased); + control->input()->push_front(&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); } @@ -138,49 +115,74 @@ DownloadList::activate() { void DownloadList::disable() { if (!is_active()) - throw std::logic_error("ui::Download::disable() called on an already disabled object"); + throw std::logic_error("ui::DownloadList::disable() called on an already disabled object"); - if (m_windowTextInput->is_active()) { - m_windowTextInput->get_input()->clear(); - receive_exit_input(INPUT_NONE); - } +// if (m_windowTextInput->is_active()) { +// m_windowTextInput->get_input()->clear(); +// receive_exit_input(INPUT_NONE); +// } - disable_display(); + activate_display(DISPLAY_NONE); + + m_frame = NULL; priority_queue_erase(&taskScheduler, &m_taskUpdate); - - m_control->display()->erase(m_window); - m_control->display()->erase(m_windowTitle); - m_control->display()->erase(m_windowTextInput); - m_control->display()->erase(m_windowLog); - m_control->display()->erase(m_windowHttpQueue); - - m_window = m_control->display()->end(); - - m_control->input()->erase(m_bindings); + control->input()->erase(&m_bindings); } void -DownloadList::activate_display(Display d) { +DownloadList::activate_display(Display displayType) { if (!is_active()) - throw std::logic_error("ui::DownloadList::activate_display(...) could not find previous display iterator"); + throw std::logic_error("ui::DownloadList::activate_display(...) !is_active()."); - if (d >= DISPLAY_MAX_SIZE) + if (displayType >= DISPLAY_MAX_SIZE) throw std::logic_error("ui::DownloadList::activate_display(...) out of bounds"); - m_state = d; - m_uiArray[d]->activate(m_control, m_window); + if (displayType == m_state) + return; - m_control->display()->adjust_layout(); + // Don't use default. + + // Cleanup previous state. + switch (m_state) { + case DISPLAY_DOWNLOAD_LIST: + case DISPLAY_LOG: + m_uiArray[m_state]->disable(); + break; + + default: + break; + } + + m_state = displayType; + + // Initialize new state. + switch (displayType) { + case DISPLAY_NONE: + break; + + case DISPLAY_DOWNLOAD_LIST: + control->ui()->window_title()->set_title("rTorrent " VERSION " - libTorrent " + std::string(torrent::version())); + + m_uiArray[displayType]->activate(m_frame); + break; + + case DISPLAY_LOG: + control->ui()->window_title()->set_title("Log"); + + m_uiArray[displayType]->activate(m_frame); + break; + + default: + break; + } + + control->display()->adjust_layout(); } -// Does not delete disabled window. -void -DownloadList::disable_display() { - m_uiArray[m_state]->disable(m_control); - - m_state = DISPLAY_MAX_SIZE; - *m_window = NULL; +display::Window* +DownloadList::window() { + return NULL; } void @@ -200,7 +202,7 @@ DownloadList::receive_start_download() { if (m_view->focus() == m_view->end_visible()) return; - m_control->core()->download_list()->start_normal(*m_view->focus()); + control->core()->download_list()->start_normal(*m_view->focus()); m_view->set_last_changed(); } @@ -210,9 +212,9 @@ DownloadList::receive_stop_download() { return; if ((*m_view->focus())->variable()->get_value("state") == 1) - m_control->core()->download_list()->stop_normal(*m_view->focus()); + control->core()->download_list()->stop_normal(*m_view->focus()); else - m_control->core()->download_list()->erase(*m_view->focus()); + control->core()->download_list()->erase(*m_view->focus()); m_view->set_last_changed(); } @@ -222,8 +224,8 @@ DownloadList::receive_close_download() { if (m_view->focus() == m_view->end_visible()) return; - m_control->core()->download_list()->stop_normal(*m_view->focus()); - m_control->core()->download_list()->close(*m_view->focus()); + control->core()->download_list()->stop_normal(*m_view->focus()); + control->core()->download_list()->close(*m_view->focus()); m_view->set_last_changed(); } @@ -237,7 +239,7 @@ DownloadList::receive_view_download() { disable(); - m_uiDownload = new Download(*m_view->focus(), m_control); + m_uiDownload = new Download(*m_view->focus(), control); m_uiDownload->activate(); m_uiDownload->get_bindings()[KEY_LEFT] = sigc::mem_fun(*this, &DownloadList::receive_exit_download); @@ -253,9 +255,9 @@ DownloadList::receive_exit_download() { m_uiDownload = NULL; m_view->set_last_changed(); - activate(); + activate(m_frame); - m_control->display()->adjust_layout(); + control->display()->adjust_layout(); } void @@ -264,7 +266,7 @@ DownloadList::receive_next_priority() { return; (*m_view->focus())->set_priority(((*m_view->focus())->priority() + 1) % 4); - (*m_window)->mark_dirty(); +// (*m_window)->mark_dirty(); } void @@ -273,7 +275,7 @@ DownloadList::receive_prev_priority() { return; (*m_view->focus())->set_priority(((*m_view->focus())->priority() - 1) % 4); - (*m_window)->mark_dirty(); +// (*m_window)->mark_dirty(); } void @@ -282,7 +284,7 @@ DownloadList::receive_check_hash() { return; // Catch here? - m_control->core()->download_list()->check_hash(*m_view->focus()); + control->core()->download_list()->check_hash(*m_view->focus()); } void @@ -292,10 +294,10 @@ DownloadList::receive_ignore_ratio() { if ((*m_view->focus())->variable()->get_value("ignore_commands") != 0) { (*m_view->focus())->variable()->set("ignore_commands", (int64_t)0); - m_control->core()->push_log("Torrent set to heed commands."); + control->core()->push_log("Torrent set to heed commands."); } else { (*m_view->focus())->variable()->set("ignore_commands", (int64_t)1); - m_control->core()->push_log("Torrent set to ignore commands"); + control->core()->push_log("Torrent set to ignore commands."); } } @@ -308,44 +310,56 @@ DownloadList::receive_clear_tied() { if (!tiedFile.empty()) { // Move this into core? - m_control->core()->delete_tied(*m_view->focus()); + control->core()->delete_tied(*m_view->focus()); - m_control->core()->push_log("Cleared tied to file association for download."); + control->core()->push_log("Cleared tied to file association for download."); } } void DownloadList::receive_view_input(Input type) { - if (m_windowTextInput->get_active()) + if (control->ui()->current_input() != NULL) return; - m_control->ui()->window_statusbar()->set_active(false); - m_windowTextInput->set_active(true); - m_control->display()->adjust_layout(); + input::PathInput* input = new input::PathInput; - m_control->input()->set_text_input(m_windowTextInput->get_input()); + switch (type) { + case INPUT_CHANGE_DIRECTORY: + input->str() = control->variable()->get_string("directory"); + input->set_pos(input->str().length()); - m_windowTextInput->set_focus(true); + break; - if (type == INPUT_CHANGE_DIRECTORY) { - m_windowTextInput->get_input()->str() = m_control->variable()->get_string("directory"); - m_windowTextInput->get_input()->set_pos(m_windowTextInput->get_input()->str().length()); + default: + break; } - (*m_bindings)['\n'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_exit_input), type); - (*m_bindings)[KEY_ENTER] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_exit_input), type); - (*m_bindings)['\x07'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_exit_input), INPUT_NONE); + control->ui()->enable_input(input); + + // These bindings should be moved to f.ex TextInput? + m_bindings['\n'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_exit_input), type); + m_bindings[KEY_ENTER] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_exit_input), type); + m_bindings['\x07'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_exit_input), INPUT_NONE); } void DownloadList::receive_exit_input(Input type) { - if (!m_windowTextInput->get_active()) + input::TextInput* input = control->ui()->current_input(); + + // We should check that this object is the one holding the input. + if (input == NULL) return; - m_control->ui()->window_statusbar()->set_active(true); - m_windowTextInput->set_active(false); - m_control->input()->set_text_input(); - + control->ui()->disable_input(); + + // Urgh... this is ugly... + m_bindings.erase('\n'); + m_bindings.erase(KEY_ENTER); + m_bindings.erase('\x07'); + + m_bindings['\n'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_view_input), INPUT_LOAD_MODIFIED); + m_bindings[KEY_ENTER] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_view_input), INPUT_LOAD_MODIFIED); + try { switch (type) { @@ -354,47 +368,27 @@ DownloadList::receive_exit_input(Input type) { case INPUT_LOAD_DEFAULT: case INPUT_LOAD_MODIFIED: - m_control->core()->try_create_download_expand(m_windowTextInput->get_input()->str(), type == INPUT_LOAD_DEFAULT); + control->core()->try_create_download_expand(input->str(), type == INPUT_LOAD_DEFAULT); break; case INPUT_CHANGE_DIRECTORY: if (m_view->focus() == m_view->end_visible()) throw torrent::input_error("No download in focus to change root directory."); - (*m_view->focus())->variable()->set("directory", rak::trim(m_windowTextInput->get_input()->str())); - m_control->core()->push_log("New root dir \"" + (*m_view->focus())->variable()->get_string("directory") + "\" for torrent."); + (*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."); break; case INPUT_COMMAND: - m_control->variable()->process_command(m_windowTextInput->get_input()->str()); + control->variable()->process_command(input->str()); break; } } catch (torrent::input_error& e) { - m_control->core()->push_log(e.what()); + control->core()->push_log(e.what()); } - // Clean up. - m_windowTextInput->get_input()->clear(); - m_windowTextInput->set_focus(false); - - m_bindings->erase('\n'); - m_bindings->erase(KEY_ENTER); - - // Urgh... this is ugly... - (*m_bindings)['\n'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_view_input), INPUT_LOAD_MODIFIED); - (*m_bindings)[KEY_ENTER] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_view_input), INPUT_LOAD_MODIFIED); - - receive_change(DISPLAY_DOWNLOAD_LIST); -} - -void -DownloadList::receive_change(Display d) { - if (d == m_state) - return; - - disable_display(); - activate_display(d); + delete input; } void @@ -410,10 +404,10 @@ DownloadList::receive_download_erased(core::Download* d) { void DownloadList::receive_change_view(const std::string& name) { - core::ViewManager::iterator itr = m_control->view_manager()->find(name); + core::ViewManager::iterator itr = control->view_manager()->find(name); - if (itr == m_control->view_manager()->end()) { - m_control->core()->push_log("Could not find view \"" + name + "\"."); + if (itr == control->view_manager()->end()) { + control->core()->push_log("Could not find view \"" + name + "\"."); return; } @@ -437,53 +431,52 @@ DownloadList::task_update() { 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['\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); - (*m_bindings)[KEY_ENTER] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_view_input), INPUT_LOAD_MODIFIED); - (*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['\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); + m_bindings[KEY_ENTER] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_view_input), INPUT_LOAD_MODIFIED); + 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::mem_fun(*this, &DownloadList::receive_view_download); - (*m_bindings)['l'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_change), DISPLAY_LOG); + 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::mem_fun(*this, &DownloadList::receive_view_download); + m_bindings['l'] = sigc::bind(sigc::mem_fun(*this, &DownloadList::activate_display), DISPLAY_LOG); - (*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_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]->get_bindings()[' '] = sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_change), DISPLAY_DOWNLOAD_LIST); + m_uiArray[DISPLAY_LOG]->bindings()[' '] = sigc::bind(sigc::mem_fun(*this, &DownloadList::activate_display), DISPLAY_DOWNLOAD_LIST); + m_uiArray[DISPLAY_LOG]->bindings()[KEY_RIGHT] = sigc::bind(sigc::mem_fun(*this, &DownloadList::activate_display), DISPLAY_DOWNLOAD_LIST); } -void -DownloadList::setup_input() { - input::PathInput* p = new input::PathInput; - ElementStringList* esl = new ElementStringList(); - m_windowTextInput = new WInput(p); +// 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->slot_dirty(sigc::mem_fun(*m_windowTextInput, &WInput::mark_dirty)); - p->signal_show_next().connect(sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_change), DISPLAY_STRING_LIST)); - p->signal_show_next().connect(sigc::mem_fun(*esl, &ElementStringList::next_screen)); +// 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::receive_change), DISPLAY_STRING_LIST)))); - p->signal_show_range().connect(sigc::mem_fun(*esl, &ElementStringList::set_range)); +// 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)); - m_uiArray[DISPLAY_STRING_LIST] = esl; -} +// } } diff --git a/src/ui/download_list.h b/src/ui/download_list.h index e91f1ecc..45ef7fec 100644 --- a/src/ui/download_list.h +++ b/src/ui/download_list.h @@ -41,6 +41,7 @@ #include "display/manager.h" +#include "element_base.h" #include "globals.h" class Control; @@ -55,33 +56,28 @@ namespace input { } namespace display { + class Frame; class WindowDownloadList; class WindowHttpQueue; class WindowInput; class WindowLog; class WindowLogComplete; - class WindowTitle; } namespace ui { class Download; -class ElementBase; -class DownloadList { +class DownloadList : public ElementBase { public: typedef display::WindowDownloadList WList; - typedef display::WindowHttpQueue WHttp; - typedef display::WindowInput WInput; typedef display::WindowLog WLog; typedef display::WindowLogComplete WLogComplete; - typedef display::WindowTitle WTitle; typedef sigc::slot1 SlotOpenUri; - typedef display::Manager::iterator MItr; - typedef enum { + DISPLAY_NONE, DISPLAY_DOWNLOAD_LIST, DISPLAY_LOG, DISPLAY_STRING_LIST, @@ -96,18 +92,15 @@ public: INPUT_COMMAND } Input; - DownloadList(Control* c); + DownloadList(); ~DownloadList(); - input::Bindings& get_bindings() { return *m_bindings; } - - bool is_active() const { return m_window != m_control->display()->end(); } - - void activate(); + void activate(display::Frame* frame); void disable(); void activate_display(Display d); - void disable_display(); + + display::Window* window(); void slot_open_uri(SlotOpenUri s) { m_slotOpenUri = s; } @@ -136,8 +129,6 @@ private: void receive_view_input(Input type); void receive_exit_input(Input type); - void receive_change(Display d); - void receive_download_erased(core::Download* d); void receive_change_view(const std::string& name); @@ -151,12 +142,7 @@ private: ElementBase* m_uiArray[DISPLAY_MAX_SIZE]; - MItr m_window; - - WTitle* m_windowTitle; WLog* m_windowLog; - WInput* m_windowTextInput; - WHttp* m_windowHttpQueue; rak::priority_item m_taskUpdate; @@ -164,9 +150,6 @@ private: core::View* m_view; - Control* m_control; - input::Bindings* m_bindings; - SlotOpenUri m_slotOpenUri; }; diff --git a/src/ui/element_base.h b/src/ui/element_base.h index d4e69020..d428b5f6 100644 --- a/src/ui/element_base.h +++ b/src/ui/element_base.h @@ -37,23 +37,32 @@ #ifndef RTORRENT_UI_ELEMENT_BASE_H #define RTORRENT_UI_ELEMENT_BASE_H -#include "display/manager.h" #include "input/bindings.h" +namespace display { + class Frame; + class Window; +} + namespace ui { class ElementBase { public: - typedef display::Manager::iterator MItr; - + ElementBase() : m_frame(NULL) {} virtual ~ElementBase() {} - virtual void activate(Control* c, MItr mItr) = 0; - virtual void disable(Control* c) = 0; + bool is_active() const { return m_frame != NULL; } - input::Bindings& get_bindings() { return m_bindings; } + input::Bindings& bindings() { return m_bindings; } + + virtual void activate(display::Frame* frame) = 0; + virtual void disable() = 0; + + virtual display::Window* window() = 0; protected: + display::Frame* m_frame; + input::Bindings m_bindings; }; diff --git a/src/ui/element_chunks_seen.cc b/src/ui/element_chunks_seen.cc index 831d6e3c..ed0462a3 100644 --- a/src/ui/element_chunks_seen.cc +++ b/src/ui/element_chunks_seen.cc @@ -36,7 +36,7 @@ #include "config.h" -#include +#include #include "display/window_download_chunks_seen.h" #include "input/manager.h" @@ -60,26 +60,32 @@ ElementChunksSeen::ElementChunksSeen(core::Download* d) : } void -ElementChunksSeen::activate(Control* c, MItr mItr) { - if (m_window != NULL) - throw std::logic_error("ui::ElementChunksSeen::activate(...) called on an object in the wrong state"); +ElementChunksSeen::activate(display::Frame* frame) { + if (is_active()) + throw torrent::client_error("ui::ElementChunksSeen::activate(...) is_active()."); - c->input()->push_front(&m_bindings); + control->input()->push_front(&m_bindings); - *mItr = m_window = new WChunksSeen(m_download, &m_focus); + m_window = new WChunksSeen(m_download, &m_focus); + m_frame = frame; } void -ElementChunksSeen::disable(Control* c) { - if (m_window == NULL) - throw std::logic_error("ui::ElementChunksSeen::disable(...) called on an object in the wrong state"); +ElementChunksSeen::disable() { + if (!is_active()) + throw torrent::client_error("ui::ElementChunksSeen::disable(...) !is_active()."); - c->input()->erase(&m_bindings); + control->input()->erase(&m_bindings); delete m_window; m_window = NULL; } +display::Window* +ElementChunksSeen::window() { + return m_window; +} + // void // ElementChunksSeen::receive_disable() { // if (m_window == NULL) diff --git a/src/ui/element_chunks_seen.h b/src/ui/element_chunks_seen.h index 5e24349c..019c43cd 100644 --- a/src/ui/element_chunks_seen.h +++ b/src/ui/element_chunks_seen.h @@ -55,8 +55,10 @@ public: ElementChunksSeen(core::Download* d); - void activate(Control* c, MItr mItr); - void disable(Control* c); + void activate(display::Frame* frame); + void disable(); + + display::Window* window(); private: // void receive_disable(); diff --git a/src/ui/element_download_list.cc b/src/ui/element_download_list.cc index 70f09986..4f42d4b5 100644 --- a/src/ui/element_download_list.cc +++ b/src/ui/element_download_list.cc @@ -36,8 +36,10 @@ #include "config.h" -#include +#include +#include "display/frame.h" +#include "display/manager.h" #include "input/manager.h" #include "control.h" @@ -46,24 +48,30 @@ namespace ui { void -ElementDownloadList::activate(Control* c, MItr mItr) { - if (m_window != NULL) - throw std::logic_error("ui::ElementDownloadList::activate(...) called on an object in the wrong state"); +ElementDownloadList::activate(display::Frame* frame) { + if (is_active()) + throw torrent::client_error("ui::ElementDownloadList::activate(...) is_active()."); - c->input()->push_front(&m_bindings); + control->input()->push_front(&m_bindings); m_window = new WDownloadList(); m_window->set_view(m_view); - *mItr = m_window; + m_frame = frame; + m_frame->initialize_window(m_window); + + control->display()->schedule(m_window, cachedTime); } void -ElementDownloadList::disable(Control* c) { - if (m_window == NULL) - throw std::logic_error("ui::ElementDownloadList::disable(...) called on an object in the wrong state"); +ElementDownloadList::disable() { + if (!is_active()) + throw torrent::client_error("ui::ElementDownloadList::disable(...) !is_active()."); - c->input()->erase(&m_bindings); + control->input()->erase(&m_bindings); + + m_frame->clear(); + m_frame = NULL; delete m_window; m_window = NULL; diff --git a/src/ui/element_download_list.h b/src/ui/element_download_list.h index 41d89ebd..2d2cc19f 100644 --- a/src/ui/element_download_list.h +++ b/src/ui/element_download_list.h @@ -56,8 +56,10 @@ public: ElementDownloadList() : m_window(NULL), m_view(NULL) {} - void activate(Control* c, MItr mItr); - void disable(Control* c); + void activate(display::Frame* frame); + void disable(); + + display::Window* window() { return m_window; } void set_view(core::View* l); diff --git a/src/ui/element_file_list.cc b/src/ui/element_file_list.cc index 2fc5d675..126f38d8 100644 --- a/src/ui/element_file_list.cc +++ b/src/ui/element_file_list.cc @@ -61,26 +61,32 @@ ElementFileList::ElementFileList(core::Download* d) : } void -ElementFileList::activate(Control* c, MItr mItr) { +ElementFileList::activate(display::Frame* frame) { if (m_window != NULL) - throw torrent::client_error("ui::ElementFileList::activate(...) called on an object in the wrong state"); + throw torrent::client_error("ui::ElementFileList::activate(...) is_active()."); - c->input()->push_front(&m_bindings); + control->input()->push_front(&m_bindings); - *mItr = m_window = new WFileList(m_download, &m_focus); +// *mItr = m_window = new WFileList(m_download, &m_focus); + m_frame = frame; } void -ElementFileList::disable(Control* c) { +ElementFileList::disable() { if (m_window == NULL) - throw torrent::client_error("ui::ElementFileList::disable(...) called on an object in the wrong state"); + throw torrent::client_error("ui::ElementFileList::disable(...) !is_active()."); - c->input()->erase(&m_bindings); + control->input()->erase(&m_bindings); delete m_window; m_window = NULL; } +display::Window* +ElementFileList::window() { + return m_window; +} + void ElementFileList::receive_next() { if (m_window == NULL) diff --git a/src/ui/element_file_list.h b/src/ui/element_file_list.h index e8112033..974dcc15 100644 --- a/src/ui/element_file_list.h +++ b/src/ui/element_file_list.h @@ -58,8 +58,10 @@ public: ElementFileList(core::Download* d); - void activate(Control* c, MItr mItr); - void disable(Control* c); + void activate(display::Frame* frame); + void disable(); + + display::Window* window(); private: void receive_next(); diff --git a/src/ui/element_log_complete.cc b/src/ui/element_log_complete.cc index 9840b000..e13be405 100644 --- a/src/ui/element_log_complete.cc +++ b/src/ui/element_log_complete.cc @@ -36,8 +36,10 @@ #include "config.h" -#include +#include +#include "display/frame.h" +#include "display/manager.h" #include "display/window_log_complete.h" #include "input/manager.h" @@ -52,24 +54,37 @@ ElementLogComplete::ElementLogComplete(core::Log* l) : } void -ElementLogComplete::activate(Control* c, MItr mItr) { - if (m_window != NULL) - throw std::logic_error("ui::ElementLogComplete::activate(...) called on an object in the wrong state"); +ElementLogComplete::activate(display::Frame* frame) { + if (is_active()) + throw torrent::client_error("ui::ElementLogComplete::activate(...) is_active()."); - c->input()->push_front(&m_bindings); + control->input()->push_front(&m_bindings); - *mItr = m_window = new WLogComplete(m_log); + m_window = new WLogComplete(m_log); + + m_frame = frame; + m_frame->initialize_window(m_window); + + control->display()->schedule(m_window, cachedTime); } void -ElementLogComplete::disable(Control* c) { - if (m_window == NULL) - throw std::logic_error("ui::ElementLogComplete::disable(...) called on an object in the wrong state"); +ElementLogComplete::disable() { + if (!is_active()) + throw torrent::client_error("ui::ElementLogComplete::disable(...) !is_active()."); - c->input()->erase(&m_bindings); + control->input()->erase(&m_bindings); + + m_frame->clear(); + m_frame = NULL; delete m_window; m_window = NULL; } +display::Window* +ElementLogComplete::window() { + return m_window; +} + } diff --git a/src/ui/element_log_complete.h b/src/ui/element_log_complete.h index 561d4955..1ec78c11 100644 --- a/src/ui/element_log_complete.h +++ b/src/ui/element_log_complete.h @@ -55,8 +55,10 @@ public: ElementLogComplete(core::Log* l); - void activate(Control* c, MItr mItr); - void disable(Control* c); + void activate(display::Frame* frame); + void disable(); + + display::Window* window(); private: WLogComplete* m_window; diff --git a/src/ui/element_peer_info.cc b/src/ui/element_peer_info.cc index fd786f9b..a08d04c9 100644 --- a/src/ui/element_peer_info.cc +++ b/src/ui/element_peer_info.cc @@ -36,7 +36,7 @@ #include "config.h" -#include +#include #include "display/window_peer_info.h" #include "input/manager.h" @@ -55,24 +55,30 @@ ElementPeerInfo::ElementPeerInfo(core::Download* d, PList* l, PList::iterator* f } void -ElementPeerInfo::activate(Control* c, MItr mItr) { - if (m_window != NULL) - throw std::logic_error("ui::ElementPeerInfo::activate(...) called on an object in the wrong state"); +ElementPeerInfo::activate(display::Frame* frame) { + if (is_active()) + throw torrent::client_error("ui::ElementPeerInfo::activate(...) is_active()."); - c->input()->push_front(&m_bindings); + control->input()->push_front(&m_bindings); - *mItr = m_window = new WPeerInfo(m_download, m_list, m_focus); + m_window = new WPeerInfo(m_download, m_list, m_focus); + m_frame = frame; } void -ElementPeerInfo::disable(Control* c) { - if (m_window == NULL) - throw std::logic_error("ui::ElementPeerInfo::disable(...) called on an object in the wrong state"); +ElementPeerInfo::disable() { + if (!is_active()) + throw torrent::client_error("ui::ElementPeerInfo::disable(...) !is_active()."); - c->input()->erase(&m_bindings); + control->input()->erase(&m_bindings); delete m_window; m_window = NULL; } +display::Window* +ElementPeerInfo::window() { + return m_window; +} + } diff --git a/src/ui/element_peer_info.h b/src/ui/element_peer_info.h index beace4e7..216a1714 100644 --- a/src/ui/element_peer_info.h +++ b/src/ui/element_peer_info.h @@ -56,8 +56,10 @@ public: ElementPeerInfo(core::Download* d, PList* l, PList::iterator* f); - void activate(Control* c, MItr mItr); - void disable(Control* c); + void activate(display::Frame* frame); + void disable(); + + display::Window* window(); private: core::Download* m_download; diff --git a/src/ui/element_peer_list.cc b/src/ui/element_peer_list.cc index bf5691fa..422ff22b 100644 --- a/src/ui/element_peer_list.cc +++ b/src/ui/element_peer_list.cc @@ -36,7 +36,7 @@ #include "config.h" -#include +#include #include "display/window_peer_list.h" #include "input/manager.h" @@ -55,24 +55,30 @@ ElementPeerList::ElementPeerList(core::Download* d, PList* l, PList::iterator* f } void -ElementPeerList::activate(Control* c, MItr mItr) { - if (m_window != NULL) - throw std::logic_error("ui::ElementPeerList::activate(...) called on an object in the wrong state"); +ElementPeerList::activate(display::Frame* frame) { + if (is_active()) + throw torrent::client_error("ui::ElementPeerList::activate(...) is_active()."); - c->input()->push_front(&m_bindings); + control->input()->push_front(&m_bindings); - *mItr = m_window = new WPeerList(m_download, m_list, m_focus); + m_window = new WPeerList(m_download, m_list, m_focus); + m_frame = frame; } void -ElementPeerList::disable(Control* c) { - if (m_window == NULL) - throw std::logic_error("ui::ElementPeerList::disable(...) called on an object in the wrong state"); +ElementPeerList::disable() { + if (!is_active()) + throw torrent::client_error("ui::ElementPeerList::disable(...) !is_active()."); - c->input()->erase(&m_bindings); + control->input()->erase(&m_bindings); delete m_window; m_window = NULL; } +display::Window* +ElementPeerList::window() { + return m_window; +} + } diff --git a/src/ui/element_peer_list.h b/src/ui/element_peer_list.h index 123743d2..a77788c5 100644 --- a/src/ui/element_peer_list.h +++ b/src/ui/element_peer_list.h @@ -56,8 +56,10 @@ public: ElementPeerList(core::Download* d, PList* l, PList::iterator* f); - void activate(Control* c, MItr mItr); - void disable(Control* c); + void activate(display::Frame* frame); + void disable(); + + display::Window* window(); private: core::Download* m_download; diff --git a/src/ui/element_string_list.cc b/src/ui/element_string_list.cc index 3f76cd62..acc05456 100644 --- a/src/ui/element_string_list.cc +++ b/src/ui/element_string_list.cc @@ -36,7 +36,7 @@ #include "config.h" -#include +#include #include "input/manager.h" @@ -50,23 +50,24 @@ ElementStringList::ElementStringList() : } void -ElementStringList::activate(Control* c, MItr mItr) { - if (m_window != NULL) - throw std::logic_error("ui::ElementStringList::activate(...) called on an object in the wrong state"); +ElementStringList::activate(display::Frame* frame) { + if (is_active()) + throw torrent::client_error("ui::ElementStringList::activate(...) is_active()."); - c->input()->push_front(&m_bindings); + control->input()->push_front(&m_bindings); - *mItr = m_window = new WStringList(); + m_window = new WStringList(); + m_frame = frame; m_window->set_range(m_list.begin(), m_list.end()); } void -ElementStringList::disable(Control* c) { - if (m_window == NULL) - throw std::logic_error("ui::ElementStringList::disable(...) called on an object in the wrong state"); +ElementStringList::disable() { + if (!is_active()) + throw torrent::client_error("ui::ElementStringList::disable(...) !is_active()."); - c->input()->erase(&m_bindings); + control->input()->erase(&m_bindings); delete m_window; m_window = NULL; diff --git a/src/ui/element_string_list.h b/src/ui/element_string_list.h index 2f3eb58a..e01781ec 100644 --- a/src/ui/element_string_list.h +++ b/src/ui/element_string_list.h @@ -57,8 +57,10 @@ public: ElementStringList(); - void activate(Control* c, MItr mItr); - void disable(Control* c); + void activate(display::Frame* frame); + void disable(); + + display::Window* window() { return m_window; } template void set_range(InputIter first, InputIter last) { diff --git a/src/ui/element_tracker_list.cc b/src/ui/element_tracker_list.cc index d2ed1b68..15343642 100644 --- a/src/ui/element_tracker_list.cc +++ b/src/ui/element_tracker_list.cc @@ -60,26 +60,32 @@ ElementTrackerList::ElementTrackerList(core::Download* d) : } void -ElementTrackerList::activate(Control* c, MItr mItr) { +ElementTrackerList::activate(display::Frame* frame) { if (m_window != NULL) - throw torrent::client_error("ui::ElementTrackerList::activate(...) called on an object in the wrong state"); + throw torrent::client_error("ui::ElementTrackerList::activate(...) is_active()."); - c->input()->push_front(&m_bindings); + control->input()->push_front(&m_bindings); - *mItr = m_window = new WTrackerList(m_download, &m_focus); + m_window = new WTrackerList(m_download, &m_focus); + m_frame = frame; } void -ElementTrackerList::disable(Control* c) { +ElementTrackerList::disable() { if (m_window == NULL) - throw torrent::client_error("ui::ElementTrackerList::disable(...) called on an object in the wrong state"); + throw torrent::client_error("ui::ElementTrackerList::disable(...) !is_active()."); - c->input()->erase(&m_bindings); + control->input()->erase(&m_bindings); delete m_window; m_window = NULL; } +display::Window* +ElementTrackerList::window() { + return m_window; +} + void ElementTrackerList::receive_disable() { if (m_window == NULL) diff --git a/src/ui/element_tracker_list.h b/src/ui/element_tracker_list.h index 430952b7..840f750b 100644 --- a/src/ui/element_tracker_list.h +++ b/src/ui/element_tracker_list.h @@ -55,8 +55,10 @@ public: ElementTrackerList(core::Download* d); - void activate(Control* c, MItr mItr); - void disable(Control* c); + void activate(display::Frame* frame); + void disable(); + + display::Window* window(); private: void receive_next(); diff --git a/src/ui/element_transfer_list.cc b/src/ui/element_transfer_list.cc index 1a9d917b..6fa9d8b2 100644 --- a/src/ui/element_transfer_list.cc +++ b/src/ui/element_transfer_list.cc @@ -36,7 +36,7 @@ #include "config.h" -#include +#include #include "display/window_download_transfer_list.h" #include "input/manager.h" @@ -60,26 +60,32 @@ ElementTransferList::ElementTransferList(core::Download* d) : } void -ElementTransferList::activate(Control* c, MItr mItr) { - if (m_window != NULL) - throw std::logic_error("ui::ElementTransferList::activate(...) called on an object in the wrong state"); +ElementTransferList::activate(display::Frame* frame) { + if (is_active()) + throw torrent::client_error("ui::ElementTransferList::activate(...) is_active()."); - c->input()->push_front(&m_bindings); + control->input()->push_front(&m_bindings); - *mItr = m_window = new WTransferList(m_download, &m_focus); + m_window = new WTransferList(m_download, &m_focus); + m_frame = frame; } void -ElementTransferList::disable(Control* c) { - if (m_window == NULL) - throw std::logic_error("ui::ElementTransferList::disable(...) called on an object in the wrong state"); +ElementTransferList::disable() { + if (!is_active()) + throw torrent::client_error("ui::ElementTransferList::disable(...) !is_active()."); - c->input()->erase(&m_bindings); + control->input()->erase(&m_bindings); delete m_window; m_window = NULL; } +display::Window* +ElementTransferList::window() { + return m_window; +} + // void // ElementTransferList::receive_disable() { // if (m_window == NULL) diff --git a/src/ui/element_transfer_list.h b/src/ui/element_transfer_list.h index ff93ad53..3a5d66ea 100644 --- a/src/ui/element_transfer_list.h +++ b/src/ui/element_transfer_list.h @@ -55,8 +55,10 @@ public: ElementTransferList(core::Download* d); - void activate(Control* c, MItr mItr); - void disable(Control* c); + void activate(display::Frame* frame); + void disable(); + + display::Window* window(); private: // void receive_disable(); diff --git a/src/ui/root.cc b/src/ui/root.cc index 74b062d4..984f4c4d 100644 --- a/src/ui/root.cc +++ b/src/ui/root.cc @@ -41,8 +41,14 @@ #include #include +#include "core/manager.h" +#include "display/frame.h" +#include "display/window_http_queue.h" +#include "display/window_title.h" +#include "display/window_input.h" #include "display/window_statusbar.h" #include "input/manager.h" +#include "input/text_input.h" #include "utils/variable_map.h" #include "control.h" @@ -55,6 +61,9 @@ namespace ui { Root::Root() : m_control(NULL), m_downloadList(NULL), + m_windowTitle(NULL), + m_windowHttpQueue(NULL), + m_windowInput(NULL), m_windowStatusbar(NULL) { } @@ -64,15 +73,30 @@ Root::init(Control* c) { throw std::logic_error("Root::init() called twice on the same object"); m_control = c; + + m_windowTitle = new WTitle(); + m_windowHttpQueue = new WHttpQueue(control->core()->http_queue()); + m_windowInput = new WInput(); + m_windowStatusbar = new WStatusbar(); + + m_downloadList = new DownloadList(); + + display::Frame* rootFrame = m_control->display()->root_frame(); + + rootFrame->initialize_container(display::Frame::TYPE_ROW, 5); + rootFrame->frame(0)->initialize_window(m_windowTitle); + rootFrame->frame(2)->initialize_window(m_windowHttpQueue); + rootFrame->frame(3)->initialize_window(m_windowInput); + rootFrame->frame(4)->initialize_window(m_windowStatusbar); + + m_control->display()->schedule(m_windowTitle, cachedTime); + m_control->display()->schedule(m_windowStatusbar, cachedTime); + + m_windowInput->set_active(false); + setup_keys(); - m_windowStatusbar = new WStatusbar(m_control); - m_downloadList = new DownloadList(m_control); - - m_control->display()->push_back(m_windowStatusbar); - - m_downloadList->activate(); - // m_downloadList->slot_open_uri(sigc::mem_fun(m_control->get_core(), &core::Manager::insert)); + m_downloadList->activate(rootFrame->frame(1)); } void @@ -83,9 +107,13 @@ Root::cleanup() { if (m_downloadList->is_active()) m_downloadList->disable(); - m_control->display()->erase(m_windowStatusbar); + m_control->display()->root_frame()->clear(); delete m_downloadList; + + delete m_windowTitle; + delete m_windowHttpQueue; + delete m_windowInput; delete m_windowStatusbar; m_control->input()->erase(&m_bindings); @@ -158,4 +186,43 @@ Root::adjust_up_throttle(int throttle) { set_up_throttle(std::max(torrent::up_throttle() / 1024 + throttle, 0)); } +void +Root::enable_input(input::TextInput* input) { + if (m_windowInput->input() != NULL) + throw torrent::client_error("Root::enable_input(...) m_windowInput->input() != NULL."); + + input->slot_dirty(sigc::mem_fun(m_windowInput, &WInput::mark_dirty)); + + m_windowStatusbar->set_active(false); + + m_windowInput->set_active(true); + m_windowInput->set_focus(true); + m_windowInput->set_input(input); + + control->input()->set_text_input(input); + control->display()->adjust_layout(); +} + +void +Root::disable_input() { + if (m_windowInput->input() == NULL) + throw torrent::client_error("Root::disable_input() m_windowInput->input() == NULL."); + + m_windowInput->input()->slot_dirty(sigc::slot0()); + + m_windowStatusbar->set_active(true); + + m_windowInput->set_active(false); + m_windowInput->set_focus(false); + m_windowInput->set_input(NULL); + + control->input()->set_text_input(NULL); + control->display()->adjust_layout(); +} + +input::TextInput* +Root::current_input() { + return m_windowInput->input(); +} + } diff --git a/src/ui/root.h b/src/ui/root.h index 7f5ce4c5..bc905dea 100644 --- a/src/ui/root.h +++ b/src/ui/root.h @@ -43,15 +43,26 @@ class Control; namespace display { + class Frame; + class WindowTitle; + class WindowHttpQueue; + class WindowInput; class WindowStatusbar; } +namespace input { + class TextInput; +} + namespace ui { class DownloadList; class Root { public: + typedef display::WindowTitle WTitle; + typedef display::WindowHttpQueue WHttpQueue; + typedef display::WindowInput WInput; typedef display::WindowStatusbar WStatusbar; Root(); @@ -59,7 +70,9 @@ public: void init(Control* c); void cleanup(); - WStatusbar* window_statusbar() { return m_windowStatusbar; } + WTitle* window_title() { return m_windowTitle; } + WStatusbar* window_statusbar() { return m_windowStatusbar; } + WInput* window_input() { return m_windowInput; } void set_down_throttle(unsigned int throttle); void set_up_throttle(unsigned int throttle); @@ -71,12 +84,20 @@ public: void adjust_down_throttle(int throttle); void adjust_up_throttle(int throttle); + void enable_input(input::TextInput* input); + void disable_input(); + + input::TextInput* current_input(); + private: void setup_keys(); Control* m_control; DownloadList* m_downloadList; + WTitle* m_windowTitle; + WHttpQueue* m_windowHttpQueue; + WInput* m_windowInput; WStatusbar* m_windowStatusbar; input::Bindings m_bindings; diff --git a/src/utils/variable_map.cc b/src/utils/variable_map.cc index 3a1ad75e..d4b9ba15 100644 --- a/src/utils/variable_map.cc +++ b/src/utils/variable_map.cc @@ -108,9 +108,7 @@ parse_unknown(std::string::const_iterator first, std::string::const_iterator las if (*first == '"') { std::string::const_iterator next = std::find_if(++first, last, std::bind2nd(std::equal_to(), '"')); - if (first == last || - first == next || - next == last) + if (first == last || first == next || next == last) throw torrent::input_error("Could not find closing '\"'."); *dest = std::string(first, next);