Root/src/browsedialog.cpp

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

Archive Download this file



interactive