From 1cda2772a8bd261ef8746e13e10d5d8abbe741d6 Mon Sep 17 00:00:00 2001 From: Ingo Ruhnke Date: Wed, 18 Nov 2009 01:07:51 +0000 Subject: [PATCH] Splitted supertux/textscroller.?pp SVN-Revision: 6016 --- src/object/infoblock.cpp | 1 + src/supertux/info_box.cpp | 121 +++++++++++++++++++ src/supertux/info_box.hpp | 55 +++++++++ src/supertux/info_box_line.cpp | 199 ++++++++++++++++++++++++++++++ src/supertux/info_box_line.hpp | 60 +++++++++ src/supertux/textscroller.cpp | 267 +---------------------------------------- src/supertux/textscroller.hpp | 55 +-------- 7 files changed, 438 insertions(+), 320 deletions(-) create mode 100644 src/supertux/info_box.cpp create mode 100644 src/supertux/info_box.hpp create mode 100644 src/supertux/info_box_line.cpp create mode 100644 src/supertux/info_box_line.hpp diff --git a/src/object/infoblock.cpp b/src/object/infoblock.cpp index 13ad9a2ca..475d7d34a 100644 --- a/src/object/infoblock.cpp +++ b/src/object/infoblock.cpp @@ -20,6 +20,7 @@ #include "sprite/sprite_manager.hpp" #include "supertux/object_factory.hpp" #include "supertux/sector.hpp" +#include "supertux/info_box_line.hpp" #include "util/reader.hpp" #include "video/drawing_context.hpp" diff --git a/src/supertux/info_box.cpp b/src/supertux/info_box.cpp new file mode 100644 index 000000000..323bbfc90 --- /dev/null +++ b/src/supertux/info_box.cpp @@ -0,0 +1,121 @@ +// SuperTux +// Copyright (C) 2006 Matthias Braun +// +// 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 3 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, see . + +#include "supertux/info_box.hpp" + +#include "supertux/main.hpp" +#include "supertux/info_box_line.hpp" +#include "util/log.hpp" +#include "video/drawing_context.hpp" +#include "video/surface.hpp" + +InfoBox::InfoBox(const std::string& text) : + firstline(0), + lines(), + images(), + arrow_scrollup(), + arrow_scrolldown() +{ + // Split text string lines into a vector + lines = InfoBoxLine::split(text, 400); + + try + { + // get the arrow sprites + arrow_scrollup = new Surface("images/engine/menu/scroll-up.png"); + arrow_scrolldown = new Surface("images/engine/menu/scroll-down.png"); + } + catch (std::exception& e) + { + log_warning << "Could not load scrolling images: " << e.what() << std::endl; + arrow_scrollup = 0; + arrow_scrolldown = 0; + } +} + +InfoBox::~InfoBox() +{ + for(std::vector::iterator i = lines.begin(); + i != lines.end(); i++) + delete *i; + + delete arrow_scrollup; + delete arrow_scrolldown; +} + +void +InfoBox::draw(DrawingContext& context) +{ + float x1 = SCREEN_WIDTH/2-200; + float y1 = SCREEN_HEIGHT/2-200; + float width = 400; + float height = 200; + + context.draw_filled_rect(Vector(x1, y1), Vector(width, height), + Color(0.6f, 0.7f, 0.8f, 0.5f), LAYER_GUI-1); + + float y = y1; + bool linesLeft = false; + for(size_t i = firstline; i < lines.size(); ++i) { + if(y >= y1 + height) { + linesLeft = true; + break; + } + + lines[i]->draw(context, Rect(x1, y, x1+width, y), LAYER_GUI); + y += lines[i]->get_height(); + } + + { + // draw the scrolling arrows + if (arrow_scrollup && firstline > 0) + context.draw_surface(arrow_scrollup, + Vector( x1 + width - arrow_scrollup->get_width(), // top-right corner of box + y1), LAYER_GUI); + + if (arrow_scrolldown && linesLeft && firstline < lines.size()-1) + context.draw_surface(arrow_scrolldown, + Vector( x1 + width - arrow_scrolldown->get_width(), // bottom-light corner of box + y1 + height - arrow_scrolldown->get_height()), + LAYER_GUI); + } +} + +void +InfoBox::scrollup() +{ + if(firstline > 0) + firstline--; +} + +void +InfoBox::scrolldown() +{ + if(firstline < lines.size()-1) + firstline++; +} + +void +InfoBox::pageup() +{ +} + +void +InfoBox::pagedown() +{ +} + +/* EOF */ diff --git a/src/supertux/info_box.hpp b/src/supertux/info_box.hpp new file mode 100644 index 000000000..190617a4a --- /dev/null +++ b/src/supertux/info_box.hpp @@ -0,0 +1,55 @@ +// SuperTux +// Copyright (C) 2006 Matthias Braun +// +// 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 3 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, see . + +#ifndef HEADER_SUPERTUX_SUPERTUX_INFO_BOX_HPP +#define HEADER_SUPERTUX_SUPERTUX_INFO_BOX_HPP + +#include +#include +#include + +class DrawingContext; +class InfoBoxLine; +class Surface; + +/** This class is displaying a box with information text inside the game */ +class InfoBox +{ +public: + InfoBox(const std::string& text); + ~InfoBox(); + + void draw(DrawingContext& context); + void scrolldown(); + void scrollup(); + void pagedown(); + void pageup(); + +private: + size_t firstline; + std::vector lines; + std::map images; + Surface* arrow_scrollup; + Surface* arrow_scrolldown; + +private: + InfoBox(const InfoBox&); + InfoBox& operator=(const InfoBox&); +}; + +#endif + +/* EOF */ diff --git a/src/supertux/info_box_line.cpp b/src/supertux/info_box_line.cpp new file mode 100644 index 000000000..c4142524e --- /dev/null +++ b/src/supertux/info_box_line.cpp @@ -0,0 +1,199 @@ +// SuperTux +// Copyright (C) 2006 Matthias Braun +// +// 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 3 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, see . + +#include "supertux/info_box_line.hpp" + +#include "supertux/textscroller.hpp" +#include "supertux/resources.hpp" +#include "video/drawing_context.hpp" +#include "video/font.hpp" +#include "video/surface.hpp" + +static const float ITEMS_SPACE = 4; + +namespace { + +Font* get_font_by_format_char(char format_char) { + switch(format_char) + { + case ' ': + return small_font; + break; + case '-': + return big_font; + break; + case '\t': + case '*': + case '#': + case '!': + return normal_font; + break; + default: + return normal_font; + log_warning << "Unknown format_char: '" << format_char << "'" << std::endl; + break; + } +} + +Color get_color_by_format_char(char format_char) { + switch(format_char) + { + case ' ': + return TextScroller::small_color; + break; + case '-': + return TextScroller::heading_color; + break; + case '*': + return TextScroller::reference_color; + case '\t': + case '#': + case '!': + return TextScroller::normal_color; + break; + default: + return Color(0,0,0); + log_warning << "Unknown format_char: '" << format_char << "'" << std::endl; + break; + } +} + +InfoBoxLine::LineType get_linetype_by_format_char(char format_char) { + switch(format_char) + { + case ' ': + return InfoBoxLine::SMALL; + break; + case '\t': + return InfoBoxLine::NORMAL; + break; + case '-': + return InfoBoxLine::HEADING; + break; + case '*': + return InfoBoxLine::REFERENCE; + break; + case '#': + return InfoBoxLine::NORMAL_LEFT; + break; + case '!': + return InfoBoxLine::IMAGE; + break; + default: + return InfoBoxLine::SMALL; + log_warning << "Unknown format_char: '" << format_char << "'" << std::endl; + break; + } +} + +} // namespace + +InfoBoxLine::InfoBoxLine(char format_char, const std::string& text) : + lineType(NORMAL), + font(normal_font), + color(), + text(text), + image(0) +{ + font = get_font_by_format_char(format_char); + lineType = get_linetype_by_format_char(format_char); + color = get_color_by_format_char(format_char); + if (lineType == IMAGE) image = new Surface(text); +} + +InfoBoxLine::~InfoBoxLine() +{ + delete image; +} + +const std::vector +InfoBoxLine::split(const std::string& text, float width) +{ + std::vector lines; + + std::string::size_type i = 0; + std::string::size_type l; + char format_char = '#'; + while(i < text.size()) { + // take care of empty lines - represent them as blank lines of normal text + if (text[i] == '\n') { + lines.push_back(new InfoBoxLine('\t', "")); + i++; + continue; + } + + // extract the format_char + format_char = text[i]; + i++; + if (i >= text.size()) break; + + // extract one line + l = text.find("\n", i); + if (l == std::string::npos) l=text.size(); + std::string s = text.substr(i, l-i); + i = l+1; + + // if we are dealing with an image, just store the line + if (format_char == '!') { + lines.push_back(new InfoBoxLine(format_char, s)); + continue; + } + + // append wrapped parts of line into list + std::string overflow; + do { + Font* font = get_font_by_format_char(format_char); + std::string s2 = s; + if (font) s2 = font->wrap_to_width(s2, width, &overflow); + lines.push_back(new InfoBoxLine(format_char, s2)); + s = overflow; + } while (s.length() > 0); + } + + return lines; +} + +void +InfoBoxLine::draw(DrawingContext& context, const Rect& bbox, int layer) +{ + Vector position = bbox.p1; + switch (lineType) { + case IMAGE: + context.draw_surface(image, Vector( (bbox.p1.x + bbox.p2.x - image->get_width()) / 2, position.y), layer); + break; + case NORMAL_LEFT: + context.draw_text(font, text, Vector(position.x, position.y), ALIGN_LEFT, layer, color); + break; + default: + context.draw_text(font, text, Vector((bbox.p1.x + bbox.p2.x) / 2, position.y), ALIGN_CENTER, layer, color); + break; + } +} + +float +InfoBoxLine::get_height() +{ + switch (lineType) { + case IMAGE: + return image->get_height() + ITEMS_SPACE; + case NORMAL_LEFT: + return font->get_height() + ITEMS_SPACE; + default: + return font->get_height() + ITEMS_SPACE; + } +} + +/* EOF */ diff --git a/src/supertux/info_box_line.hpp b/src/supertux/info_box_line.hpp new file mode 100644 index 000000000..ac1f07982 --- /dev/null +++ b/src/supertux/info_box_line.hpp @@ -0,0 +1,60 @@ +// SuperTux +// Copyright (C) 2006 Matthias Braun +// +// 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 3 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, see . + +#ifndef HEADER_SUPERTUX_SUPERTUX_INFO_BOX_LINE_HPP +#define HEADER_SUPERTUX_SUPERTUX_INFO_BOX_LINE_HPP + +#include +#include + +#include "video/color.hpp" + +class DrawingContext; +class Font; +class Rect; +class Surface; + +/** + * Helper class for InfoBox: Represents a line of text + */ +class InfoBoxLine +{ +public: + enum LineType { NORMAL, NORMAL_LEFT, SMALL, HEADING, REFERENCE, IMAGE}; + + InfoBoxLine(char format_char, const std::string& text); + ~InfoBoxLine(); + + void draw(DrawingContext& context, const Rect& bbox, int layer); + float get_height(); + + static const std::vector split(const std::string& text, float width); + +private: + InfoBoxLine::LineType lineType; + Font* font; + Color color; + std::string text; + Surface* image; + +private: + InfoBoxLine(const InfoBoxLine&); + InfoBoxLine& operator=(const InfoBoxLine&); +}; + +#endif + +/* EOF */ diff --git a/src/supertux/textscroller.cpp b/src/supertux/textscroller.cpp index db7dd4e19..84f0737a5 100644 --- a/src/supertux/textscroller.cpp +++ b/src/supertux/textscroller.cpp @@ -21,6 +21,7 @@ #include "lisp/lisp.hpp" #include "lisp/parser.hpp" #include "supertux/fadeout.hpp" +#include "supertux/info_box_line.hpp" #include "supertux/main.hpp" #include "supertux/mainloop.hpp" #include "supertux/resources.hpp" @@ -29,7 +30,6 @@ static const float DEFAULT_SPEED = 20; static const float LEFT_BORDER = 50; static const float SCROLL = 60; -static const float ITEMS_SPACE = 4; TextScroller::TextScroller(const std::string& filename) : defaultspeed(), @@ -133,269 +133,4 @@ TextScroller::draw(DrawingContext& context) } } -InfoBox::InfoBox(const std::string& text) : - firstline(0), - lines(), - images(), - arrow_scrollup(), - arrow_scrolldown() -{ - // Split text string lines into a vector - lines = InfoBoxLine::split(text, 400); - - try - { - // get the arrow sprites - arrow_scrollup = new Surface("images/engine/menu/scroll-up.png"); - arrow_scrolldown = new Surface("images/engine/menu/scroll-down.png"); - } - catch (std::exception& e) - { - log_warning << "Could not load scrolling images: " << e.what() << std::endl; - arrow_scrollup = 0; - arrow_scrolldown = 0; - } -} - -InfoBox::~InfoBox() -{ - for(std::vector::iterator i = lines.begin(); - i != lines.end(); i++) - delete *i; - delete arrow_scrollup; - delete arrow_scrolldown; -} - -void -InfoBox::draw(DrawingContext& context) -{ - float x1 = SCREEN_WIDTH/2-200; - float y1 = SCREEN_HEIGHT/2-200; - float width = 400; - float height = 200; - - context.draw_filled_rect(Vector(x1, y1), Vector(width, height), - Color(0.6f, 0.7f, 0.8f, 0.5f), LAYER_GUI-1); - - float y = y1; - bool linesLeft = false; - for(size_t i = firstline; i < lines.size(); ++i) { - if(y >= y1 + height) { - linesLeft = true; - break; - } - - lines[i]->draw(context, Rect(x1, y, x1+width, y), LAYER_GUI); - y += lines[i]->get_height(); - } - - { - // draw the scrolling arrows - if (arrow_scrollup && firstline > 0) - context.draw_surface(arrow_scrollup, - Vector( x1 + width - arrow_scrollup->get_width(), // top-right corner of box - y1), LAYER_GUI); - - if (arrow_scrolldown && linesLeft && firstline < lines.size()-1) - context.draw_surface(arrow_scrolldown, - Vector( x1 + width - arrow_scrolldown->get_width(), // bottom-light corner of box - y1 + height - arrow_scrolldown->get_height()), - LAYER_GUI); - } -} - -void -InfoBox::scrollup() -{ - if(firstline > 0) - firstline--; -} - -void -InfoBox::scrolldown() -{ - if(firstline < lines.size()-1) - firstline++; -} - -void -InfoBox::pageup() -{ -} - -void -InfoBox::pagedown() -{ -} - -namespace { -Font* get_font_by_format_char(char format_char) { - switch(format_char) - { - case ' ': - return small_font; - break; - case '-': - return big_font; - break; - case '\t': - case '*': - case '#': - case '!': - return normal_font; - break; - default: - return normal_font; - log_warning << "Unknown format_char: '" << format_char << "'" << std::endl; - break; - } -} - -Color get_color_by_format_char(char format_char) { - switch(format_char) - { - case ' ': - return TextScroller::small_color; - break; - case '-': - return TextScroller::heading_color; - break; - case '*': - return TextScroller::reference_color; - case '\t': - case '#': - case '!': - return TextScroller::normal_color; - break; - default: - return Color(0,0,0); - log_warning << "Unknown format_char: '" << format_char << "'" << std::endl; - break; - } -} - -InfoBoxLine::LineType get_linetype_by_format_char(char format_char) { - switch(format_char) - { - case ' ': - return InfoBoxLine::SMALL; - break; - case '\t': - return InfoBoxLine::NORMAL; - break; - case '-': - return InfoBoxLine::HEADING; - break; - case '*': - return InfoBoxLine::REFERENCE; - break; - case '#': - return InfoBoxLine::NORMAL_LEFT; - break; - case '!': - return InfoBoxLine::IMAGE; - break; - default: - return InfoBoxLine::SMALL; - log_warning << "Unknown format_char: '" << format_char << "'" << std::endl; - break; - } -} -} - -InfoBoxLine::InfoBoxLine(char format_char, const std::string& text) : - lineType(NORMAL), - font(normal_font), - color(), - text(text), - image(0) -{ - font = get_font_by_format_char(format_char); - lineType = get_linetype_by_format_char(format_char); - color = get_color_by_format_char(format_char); - if (lineType == IMAGE) image = new Surface(text); -} - -InfoBoxLine::~InfoBoxLine() -{ - delete image; -} - -const std::vector -InfoBoxLine::split(const std::string& text, float width) -{ - std::vector lines; - - std::string::size_type i = 0; - std::string::size_type l; - char format_char = '#'; - while(i < text.size()) { - // take care of empty lines - represent them as blank lines of normal text - if (text[i] == '\n') { - lines.push_back(new InfoBoxLine('\t', "")); - i++; - continue; - } - - // extract the format_char - format_char = text[i]; - i++; - if (i >= text.size()) break; - - // extract one line - l = text.find("\n", i); - if (l == std::string::npos) l=text.size(); - std::string s = text.substr(i, l-i); - i = l+1; - - // if we are dealing with an image, just store the line - if (format_char == '!') { - lines.push_back(new InfoBoxLine(format_char, s)); - continue; - } - - // append wrapped parts of line into list - std::string overflow; - do { - Font* font = get_font_by_format_char(format_char); - std::string s2 = s; - if (font) s2 = font->wrap_to_width(s2, width, &overflow); - lines.push_back(new InfoBoxLine(format_char, s2)); - s = overflow; - } while (s.length() > 0); - } - - return lines; -} - -void -InfoBoxLine::draw(DrawingContext& context, const Rect& bbox, int layer) -{ - Vector position = bbox.p1; - switch (lineType) { - case IMAGE: - context.draw_surface(image, Vector( (bbox.p1.x + bbox.p2.x - image->get_width()) / 2, position.y), layer); - break; - case NORMAL_LEFT: - context.draw_text(font, text, Vector(position.x, position.y), ALIGN_LEFT, layer, color); - break; - default: - context.draw_text(font, text, Vector((bbox.p1.x + bbox.p2.x) / 2, position.y), ALIGN_CENTER, layer, color); - break; - } -} - -float -InfoBoxLine::get_height() -{ - switch (lineType) { - case IMAGE: - return image->get_height() + ITEMS_SPACE; - case NORMAL_LEFT: - return font->get_height() + ITEMS_SPACE; - default: - return font->get_height() + ITEMS_SPACE; - } -} - /* EOF */ diff --git a/src/supertux/textscroller.hpp b/src/supertux/textscroller.hpp index fca80d764..da4bc6530 100644 --- a/src/supertux/textscroller.hpp +++ b/src/supertux/textscroller.hpp @@ -26,60 +26,7 @@ class DrawingContext; class Surface; class Font; - -/** - * Helper class for InfoBox: Represents a line of text - */ -class InfoBoxLine -{ -public: - enum LineType { NORMAL, NORMAL_LEFT, SMALL, HEADING, REFERENCE, IMAGE}; - - InfoBoxLine(char format_char, const std::string& text); - ~InfoBoxLine(); - - void draw(DrawingContext& context, const Rect& bbox, int layer); - float get_height(); - - static const std::vector split(const std::string& text, float width); - -private: - InfoBoxLine::LineType lineType; - Font* font; - Color color; - std::string text; - Surface* image; - -private: - InfoBoxLine(const InfoBoxLine&); - InfoBoxLine& operator=(const InfoBoxLine&); -}; - -/** This class is displaying a box with information text inside the game - */ -class InfoBox -{ -public: - InfoBox(const std::string& text); - ~InfoBox(); - - void draw(DrawingContext& context); - void scrolldown(); - void scrollup(); - void pagedown(); - void pageup(); - -private: - size_t firstline; - std::vector lines; - std::map images; - Surface* arrow_scrollup; - Surface* arrow_scrolldown; - -private: - InfoBox(const InfoBox&); - InfoBox& operator=(const InfoBox&); -}; +class InfoBoxLine; /** * Screen that displays intro text, extro text, etc. -- 2.11.0