mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-10-04 21:29:21 +00:00
rtorrent: Layout dynamically resizes vertically.
git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@240 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
+32
-21
@@ -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 <typename Type, typename Ftor>
|
||||
struct _accumulate {
|
||||
_accumulate(Type& t, Ftor f) : m_t(t), m_f(f) {}
|
||||
|
||||
template <typename Arg>
|
||||
void operator () (Arg& a) { m_t += m_f(a); }
|
||||
|
||||
Type& m_t;
|
||||
Ftor m_f;
|
||||
};
|
||||
|
||||
template <typename Type, typename Ftor>
|
||||
_accumulate<Type, Ftor> accumulate(Type& t, Ftor f) {
|
||||
return _accumulate<Type, Ftor>(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();
|
||||
}
|
||||
|
||||
+8
-11
@@ -1,14 +1,15 @@
|
||||
#ifndef RTORRENT_DISPLAY_MANAGER_H
|
||||
#define RTORRENT_DISPLAY_MANAGER_H
|
||||
|
||||
#include <list>
|
||||
#include "manager_element.h"
|
||||
#include <vector>
|
||||
|
||||
namespace display {
|
||||
|
||||
class Manager : private std::list<ManagerElement> {
|
||||
class Window;
|
||||
|
||||
class Manager : private std::vector<Window*> {
|
||||
public:
|
||||
typedef std::list<ManagerElement> Base;
|
||||
typedef std::vector<Window*> 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);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
+29
-5
@@ -1,4 +1,6 @@
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user