Root/src/textdialog.cpp

1/***************************************************************************
2 * Copyright (C) 2006 by Massimiliano Torromeo *
3 * massimiliano.torromeo@gmail.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20
21#include "textdialog.h"
22
23#include "gmenu2x.h"
24#include "utilities.h"
25
26using namespace std;
27
28TextDialog::TextDialog(GMenu2X *gmenu2x, const string &title, const string &description, const string &icon, vector<string> *text)
29    : Dialog(gmenu2x)
30{
31    this->text = text;
32    this->title = title;
33    this->description = description;
34    this->icon = icon;
35    preProcess();
36}
37
38void TextDialog::preProcess() {
39    unsigned i = 0;
40    string row;
41
42    while (i<text->size()) {
43        //clean this row
44        row = trim(text->at(i));
45
46        //check if this row is not too long
47        if (gmenu2x->font->getTextWidth(row)>(int)gmenu2x->resX-15) {
48            vector<string> words;
49            split(words, row, " ");
50
51            unsigned numWords = words.size();
52            //find the maximum number of rows that can be printed on screen
53            while (gmenu2x->font->getTextWidth(row)>(int)gmenu2x->resX-15 && numWords>0) {
54                numWords--;
55                row = "";
56                for (unsigned x=0; x<numWords; x++)
57                    row += words[x] + " ";
58                row = trim(row);
59            }
60
61            //if numWords==0 then the string must be printed as-is, it cannot be split
62            if (numWords>0) {
63                //replace with the shorter version
64                text->at(i) = row;
65
66                //build the remaining text in another row
67                row = "";
68                for (unsigned x=numWords; x<words.size(); x++)
69                    row += words[x] + " ";
70                row = trim(row);
71
72                if (!row.empty())
73                    text->insert(text->begin()+i+1, row);
74            }
75        }
76        i++;
77    }
78}
79
80void TextDialog::drawText(vector<string> *text, unsigned int y,
81        unsigned int firstRow, unsigned int rowsPerPage)
82{
83    const int fontHeight = gmenu2x->font->getHeight();
84
85    for (unsigned i = firstRow; i < firstRow + rowsPerPage && i < text->size(); i++) {
86        const string &line = text->at(i);
87        int rowY = y + (i - firstRow) * fontHeight;
88        if (line == "----") { // horizontal ruler
89            rowY += fontHeight / 2;
90            gmenu2x->s->hline(5, rowY, gmenu2x->resX - 16, 255, 255, 255, 130);
91            gmenu2x->s->hline(5, rowY+1, gmenu2x->resX - 16, 0, 0, 0, 130);
92        } else {
93            gmenu2x->font->write(gmenu2x->s, line, 5, rowY);
94        }
95    }
96
97    gmenu2x->drawScrollBar(rowsPerPage, text->size(), firstRow);
98}
99
100void TextDialog::exec() {
101    bool close = false;
102
103    Surface bg(gmenu2x->bg);
104
105    //link icon
106    if (!fileExists(icon))
107        drawTitleIcon("icons/ebook.png",true,&bg);
108    else
109        drawTitleIcon(icon,false,&bg);
110    writeTitle(title,&bg);
111    writeSubTitle(description,&bg);
112
113    gmenu2x->drawButton(&bg, "start", gmenu2x->tr["Exit"],
114    gmenu2x->drawButton(&bg, "cancel", "",
115    gmenu2x->drawButton(&bg, "down", gmenu2x->tr["Scroll"],
116    gmenu2x->drawButton(&bg, "up", "", 5)-10))-10);
117
118    bg.convertToDisplayFormat();
119
120    const int fontHeight = gmenu2x->font->getHeight();
121    unsigned int contentY, contentHeight;
122    tie(contentY, contentHeight) = gmenu2x->getContentArea();
123    const unsigned rowsPerPage = contentHeight / fontHeight;
124    contentY += (contentHeight % fontHeight) / 2;
125
126    unsigned firstRow = 0;
127    while (!close) {
128        bg.blit(gmenu2x->s, 0, 0);
129        drawText(text, contentY, firstRow, rowsPerPage);
130        gmenu2x->s->flip();
131
132        switch(gmenu2x->input.waitForPressedButton()) {
133            case InputManager::UP:
134                if (firstRow > 0) firstRow--;
135                break;
136            case InputManager::DOWN:
137                if (firstRow + rowsPerPage < text->size()) firstRow++;
138                break;
139            case InputManager::ALTLEFT:
140                if (firstRow >= rowsPerPage-1) firstRow -= rowsPerPage-1;
141                else firstRow = 0;
142                break;
143            case InputManager::ALTRIGHT:
144                if (firstRow + rowsPerPage*2 -1 < text->size()) {
145                    firstRow += rowsPerPage-1;
146                } else {
147                    firstRow = max(0ul, (unsigned long) (text->size() - rowsPerPage));
148                }
149                break;
150            case InputManager::SETTINGS:
151            case InputManager::CANCEL:
152                close = true;
153                break;
154            default:
155                break;
156        }
157    }
158}
159

Archive Download this file



interactive