diff --git a/src/command_ui.cc b/src/command_ui.cc index 7e3b7aae7..99040d081 100644 --- a/src/command_ui.cc +++ b/src/command_ui.cc @@ -1,39 +1,3 @@ -// rTorrent - BitTorrent client -// Copyright (C) 2005-2011, Jari Sundell -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - #include "config.h" #include @@ -47,8 +11,10 @@ #include "core/manager.h" #include "core/view_manager.h" +#include "display/canvas.h" #include "ui/root.h" #include "ui/download_list.h" +#include "display/color_map.h" #include "rpc/parse.h" #include "globals.h" @@ -796,6 +762,13 @@ cmd_status_throttle_names(bool up, const torrent::Object::list_type& args) { return torrent::Object(); } +torrent::Object +apply_set_color(int color_id, const torrent::Object::string_type& color_str) { + control->object_storage()->set_str_string(display::color_vars[color_id], color_str); + display::Canvas::build_colors(); + return torrent::Object(); +} + void initialize_command_ui() { CMD2_VAR_STRING("keys.layout", "qwerty"); @@ -893,4 +866,15 @@ initialize_command_ui() { CMD2_ANY_LIST ("elapsed.less", std::bind(&apply_elapsed_less, std::placeholders::_2)); CMD2_ANY_LIST ("elapsed.greater", std::bind(&apply_elapsed_greater, std::placeholders::_2)); + + // Build set/get methods for all color definitions + for (int color_id = 1; color_id < display::RCOLOR_MAX; color_id++) { + control->object_storage()->insert_str(display::color_vars[color_id], "", rpc::object_storage::flag_string_type); + CMD2_ANY_STRING(std::string(display::color_vars[color_id]) + ".set", [color_id](const auto&, const auto& arg) { + return apply_set_color(color_id, arg); + }); + CMD2_ANY(display::color_vars[color_id], [color_id](const auto&, const auto&) { + return control->object_storage()->get_str(display::color_vars[color_id]); + }); + } } diff --git a/src/display/canvas.cc b/src/display/canvas.cc index fc24bbc3f..51cc592df 100644 --- a/src/display/canvas.cc +++ b/src/display/canvas.cc @@ -1,45 +1,9 @@ -// rTorrent - BitTorrent client -// Copyright (C) 2005-2011, Jari Sundell -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - #include "config.h" -#include #include #include #include +#include #include "rpc/parse_commands.h" @@ -48,14 +12,16 @@ namespace display { bool Canvas::m_isInitialized = false; -bool Canvas::m_isDaemon = false; +bool Canvas::m_isDaemon = false; +// Maps ncurses color IDs to a ncurses attribute int +std::unordered_map Canvas::m_attr_map = {}; Canvas::Canvas(int x, int y, int width, int height) { if (!m_isDaemon) { - m_window = newwin(height, width, y, x); + m_window = newwin(height, width, y, x); - if (m_window == NULL) - throw torrent::internal_error("Could not allocate ncurses canvas."); + if (m_window == NULL) + throw torrent::internal_error("Could not allocate ncurses canvas."); } } @@ -73,7 +39,7 @@ Canvas::print_attributes(unsigned int x, unsigned int y, const char* first, cons move(x, y); attr_t org_attr; - short org_pair; + short org_pair; wattr_get(m_window, &org_attr, &org_pair, NULL); attributes_list::const_iterator attrItr = attributes->begin(); @@ -111,6 +77,9 @@ Canvas::initialize() { if (!m_isDaemon) { initscr(); + start_color(); + use_default_colors(); + Canvas::build_colors(); raw(); noecho(); nodelay(stdscr, TRUE); @@ -119,6 +88,114 @@ Canvas::initialize() { } } +// Function wrapper for what possibly is a macro +int +get_colors() { + return COLORS; +} + +// Turns the string color definitions from the "ui.color.*" RPC +// commands into valid ncurses color pairs +void +Canvas::build_colors() { + + // This may get called early in the start process by the config + // file, so we need to delay building until initscr() has a chance + // to run + if (!m_isInitialized || m_isDaemon) + return; + + // basic color names, index maps to ncurses COLOR_* + static const char* color_names[] = { + "black", "red", "green", "yellow", "blue", "magenta", "cyan", "white"}; + + // Those hold the background colors of "odd" and "even" + int bg_odd = -1; + int bg_even = -1; + + for (int k = 1; k < RCOLOR_MAX; k++) { + init_pair(k, -1, -1); + std::string color_def = rpc::call_command_string(color_vars[k]); + if (color_def.empty()) + continue; // Use terminal default if definition is empty + + short color[2] = {-1, -1}; // fg, bg + short color_idx = 0; // 0 = fg; 1 = bg + short bright = 0; + unsigned long attr = A_NORMAL; + + // Process string as space-separated words + size_t start = 0, end = 0; + while (true) { + end = color_def.find(' ', start); + std::string word = color_def.substr(start, end - start); + + if (word == "bold") + attr |= A_BOLD; + else if (word == "standout") + attr |= A_STANDOUT; + else if (word == "underline") + attr |= A_UNDERLINE; + else if (word == "reverse") + attr |= A_REVERSE; + else if (word == "blink") + attr |= A_BLINK; + else if (word == "dim") + attr |= A_DIM; + else if (word == "on") { + color_idx = 1; + bright = 0; + } // Switch to background color + else if (word == "gray" || word == "grey") + color[color_idx] = bright ? 7 : 8; // Bright gray is white + else if (word == "bright") + bright = 8; + else if (word.find_first_not_of("0123456789") == std::string::npos) { + // Handle numeric index + short c = -1; + sscanf(word.c_str(), "%hd", &c); + color[color_idx] = c; + } else + for (short c = 0; c < 8; c++) { // Check for basic color names + if (word == color_names[c]) { + color[color_idx] = bright + c; + break; + } + } + if (end == std::string::npos) + break; + start = end + 1; + } + + // Check that fg & bg color index is valid + if ((color[0] != -1 && color[0] >= get_colors()) || (color[1] != -1 && color[1] >= get_colors())) { + char buf[33]; + sprintf(buf, "%d", get_colors()); + Canvas::cleanup(); + throw torrent::input_error(color_def + ": your terminal only supports " + buf + " colors."); + } + + m_attr_map[k] = attr; // overwrite or insert the value + init_pair(k, color[0], color[1]); + if (k == RCOLOR_EVEN) + bg_even = color[1]; + if (k == RCOLOR_ODD) + bg_odd = color[1]; + } + + // Now make copies of the basic colors with the "odd" and "even" definitions mixed in + for (int k = 1; k < RCOLOR_MAX; k++) { + short fg, bg; + pair_content(k, &fg, &bg); + + // Replace the background color, and mix in the attributes + m_attr_map[k + 1 * RCOLOR_MAX] = m_attr_map[k] | m_attr_map[RCOLOR_EVEN]; + m_attr_map[k + 2 * RCOLOR_MAX] = m_attr_map[k] | m_attr_map[RCOLOR_ODD]; + init_pair(k + 1 * RCOLOR_MAX, fg, bg == -1 ? bg_even : bg); + init_pair(k + 2 * RCOLOR_MAX, fg, bg == -1 ? bg_odd : bg); + } +} + void Canvas::cleanup() { if (!m_isInitialized) @@ -143,4 +220,4 @@ Canvas::term_size() { return std::pair(80, 24); } -} +} // namespace display diff --git a/src/display/canvas.h b/src/display/canvas.h index b324d81a2..51c73f3fc 100644 --- a/src/display/canvas.h +++ b/src/display/canvas.h @@ -1,123 +1,206 @@ -// rTorrent - BitTorrent client -// Copyright (C) 2005-2011, Jari Sundell -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - #ifndef RTORRENT_DISPLAY_CANVAS_H #define RTORRENT_DISPLAY_CANVAS_H #include +#include #include #include "attributes.h" +#include "color_map.h" namespace display { class Canvas { public: - typedef std::vector attributes_list; + typedef std::vector attributes_list; + typedef std::unordered_map attributes_map; Canvas(int x = 0, int y = 0, int width = 0, int height = 0); - ~Canvas() { if (!m_isDaemon) { delwin(m_window); } } - - void refresh() { if (!m_isDaemon) { wnoutrefresh(m_window); } } - static void refresh_std() { if (!m_isDaemon) { wnoutrefresh(stdscr); } } - void redraw() { if (!m_isDaemon) { redrawwin(m_window); } } - static void redraw_std() { if (!m_isDaemon) { redrawwin(stdscr); } } - - void resize(int w, int h) { if (!m_isDaemon) { wresize(m_window, h, w); } } - void resize(int x, int y, int w, int h); + ~Canvas() { + if (!m_isDaemon) { + delwin(m_window); + } + } - static void resize_term(int x, int y) { if (!m_isDaemon) { resizeterm(y, x); } } - static void resize_term(std::pair dim) { if (!m_isDaemon) { resizeterm(dim.second, dim.first); } } + void refresh() { + if (!m_isDaemon) { + wnoutrefresh(m_window); + } + } + static void refresh_std() { + if (!m_isDaemon) { + wnoutrefresh(stdscr); + } + } + void redraw() { + if (!m_isDaemon) { + redrawwin(m_window); + } + } + static void redraw_std() { + if (!m_isDaemon) { + redrawwin(stdscr); + } + } - unsigned int get_x() { int x, __UNUSED y; if (!m_isDaemon) { getyx(m_window, y, x); } else { x=1; } return x; } - unsigned int get_y() { int x, y; if (!m_isDaemon) { getyx(m_window, y, x); } else { y=1; } return y; } + void resize(int w, int h) { + if (!m_isDaemon) { + wresize(m_window, h, w); + } + } + void resize(int x, int y, int w, int h); - unsigned int width() { int x, __UNUSED y; if (!m_isDaemon) { getmaxyx(m_window, y, x); } else { x=80; } return x; } - unsigned int height() { int x, y; if (!m_isDaemon) { getmaxyx(m_window, y, x); } else { y=24; } return y; } + static void resize_term(int x, int y) { + if (!m_isDaemon) { + resizeterm(y, x); + } + } + static void resize_term(std::pair dim) { + if (!m_isDaemon) { + resizeterm(dim.second, dim.first); + } + } - void move(unsigned int x, unsigned int y) { if (!m_isDaemon) { wmove(m_window, y, x); } } + unsigned int get_x() { + int x, __UNUSED y; + if (!m_isDaemon) { + getyx(m_window, y, x); + } else { + x = 1; + } + return x; + } + unsigned int get_y() { + int x, y; + if (!m_isDaemon) { + getyx(m_window, y, x); + } else { + y = 1; + } + return y; + } - chtype get_background() { chtype bg=0; if (!m_isDaemon) { bg=getbkgd(m_window); } return bg; } - void set_background(chtype c) { if (!m_isDaemon) { return wbkgdset(m_window, c); } } + unsigned int width() { + int x, __UNUSED y; + if (!m_isDaemon) { + getmaxyx(m_window, y, x); + } else { + x = 80; + } + return x; + } + unsigned int height() { + int x, y; + if (!m_isDaemon) { + getmaxyx(m_window, y, x); + } else { + y = 24; + } + return y; + } - void erase() { if (!m_isDaemon) { werase(m_window); } } - static void erase_std() { if (!m_isDaemon) { werase(stdscr); } } + void move(unsigned int x, unsigned int y) { + if (!m_isDaemon) { + wmove(m_window, y, x); + } + } - void print_border(chtype ls, chtype rs, - chtype ts, chtype bs, - chtype tl, chtype tr, - chtype bl, chtype br) { if (!m_isDaemon) { wborder(m_window, ls, rs, ts, bs, tl, tr, bl, br); } } + void erase() { + if (!m_isDaemon) { + werase(m_window); + } + } + static void erase_std() { + if (!m_isDaemon) { + werase(stdscr); + } + } // The format string is non-const, but that will not be a problem // since the string shall always be a C string choosen at // compiletime. Might cause extra copying of the string? - void print(const char* str, ...); - void print(unsigned int x, unsigned int y, const char* str, ...); + void print(const char* str, ...); + void print(unsigned int x, unsigned int y, const char* str, ...); - void print_attributes(unsigned int x, unsigned int y, const char* first, const char* last, const attributes_list* attributes); + void print_attributes(unsigned int x, unsigned int y, const char* first, const char* last, const attributes_list* attributes); - void print_char(const chtype ch) { if (!m_isDaemon) { waddch(m_window, ch); } } - void print_char(unsigned int x, unsigned int y, const chtype ch) { if (!m_isDaemon) { mvwaddch(m_window, y, x, ch); } } + void print_char(const chtype ch) { + if (!m_isDaemon) { + waddch(m_window, ch); + } + } + void print_char(unsigned int x, unsigned int y, const chtype ch) { + if (!m_isDaemon) { + mvwaddch(m_window, y, x, ch); + } + } - void set_attr(unsigned int x, unsigned int y, unsigned int n, int attr, int color) { if (!m_isDaemon) { 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) { + if (!m_isDaemon) { + mvwchgat(m_window, y, x, n, attr, color, NULL); + } + } - void set_default_attributes(int attr) { if (!m_isDaemon) { (void)wattrset(m_window, attr); } } + void set_attr(unsigned int x, unsigned int y, unsigned int n, ColorKind k) { + if (!m_isDaemon) { + mvwchgat(m_window, y, x, n, m_attr_map[k], k, NULL); + } + } - // Initialize stdscr. - static void initialize(); - static void cleanup(); + void set_default_attributes(int attr) { + if (!m_isDaemon) { + (void)wattrset(m_window, attr); + } + } - static int get_screen_width() { int x, __UNUSED y; if (!m_isDaemon) { getmaxyx(stdscr, y, x); } else { x=80; } return x; } - static int get_screen_height() { int x, y; if (!m_isDaemon) { getmaxyx(stdscr, y, x); } else { y=24;} return y; } + // Initialize stdscr. + static void initialize(); + static void build_colors(); + static void cleanup(); + + static int get_screen_width() { + int x, __UNUSED y; + if (!m_isDaemon) { + getmaxyx(stdscr, y, x); + } else { + x = 80; + } + return x; + } + static int get_screen_height() { + int x, y; + if (!m_isDaemon) { + getmaxyx(stdscr, y, x); + } else { + y = 24; + } + return y; + } static std::pair term_size(); - static void do_update() { if (!m_isDaemon) { doupdate(); } } + static void do_update() { + if (!m_isDaemon) { + doupdate(); + } + } - static bool daemon() { return m_isDaemon; } + static bool daemon() { return m_isDaemon; } + + static const attributes_map& attr_map() { return m_attr_map; } private: Canvas(const Canvas&); - void operator = (const Canvas&); + void operator=(const Canvas&); + + static bool m_isInitialized; + static bool m_isDaemon; - static bool m_isInitialized; - static bool m_isDaemon; + // Maps ncurses color IDs to a ncurses attribute int + static std::unordered_map m_attr_map; - WINDOW* m_window; + WINDOW* m_window; }; inline void @@ -143,6 +226,6 @@ Canvas::print(unsigned int x, unsigned int y, const char* str, ...) { } } -} +} // namespace display #endif diff --git a/src/display/color_map.h b/src/display/color_map.h new file mode 100644 index 000000000..3a9fb1e08 --- /dev/null +++ b/src/display/color_map.h @@ -0,0 +1,48 @@ +#ifndef RTORRENT_DISPLAY_COLOR_MAP_H +#define RTORRENT_DISPLAY_COLOR_MAP_H + +#include + +#include + +namespace display { + +enum ColorKind { + RCOLOR_NCURSES_DEFAULT, // Color 0 is reserved by ncurses and cannot be changed + RCOLOR_TITLE, + RCOLOR_FOOTER, + RCOLOR_FOCUS, + RCOLOR_LABEL, + RCOLOR_INFO, + RCOLOR_ALARM, + RCOLOR_COMPLETE, + RCOLOR_SEEDING, + RCOLOR_STOPPED, + RCOLOR_QUEUED, + RCOLOR_INCOMPLETE, + RCOLOR_LEECHING, + RCOLOR_ODD, + RCOLOR_EVEN, + RCOLOR_MAX, +}; + +static const char* color_vars[RCOLOR_MAX] = { + 0, + "ui.color.title", + "ui.color.footer", + "ui.color.focus", + "ui.color.label", + "ui.color.info", + "ui.color.alarm", + "ui.color.complete", + "ui.color.seeding", + "ui.color.stopped", + "ui.color.queued", + "ui.color.incomplete", + "ui.color.leeching", + "ui.color.odd", + "ui.color.even", +}; + +} // namespace display +#endif diff --git a/src/display/window_download_list.cc b/src/display/window_download_list.cc index 6b4936d22..428b786df 100644 --- a/src/display/window_download_list.cc +++ b/src/display/window_download_list.cc @@ -1,41 +1,6 @@ -// rTorrent - BitTorrent client -// Copyright (C) 2005-2011, Jari Sundell -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - #include "config.h" +#include "display/color_map.h" #include #include "core/download.h" @@ -50,14 +15,14 @@ namespace display { WindowDownloadList::WindowDownloadList() : - Window(new Canvas, 0, 120, 1, extent_full, extent_full), - m_view(NULL) { + Window(new Canvas, 0, 120, 1, extent_full, extent_full), + m_view(NULL) { } WindowDownloadList::~WindowDownloadList() { if (m_view != NULL) m_view->signal_changed().erase(m_changed_itr); - + m_view = NULL; } @@ -72,8 +37,26 @@ WindowDownloadList::set_view(core::View* l) { m_changed_itr = m_view->signal_changed().insert(m_view->signal_changed().begin(), std::bind(&Window::mark_dirty, this)); } +// Return a pair of ints, representing a) the ncurses attributes and b) the ncurses color pair ID to use +std::pair +WindowDownloadList::get_attr_color(core::View::iterator selected) { + core::Download* item = *selected; + unsigned long focus_attr = selected == m_view->focus() ? m_canvas->attr_map().at(RCOLOR_FOCUS) : 0; + int offset = (((selected - m_view->begin_visible()) & 1) + 1) * RCOLOR_MAX; // Determine the even/odd offset for the color pair + bool active = item->is_open() && item->is_active(); + int title_color; + if (item->is_done()) + title_color = (active ? item->info()->up_rate()->rate() ? RCOLOR_SEEDING : RCOLOR_COMPLETE : RCOLOR_STOPPED) + offset; + else + title_color = (active ? item->info()->down_rate()->rate() ? RCOLOR_LEECHING : RCOLOR_INCOMPLETE : RCOLOR_QUEUED) + offset; + return std::make_pair(m_canvas->attr_map().at(title_color) | focus_attr, title_color); +} + void WindowDownloadList::redraw() { + if (m_canvas->daemon()) + return; + m_slotSchedule(this, (cachedTime + rak::timer::from_seconds(1)).round_seconds()); m_canvas->erase(); @@ -81,7 +64,7 @@ WindowDownloadList::redraw() { if (m_view == NULL) return; - m_canvas->print(0, 0, "%s", ("[View: " + m_view->name() + (m_view->get_filter_temp().is_empty() ? "" : " (filtered)") + "]").c_str()); + m_canvas->print("%s", ("[View: " + m_view->name() + (m_view->get_filter_temp().is_empty() ? "" : " (filtered)") + "]").c_str()); if (m_view->empty_visible() || m_canvas->width() < 5 || m_canvas->height() < 2) return; @@ -95,7 +78,9 @@ WindowDownloadList::redraw() { m_canvas->print(m_canvas->width() - 16, 0, "[%5d of %-5d]", item_idx + 1, m_view->size()); } - int layout_height; + m_canvas->set_attr(0, 0, -1, RCOLOR_TITLE); + + int layout_height; const std::string layout_name = rpc::call_command_string("ui.torrent_list.layout"); if (layout_name == "full") { @@ -107,12 +92,10 @@ WindowDownloadList::redraw() { return; } - typedef std::pair Range; - - Range range = rak::advance_bidirectional(m_view->begin_visible(), - m_view->focus() != m_view->end_visible() ? m_view->focus() : m_view->begin_visible(), - m_view->end_visible(), - m_canvas->height() / layout_height); + ViewRange range = rak::advance_bidirectional(m_view->begin_visible(), + m_view->focus() != m_view->end_visible() ? m_view->focus() : m_view->begin_visible(), + m_view->end_visible(), + m_canvas->height() / layout_height); // Make sure we properly fill out the last lines so it looks like // there are more torrents, yet don't hide it if we got the last one @@ -120,8 +103,8 @@ WindowDownloadList::redraw() { if (range.second != m_view->end_visible()) ++range.second; - int pos = 1; - char buffer[m_canvas->width() + 1]; + int pos = 1; + char buffer[m_canvas->width() + 1]; char* last = buffer + m_canvas->width() - 2 + 1; // Add a proper 'column info' method. @@ -134,25 +117,38 @@ WindowDownloadList::redraw() { if (layout_name == "full") { while (range.first != range.second) { + bool is_focused = range.first == m_view->focus(); + char focus_char = is_focused ? '*' : ' '; + ColorKind focus_color = is_focused ? RCOLOR_FOCUS : RCOLOR_LABEL; + auto attr_color = get_attr_color(range.first); + print_download_title(buffer, last, *range.first); - m_canvas->print(0, pos++, "%c %s", range.first == m_view->focus() ? '*' : ' ', buffer); + m_canvas->print(0, pos, "%c %s", focus_char, buffer); + m_canvas->set_attr(2, pos++, -1, attr_color.first, attr_color.second); + print_download_info_full(buffer, last, *range.first); - m_canvas->print(0, pos++, "%c %s", range.first == m_view->focus() ? '*' : ' ', buffer); + m_canvas->print(0, pos, "%c %s", focus_char, buffer); + m_canvas->set_attr(2, pos++, -1, focus_color); + print_download_status(buffer, last, *range.first); - m_canvas->print(0, pos++, "%c %s", range.first == m_view->focus() ? '*' : ' ', buffer); + m_canvas->print(0, pos, "%c %s", focus_char, buffer); + m_canvas->set_attr(2, pos++, -1, focus_color); range.first++; } } else { while (range.first != range.second) { + char focus_char = range.first == m_view->focus() ? '*' : ' '; + auto attr_color = get_attr_color(range.first); + print_download_info_compact(buffer, last, *range.first); - m_canvas->set_default_attributes(range.first == m_view->focus() ? A_REVERSE : A_NORMAL); - m_canvas->print(0, pos++, "%c %s", range.first == m_view->focus() ? '*' : ' ', buffer); + m_canvas->print(0, pos, "%c %s", focus_char, buffer); + m_canvas->set_attr(2, pos++, -1, attr_color.first, attr_color.second); range.first++; } } } -} +} // namespace display diff --git a/src/display/window_download_list.h b/src/display/window_download_list.h index 8e15cac9b..897d7c252 100644 --- a/src/display/window_download_list.h +++ b/src/display/window_download_list.h @@ -1,39 +1,3 @@ -// rTorrent - BitTorrent client -// Copyright (C) 2005-2011, Jari Sundell -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - #ifndef RTORRENT_DISPLAY_WINDOW_DOWNLOAD_LIST_H #define RTORRENT_DISPLAY_WINDOW_DOWNLOAD_LIST_H @@ -47,6 +11,7 @@ namespace display { class WindowDownloadList : public Window { public: typedef core::View::signal_void::iterator signal_void_itr; + typedef std::pair ViewRange; WindowDownloadList(); ~WindowDownloadList(); @@ -58,6 +23,7 @@ class WindowDownloadList : public Window { private: core::View* m_view; + std::pair get_attr_color(core::View::iterator selected); signal_void_itr m_changed_itr; }; diff --git a/src/display/window_download_statusbar.cc b/src/display/window_download_statusbar.cc index 284b8b54a..dfc7347da 100644 --- a/src/display/window_download_statusbar.cc +++ b/src/display/window_download_statusbar.cc @@ -1,39 +1,3 @@ -// rTorrent - BitTorrent client -// Copyright (C) 2005-2011, Jari Sundell -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - #include "config.h" #include @@ -59,6 +23,9 @@ WindowDownloadStatusbar::WindowDownloadStatusbar(core::Download* d) : void WindowDownloadStatusbar::redraw() { + if (m_canvas->daemon()) + return; + m_slotSchedule(this, (cachedTime + rak::timer::from_seconds(1)).round_seconds()); m_canvas->erase(); diff --git a/src/display/window_statusbar.cc b/src/display/window_statusbar.cc index 9592a3386..4447d5b6f 100644 --- a/src/display/window_statusbar.cc +++ b/src/display/window_statusbar.cc @@ -1,41 +1,6 @@ -// rTorrent - BitTorrent client -// Copyright (C) 2005-2011, Jari Sundell -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - #include "config.h" +#include "display/color_map.h" #include #include @@ -66,6 +31,7 @@ WindowStatusbar::redraw() { position = print_status_extra(buffer, last); m_canvas->print(m_canvas->width() - (position - buffer), 0, "%s", buffer); } + m_canvas->set_attr(0, 0, -1, RCOLOR_FOOTER); m_lastTick = control->tick(); } diff --git a/src/display/window_title.cc b/src/display/window_title.cc index 1df79adf4..a0f70f381 100644 --- a/src/display/window_title.cc +++ b/src/display/window_title.cc @@ -1,39 +1,3 @@ -// rTorrent - BitTorrent client -// Copyright (C) 2005-2011, Jari Sundell -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - #include "config.h" #include "canvas.h" @@ -43,11 +7,13 @@ namespace display { void WindowTitle::redraw() { + if (m_canvas->daemon()) + return; + m_slotSchedule(this, (cachedTime + rak::timer::from_seconds(1)).round_seconds()); m_canvas->erase(); - m_canvas->print(std::max(0, ((int)m_canvas->width() - (int)m_title.size()) / 2 - 4), 0, - "*** %s ***", m_title.c_str()); + m_canvas->print(std::max(0, ((int)m_canvas->width() - (int)m_title.size()) / 2 - 4), 0, "*** %s ***", m_title.c_str()); } -} +} // namespace display