Root/src/browsedialog.cpp

1#include "browsedialog.h"
2
3#include "filelister.h"
4#include "gmenu2x.h"
5#include "iconbutton.h"
6#include "surface.h"
7#include "utilities.h"
8
9using std::string;
10
11BrowseDialog::BrowseDialog(
12        GMenu2X *gmenu2x, Touchscreen &ts_,
13        const string &title, const string &subtitle)
14    : Dialog(gmenu2x)
15    , ts(ts_)
16    , title(title)
17    , subtitle(subtitle)
18    , ts_pressed(false)
19    , buttonBox(gmenu2x)
20{
21    IconButton *btn;
22
23    buttonBox.add(new IconButton(gmenu2x, ts, "skin:imgs/buttons/left.png"));
24    btn = new IconButton(gmenu2x, ts, "skin:imgs/buttons/cancel.png", gmenu2x->tr["Up one folder"]);
25    btn->setAction(BIND(&BrowseDialog::directoryUp));
26    buttonBox.add(btn);
27
28    btn = new IconButton(gmenu2x, ts, "skin:imgs/buttons/accept.png", gmenu2x->tr["Enter folder"]);
29    btn->setAction(BIND(&BrowseDialog::directoryEnter));
30    buttonBox.add(btn);
31
32    btn = new IconButton(gmenu2x, ts, "skin:imgs/buttons/start.png", gmenu2x->tr["Confirm"]);
33    btn->setAction(BIND(&BrowseDialog::confirm));
34    buttonBox.add(btn);
35
36    btn = new IconButton(gmenu2x, ts, "skin:imgs/buttons/select.png", gmenu2x->tr["Exit"]);
37    btn->setAction(BIND(&BrowseDialog::quit));
38    buttonBox.add(btn);
39
40    iconGoUp = gmenu2x->sc.skinRes("imgs/go-up.png");
41    iconFolder = gmenu2x->sc.skinRes("imgs/folder.png");
42    iconFile = gmenu2x->sc.skinRes("imgs/file.png");
43}
44
45BrowseDialog::~BrowseDialog()
46{
47}
48
49bool BrowseDialog::exec()
50{
51    if (!fl)
52        return false;
53
54    string path = fl->getPath();
55    if (path.empty() || !fileExists(path) || path.compare(0,
56                    strlen(CARD_ROOT), CARD_ROOT) != 0)
57        setPath(CARD_ROOT);
58
59    fl->browse();
60
61    const int topBarHeight = gmenu2x->skinConfInt["topBarHeight"];
62    rowHeight = gmenu2x->font->getHeight() + 1; // gp2x=15+1 / pandora=19+1
63    numRows = (gmenu2x->resY - topBarHeight - 20) / rowHeight;
64    clipRect = (SDL_Rect) {
65        0,
66        static_cast<Sint16>(topBarHeight + 1),
67        static_cast<Uint16>(gmenu2x->resX - 9),
68        static_cast<Uint16>(gmenu2x->resY - topBarHeight - 25)
69    };
70    touchRect = (SDL_Rect) {
71        2,
72        static_cast<Sint16>(topBarHeight + 4),
73        static_cast<Uint16>(gmenu2x->resX - 12),
74        clipRect.h
75    };
76
77    selected = 0;
78    close = false;
79    while (!close) {
80        if (ts.available()) ts.poll();
81
82        paint();
83
84        handleInput();
85    }
86
87    return result;
88}
89
90BrowseDialog::Action BrowseDialog::getAction(InputManager::Button button)
91{
92    switch (button) {
93        case InputManager::MENU:
94            return BrowseDialog::ACT_CLOSE;
95        case InputManager::UP:
96            return BrowseDialog::ACT_UP;
97        case InputManager::DOWN:
98            return BrowseDialog::ACT_DOWN;
99        case InputManager::ALTLEFT:
100            return BrowseDialog::ACT_SCROLLUP;
101        case InputManager::ALTRIGHT:
102            return BrowseDialog::ACT_SCROLLDOWN;
103        case InputManager::LEFT:
104        case InputManager::CANCEL:
105            return BrowseDialog::ACT_GOUP;
106        case InputManager::ACCEPT:
107            return BrowseDialog::ACT_SELECT;
108        case InputManager::SETTINGS:
109            return BrowseDialog::ACT_CONFIRM;
110        default:
111            return BrowseDialog::ACT_NONE;
112    }
113}
114
115void BrowseDialog::handleInput()
116{
117    InputManager::Button button = gmenu2x->input.waitForPressedButton();
118
119    BrowseDialog::Action action;
120    if (ts_pressed && !ts.pressed()) {
121        action = BrowseDialog::ACT_SELECT;
122        ts_pressed = false;
123    } else {
124        action = getAction(button);
125    }
126
127    if (ts.available() && ts.pressed() && !ts.inRect(touchRect)) {
128        ts_pressed = false;
129    }
130
131    if (action == BrowseDialog::ACT_SELECT && (*fl)[selected] == "..") {
132        action = BrowseDialog::ACT_GOUP;
133    }
134    switch (action) {
135    case BrowseDialog::ACT_CLOSE:
136        quit();
137        break;
138    case BrowseDialog::ACT_UP:
139        if (selected == 0)
140            selected = fl->size() - 1;
141        else
142            selected -= 1;
143        break;
144    case BrowseDialog::ACT_SCROLLUP:
145        if (selected <= numRows - 2)
146            selected = 0;
147        else
148            selected -= numRows - 2;
149        break;
150    case BrowseDialog::ACT_DOWN:
151        if (fl->size() - 1 <= selected)
152            selected = 0;
153        else
154            selected += 1;
155        break;
156    case BrowseDialog::ACT_SCROLLDOWN:
157        if (selected+(numRows-2)>=fl->size())
158            selected = fl->size()-1;
159        else
160            selected += numRows-2;
161        break;
162    case BrowseDialog::ACT_GOUP:
163        directoryUp();
164        break;
165    case BrowseDialog::ACT_SELECT:
166        if (fl->isDirectory(selected)) {
167            directoryEnter();
168            break;
169        }
170        /* Falltrough */
171    case BrowseDialog::ACT_CONFIRM:
172        confirm();
173        break;
174    default:
175        break;
176    }
177
178    buttonBox.handleTS();
179}
180
181#include <iostream>
182
183void BrowseDialog::directoryUp()
184{
185    string path = fl->getPath();
186    string::size_type p = path.rfind("/");
187
188    if (p == path.size() - 1) {
189        p = path.rfind("/", p - 1);
190    }
191
192    if (p == string::npos || path.compare(0, 1, "/") != 0 || path.length() < 2) {
193        quit();
194    } else {
195        selected = 0;
196        setPath(path.substr(0, p));
197    }
198}
199
200void BrowseDialog::directoryEnter()
201{
202    string path = fl->getPath();
203    if (path[path.size()-1] != '/') {
204        path += "/";
205    }
206
207    setPath(path + fl->at(selected));
208
209    selected = 0;
210}
211
212void BrowseDialog::confirm()
213{
214    result = true;
215    close = true;
216}
217
218void BrowseDialog::quit()
219{
220    result = false;
221    close = true;
222}
223
224void BrowseDialog::paint()
225{
226    unsigned int i, iY;
227    unsigned int firstElement, lastElement;
228    unsigned int offsetY;
229
230    gmenu2x->bg->blit(gmenu2x->s, 0, 0);
231    drawTitleIcon("icons/explorer.png", true);
232    writeTitle(title);
233    writeSubTitle(subtitle);
234
235    buttonBox.paint(5);
236
237    // TODO(MtH): I have no idea what the right value of firstElement would be,
238    // but originally it was undefined and that is never a good idea.
239    firstElement = 0;
240    if (selected>firstElement+numRows - 1) {
241        firstElement = selected-numRows + 1;
242    } else if (selected < firstElement) {
243        firstElement = selected;
244    }
245
246    //Selection
247    const int topBarHeight = gmenu2x->skinConfInt["topBarHeight"];
248    iY = topBarHeight + 1 + (selected - firstElement) * rowHeight;
249    gmenu2x->s->box(2, iY, gmenu2x->resX - 12, rowHeight - 1,
250            gmenu2x->skinConfColors[COLOR_SELECTION_BG]);
251
252    lastElement = firstElement + numRows;
253    if (lastElement > fl->size())
254        lastElement = fl->size();
255
256    offsetY = topBarHeight + 1;
257
258    //Files & Directories
259    gmenu2x->s->setClipRect(clipRect);
260    for (i = firstElement; i < lastElement; i++) {
261        Surface *icon;
262        if (fl->isDirectory(i)) {
263            if ((*fl)[i] == "..") {
264                icon = iconGoUp;
265            } else {
266                icon = iconFolder;
267            }
268        } else {
269            icon = iconFile;
270        }
271        icon->blit(gmenu2x->s, 5, offsetY);
272        gmenu2x->s->write(gmenu2x->font, (*fl)[i], 24, offsetY + 8,
273                Font::HAlignLeft, Font::VAlignMiddle);
274
275        if (ts.available() && ts.pressed()
276                && ts.inRect(touchRect.x, offsetY + 3, touchRect.w, rowHeight)) {
277            ts_pressed = true;
278            selected = i;
279        }
280
281        offsetY += rowHeight;
282    }
283    gmenu2x->s->clearClipRect();
284
285    gmenu2x->drawScrollBar(numRows,fl->size(), firstElement);
286    gmenu2x->s->flip();
287}
288

Archive Download this file



interactive