mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-08-13 05:32:31 +00:00
* Use varargs in Canvas::print.
* Added min/max size to display::Window. Added flags for windows that should be on located at the left/bottom side of a Frame. * Reversed print order in WindowLog*. * Added display::TextElement and subclasses for flexible printing to a char buffer with associated attributes. Added display::Attributes and display::Canvas::print_attributes. * Added display::WindowText for use with display::TextElement's. * Added ui::ElementMenu for generic menus, and started work adding this to ui::Download. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@751 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
+23
-10
@@ -317,24 +317,37 @@ mem_ptr(Member Class::*m) {
|
||||
}
|
||||
|
||||
template <typename Class, typename Member>
|
||||
struct mem_ptr_ref_t : public std::unary_function<Class&, Member&> {
|
||||
mem_ptr_ref_t(Member Class::*m) : m_member(m) {}
|
||||
struct mem_ref_t : public std::unary_function<Class&, Member&> {
|
||||
mem_ref_t(Member Class::*m) : m_member(m) {}
|
||||
|
||||
Member& operator () (Class& c) {
|
||||
return c.*m_member;
|
||||
}
|
||||
|
||||
const Member& operator () (const Class& c) {
|
||||
return c.*m_member;
|
||||
}
|
||||
|
||||
Member Class::*m_member;
|
||||
};
|
||||
|
||||
template <typename Class, typename Member>
|
||||
inline mem_ptr_ref_t<Class, Member>
|
||||
mem_ptr_ref(Member Class::*m) {
|
||||
return mem_ptr_ref_t<Class, Member>(m);
|
||||
struct const_mem_ref_t : public std::unary_function<const Class&, const Member&> {
|
||||
const_mem_ref_t(const Member Class::*m) : m_member(m) {}
|
||||
|
||||
const Member& operator () (const Class& c) {
|
||||
return c.*m_member;
|
||||
}
|
||||
|
||||
const Member Class::*m_member;
|
||||
};
|
||||
|
||||
template <typename Class, typename Member>
|
||||
inline mem_ref_t<Class, Member>
|
||||
mem_ref(Member Class::*m) {
|
||||
return mem_ref_t<Class, Member>(m);
|
||||
}
|
||||
|
||||
template <typename Class, typename Member>
|
||||
inline const_mem_ref_t<Class, Member>
|
||||
const_mem_ref(const Member Class::*m) {
|
||||
return const_mem_ref_t<Class, Member>(m);
|
||||
}
|
||||
|
||||
template <typename Cond, typename Then>
|
||||
@@ -415,7 +428,7 @@ protected:
|
||||
Operation m_op;
|
||||
value_type m_value;
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
template <typename Operation, typename Type>
|
||||
inline bind2nd_t<Operation>
|
||||
|
||||
+4
-4
@@ -83,7 +83,7 @@ ranges<Type>::insert(value_type r) {
|
||||
if (r.first >= r.second)
|
||||
return;
|
||||
|
||||
iterator first = std::find_if(begin(), end(), rak::less_equal(r.first, rak::mem_ptr_ref(&value_type::second)));
|
||||
iterator first = std::find_if(begin(), end(), rak::less_equal(r.first, rak::const_mem_ref(&value_type::second)));
|
||||
|
||||
if (first == end() || r.second < first->first) {
|
||||
// The new range is before the first, after the last or between
|
||||
@@ -107,13 +107,13 @@ ranges<Type>::insert(value_type r) {
|
||||
template <typename Type>
|
||||
inline typename ranges<Type>::iterator
|
||||
ranges<Type>::find(Type index) {
|
||||
return std::find_if(begin(), end(), rak::less(index, rak::mem_ptr_ref(&value_type::second)));
|
||||
return std::find_if(begin(), end(), rak::less(index, rak::const_mem_ref(&value_type::second)));
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
inline typename ranges<Type>::const_iterator
|
||||
ranges<Type>::find(Type index) const {
|
||||
return std::find_if(begin(), end(), rak::less(index, rak::mem_ptr_ref(&value_type::second)));
|
||||
return std::find_if(begin(), end(), rak::less(index, rak::const_mem_ref(&value_type::second)));
|
||||
}
|
||||
|
||||
// Use find with no closest match.
|
||||
@@ -128,7 +128,7 @@ ranges<Type>::has(Type index) const {
|
||||
template <typename Type>
|
||||
inline void
|
||||
ranges<Type>::unify(iterator first) {
|
||||
iterator last = std::find_if((first + 1), end(), rak::less(first->second, rak::mem_ptr_ref(&value_type::first)));
|
||||
iterator last = std::find_if((first + 1), end(), rak::less(first->second, rak::const_mem_ref(&value_type::first)));
|
||||
|
||||
first->second = std::max(first->second, (last - 1)->second);
|
||||
Base::erase((first + 1), last);
|
||||
|
||||
+1
-1
@@ -59,7 +59,7 @@ Log::push_front(const std::string& msg) {
|
||||
|
||||
Log::iterator
|
||||
Log::find_older(rak::timer t) {
|
||||
return std::find_if(begin(), end(), rak::on(rak::mem_ptr_ref(&Type::first), std::bind2nd(std::less_equal<rak::timer>(), t)));
|
||||
return std::find_if(begin(), end(), rak::on(rak::mem_ref(&Type::first), std::bind2nd(std::less_equal<rak::timer>(), t)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ ViewManager::ViewManager(DownloadList* dl) :
|
||||
void
|
||||
ViewManager::clear() {
|
||||
std::for_each(begin(), end(), rak::call_delete<View>());
|
||||
std::for_each(m_sort.begin(), m_sort.end(), rak::on(rak::mem_ptr_ref(&sort_map::value_type::second), rak::call_delete<ViewSort>()));
|
||||
std::for_each(m_sort.begin(), m_sort.end(), rak::on(rak::mem_ref(&sort_map::value_type::second), rak::call_delete<ViewSort>()));
|
||||
|
||||
base_type::clear();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
noinst_LIBRARIES = libsub_display.a
|
||||
|
||||
libsub_display_a_SOURCES = \
|
||||
attributes.h \
|
||||
canvas.cc \
|
||||
canvas.h \
|
||||
client_info.cc \
|
||||
@@ -11,6 +12,11 @@ libsub_display_a_SOURCES = \
|
||||
manager.h \
|
||||
utils.cc \
|
||||
utils.h \
|
||||
text_element.h \
|
||||
text_element_list.cc \
|
||||
text_element_list.h \
|
||||
text_element_string.cc \
|
||||
text_element_string.h \
|
||||
window.cc \
|
||||
window.h \
|
||||
window_download_chunks_seen.cc \
|
||||
@@ -39,6 +45,8 @@ libsub_display_a_SOURCES = \
|
||||
window_statusbar.h \
|
||||
window_string_list.cc \
|
||||
window_string_list.h \
|
||||
window_text.cc \
|
||||
window_text.h \
|
||||
window_title.cc \
|
||||
window_title.h \
|
||||
window_tracker_list.cc \
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
// 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 <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
#ifndef RTORRENT_DISPLAY_ATTRIBUTES_H
|
||||
#define RTORRENT_DISPLAY_ATTRIBUTES_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <ncurses.h>
|
||||
|
||||
// Let us hail the creators of curses for being idiots. The only
|
||||
// clever move they made was in the naming.
|
||||
#undef timeout
|
||||
#undef move
|
||||
|
||||
namespace display {
|
||||
|
||||
class Attributes {
|
||||
public:
|
||||
static const int a_invalid = ~int();
|
||||
static const int a_normal = A_NORMAL;
|
||||
static const int a_bold = A_BOLD;
|
||||
static const int a_reverse = A_REVERSE;
|
||||
|
||||
static const int color_invalid = ~int();
|
||||
static const int color_default = 0;
|
||||
|
||||
Attributes() {}
|
||||
Attributes(const char* pos, int attr, int col) :
|
||||
m_position(pos), m_attributes(attr), m_colors(col) {}
|
||||
|
||||
const char* position() const { return m_position; }
|
||||
void set_position(const char* pos) { m_position = pos; }
|
||||
|
||||
int attributes() const { return m_attributes; }
|
||||
void set_attributes(int attr) { m_attributes = attr; }
|
||||
|
||||
int colors() const { return m_colors; }
|
||||
void set_colors(int col) { m_colors = col; }
|
||||
|
||||
private:
|
||||
const char* m_position;
|
||||
int m_attributes;
|
||||
int m_colors;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -39,6 +39,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/termios.h>
|
||||
#include <torrent/exceptions.h>
|
||||
|
||||
#include "canvas.h"
|
||||
|
||||
@@ -52,6 +53,28 @@ Canvas::resize(int x, int y, int w, int h) {
|
||||
mvwin(m_window, y, x);
|
||||
}
|
||||
|
||||
void
|
||||
Canvas::print_attributes(unsigned int x, unsigned int y, const char* first, const char* last, const attributes_list* attributes) {
|
||||
move(x, y);
|
||||
|
||||
int attr = A_NORMAL;
|
||||
attributes_list::const_iterator attrItr = attributes->begin();
|
||||
|
||||
while (first != last) {
|
||||
if (attrItr != attributes->end() && attrItr->position() == first) {
|
||||
attr = attrItr->attributes();
|
||||
// Set colors or something.
|
||||
|
||||
attrItr++;
|
||||
continue;
|
||||
}
|
||||
|
||||
waddch(m_window, *first++ | attr);
|
||||
}
|
||||
|
||||
// Reset the color.
|
||||
}
|
||||
|
||||
void
|
||||
Canvas::initialize() {
|
||||
if (m_isInitialized)
|
||||
|
||||
+26
-42
@@ -38,12 +38,16 @@
|
||||
#define RTORRENT_DISPLAY_CANVAS_H
|
||||
|
||||
#include <string>
|
||||
#include <ncurses.h>
|
||||
#include <vector>
|
||||
|
||||
#include "attributes.h"
|
||||
|
||||
namespace display {
|
||||
|
||||
class Canvas {
|
||||
public:
|
||||
typedef std::vector<Attributes> attributes_list;
|
||||
|
||||
Canvas(int x = 0, int y = 0, int width = 0, int height = 0) :
|
||||
m_window(newwin(height, width, y, x)) {}
|
||||
~Canvas() { delwin(m_window); }
|
||||
@@ -59,10 +63,13 @@ public:
|
||||
static void resize_term(int x, int y) { resizeterm(y, x); }
|
||||
static void resize_term(std::pair<int, int> dim) { resizeterm(dim.second, dim.first); }
|
||||
|
||||
int get_x() { int x, y; getyx(m_window, y, x); return x; }
|
||||
int get_y() { int x, y; getyx(m_window, y, x); return y; }
|
||||
int width() { int x, y; getmaxyx(m_window, y, x); return x; }
|
||||
int height() { int x, y; getmaxyx(m_window, y, x); return y; }
|
||||
unsigned int get_x() { int x, y; getyx(m_window, y, x); return x; }
|
||||
unsigned int get_y() { int x, y; getyx(m_window, y, x); return y; }
|
||||
|
||||
unsigned int width() { int x, y; getmaxyx(m_window, y, x); return x; }
|
||||
unsigned int height() { int x, y; getmaxyx(m_window, y, x); return y; }
|
||||
|
||||
void move(unsigned int x, unsigned int y) { wmove(m_window, y, x); }
|
||||
|
||||
chtype get_background() { return getbkgd(m_window); }
|
||||
void set_background(chtype c) { return wbkgdset(m_window, c); }
|
||||
@@ -79,43 +86,14 @@ public:
|
||||
// since the string shall always be a C string choosen at
|
||||
// compiletime. Might cause extra copying of the string?
|
||||
|
||||
void print(int x, int y, char* str) { mvwprintw(m_window, y, x, str); }
|
||||
void print(unsigned int x, unsigned int y, const char* str, ...);
|
||||
|
||||
template <typename A1>
|
||||
void print(int x, int y, char* str, A1 a1) { mvwprintw(m_window, y, x, str, a1); }
|
||||
void print_attributes(unsigned int x, unsigned int y, const char* first, const char* last, const attributes_list* attributes);
|
||||
|
||||
template <typename A1, typename A2>
|
||||
void print(int x, int y, char* str, A1 a1, A2 a2) { mvwprintw(m_window, y, x, str, a1, a2); }
|
||||
void print_char(const chtype ch) { waddch(m_window, ch); }
|
||||
void print_char(unsigned int x, unsigned int y, const chtype ch) { mvwaddch(m_window, y, x, ch); }
|
||||
|
||||
template <typename A1, typename A2, typename A3>
|
||||
void print(int x, int y, char* str,
|
||||
A1 a1, A2 a2, A3 a3) { mvwprintw(m_window, y, x, str, a1, a2, a3); }
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4>
|
||||
void print(int x, int y, char* str,
|
||||
A1 a1, A2 a2, A3 a3, A4 a4) { mvwprintw(m_window, y, x, str, a1, a2, a3, a4); }
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5>
|
||||
void print(int x, int y, char* str,
|
||||
A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { mvwprintw(m_window, y, x, str, a1, a2, a3, a4, a5); }
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
|
||||
void print(int x, int y, char* str,
|
||||
A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) { mvwprintw(m_window, y, x, str, a1, a2, a3, a4, a5, a6); }
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
|
||||
void print(int x, int y, char* str,
|
||||
A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) { mvwprintw(m_window, y, x, str, a1, a2, a3, a4, a5, a6, a7); }
|
||||
|
||||
template <typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8>
|
||||
void print(int x, int y, char* str,
|
||||
A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) { mvwprintw(m_window, y, x, str, a1, a2, a3, a4, a5, a6, a7, a8); }
|
||||
|
||||
void print_char(const chtype ch) { waddch(m_window, ch); }
|
||||
|
||||
void print_char(int x, int y, const chtype ch) { mvwaddch(m_window, y, x, ch); }
|
||||
|
||||
void set_attr(int x, int y, int n, int attr, int color) { mvwchgat(m_window, y, x, n, attr, color, NULL); }
|
||||
void set_attr(unsigned int x, unsigned int y, unsigned int n, int attr, int color) { mvwchgat(m_window, y, x, n, attr, color, NULL); }
|
||||
|
||||
// Initialize stdscr.
|
||||
static void initialize();
|
||||
@@ -137,9 +115,15 @@ private:
|
||||
WINDOW* m_window;
|
||||
};
|
||||
|
||||
// Undefines 'timeout' that ncurses defines which screws up the global
|
||||
// namespace. Idiots; Especially you, ESR.
|
||||
#undef timeout
|
||||
inline void
|
||||
Canvas::print(unsigned int x, unsigned int y, const char* str, ...) {
|
||||
va_list arglist;
|
||||
|
||||
va_start(arglist, str);
|
||||
wmove(m_window, y, x);
|
||||
vw_printw(m_window, str, arglist);
|
||||
va_end(arglist);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
+214
-64
@@ -58,11 +58,8 @@ Frame::Frame() :
|
||||
bool
|
||||
Frame::is_width_dynamic() const {
|
||||
switch (m_type) {
|
||||
case TYPE_NONE:
|
||||
return false;
|
||||
|
||||
case TYPE_WINDOW:
|
||||
return m_window->is_active() && m_window->is_width_dynamic();
|
||||
case TYPE_NONE: return false;
|
||||
case TYPE_WINDOW: return m_window->is_active() && m_window->is_width_dynamic();
|
||||
|
||||
case TYPE_ROW:
|
||||
case TYPE_COLUMN:
|
||||
@@ -79,11 +76,8 @@ Frame::is_width_dynamic() const {
|
||||
bool
|
||||
Frame::is_height_dynamic() const {
|
||||
switch (m_type) {
|
||||
case TYPE_NONE:
|
||||
return false;
|
||||
|
||||
case TYPE_WINDOW:
|
||||
return m_window->is_active() && m_window->is_height_dynamic();
|
||||
case TYPE_NONE: return false;
|
||||
case TYPE_WINDOW: return m_window->is_active() && m_window->is_height_dynamic();
|
||||
|
||||
case TYPE_ROW:
|
||||
case TYPE_COLUMN:
|
||||
@@ -97,35 +91,82 @@ Frame::is_height_dynamic() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
Frame::pair_type
|
||||
bool
|
||||
Frame::has_left_frame() const {
|
||||
switch (m_type) {
|
||||
case TYPE_NONE:
|
||||
case TYPE_ROW: return false;
|
||||
case TYPE_WINDOW: return m_window->is_active() && m_window->is_left();
|
||||
|
||||
case TYPE_COLUMN:
|
||||
for (size_type i = 0; i < m_containerSize; ++i)
|
||||
if (m_container[i]->has_left_frame())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
Frame::has_bottom_frame() const {
|
||||
switch (m_type) {
|
||||
case TYPE_NONE:
|
||||
case TYPE_COLUMN: return false;
|
||||
case TYPE_WINDOW: return m_window->is_active() && m_window->is_bottom();
|
||||
|
||||
case TYPE_ROW:
|
||||
for (size_type i = 0; i < m_containerSize; ++i)
|
||||
if (m_container[i]->has_bottom_frame())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Frame::bounds_type
|
||||
Frame::preferred_size() const {
|
||||
switch (m_type) {
|
||||
case TYPE_NONE:
|
||||
return pair_type(0, 0);
|
||||
return bounds_type(0, 0, 0, 0);
|
||||
|
||||
case TYPE_WINDOW:
|
||||
if (m_window->is_active())
|
||||
return pair_type(std::max<uint32_t>(m_window->min_width(), 1), std::max<uint32_t>(m_window->min_height(), 1));
|
||||
return bounds_type(m_window->min_width(), m_window->min_height(),
|
||||
m_window->max_width(), m_window->max_height());
|
||||
else
|
||||
return pair_type(0, 0);
|
||||
return bounds_type(0, 0, 0, 0);
|
||||
|
||||
case TYPE_ROW:
|
||||
case TYPE_COLUMN:
|
||||
{
|
||||
pair_type accum(0, 0);
|
||||
bounds_type accum(0, 0, 0, 0);
|
||||
|
||||
for (size_type i = 0; i < m_containerSize; ++i) {
|
||||
pair_type p = m_container[i]->preferred_size();
|
||||
bounds_type p = m_container[i]->preferred_size();
|
||||
|
||||
accum.first += p.first;
|
||||
accum.second += p.second;
|
||||
accum.minWidth += p.minWidth;
|
||||
accum.minHeight += p.minHeight;
|
||||
|
||||
if (p.maxWidth == Window::extent_full || accum.maxWidth == Window::extent_full)
|
||||
accum.maxWidth = Window::extent_full;
|
||||
else
|
||||
accum.maxWidth += p.maxWidth;
|
||||
|
||||
if (p.maxHeight == Window::extent_full || accum.maxHeight == Window::extent_full)
|
||||
accum.maxHeight = Window::extent_full;
|
||||
else
|
||||
accum.maxHeight += p.maxHeight;
|
||||
}
|
||||
|
||||
return accum;
|
||||
}
|
||||
}
|
||||
|
||||
return pair_type(0, 0);
|
||||
return bounds_type(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -185,6 +226,12 @@ Frame::initialize_column(size_type size) {
|
||||
void
|
||||
Frame::clear() {
|
||||
switch (m_type) {
|
||||
case TYPE_WINDOW:
|
||||
if (m_window != NULL)
|
||||
m_window->set_offscreen(true);
|
||||
|
||||
break;
|
||||
|
||||
case TYPE_ROW:
|
||||
case TYPE_COLUMN:
|
||||
for (size_type i = 0; i < m_containerSize; ++i) {
|
||||
@@ -249,41 +296,64 @@ Frame::balance(uint32_t x, uint32_t y, uint32_t width, uint32_t height) {
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
|
||||
if (m_type == TYPE_NONE)
|
||||
return;
|
||||
switch (m_type) {
|
||||
case TYPE_NONE: break;
|
||||
case TYPE_WINDOW: balance_window(x, y, width, height); break;
|
||||
case TYPE_ROW: balance_row(x, y, width, height); break;
|
||||
case TYPE_COLUMN: balance_column(x, y, width, height); break;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_type == TYPE_WINDOW) {
|
||||
// Ensure that we don't draw windows that are offscreen or have
|
||||
// zero extent.
|
||||
if (width == 0 || height == 0 || !m_window->is_active()) {
|
||||
m_window->set_offscreen(true);
|
||||
return;
|
||||
}
|
||||
|
||||
m_window->set_offscreen(false);
|
||||
m_window->resize(x, y, width, height);
|
||||
m_window->mark_dirty();
|
||||
inline void
|
||||
Frame::balance_window(uint32_t x, uint32_t y, uint32_t width, uint32_t height) {
|
||||
// Ensure that we don't draw windows that are offscreen or have
|
||||
// zero extent.
|
||||
if (width == 0 || height == 0 || !m_window->is_active()) {
|
||||
m_window->set_offscreen(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (width > m_window->max_width()) {
|
||||
if (m_window->is_left())
|
||||
x += width - m_window->max_width();
|
||||
|
||||
width = m_window->max_width();
|
||||
}
|
||||
|
||||
if (height > m_window->max_height()) {
|
||||
if (m_window->is_bottom())
|
||||
y += height - m_window->max_height();
|
||||
|
||||
height = m_window->max_height();
|
||||
}
|
||||
|
||||
m_window->set_offscreen(false);
|
||||
m_window->resize(x, y, width, height);
|
||||
m_window->mark_dirty();
|
||||
}
|
||||
|
||||
inline void
|
||||
Frame::balance_row(uint32_t x, uint32_t y, uint32_t width, uint32_t height) {
|
||||
// Find the size of the static frames. The dynamic frames are added
|
||||
// to a temporary list for the second pass. Each frame uses the
|
||||
// m_width and m_height as temporary storage for width and height in
|
||||
// this algorithm.
|
||||
size_type dynamicSize = 0;
|
||||
Frame* dynamicFrames[max_size];
|
||||
size_type dynamicSize = 0;
|
||||
dynamic_type dynamicFrames[max_size];
|
||||
|
||||
int remaining = m_type == TYPE_ROW ? height : width;
|
||||
int remaining = height;
|
||||
|
||||
for (Frame **itr = m_container, **last = m_container + m_containerSize; itr != last; ++itr) {
|
||||
pair_type p = (*itr)->preferred_size();
|
||||
(*itr)->m_width = p.first;
|
||||
(*itr)->m_height = p.second;
|
||||
bounds_type bounds = (*itr)->preferred_size();
|
||||
|
||||
if ((*itr)->is_height_dynamic()) {
|
||||
(*itr)->m_height = 0;
|
||||
dynamicFrames[dynamicSize++] = std::make_pair(*itr, bounds);
|
||||
|
||||
if ((m_type == TYPE_ROW && (*itr)->is_height_dynamic()) || (m_type == TYPE_COLUMN && (*itr)->is_width_dynamic()))
|
||||
dynamicFrames[dynamicSize++] = *itr;
|
||||
else
|
||||
remaining -= m_type == TYPE_ROW ? p.second : p.first;
|
||||
} else {
|
||||
(*itr)->m_height = bounds.minHeight;
|
||||
remaining -= bounds.minHeight;
|
||||
}
|
||||
}
|
||||
|
||||
// Sort the dynamic frames by the min size in the direction we are
|
||||
@@ -292,42 +362,122 @@ Frame::balance(uint32_t x, uint32_t y, uint32_t width, uint32_t height) {
|
||||
// following frames.
|
||||
//
|
||||
// Else if we're short, only give each what they require.
|
||||
std::sort(dynamicFrames, dynamicFrames + dynamicSize,
|
||||
rak::greater2(rak::on(rak::const_mem_ref(&dynamic_type::second), rak::const_mem_ref(&Frame::bounds_type::minHeight)),
|
||||
rak::on(rak::const_mem_ref(&dynamic_type::second), rak::const_mem_ref(&Frame::bounds_type::minHeight))));
|
||||
|
||||
if (m_type == TYPE_ROW)
|
||||
std::sort(dynamicFrames, dynamicFrames + dynamicSize, rak::greater2(rak::mem_ptr(&Frame::m_height), rak::mem_ptr(&Frame::m_height)));
|
||||
else
|
||||
std::sort(dynamicFrames, dynamicFrames + dynamicSize, rak::greater2(rak::mem_ptr(&Frame::m_width), rak::mem_ptr(&Frame::m_width)));
|
||||
bool retry;
|
||||
|
||||
for (Frame **itr = dynamicFrames, **last = dynamicFrames + dynamicSize; itr != last; ++itr, --dynamicSize) {
|
||||
uint32_t s = std::max<uint32_t>((std::max(remaining, 0) + dynamicSize - 1) / dynamicSize,
|
||||
m_type == TYPE_ROW ? (*itr)->m_height : (*itr)->m_width);
|
||||
do {
|
||||
retry = false;
|
||||
|
||||
for (dynamic_type *itr = dynamicFrames, *last = dynamicFrames + dynamicSize; itr != last; ++itr) {
|
||||
uint32_t adjust = (std::max(remaining, 0) + std::distance(itr, last) - 1) / std::distance(itr, last);
|
||||
|
||||
remaining -= s;
|
||||
|
||||
if (m_type == TYPE_ROW)
|
||||
(*itr)->m_height = s;
|
||||
else
|
||||
(*itr)->m_width = s;
|
||||
}
|
||||
adjust += itr->first->m_height;
|
||||
adjust = std::max(adjust, itr->second.minHeight);
|
||||
adjust = std::min(adjust, itr->second.maxHeight);
|
||||
|
||||
remaining -= adjust - itr->first->m_height;
|
||||
|
||||
retry = retry || itr->first->m_height != adjust;
|
||||
|
||||
itr->first->m_height = adjust;
|
||||
}
|
||||
|
||||
} while (retry && remaining > 0);
|
||||
|
||||
// Use the pre-calculated frame sizes to balance the sub-frames. If
|
||||
// the frame is too small, it will set the remaining windows to zero
|
||||
// extent which will flag them as offscreen.
|
||||
|
||||
for (Frame **itr = m_container, **last = m_container + m_containerSize; itr != last; ++itr) {
|
||||
if (m_type == TYPE_ROW) {
|
||||
(*itr)->balance(x, y, m_width, std::min((*itr)->m_height, height));
|
||||
// If there is any remaining space, check if we want to shift
|
||||
// the subsequent frames to the other side of this frame.
|
||||
if (remaining > 0 && (*itr)->has_bottom_frame()) {
|
||||
(*itr)->m_height += remaining;
|
||||
remaining = 0;
|
||||
}
|
||||
|
||||
y += (*itr)->m_height;
|
||||
height -= (*itr)->m_height;
|
||||
(*itr)->balance(x, y, m_width, std::min((*itr)->m_height, height));
|
||||
|
||||
y += (*itr)->m_height;
|
||||
height -= (*itr)->m_height;
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
Frame::balance_column(uint32_t x, uint32_t y, uint32_t width, uint32_t height) {
|
||||
// Find the size of the static frames. The dynamic frames are added
|
||||
// to a temporary list for the second pass. Each frame uses the
|
||||
// m_width and m_height as temporary storage for width and height in
|
||||
// this algorithm.
|
||||
size_type dynamicSize = 0;
|
||||
dynamic_type dynamicFrames[max_size];
|
||||
|
||||
int remaining = width;
|
||||
|
||||
for (Frame **itr = m_container, **last = m_container + m_containerSize; itr != last; ++itr) {
|
||||
bounds_type bounds = (*itr)->preferred_size();
|
||||
|
||||
if ((*itr)->is_width_dynamic()) {
|
||||
(*itr)->m_width = 0;
|
||||
dynamicFrames[dynamicSize++] = std::make_pair(*itr, bounds);
|
||||
|
||||
} else {
|
||||
(*itr)->balance(x, y, std::min((*itr)->m_width, width), m_height);
|
||||
|
||||
x += (*itr)->m_width;
|
||||
width -= (*itr)->m_width;
|
||||
(*itr)->m_width = bounds.minWidth;
|
||||
remaining -= bounds.minWidth;
|
||||
}
|
||||
}
|
||||
|
||||
// Sort the dynamic frames by the min size in the direction we are
|
||||
// interested in. Then try to satisfy the largest first, and if we
|
||||
// have any remaining space we can use that to extend it and any
|
||||
// following frames.
|
||||
//
|
||||
// Else if we're short, only give each what they require.
|
||||
std::sort(dynamicFrames, dynamicFrames + dynamicSize,
|
||||
rak::greater2(rak::on(rak::const_mem_ref(&dynamic_type::second), rak::const_mem_ref(&Frame::bounds_type::minWidth)),
|
||||
rak::on(rak::const_mem_ref(&dynamic_type::second), rak::const_mem_ref(&Frame::bounds_type::minWidth))));
|
||||
|
||||
bool retry;
|
||||
|
||||
do {
|
||||
retry = false;
|
||||
|
||||
for (dynamic_type *itr = dynamicFrames, *last = dynamicFrames + dynamicSize; itr != last; ++itr) {
|
||||
uint32_t adjust = (std::max(remaining, 0) + std::distance(itr, last) - 1) / std::distance(itr, last);
|
||||
|
||||
adjust += itr->first->m_width;
|
||||
adjust = std::max(adjust, itr->second.minWidth);
|
||||
adjust = std::min(adjust, itr->second.maxWidth);
|
||||
|
||||
remaining -= adjust - itr->first->m_width;
|
||||
|
||||
retry = retry || itr->first->m_width != adjust;
|
||||
|
||||
itr->first->m_width = adjust;
|
||||
}
|
||||
|
||||
} while (retry && remaining > 0);
|
||||
|
||||
// Use the pre-calculated frame sizes to balance the sub-frames. If
|
||||
// the frame is too small, it will set the remaining windows to zero
|
||||
// extent which will flag them as offscreen.
|
||||
|
||||
for (Frame **itr = m_container, **last = m_container + m_containerSize; itr != last; ++itr) {
|
||||
// If there is any remaining space, check if we want to shift
|
||||
// the subsequent frames to the other side of this frame.
|
||||
if (remaining > 0 && (*itr)->has_left_frame()) {
|
||||
(*itr)->m_width += remaining;
|
||||
remaining = 0;
|
||||
}
|
||||
|
||||
(*itr)->balance(x, y, std::min((*itr)->m_width, width), m_height);
|
||||
|
||||
y += (*itr)->m_width;
|
||||
width -= (*itr)->m_width;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+24
-3
@@ -45,6 +45,9 @@ class Window;
|
||||
|
||||
class Frame {
|
||||
public:
|
||||
typedef uint32_t extent_type;
|
||||
typedef uint32_t size_type;
|
||||
|
||||
enum Type {
|
||||
TYPE_NONE,
|
||||
TYPE_WINDOW,
|
||||
@@ -52,8 +55,19 @@ public:
|
||||
TYPE_COLUMN
|
||||
};
|
||||
|
||||
typedef uint32_t size_type;
|
||||
typedef std::pair<uint32_t, uint32_t> pair_type;
|
||||
struct bounds_type {
|
||||
bounds_type() {}
|
||||
bounds_type(extent_type minW, extent_type minH, extent_type maxW, extent_type maxH) :
|
||||
minWidth(minW), minHeight(minH), maxWidth(maxW), maxHeight(maxH) {}
|
||||
|
||||
extent_type minWidth;
|
||||
extent_type minHeight;
|
||||
|
||||
extent_type maxWidth;
|
||||
extent_type maxHeight;
|
||||
};
|
||||
|
||||
typedef std::pair<Frame*, bounds_type> dynamic_type;
|
||||
|
||||
static const size_type max_size = 5;
|
||||
|
||||
@@ -62,7 +76,10 @@ public:
|
||||
bool is_width_dynamic() const;
|
||||
bool is_height_dynamic() const;
|
||||
|
||||
pair_type preferred_size() const;
|
||||
bool has_left_frame() const;
|
||||
bool has_bottom_frame() const;
|
||||
|
||||
bounds_type preferred_size() const;
|
||||
|
||||
uint32_t position_x() const { return m_positionX; }
|
||||
uint32_t position_y() const { return m_positionY; }
|
||||
@@ -92,6 +109,10 @@ public:
|
||||
void balance(uint32_t x, uint32_t y, uint32_t width, uint32_t height);
|
||||
|
||||
private:
|
||||
inline void balance_window(uint32_t x, uint32_t y, uint32_t width, uint32_t height);
|
||||
inline void balance_row(uint32_t x, uint32_t y, uint32_t width, uint32_t height);
|
||||
inline void balance_column(uint32_t x, uint32_t y, uint32_t width, uint32_t height);
|
||||
|
||||
Type m_type;
|
||||
|
||||
uint32_t m_positionX;
|
||||
|
||||
@@ -77,6 +77,7 @@ Manager::unschedule(Window* w) {
|
||||
|
||||
void
|
||||
Manager::adjust_layout() {
|
||||
Canvas::redraw_std();
|
||||
m_rootFrame.balance(0, 0, Canvas::get_screen_width(), Canvas::get_screen_height());
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
// 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 <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
#ifndef RTORRENT_DISPLAY_TEXT_ELEMENT_H
|
||||
#define RTORRENT_DISPLAY_TEXT_ELEMENT_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "display/canvas.h"
|
||||
|
||||
namespace display {
|
||||
|
||||
class TextElement {
|
||||
public:
|
||||
virtual ~TextElement() {}
|
||||
|
||||
// The last element must point to a valid memory location into which
|
||||
// the caller must write a '\0' to terminate the c string. The
|
||||
// attributes must contain at least one attribute.
|
||||
virtual char* print(char* first, const char* last, Canvas::attributes_list* attributes, void* object) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,62 @@
|
||||
// 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 <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <rak/functional.h>
|
||||
|
||||
#include "text_element_list.h"
|
||||
|
||||
namespace display {
|
||||
|
||||
void
|
||||
TextElementList::clear() {
|
||||
std::for_each(begin(), end(), rak::call_delete<TextElement>());
|
||||
base_type::clear();
|
||||
}
|
||||
|
||||
char*
|
||||
TextElementList::print(char* first, const char* last, Canvas::attributes_list* attributes, void* object) {
|
||||
// Call print for each element even if first == last so that any
|
||||
// attributes gets added to the list.
|
||||
for (iterator itr = begin(); itr != end(); ++itr)
|
||||
first = (*itr)->print(first, last, attributes, object);
|
||||
|
||||
return first;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
// 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 <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
#ifndef RTORRENT_DISPLAY_TEXT_ELEMENT_LIST_H
|
||||
#define RTORRENT_DISPLAY_TEXT_ELEMENT_LIST_H
|
||||
|
||||
#include "text_element.h"
|
||||
|
||||
namespace display {
|
||||
|
||||
class TextElementList : public TextElement, public std::vector<TextElement*> {
|
||||
public:
|
||||
typedef std::vector<TextElement*> base_type;
|
||||
|
||||
typedef base_type::value_type value_type;
|
||||
typedef base_type::reference reference;
|
||||
typedef base_type::iterator iterator;
|
||||
typedef base_type::const_iterator const_iterator;
|
||||
typedef base_type::reverse_iterator reverse_iterator;
|
||||
|
||||
using base_type::empty;
|
||||
using base_type::size;
|
||||
|
||||
using base_type::begin;
|
||||
using base_type::end;
|
||||
using base_type::rbegin;
|
||||
using base_type::rend;
|
||||
|
||||
using base_type::push_back;
|
||||
|
||||
virtual ~TextElementList() { clear(); }
|
||||
|
||||
void clear();
|
||||
|
||||
virtual char* print(char* first, const char* last, Canvas::attributes_list* attributes, void* object);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,76 @@
|
||||
// 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 <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "text_element_string.h"
|
||||
|
||||
namespace display {
|
||||
|
||||
char*
|
||||
TextElementString::print(char* first, const char* last, Canvas::attributes_list* attributes, void* object) {
|
||||
size_t length = std::min<size_t>(last - first, m_string.size());
|
||||
|
||||
if (length == 0)
|
||||
return first;
|
||||
|
||||
std::memcpy(first, m_string.c_str(), length);
|
||||
|
||||
// Move this stuff into a function in TextElement.
|
||||
Attributes base = attributes->back();
|
||||
Attributes current(NULL, m_attributes, Attributes::color_invalid);
|
||||
|
||||
if (current.attributes() == Attributes::a_invalid)
|
||||
current.set_attributes(base.attributes());
|
||||
else if (current.attributes() != base.attributes())
|
||||
current.set_position(first);
|
||||
|
||||
if (current.colors() == Attributes::color_invalid)
|
||||
current.set_colors(base.colors());
|
||||
else if (current.colors() != base.colors())
|
||||
current.set_position(first);
|
||||
|
||||
if (current.position() != NULL) {
|
||||
attributes->push_back(current);
|
||||
attributes->push_back(Attributes(first + length, base.attributes(), base.colors()));
|
||||
}
|
||||
|
||||
return first + length;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
// 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 <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
#ifndef RTORRENT_DISPLAY_TEXT_ELEMENT_LIST_H
|
||||
#define RTORRENT_DISPLAY_TEXT_ELEMENT_LIST_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "text_element.h"
|
||||
|
||||
namespace display {
|
||||
|
||||
class TextElementString : public TextElement {
|
||||
public:
|
||||
TextElementString() {}
|
||||
TextElementString(const std::string& s, int attributes = Attributes::a_invalid) : m_string(s), m_attributes(attributes) {}
|
||||
|
||||
const std::string& str() const { return m_string; }
|
||||
void set_str(const std::string& s) { m_string = s; }
|
||||
|
||||
int attributes() const { return m_attributes; }
|
||||
void set_attributes(int a) { m_attributes = a; }
|
||||
|
||||
virtual char* print(char* first, const char* last, Canvas::attributes_list* attributes, void* object);
|
||||
|
||||
private:
|
||||
std::string m_string;
|
||||
int m_attributes;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -49,11 +49,15 @@ Window::Slot Window::m_slotAdjust;
|
||||
// When constructing the window we set flag_offscreen so that redraw
|
||||
// doesn't get triggered until after a successful Frame::balance call.
|
||||
|
||||
Window::Window(Canvas* canvas, int flags, extent_type minWidth, extent_type minHeight) :
|
||||
Window::Window(Canvas* canvas, int flags, extent_type minWidth, extent_type minHeight, extent_type maxWidth, extent_type maxHeight) :
|
||||
m_canvas(canvas),
|
||||
m_flags(flags | flag_offscreen),
|
||||
|
||||
m_minWidth(minWidth),
|
||||
m_minHeight(minHeight) {
|
||||
m_minHeight(minHeight),
|
||||
|
||||
m_maxWidth(maxWidth),
|
||||
m_maxHeight(maxHeight) {
|
||||
|
||||
m_taskUpdate.set_slot(rak::mem_fn(this, &Window::redraw));
|
||||
}
|
||||
|
||||
+24
-7
@@ -56,12 +56,17 @@ public:
|
||||
typedef rak::mem_fun1<Manager, void, Window*> SlotWindow;
|
||||
typedef rak::mem_fun2<Manager, void, Window*, rak::timer> SlotTimer;
|
||||
|
||||
static const int flag_active = (1 << 0);
|
||||
static const int flag_offscreen = (1 << 1);
|
||||
static const int flag_width_dynamic = (1 << 2);
|
||||
static const int flag_height_dynamic = (1 << 3);
|
||||
static const int flag_active = (1 << 0);
|
||||
static const int flag_offscreen = (1 << 1);
|
||||
static const int flag_left = (1 << 2);
|
||||
static const int flag_bottom = (1 << 3);
|
||||
|
||||
Window(Canvas* canvas, int flags, extent_type minWidth, extent_type minHeight);
|
||||
static const extent_type extent_static = extent_type();
|
||||
static const extent_type extent_full = ~extent_type();
|
||||
|
||||
Window(Canvas* canvas, int flags,
|
||||
extent_type minWidth, extent_type minHeight,
|
||||
extent_type maxWidth, extent_type maxHeight);
|
||||
|
||||
virtual ~Window();
|
||||
|
||||
@@ -71,8 +76,14 @@ public:
|
||||
bool is_offscreen() const { return m_flags & flag_offscreen; }
|
||||
void set_offscreen(bool state) { if (state) m_flags |= flag_offscreen; else m_flags &= ~flag_offscreen; }
|
||||
|
||||
bool is_width_dynamic() const { return m_flags & flag_width_dynamic; }
|
||||
bool is_height_dynamic() const { return m_flags & flag_height_dynamic; }
|
||||
bool is_left() const { return m_flags & flag_left; }
|
||||
void set_left(bool state) { if (state) m_flags |= flag_left; else m_flags &= ~flag_left; }
|
||||
|
||||
bool is_bottom() const { return m_flags & flag_bottom; }
|
||||
void set_bottom(bool state) { if (state) m_flags |= flag_bottom; else m_flags &= ~flag_bottom; }
|
||||
|
||||
bool is_width_dynamic() const { return m_maxWidth > m_minWidth; }
|
||||
bool is_height_dynamic() const { return m_maxHeight > m_minHeight; }
|
||||
|
||||
bool is_dirty() { return m_taskUpdate.is_queued(); }
|
||||
void mark_dirty() { m_slotSchedule(this, cachedTime + 1); }
|
||||
@@ -80,6 +91,9 @@ public:
|
||||
extent_type min_width() const { return m_minWidth; }
|
||||
extent_type min_height() const { return m_minHeight; }
|
||||
|
||||
extent_type max_width() const { return std::max(m_maxWidth, m_minWidth); }
|
||||
extent_type max_height() const { return std::max(m_maxHeight, m_minHeight); }
|
||||
|
||||
extent_type width() const { return m_canvas->width(); }
|
||||
extent_type height() const { return m_canvas->height(); }
|
||||
|
||||
@@ -110,6 +124,9 @@ protected:
|
||||
extent_type m_minWidth;
|
||||
extent_type m_minHeight;
|
||||
|
||||
extent_type m_maxWidth;
|
||||
extent_type m_maxHeight;
|
||||
|
||||
rak::priority_item m_taskUpdate;
|
||||
};
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
namespace display {
|
||||
|
||||
WindowDownloadChunksSeen::WindowDownloadChunksSeen(core::Download* d, unsigned int *focus) :
|
||||
Window(new Canvas, flag_width_dynamic | flag_height_dynamic, 0, 0),
|
||||
Window(new Canvas, 0, 0, 0, extent_full, extent_full),
|
||||
m_download(d),
|
||||
m_focus(focus) {
|
||||
}
|
||||
@@ -102,7 +102,7 @@ WindowDownloadChunksSeen::redraw() {
|
||||
while (itrTransfer != transferChunks.end() && (uint32_t)(chunk - seen) > (*itrTransfer)->index())
|
||||
itrTransfer++;
|
||||
|
||||
for (int y = 1; y < m_canvas->height() && chunk < last; ++y) {
|
||||
for (unsigned int y = 1; y < m_canvas->height() && chunk < last; ++y) {
|
||||
m_canvas->print(0, y, "%5u ", (int)(chunk - seen));
|
||||
|
||||
while (chunk < last) {
|
||||
|
||||
@@ -92,9 +92,9 @@ WindowDownloadList::redraw() {
|
||||
int pos = 1;
|
||||
|
||||
while (range.first != range.second) {
|
||||
char buffer[m_canvas->width()];
|
||||
char buffer[m_canvas->width() + 1];
|
||||
char* position;
|
||||
char* last = buffer + m_canvas->width() - 2;
|
||||
char* last = buffer + m_canvas->width() - 2 + 1;
|
||||
|
||||
position = print_download_title(buffer, last, *range.first);
|
||||
m_canvas->print(0, pos++, "%c %s", range.first == m_view->focus() ? '*' : ' ', buffer);
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace display {
|
||||
class WindowDownloadList : public Window {
|
||||
public:
|
||||
WindowDownloadList() :
|
||||
Window(new Canvas, flag_width_dynamic | flag_height_dynamic, 120, 1),
|
||||
Window(new Canvas, 0, 120, 1, extent_full, extent_full),
|
||||
m_view(NULL) {}
|
||||
~WindowDownloadList();
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
namespace display {
|
||||
|
||||
WindowDownloadStatusbar::WindowDownloadStatusbar(core::Download* d) :
|
||||
Window(new Canvas, flag_width_dynamic, 0, 3),
|
||||
Window(new Canvas, 0, 0, 3, extent_full, extent_static),
|
||||
m_download(d) {
|
||||
}
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
namespace display {
|
||||
|
||||
WindowDownloadTransferList::WindowDownloadTransferList(core::Download* d, unsigned int *focus) :
|
||||
Window(new Canvas, flag_width_dynamic | flag_height_dynamic, 0, 0),
|
||||
Window(new Canvas, 0, 0, 0, extent_full, extent_full),
|
||||
m_download(d),
|
||||
m_focus(focus) {
|
||||
}
|
||||
@@ -73,7 +73,7 @@ WindowDownloadTransferList::redraw() {
|
||||
// is just something i threw in there, someone really should
|
||||
// prettify this. (This is a very subtle hint)
|
||||
|
||||
for (int y = 1; y < m_canvas->height() && itr != transfers->end(); ++y, ++itr) {
|
||||
for (unsigned int y = 1; y < m_canvas->height() && itr != transfers->end(); ++y, ++itr) {
|
||||
m_canvas->print(0, y, "%5u [P: %u F: %u]", (*itr)->index(), (*itr)->priority(), (*itr)->failed());
|
||||
|
||||
// Handle window size.
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
namespace display {
|
||||
|
||||
WindowFileList::WindowFileList(core::Download* d, unsigned int* focus) :
|
||||
Window(new Canvas, flag_width_dynamic | flag_height_dynamic, 0, 0),
|
||||
Window(new Canvas, 0, 0, 0, extent_full, extent_full),
|
||||
m_download(d),
|
||||
m_focus(focus) {
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
namespace display {
|
||||
|
||||
WindowHttpQueue::WindowHttpQueue(core::HttpQueue* q) :
|
||||
Window(new Canvas, flag_width_dynamic, 0, 1),
|
||||
Window(new Canvas, 0, 0, 1, extent_full, 1),
|
||||
m_queue(q) {
|
||||
|
||||
set_active(false);
|
||||
@@ -72,7 +72,7 @@ WindowHttpQueue::redraw() {
|
||||
m_canvas->erase();
|
||||
m_canvas->print(0, 0, "Http [%i]", m_queue->size());
|
||||
|
||||
int pos = 10;
|
||||
unsigned int pos = 10;
|
||||
Container::iterator itr = m_container.begin();
|
||||
|
||||
while (itr != m_container.end() && pos + 20 < m_canvas->width()) {
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace display {
|
||||
class WindowInput : public Window {
|
||||
public:
|
||||
WindowInput() :
|
||||
Window(new Canvas, flag_width_dynamic, 0, 1),
|
||||
Window(new Canvas, 0, 0, 1, extent_full, 1),
|
||||
m_input(NULL),
|
||||
m_focus(false) {}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
namespace display {
|
||||
|
||||
WindowLog::WindowLog(core::Log* l) :
|
||||
Window(new Canvas, flag_width_dynamic, 0, 0),
|
||||
Window(new Canvas, 0, 0, 0, extent_full, extent_static),
|
||||
m_log(l) {
|
||||
|
||||
m_taskUpdate.set_slot(rak::mem_fn(this, &WindowLog::receive_update)),
|
||||
@@ -68,13 +68,13 @@ void
|
||||
WindowLog::redraw() {
|
||||
m_canvas->erase();
|
||||
|
||||
int pos = 0;
|
||||
int pos = m_canvas->height();
|
||||
|
||||
for (core::Log::iterator itr = m_log->begin(), end = find_older(); itr != end && pos < m_canvas->height(); ++itr) {
|
||||
for (core::Log::iterator itr = m_log->begin(), last = find_older(); itr != last && pos > 0; ++itr, --pos) {
|
||||
char buffer[16];
|
||||
print_hhmmss_local(buffer, buffer + 16, static_cast<time_t>(itr->first.seconds()));
|
||||
|
||||
m_canvas->print(0, pos++, "(%s) %s", buffer, itr->second.c_str());
|
||||
m_canvas->print(0, pos - 1, "(%s) %s", buffer, itr->second.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,10 +86,11 @@ WindowLog::receive_update() {
|
||||
return;
|
||||
|
||||
iterator itr = find_older();
|
||||
extent_type h = std::min(std::distance(m_log->begin(), itr), (std::iterator_traits<iterator>::difference_type)10);
|
||||
extent_type height = std::min(std::distance(m_log->begin(), itr), (std::iterator_traits<iterator>::difference_type)10);
|
||||
|
||||
if (h != m_minHeight) {
|
||||
m_minHeight = h;
|
||||
if (height != m_maxHeight) {
|
||||
m_minHeight = height != 0 ? 1 : 0;
|
||||
m_maxHeight = height;
|
||||
m_slotAdjust();
|
||||
|
||||
} else {
|
||||
@@ -98,7 +99,7 @@ WindowLog::receive_update() {
|
||||
|
||||
priority_queue_erase(&taskScheduler, &m_taskUpdate);
|
||||
|
||||
if (h != 0)
|
||||
if (height != 0)
|
||||
priority_queue_insert(&taskScheduler, &m_taskUpdate, (cachedTime + rak::timer::from_seconds(30)).round_seconds());
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
namespace display {
|
||||
|
||||
WindowLogComplete::WindowLogComplete(core::Log* l) :
|
||||
Window(new Canvas, flag_width_dynamic | flag_height_dynamic, 30, 1),
|
||||
Window(new Canvas, 0, 30, 1, extent_full, extent_full),
|
||||
m_log(l) {
|
||||
|
||||
// We're trying out scheduled tasks instead.
|
||||
@@ -65,15 +65,27 @@ void
|
||||
WindowLogComplete::redraw() {
|
||||
m_canvas->erase();
|
||||
|
||||
int pos = 0;
|
||||
if (m_canvas->width() < 16)
|
||||
return;
|
||||
|
||||
// m_canvas->print(std::max(0, (int)m_canvas->width() / 2 - 5), pos++, "*** Log ***");
|
||||
int pos = m_canvas->height();
|
||||
|
||||
for (core::Log::iterator itr = m_log->begin(), e = m_log->end(); itr != e && pos < m_canvas->height(); ++itr) {
|
||||
for (core::Log::iterator itr = m_log->begin(), last = m_log->end(); itr != last && pos > 0; ++itr) {
|
||||
char buffer[16];
|
||||
print_hhmmss_local(buffer, buffer + 16, static_cast<time_t>(itr->first.seconds()));
|
||||
|
||||
m_canvas->print(0, pos++, "(%s) %s", buffer, itr->second.c_str());
|
||||
// Use an arbitrary min width of 60 for allowing multiple
|
||||
// lines. This should ensure we don't mess up the display when the
|
||||
// screen is shrunk too much.
|
||||
unsigned int timeWidth = 3 + print_hhmmss_local(buffer, buffer + 16, static_cast<time_t>(itr->first.seconds())) - buffer;
|
||||
|
||||
unsigned int logWidth = m_canvas->width() > 60 ? (m_canvas->width() - timeWidth) : (60 - timeWidth);
|
||||
unsigned int logHeight = (itr->second.size() + logWidth - 1) / logWidth;
|
||||
|
||||
for (unsigned int j = logHeight; j > 0 && pos > 0; --j, --pos)
|
||||
if (j == 1)
|
||||
m_canvas->print(0, pos - 1, "(%s) %s", buffer, itr->second.substr(0, m_canvas->width() - timeWidth).c_str());
|
||||
else
|
||||
m_canvas->print(timeWidth, pos - 1, "%s", itr->second.substr(logWidth * (j - 1), m_canvas->width() - timeWidth).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
namespace display {
|
||||
|
||||
WindowPeerInfo::WindowPeerInfo(core::Download* d, PList* l, PList::iterator* f) :
|
||||
Window(new Canvas, flag_width_dynamic | flag_height_dynamic, 0, 0),
|
||||
Window(new Canvas, 0, 0, 0, extent_full, extent_full),
|
||||
m_download(d),
|
||||
m_list(l),
|
||||
m_focus(f) {
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
namespace display {
|
||||
|
||||
WindowPeerList::WindowPeerList(core::Download* d, PList* l, PList::iterator* f) :
|
||||
Window(new Canvas, flag_width_dynamic | flag_height_dynamic, 0, 0),
|
||||
Window(new Canvas, 0, 0, 0, extent_full, extent_full),
|
||||
m_download(d),
|
||||
m_list(l),
|
||||
m_focus(f) {
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace display {
|
||||
class WindowStatusbar : public Window {
|
||||
public:
|
||||
WindowStatusbar() :
|
||||
Window(new Canvas, flag_width_dynamic, 0, 1),
|
||||
Window(new Canvas, 0, 0, 1, extent_full, extent_static),
|
||||
m_lastTick(0) {}
|
||||
|
||||
virtual void redraw();
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
namespace display {
|
||||
|
||||
WindowStringList::WindowStringList() :
|
||||
Window(new Canvas, flag_width_dynamic | flag_height_dynamic, 0, 0) {
|
||||
Window(new Canvas, 0, 0, 0, extent_full, extent_full) {
|
||||
}
|
||||
|
||||
WindowStringList::~WindowStringList() {
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
// 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 <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <rak/functional.h>
|
||||
|
||||
#include "canvas.h"
|
||||
#include "utils.h"
|
||||
#include "window_text.h"
|
||||
|
||||
namespace display {
|
||||
|
||||
void
|
||||
WindowText::clear() {
|
||||
std::for_each(begin(), end(), rak::call_delete<TextElement>());
|
||||
base_type::clear();
|
||||
}
|
||||
|
||||
void
|
||||
WindowText::push_back(TextElement* element) {
|
||||
base_type::push_back(element);
|
||||
|
||||
// m_minHeight = size();
|
||||
m_maxHeight = size();
|
||||
|
||||
// Check if active, if so do the update thingie. Or be lazy?
|
||||
}
|
||||
|
||||
void
|
||||
WindowText::redraw() {
|
||||
m_canvas->erase();
|
||||
|
||||
unsigned int position = 0;
|
||||
|
||||
for (iterator itr = begin(); itr != end() && position < m_canvas->height(); ++itr, ++position) {
|
||||
if (*itr == NULL)
|
||||
continue;
|
||||
|
||||
char buffer[m_canvas->width() + 1];
|
||||
|
||||
// Add a print function that sets up attributes etc?
|
||||
Canvas::attributes_list attributes;
|
||||
attributes.push_back(Attributes(buffer, Attributes::a_normal, Attributes::color_default));
|
||||
|
||||
char* last = (*itr)->print(buffer, buffer + m_canvas->width(), &attributes, NULL);
|
||||
|
||||
m_canvas->print_attributes(0, position, buffer, last, &attributes);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
// 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 <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
#ifndef RTORRENT_DISPLAY_WINDOW_TEXT_H
|
||||
#define RTORRENT_DISPLAY_WINDOW_TEXT_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "text_element.h"
|
||||
#include "window.h"
|
||||
|
||||
namespace display {
|
||||
|
||||
class WindowText : public Window, public std::vector<TextElement*> {
|
||||
public:
|
||||
typedef std::vector<TextElement*> base_type;
|
||||
|
||||
typedef base_type::value_type value_type;
|
||||
typedef base_type::reference reference;
|
||||
typedef base_type::iterator iterator;
|
||||
typedef base_type::const_iterator const_iterator;
|
||||
typedef base_type::reverse_iterator reverse_iterator;
|
||||
|
||||
using base_type::empty;
|
||||
using base_type::size;
|
||||
|
||||
using base_type::begin;
|
||||
using base_type::end;
|
||||
using base_type::rbegin;
|
||||
using base_type::rend;
|
||||
|
||||
WindowText() : Window(new Canvas, 0, 0, 0, extent_full, extent_static) {}
|
||||
~WindowText() { clear(); }
|
||||
|
||||
void clear();
|
||||
|
||||
void push_back(TextElement* element);
|
||||
|
||||
virtual void redraw();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -46,7 +46,7 @@ WindowTitle::redraw() {
|
||||
m_slotSchedule(this, (cachedTime + rak::timer::from_seconds(1)).round_seconds());
|
||||
m_canvas->erase();
|
||||
|
||||
m_canvas->print(std::max(0, (m_canvas->width() - (int)m_title.size()) / 2 - 4), 0,
|
||||
m_canvas->print(std::max(0, ((int)m_canvas->width() - (int)m_title.size()) / 2 - 4), 0,
|
||||
"*** %s ***", m_title.c_str());
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace display {
|
||||
|
||||
class WindowTitle : public Window {
|
||||
public:
|
||||
WindowTitle() : Window(new Canvas, flag_width_dynamic, 0, 1) {}
|
||||
WindowTitle() : Window(new Canvas, 0, 0, 1, extent_full, extent_static) {}
|
||||
|
||||
const std::string& title() const { return m_title; }
|
||||
void set_title(const std::string& title) { m_title = title; mark_dirty(); }
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
namespace display {
|
||||
|
||||
WindowTrackerList::WindowTrackerList(core::Download* d, unsigned int* focus) :
|
||||
Window(new Canvas, flag_width_dynamic | flag_height_dynamic, 0, 0),
|
||||
Window(new Canvas, 0, 0, 0, extent_full, extent_full),
|
||||
m_download(d),
|
||||
m_focus(focus) {
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <stdexcept>
|
||||
#include <torrent/exceptions.h>
|
||||
|
||||
#include "manager.h"
|
||||
#include "bindings.h"
|
||||
@@ -51,12 +51,12 @@ Manager::erase(Bindings* b) {
|
||||
iterator itr = std::find(begin(), end(), b);
|
||||
|
||||
if (itr == end())
|
||||
throw std::logic_error("Manager::erase(...) could not find binding");
|
||||
return;
|
||||
|
||||
Base::erase(itr);
|
||||
|
||||
if (std::find(begin(), end(), b) != end())
|
||||
throw std::logic_error("Manager::erase(...) found duplicate bindings");
|
||||
throw torrent::client_error("Manager::erase(...) found duplicate bindings.");
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -14,6 +14,8 @@ libsub_ui_a_SOURCES = \
|
||||
element_file_list.h \
|
||||
element_log_complete.cc \
|
||||
element_log_complete.h \
|
||||
element_menu.cc \
|
||||
element_menu.h \
|
||||
element_peer_info.cc \
|
||||
element_peer_info.h \
|
||||
element_peer_list.cc \
|
||||
|
||||
+59
-43
@@ -51,6 +51,7 @@
|
||||
#include "download.h"
|
||||
#include "root.h"
|
||||
#include "element_file_list.h"
|
||||
#include "element_menu.h"
|
||||
#include "element_peer_info.h"
|
||||
#include "element_peer_list.h"
|
||||
#include "element_tracker_list.h"
|
||||
@@ -62,11 +63,25 @@ namespace ui {
|
||||
Download::Download(DPtr d) :
|
||||
m_download(d),
|
||||
m_state(DISPLAY_MAX_SIZE),
|
||||
|
||||
m_windowDownloadStatus(new WDownloadStatus(d)) {
|
||||
m_focusDisplay(false) {
|
||||
|
||||
m_focus = m_peers.end();
|
||||
|
||||
m_windowDownloadStatus = new WDownloadStatus(d);
|
||||
m_windowDownloadStatus->set_bottom(true);
|
||||
|
||||
ElementMenu* elementMenu = new ElementMenu;
|
||||
|
||||
elementMenu->push_back("Peer List", sigc::bind(sigc::mem_fun(this, &Download::activate_display_focus), DISPLAY_PEER_LIST));
|
||||
// elementMenu->push_back("Peer Info", sigc::bind(sigc::mem_fun(this, &Download::activate_display_focus), DISPLAY_PEER_INFO));
|
||||
elementMenu->push_back("File List", sigc::bind(sigc::mem_fun(this, &Download::activate_display_focus), DISPLAY_FILE_LIST));
|
||||
elementMenu->push_back("Tracker List", sigc::bind(sigc::mem_fun(this, &Download::activate_display_focus), DISPLAY_TRACKER_LIST));
|
||||
elementMenu->push_back("Chunks Seen", sigc::bind(sigc::mem_fun(this, &Download::activate_display_focus), DISPLAY_CHUNKS_SEEN));
|
||||
elementMenu->push_back("Transfer List", sigc::bind(sigc::mem_fun(this, &Download::activate_display_focus), DISPLAY_TRANSFER_LIST));
|
||||
|
||||
elementMenu->focus_next();
|
||||
|
||||
m_uiArray[DISPLAY_MENU] = elementMenu;
|
||||
m_uiArray[DISPLAY_PEER_LIST] = new ElementPeerList(d, &m_peers, &m_focus);
|
||||
m_uiArray[DISPLAY_PEER_INFO] = new ElementPeerInfo(d, &m_peers, &m_focus);
|
||||
m_uiArray[DISPLAY_FILE_LIST] = new ElementFileList(d);
|
||||
@@ -95,14 +110,19 @@ Download::~Download() {
|
||||
}
|
||||
|
||||
void
|
||||
Download::activate(display::Frame* frame) {
|
||||
Download::activate(display::Frame* frame, bool focus) {
|
||||
if (is_active())
|
||||
throw torrent::client_error("ui::Download::activate() called on an already activated object.");
|
||||
|
||||
control->input()->push_back(&m_bindings);
|
||||
|
||||
m_frame = frame;
|
||||
activate_display(DISPLAY_PEER_LIST);
|
||||
m_frame->initialize_row(2);
|
||||
|
||||
m_frame->frame(1)->initialize_window(m_windowDownloadStatus);
|
||||
m_windowDownloadStatus->set_active(true);
|
||||
|
||||
activate_display_menu(DISPLAY_PEER_LIST);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -112,35 +132,42 @@ Download::disable() {
|
||||
|
||||
control->input()->erase(&m_bindings);
|
||||
|
||||
activate_display(DISPLAY_MAX_SIZE);
|
||||
activate_display_focus(DISPLAY_MAX_SIZE);
|
||||
|
||||
m_windowDownloadStatus->set_active(false);
|
||||
m_frame->clear();
|
||||
|
||||
m_frame = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
Download::activate_display(Display displayType) {
|
||||
Download::activate_display(Display displayType, bool focusDisplay) {
|
||||
if (!is_active())
|
||||
throw torrent::client_error("ui::Download::activate_display(...) !is_active().");
|
||||
|
||||
if (displayType > DISPLAY_MAX_SIZE)
|
||||
throw torrent::client_error("ui::Download::activate_display(...) out of bounds");
|
||||
|
||||
if (displayType == m_state)
|
||||
if (focusDisplay == m_focusDisplay && displayType == m_state)
|
||||
return;
|
||||
|
||||
display::Frame* frame = m_frame->frame(0);
|
||||
|
||||
// Cleanup previous state.
|
||||
switch (m_state) {
|
||||
case DISPLAY_MENU:
|
||||
break;
|
||||
|
||||
case DISPLAY_PEER_LIST:
|
||||
case DISPLAY_PEER_INFO:
|
||||
case DISPLAY_FILE_LIST:
|
||||
case DISPLAY_TRACKER_LIST:
|
||||
case DISPLAY_CHUNKS_SEEN:
|
||||
case DISPLAY_TRANSFER_LIST:
|
||||
m_uiArray[DISPLAY_MENU]->disable();
|
||||
m_uiArray[m_state]->disable();
|
||||
|
||||
m_windowDownloadStatus->set_active(false);
|
||||
m_frame->frame(1)->clear();
|
||||
|
||||
m_frame->clear();
|
||||
frame->clear();
|
||||
break;
|
||||
|
||||
case DISPLAY_MAX_SIZE:
|
||||
@@ -148,21 +175,23 @@ Download::activate_display(Display displayType) {
|
||||
}
|
||||
|
||||
m_state = displayType;
|
||||
m_focusDisplay = focusDisplay;
|
||||
|
||||
// Initialize new state.
|
||||
switch (displayType) {
|
||||
case DISPLAY_MENU:
|
||||
break;
|
||||
|
||||
case DISPLAY_PEER_LIST:
|
||||
case DISPLAY_PEER_INFO:
|
||||
case DISPLAY_FILE_LIST:
|
||||
case DISPLAY_TRACKER_LIST:
|
||||
case DISPLAY_CHUNKS_SEEN:
|
||||
case DISPLAY_TRANSFER_LIST:
|
||||
m_frame->initialize_row(2);
|
||||
frame->initialize_column(2);
|
||||
|
||||
m_uiArray[displayType]->activate(m_frame->frame(0));
|
||||
|
||||
m_frame->frame(1)->initialize_window(m_windowDownloadStatus);
|
||||
m_windowDownloadStatus->set_active(true);
|
||||
m_uiArray[DISPLAY_MENU]->activate(frame->frame(0), !focusDisplay);
|
||||
m_uiArray[displayType]->activate(frame->frame(1), focusDisplay);
|
||||
break;
|
||||
|
||||
case DISPLAY_MAX_SIZE:
|
||||
@@ -185,7 +214,7 @@ Download::receive_next() {
|
||||
else
|
||||
m_focus = m_peers.begin();
|
||||
|
||||
mark_dirty();
|
||||
// mark_dirty();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -195,7 +224,7 @@ Download::receive_prev() {
|
||||
else
|
||||
m_focus = m_peers.end();
|
||||
|
||||
mark_dirty();
|
||||
// mark_dirty();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -205,7 +234,7 @@ Download::receive_disconnect_peer() {
|
||||
|
||||
m_download->download()->disconnect_peer(*m_focus);
|
||||
|
||||
mark_dirty();
|
||||
// mark_dirty();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -247,14 +276,6 @@ Download::receive_max_peers(int t) {
|
||||
m_download->download()->set_peers_max(std::max(m_download->download()->peers_max() + t, (uint32_t)5));
|
||||
}
|
||||
|
||||
void
|
||||
Download::receive_change(Display d) {
|
||||
if (d == m_state)
|
||||
return;
|
||||
|
||||
activate_display(d);
|
||||
}
|
||||
|
||||
void
|
||||
Download::receive_snub_peer() {
|
||||
if (m_focus == m_peers.end())
|
||||
@@ -262,7 +283,7 @@ Download::receive_snub_peer() {
|
||||
|
||||
m_focus->set_snubbed(!m_focus->is_snubbed());
|
||||
|
||||
mark_dirty();
|
||||
// mark_dirty();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -291,30 +312,25 @@ Download::bind_keys() {
|
||||
m_bindings['t'] = sigc::bind(sigc::mem_fun(m_download->tracker_list(), &torrent::TrackerList::manual_request), false);
|
||||
m_bindings['T'] = sigc::bind(sigc::mem_fun(m_download->tracker_list(), &torrent::TrackerList::manual_request), true);
|
||||
|
||||
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['i'] = sigc::bind(sigc::mem_fun(this, &Download::receive_change), DISPLAY_CHUNKS_SEEN);
|
||||
m_bindings['u'] = sigc::bind(sigc::mem_fun(this, &Download::receive_change), DISPLAY_TRANSFER_LIST);
|
||||
m_bindings['p'] = sigc::bind(sigc::mem_fun(this, &Download::activate_display_focus), DISPLAY_PEER_INFO);
|
||||
m_bindings['o'] = sigc::bind(sigc::mem_fun(this, &Download::activate_display_focus), DISPLAY_TRACKER_LIST);
|
||||
m_bindings['i'] = sigc::bind(sigc::mem_fun(this, &Download::activate_display_focus), DISPLAY_CHUNKS_SEEN);
|
||||
m_bindings['u'] = sigc::bind(sigc::mem_fun(this, &Download::activate_display_focus), DISPLAY_TRANSFER_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_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);
|
||||
m_uiArray[DISPLAY_PEER_LIST]->bindings()[KEY_LEFT] = sigc::bind(sigc::mem_fun(this, &Download::activate_display_focus), DISPLAY_MENU);
|
||||
m_uiArray[DISPLAY_PEER_INFO]->bindings()[KEY_LEFT] = sigc::bind(sigc::mem_fun(this, &Download::activate_display_focus), DISPLAY_MENU);
|
||||
m_uiArray[DISPLAY_FILE_LIST]->bindings()[KEY_LEFT] = sigc::bind(sigc::mem_fun(this, &Download::activate_display_focus), DISPLAY_MENU);
|
||||
m_uiArray[DISPLAY_TRACKER_LIST]->bindings()[KEY_LEFT] = sigc::bind(sigc::mem_fun(this, &Download::activate_display_focus), DISPLAY_MENU);
|
||||
m_uiArray[DISPLAY_CHUNKS_SEEN]->bindings()[KEY_LEFT] = sigc::bind(sigc::mem_fun(this, &Download::activate_display_focus), DISPLAY_MENU);
|
||||
m_uiArray[DISPLAY_TRANSFER_LIST]->bindings()[KEY_LEFT]= sigc::bind(sigc::mem_fun(this, &Download::activate_display_focus), DISPLAY_MENU);
|
||||
|
||||
// Doesn't belong here.
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+8
-5
@@ -64,6 +64,7 @@ public:
|
||||
typedef std::list<torrent::Peer> PList;
|
||||
|
||||
typedef enum {
|
||||
DISPLAY_MENU,
|
||||
DISPLAY_PEER_LIST,
|
||||
DISPLAY_PEER_INFO,
|
||||
DISPLAY_FILE_LIST,
|
||||
@@ -76,10 +77,13 @@ public:
|
||||
Download(DPtr d);
|
||||
~Download();
|
||||
|
||||
void activate(display::Frame* frame);
|
||||
void activate(display::Frame* frame, bool focus = true);
|
||||
void disable();
|
||||
|
||||
void activate_display(Display d);
|
||||
void activate_display(Display d, bool focusDisplay);
|
||||
|
||||
void activate_display_focus(Display d) { activate_display(d, true); }
|
||||
void activate_display_menu(Display d) { activate_display(d, false); }
|
||||
|
||||
void receive_next_priority();
|
||||
void receive_prev_priority();
|
||||
@@ -101,14 +105,11 @@ private:
|
||||
void receive_max_uploads(int t);
|
||||
void receive_min_peers(int t);
|
||||
void receive_max_peers(int t);
|
||||
void receive_change(Display d);
|
||||
|
||||
void receive_snub_peer();
|
||||
|
||||
void bind_keys();
|
||||
|
||||
void mark_dirty();
|
||||
|
||||
DPtr m_download;
|
||||
PList m_peers;
|
||||
PList::iterator m_focus;
|
||||
@@ -116,6 +117,8 @@ private:
|
||||
Display m_state;
|
||||
ElementBase* m_uiArray[DISPLAY_MAX_SIZE];
|
||||
|
||||
bool m_focusDisplay;
|
||||
|
||||
WDownloadStatus* m_windowDownloadStatus;
|
||||
|
||||
sigc::connection m_connPeerConnected;
|
||||
|
||||
@@ -55,7 +55,6 @@
|
||||
|
||||
#include "display/window_log.h"
|
||||
#include "display/window_title.h"
|
||||
#include "display/window_statusbar.h"
|
||||
|
||||
#include "control.h"
|
||||
#include "download.h"
|
||||
@@ -90,7 +89,7 @@ DownloadList::~DownloadList() {
|
||||
}
|
||||
|
||||
void
|
||||
DownloadList::activate(display::Frame* frame) {
|
||||
DownloadList::activate(display::Frame* frame, bool focus) {
|
||||
if (is_active())
|
||||
throw torrent::client_error("ui::DownloadList::activate() called on an already activated object");
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ public:
|
||||
DownloadList();
|
||||
~DownloadList();
|
||||
|
||||
void activate(display::Frame* frame);
|
||||
void activate(display::Frame* frame, bool focus = true);
|
||||
void disable();
|
||||
|
||||
void activate_display(Display d);
|
||||
|
||||
@@ -55,7 +55,7 @@ public:
|
||||
|
||||
input::Bindings& bindings() { return m_bindings; }
|
||||
|
||||
virtual void activate(display::Frame* frame) = 0;
|
||||
virtual void activate(display::Frame* frame, bool focus = true) = 0;
|
||||
virtual void disable() = 0;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -61,11 +61,12 @@ ElementChunksSeen::ElementChunksSeen(core::Download* d) :
|
||||
}
|
||||
|
||||
void
|
||||
ElementChunksSeen::activate(display::Frame* frame) {
|
||||
ElementChunksSeen::activate(display::Frame* frame, bool focus) {
|
||||
if (is_active())
|
||||
throw torrent::client_error("ui::ElementChunksSeen::activate(...) is_active().");
|
||||
|
||||
control->input()->push_back(&m_bindings);
|
||||
if (focus)
|
||||
control->input()->push_back(&m_bindings);
|
||||
|
||||
m_window = new WChunksSeen(m_download, &m_focus);
|
||||
m_window->set_active(true);
|
||||
|
||||
@@ -55,7 +55,7 @@ public:
|
||||
|
||||
ElementChunksSeen(core::Download* d);
|
||||
|
||||
void activate(display::Frame* frame);
|
||||
void activate(display::Frame* frame, bool focus = true);
|
||||
void disable();
|
||||
|
||||
display::Window* window();
|
||||
|
||||
@@ -83,7 +83,7 @@ ElementDownloadList::ElementDownloadList() :
|
||||
}
|
||||
|
||||
void
|
||||
ElementDownloadList::activate(display::Frame* frame) {
|
||||
ElementDownloadList::activate(display::Frame* frame, bool focus) {
|
||||
if (is_active())
|
||||
throw torrent::client_error("ui::ElementDownloadList::activate(...) is_active().");
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ public:
|
||||
|
||||
ElementDownloadList();
|
||||
|
||||
void activate(display::Frame* frame);
|
||||
void activate(display::Frame* frame, bool focus = true);
|
||||
void disable();
|
||||
|
||||
core::View* view() { return m_view; }
|
||||
|
||||
@@ -62,11 +62,12 @@ ElementFileList::ElementFileList(core::Download* d) :
|
||||
}
|
||||
|
||||
void
|
||||
ElementFileList::activate(display::Frame* frame) {
|
||||
ElementFileList::activate(display::Frame* frame, bool focus) {
|
||||
if (m_window != NULL)
|
||||
throw torrent::client_error("ui::ElementFileList::activate(...) is_active().");
|
||||
|
||||
control->input()->push_back(&m_bindings);
|
||||
if (focus)
|
||||
control->input()->push_back(&m_bindings);
|
||||
|
||||
m_window = new WFileList(m_download, &m_focus);
|
||||
m_window->set_active(true);
|
||||
|
||||
@@ -58,7 +58,7 @@ public:
|
||||
|
||||
ElementFileList(core::Download* d);
|
||||
|
||||
void activate(display::Frame* frame);
|
||||
void activate(display::Frame* frame, bool focus = true);
|
||||
void disable();
|
||||
|
||||
display::Window* window();
|
||||
|
||||
@@ -54,7 +54,7 @@ ElementLogComplete::ElementLogComplete(core::Log* l) :
|
||||
}
|
||||
|
||||
void
|
||||
ElementLogComplete::activate(display::Frame* frame) {
|
||||
ElementLogComplete::activate(display::Frame* frame, bool focus) {
|
||||
if (is_active())
|
||||
throw torrent::client_error("ui::ElementLogComplete::activate(...) is_active().");
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ public:
|
||||
|
||||
ElementLogComplete(core::Log* l);
|
||||
|
||||
void activate(display::Frame* frame);
|
||||
void activate(display::Frame* frame, bool focus = true);
|
||||
void disable();
|
||||
|
||||
display::Window* window();
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
// 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 <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <torrent/exceptions.h>
|
||||
|
||||
#include "display/frame.h"
|
||||
#include "display/window_text.h"
|
||||
#include "display/text_element_string.h"
|
||||
#include "input/manager.h"
|
||||
|
||||
#include "control.h"
|
||||
#include "element_menu.h"
|
||||
|
||||
namespace ui {
|
||||
|
||||
struct ElementMenuEntry {
|
||||
display::TextElementString* m_element;
|
||||
|
||||
ElementMenu::slot_type m_slotFocus;
|
||||
ElementMenu::slot_type m_slotSelect;
|
||||
};
|
||||
|
||||
ElementMenu::ElementMenu() :
|
||||
m_window(new WindowText),
|
||||
m_focus(focus_invalid) {
|
||||
|
||||
// Move bindings.
|
||||
m_bindings[KEY_UP] = sigc::mem_fun(this, &ElementMenu::focus_prev);
|
||||
m_bindings[KEY_DOWN] = sigc::mem_fun(this, &ElementMenu::focus_next);
|
||||
m_bindings[KEY_RIGHT] = sigc::mem_fun(this, &ElementMenu::focus_select);
|
||||
}
|
||||
|
||||
ElementMenu::~ElementMenu() {
|
||||
delete m_window;
|
||||
}
|
||||
|
||||
void
|
||||
ElementMenu::activate(display::Frame* frame, bool focus) {
|
||||
if (is_active())
|
||||
throw torrent::client_error("ui::ElementMenu::activate(...) is_active().");
|
||||
|
||||
if (focus)
|
||||
control->input()->push_back(&m_bindings);
|
||||
|
||||
m_window->set_active(true);
|
||||
|
||||
m_frame = frame;
|
||||
m_frame->initialize_window(m_window);
|
||||
}
|
||||
|
||||
void
|
||||
ElementMenu::disable() {
|
||||
if (!is_active())
|
||||
throw torrent::client_error("ui::ElementMenu::disable(...) !is_active().");
|
||||
|
||||
control->input()->erase(&m_bindings);
|
||||
|
||||
m_frame->clear();
|
||||
m_frame = NULL;
|
||||
|
||||
m_window->set_active(false);
|
||||
}
|
||||
|
||||
void
|
||||
ElementMenu::push_back(const std::string& name, const slot_type& slotSelect, const slot_type& slotFocus) {
|
||||
entry_type* entry = new entry_type;
|
||||
|
||||
entry->m_element = new display::TextElementString(name);
|
||||
entry->m_slotSelect = slotSelect;
|
||||
entry->m_slotFocus = slotFocus;
|
||||
|
||||
m_window->push_back(NULL);
|
||||
m_window->push_back(entry->m_element);
|
||||
|
||||
base_type::push_back(entry);
|
||||
|
||||
// For the moment, don't bother doing anything if the window is
|
||||
// already active.
|
||||
m_window->mark_dirty();
|
||||
}
|
||||
|
||||
void
|
||||
ElementMenu::focus_next() {
|
||||
if (empty() || (size() == 1 && m_focus == 0))
|
||||
return;
|
||||
|
||||
if (m_focus < size())
|
||||
base_type::operator[](m_focus)->m_element->set_attributes(display::Attributes::a_normal);
|
||||
|
||||
if (++m_focus >= size())
|
||||
m_focus = 0;
|
||||
|
||||
base_type::operator[](m_focus)->m_slotFocus();
|
||||
base_type::operator[](m_focus)->m_element->set_attributes(display::Attributes::a_reverse);
|
||||
|
||||
m_window->mark_dirty();
|
||||
}
|
||||
|
||||
void
|
||||
ElementMenu::focus_prev() {
|
||||
if (empty() || (size() == 1 && m_focus == 0))
|
||||
return;
|
||||
|
||||
if (m_focus < size())
|
||||
base_type::operator[](m_focus)->m_element->set_attributes(display::Attributes::a_normal);
|
||||
|
||||
if (--m_focus >= size())
|
||||
m_focus = size() - 1;
|
||||
|
||||
base_type::operator[](m_focus)->m_slotFocus();
|
||||
base_type::operator[](m_focus)->m_element->set_attributes(display::Attributes::a_reverse);
|
||||
|
||||
m_window->mark_dirty();
|
||||
}
|
||||
|
||||
void
|
||||
ElementMenu::focus_select() {
|
||||
if (m_focus >= size())
|
||||
return;
|
||||
|
||||
base_type::operator[](m_focus)->m_slotSelect();
|
||||
|
||||
m_window->mark_dirty();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
// 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 <jaris@ifi.uio.no>
|
||||
//
|
||||
// Skomakerveien 33
|
||||
// 3185 Skoppum, NORWAY
|
||||
|
||||
#ifndef RTORRENT_UI_ELEMENT_MENU_H
|
||||
#define RTORRENT_UI_ELEMENT_MENU_H
|
||||
|
||||
#include <sigc++/slot.h>
|
||||
|
||||
#include "core/download.h"
|
||||
|
||||
#include "element_base.h"
|
||||
|
||||
namespace display {
|
||||
class WindowText;
|
||||
}
|
||||
|
||||
namespace ui {
|
||||
|
||||
struct ElementMenuEntry;
|
||||
|
||||
class ElementMenu : public ElementBase, public std::vector<ElementMenuEntry*> {
|
||||
public:
|
||||
typedef ElementMenuEntry entry_type;
|
||||
typedef std::vector<entry_type*> base_type;
|
||||
typedef sigc::slot0<void> slot_type;
|
||||
|
||||
typedef display::WindowText WindowText;
|
||||
|
||||
typedef uint32_t size_type;
|
||||
|
||||
typedef base_type::value_type value_type;
|
||||
typedef base_type::reference reference;
|
||||
typedef base_type::iterator iterator;
|
||||
typedef base_type::const_iterator const_iterator;
|
||||
typedef base_type::reverse_iterator reverse_iterator;
|
||||
|
||||
using base_type::empty;
|
||||
using base_type::size;
|
||||
|
||||
static const size_type focus_invalid = ~size_type();
|
||||
|
||||
ElementMenu();
|
||||
~ElementMenu();
|
||||
|
||||
void activate(display::Frame* frame, bool focus = false);
|
||||
void disable();
|
||||
|
||||
// Consider returning a pointer that can be used to manipulate
|
||||
// entries, f.ex disabling them.
|
||||
|
||||
void push_back(const std::string& name,
|
||||
const slot_type& slotSelect = slot_type(),
|
||||
const slot_type& slotFocus = slot_type());
|
||||
|
||||
void focus_next();
|
||||
void focus_prev();
|
||||
|
||||
void focus_select();
|
||||
|
||||
private:
|
||||
WindowText* m_window;
|
||||
|
||||
size_type m_focus;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -56,11 +56,12 @@ ElementPeerInfo::ElementPeerInfo(core::Download* d, PList* l, PList::iterator* f
|
||||
}
|
||||
|
||||
void
|
||||
ElementPeerInfo::activate(display::Frame* frame) {
|
||||
ElementPeerInfo::activate(display::Frame* frame, bool focus) {
|
||||
if (is_active())
|
||||
throw torrent::client_error("ui::ElementPeerInfo::activate(...) is_active().");
|
||||
|
||||
control->input()->push_back(&m_bindings);
|
||||
if (focus)
|
||||
control->input()->push_back(&m_bindings);
|
||||
|
||||
m_window = new WPeerInfo(m_download, m_list, m_focus);
|
||||
m_window->set_active(true);
|
||||
|
||||
@@ -56,7 +56,7 @@ public:
|
||||
|
||||
ElementPeerInfo(core::Download* d, PList* l, PList::iterator* f);
|
||||
|
||||
void activate(display::Frame* frame);
|
||||
void activate(display::Frame* frame, bool focus = true);
|
||||
void disable();
|
||||
|
||||
display::Window* window();
|
||||
|
||||
@@ -55,11 +55,12 @@ ElementPeerList::ElementPeerList(core::Download* d, PList* l, PList::iterator* f
|
||||
}
|
||||
|
||||
void
|
||||
ElementPeerList::activate(display::Frame* frame) {
|
||||
ElementPeerList::activate(display::Frame* frame, bool focus) {
|
||||
if (is_active())
|
||||
throw torrent::client_error("ui::ElementPeerList::activate(...) is_active().");
|
||||
|
||||
control->input()->push_back(&m_bindings);
|
||||
if (focus)
|
||||
control->input()->push_back(&m_bindings);
|
||||
|
||||
m_window = new WPeerList(m_download, m_list, m_focus);
|
||||
m_window->set_active(true);
|
||||
@@ -82,9 +83,4 @@ ElementPeerList::disable() {
|
||||
m_window = NULL;
|
||||
}
|
||||
|
||||
display::Window*
|
||||
ElementPeerList::window() {
|
||||
return m_window;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -41,8 +41,6 @@
|
||||
|
||||
#include "element_base.h"
|
||||
|
||||
class Control;
|
||||
|
||||
namespace display {
|
||||
class WindowPeerList;
|
||||
}
|
||||
@@ -56,11 +54,9 @@ public:
|
||||
|
||||
ElementPeerList(core::Download* d, PList* l, PList::iterator* f);
|
||||
|
||||
void activate(display::Frame* frame);
|
||||
void activate(display::Frame* frame, bool focus = true);
|
||||
void disable();
|
||||
|
||||
display::Window* window();
|
||||
|
||||
private:
|
||||
core::Download* m_download;
|
||||
WPeerList* m_window;
|
||||
|
||||
@@ -51,7 +51,7 @@ ElementStringList::ElementStringList() :
|
||||
}
|
||||
|
||||
void
|
||||
ElementStringList::activate(display::Frame* frame) {
|
||||
ElementStringList::activate(display::Frame* frame, bool focus) {
|
||||
if (is_active())
|
||||
throw torrent::client_error("ui::ElementStringList::activate(...) is_active().");
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ public:
|
||||
|
||||
ElementStringList();
|
||||
|
||||
void activate(display::Frame* frame);
|
||||
void activate(display::Frame* frame, bool focus = true);
|
||||
void disable();
|
||||
|
||||
display::Window* window() { return m_window; }
|
||||
|
||||
@@ -61,11 +61,12 @@ ElementTrackerList::ElementTrackerList(core::Download* d) :
|
||||
}
|
||||
|
||||
void
|
||||
ElementTrackerList::activate(display::Frame* frame) {
|
||||
ElementTrackerList::activate(display::Frame* frame, bool focus) {
|
||||
if (m_window != NULL)
|
||||
throw torrent::client_error("ui::ElementTrackerList::activate(...) is_active().");
|
||||
|
||||
control->input()->push_back(&m_bindings);
|
||||
if (focus)
|
||||
control->input()->push_back(&m_bindings);
|
||||
|
||||
m_window = new WTrackerList(m_download, &m_focus);
|
||||
m_window->set_active(true);
|
||||
|
||||
@@ -55,7 +55,7 @@ public:
|
||||
|
||||
ElementTrackerList(core::Download* d);
|
||||
|
||||
void activate(display::Frame* frame);
|
||||
void activate(display::Frame* frame, bool focus = true);
|
||||
void disable();
|
||||
|
||||
display::Window* window();
|
||||
|
||||
@@ -61,11 +61,12 @@ ElementTransferList::ElementTransferList(core::Download* d) :
|
||||
}
|
||||
|
||||
void
|
||||
ElementTransferList::activate(display::Frame* frame) {
|
||||
ElementTransferList::activate(display::Frame* frame, bool focus) {
|
||||
if (is_active())
|
||||
throw torrent::client_error("ui::ElementTransferList::activate(...) is_active().");
|
||||
|
||||
control->input()->push_back(&m_bindings);
|
||||
if (focus)
|
||||
control->input()->push_back(&m_bindings);
|
||||
|
||||
m_window = new WTransferList(m_download, &m_focus);
|
||||
m_window->set_active(true);
|
||||
|
||||
@@ -55,7 +55,7 @@ public:
|
||||
|
||||
ElementTransferList(core::Download* d);
|
||||
|
||||
void activate(display::Frame* frame);
|
||||
void activate(display::Frame* frame, bool focus = true);
|
||||
void disable();
|
||||
|
||||
display::Window* window();
|
||||
|
||||
@@ -91,6 +91,7 @@ Root::init(Control* c) {
|
||||
|
||||
m_windowTitle->set_active(true);
|
||||
m_windowStatusbar->set_active(true);
|
||||
m_windowStatusbar->set_bottom(true);
|
||||
|
||||
setup_keys();
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
namespace utils {
|
||||
|
||||
VariableMap::~VariableMap() {
|
||||
std::for_each(base_type::begin(), base_type::end(), rak::on(rak::mem_ptr_ref(&value_type::second), rak::call_delete<Variable>()));
|
||||
std::for_each(base_type::begin(), base_type::end(), rak::on(rak::mem_ref(&value_type::second), rak::call_delete<Variable>()));
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
Reference in New Issue
Block a user