-InfoBox::InfoBox(const std::string& text)
- : firstline(0)
-{
- // 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<InfoBoxLine*>::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),
- 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*>
-InfoBoxLine::split(const std::string& text, float width)
-{
- std::vector<InfoBoxLine*> 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;
- }
-}
-