From 27109b542c24ce464a666b2053ecb6e983e61ad6 Mon Sep 17 00:00:00 2001 From: rakshasa Date: Fri, 28 Jan 2005 23:45:57 +0000 Subject: [PATCH] rtorrent: Layout dynamically resizes vertically. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@240 e378c898-3ddf-0310-93e7-cc216c733640 --- src/display/manager.cc | 53 +++++++++++++++++++++-------------- src/display/manager.h | 19 ++++++------- src/display/manager_element.h | 28 ------------------ src/display/window.cc | 8 ++++++ src/display/window.h | 13 ++++++--- src/rtorrent.cc | 34 ++++++++++++++++++---- 6 files changed, 86 insertions(+), 69 deletions(-) delete mode 100644 src/display/manager_element.h diff --git a/src/display/manager.cc b/src/display/manager.cc index eb290b7e..2a9c0b2a 100644 --- a/src/display/manager.cc +++ b/src/display/manager.cc @@ -10,38 +10,49 @@ namespace display { -void -Manager::adjust_layout() { - adjust_row(begin(), end(), 0, 0, display::Canvas::get_screen_width(), display::Canvas::get_screen_height()); +template +struct _accumulate { + _accumulate(Type& t, Ftor f) : m_t(t), m_f(f) {} + + template + void operator () (Arg& a) { m_t += m_f(a); } + + Type& m_t; + Ftor m_f; +}; + +template +_accumulate accumulate(Type& t, Ftor f) { + return _accumulate(t, f); } void -Manager::adjust_row(iterator bItr, iterator eItr, int x, int y, int w, int h) { - int t; - int dist = std::distance(bItr, eItr); +Manager::adjust_layout() { + int countDynamic = 0; + int staticHeight = 0; - switch (dist) { - case 1: - bItr->get_window()->resize(x, y, w, h); - break; + std::for_each(begin(), end(), accumulate(staticHeight, std::mem_fun(&Window::get_min_height))); + std::for_each(begin(), end(), accumulate(countDynamic, std::mem_fun(&Window::is_dynamic))); - case 2: - t = w / 2 + w % 2; + int dynamic = std::max(0, Canvas::get_screen_height() - staticHeight); + int height = 0, h; - bItr->get_window()->resize(x, y, t, h); - ++bItr; - bItr->get_window()->resize(x + t, y, w - t, h); - break; + for (iterator itr = begin(); itr != end(); ++itr, height += h) { + h = (*itr)->is_dynamic() ? ((dynamic + countDynamic - 1) / countDynamic) : 0; - default: - throw std::logic_error("Manager::adjust_row(...) got a range with invalid number of elements"); + countDynamic--; + dynamic -= h; + + h += (*itr)->get_min_height(); + + (*itr)->resize(0, height, Canvas::get_screen_width(), h); } -} +} void Manager::do_update() { - std::for_each(begin(), end(), std::mem_fun_ref(&ManagerElement::redraw)); - std::for_each(begin(), end(), std::mem_fun_ref(&ManagerElement::refresh)); + std::for_each(begin(), end(), std::mem_fun(&Window::redraw)); + std::for_each(begin(), end(), std::mem_fun(&Window::refresh)); Canvas::do_update(); } diff --git a/src/display/manager.h b/src/display/manager.h index 078c54a2..42759a47 100644 --- a/src/display/manager.h +++ b/src/display/manager.h @@ -1,14 +1,15 @@ #ifndef RTORRENT_DISPLAY_MANAGER_H #define RTORRENT_DISPLAY_MANAGER_H -#include -#include "manager_element.h" +#include namespace display { -class Manager : private std::list { +class Window; + +class Manager : private std::vector { public: - typedef std::list Base; + typedef std::vector Base; using Base::iterator; using Base::const_iterator; @@ -20,18 +21,14 @@ public: using Base::rbegin; using Base::rend; - enum { - NEW_ROW = 0x1 - }; - - Base::iterator add(Window* w, int flags = 0) { return Base::insert(end(), ManagerElement(w, flags)); } + using Base::insert; + using Base::erase; + using Base::push_back; void adjust_layout(); void do_update(); private: - // Functions for adjusting ranges in different directions. - void adjust_row(iterator bItr, iterator eItr, int x, int y, int w, int h); }; } diff --git a/src/display/manager_element.h b/src/display/manager_element.h deleted file mode 100644 index b4941ff4..00000000 --- a/src/display/manager_element.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef RTORRENT_DISPLAY_MANAGER_ELEMENT_H -#define RTORRENT_DISPLAY_MANAGER_ELEMENT_H - -#include "window.h" - -namespace display { - -class ManagerElement { -public: - ManagerElement(Window* w, int flags) : m_window(w), m_flags(flags) {} - - void refresh() { m_window->refresh(); } - void redraw() { m_window->redraw(); } - - Window* get_window() { return m_window; } - void set_window(Window* w) { m_window = w; } - - int get_flags() { return m_flags; } - void set_flags(int flags) { m_flags = flags; } - -private: - Window* m_window; - int m_flags; -}; - -} - -#endif diff --git a/src/display/window.cc b/src/display/window.cc index 189e14a1..e917e5b2 100644 --- a/src/display/window.cc +++ b/src/display/window.cc @@ -1,5 +1,7 @@ #include "config.h" +#include + #include "canvas.h" #include "window.h" @@ -12,6 +14,12 @@ Window::refresh() { void Window::resize(int x, int y, int w, int h) { + if (x < 0 || y < 0) + throw std::logic_error("Window::resize(...) bad x or y position"); + + if (w <= 0 || h <= 0) + throw std::logic_error("Window::resize(...) bad size"); + m_canvas->resize(x, y, w, h); } diff --git a/src/display/window.h b/src/display/window.h index ece4556a..c4e5121c 100644 --- a/src/display/window.h +++ b/src/display/window.h @@ -7,11 +7,13 @@ class Canvas; class Window { public: - Window(Canvas* c = NULL) : m_canvas(c) {} + Window(Canvas* c = NULL, bool d = false, int h = 1) : + m_canvas(c), m_dynamic(d), m_minHeight(h) {} virtual ~Window() {} - Canvas* get_canvas() { return m_canvas; } - + bool is_dynamic() { return m_dynamic; } + int get_min_height() { return m_minHeight; } + void refresh(); void resize(int x, int y, int w, int h); @@ -21,7 +23,10 @@ protected: Window(const Window&); void operator = (const Window&); - Canvas* m_canvas; + Canvas* m_canvas; + + bool m_dynamic; + int m_minHeight; }; } diff --git a/src/rtorrent.cc b/src/rtorrent.cc index 75cf2493..0d70f898 100644 --- a/src/rtorrent.cc +++ b/src/rtorrent.cc @@ -1,4 +1,6 @@ #include +#include +#include #include "display/window.h" #include "display/canvas.h" @@ -8,7 +10,8 @@ class WindowTest : public display::Window { public: - WindowTest(const std::string& str, bool reverse = false) : Window(new display::Canvas), m_str(str), m_reverse(reverse) {} + WindowTest(const std::string& str, bool reverse = false) : + Window(new display::Canvas, true, 3), m_str(str), m_reverse(reverse) {} virtual void redraw() { if (m_canvas == NULL) @@ -21,13 +24,22 @@ public: m_canvas->erase(); m_canvas->print_border('|', '|', '-', '-', '+', '+', '+', '+'); - m_canvas->print(1, 1, "%s", m_str.c_str()); + m_canvas->print(1, 1, "%s minHeight %i", m_str.c_str(), m_minHeight); } void reverse() { m_reverse = !m_reverse; } + void inc_min() { + m_minHeight++; + } + + void dec_min() { + if (m_minHeight) + m_minHeight--; + } + private: std::string m_str; @@ -35,6 +47,8 @@ private: }; int main(int argc, char** argv) { + try { + display::Canvas::init(); display::Manager display; input::Manager inputManager; @@ -48,24 +62,34 @@ int main(int argc, char** argv) { inputManager.push_back(&bindings1); inputManager.push_back(&bindings2); + bindings1[KEY_LEFT] = sigc::mem_fun(window1, &WindowTest::reverse); + bindings1[KEY_UP] = sigc::mem_fun(window1, &WindowTest::inc_min); + bindings1[KEY_DOWN] = sigc::mem_fun(window1, &WindowTest::dec_min); bindings1[KEY_LEFT] = sigc::mem_fun(window1, &WindowTest::reverse); bindings2[KEY_LEFT] = sigc::mem_fun(window2, &WindowTest::reverse); bindings2[KEY_RIGHT] = sigc::mem_fun(window2, &WindowTest::reverse); - display.add(&window1); - display.add(&window2); + display.push_back(&window1); + display.push_back(&window2); display.adjust_layout(); while (true) { + display.adjust_layout(); display.do_update(); inputManager.pressed(getch()); - sleep(1); + sleep(0); } display::Canvas::cleanup(); + } catch (std::exception& e) { + display::Canvas::cleanup(); + + std::cout << "Caught exception: \"" << e.what() << '"' << std::endl; + } + return 0; }