Root/src/selector.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 <SDL.h>
22#include <SDL_gfxPrimitives.h>
23
24//for browsing the filesystem
25#include <sys/stat.h>
26#include <sys/types.h>
27#include <dirent.h>
28#include <fstream>
29
30#include "menu.h"
31#include "linkapp.h"
32#include "selector.h"
33#include "filelister.h"
34#include "gmenu2x.h"
35#include "debug.h"
36
37using namespace std;
38
39Selector::Selector(GMenu2X *gmenu2x, LinkApp *link, const string &selectorDir) :
40    Dialog(gmenu2x)
41{
42    this->link = link;
43    loadAliases();
44    selRow = 0;
45    if (selectorDir=="")
46        dir = link->getSelectorDir();
47    else
48        dir = selectorDir;
49    if (dir[dir.length()-1]!='/') dir += "/";
50}
51
52int Selector::exec(int startSelection) {
53    bool close = false, result = true;
54    vector<string> screens, titles;
55
56    FileLister fl(dir, link->getSelectorBrowser());
57    fl.setFilter(link->getSelectorFilter());
58    fl.browse();
59
60    Surface bg(gmenu2x->bg);
61    drawTitleIcon(link->getIconPath(), true, &bg);
62    writeTitle(link->getTitle(), &bg);
63    writeSubTitle(link->getDescription(), &bg);
64
65    if (link->getSelectorBrowser()) {
66        gmenu2x->drawButton(&bg, "start", gmenu2x->tr["Exit"],
67        gmenu2x->drawButton(&bg, "b", gmenu2x->tr["Select a file"],
68        gmenu2x->drawButton(&bg, "x", gmenu2x->tr["Up one folder"], 5)));
69    } else {
70        gmenu2x->drawButton(&bg, "x", gmenu2x->tr["Exit"],
71        gmenu2x->drawButton(&bg, "b", gmenu2x->tr["Select a file"], 5));
72    }
73
74    Uint32 selTick = SDL_GetTicks(), curTick;
75    uint i, firstElement = 0, iY;
76
77    prepare(&fl,&screens,&titles);
78    uint selected = constrain(startSelection,0,fl.size()-1);
79
80    //Add the folder icon manually to be sure to load it with alpha support since we are going to disable it for screenshots
81    if (gmenu2x->sc.skinRes("imgs/folder.png")==NULL)
82        gmenu2x->sc.addSkinRes("imgs/folder.png");
83    gmenu2x->sc.defaultAlpha = false;
84    while (!close) {
85        bg.blit(gmenu2x->s,0,0);
86
87        if (selected>=firstElement+SELECTOR_ELEMENTS) firstElement=selected-SELECTOR_ELEMENTS+1;
88        if (selected<firstElement) firstElement=selected;
89
90        //Selection
91        iY = selected-firstElement;
92        iY = 42+(iY*16);
93        if (selected<fl.size())
94            gmenu2x->s->box(1, iY, 309, 14, gmenu2x->skinConfColors[COLOR_SELECTION_BG]);
95
96        //Screenshot
97        if (selected-fl.dirCount()<screens.size() && screens[selected-fl.dirCount()]!="") {
98            curTick = SDL_GetTicks();
99            if (curTick-selTick>200)
100                gmenu2x->sc[screens[selected-fl.dirCount()]]->blitRight(gmenu2x->s, 311, 42, 160, 160, min((curTick-selTick-200)/3,255));
101        }
102
103        //Files & Dirs
104        gmenu2x->s->setClipRect(0,41,311,179);
105        for (i=firstElement; i<fl.size() && i<firstElement+SELECTOR_ELEMENTS; i++) {
106            iY = i-firstElement;
107            if (fl.isDirectory(i)) {
108                gmenu2x->sc["imgs/folder.png"]->blit(gmenu2x->s, 4, 42+(iY*16));
109                gmenu2x->s->write(gmenu2x->font, fl[i], 21, 49+(iY*16), ASFont::HAlignLeft, ASFont::VAlignMiddle);
110            } else
111                gmenu2x->s->write(gmenu2x->font, titles[i-fl.dirCount()], 4, 49+(iY*16), ASFont::HAlignLeft, ASFont::VAlignMiddle);
112        }
113        gmenu2x->s->clearClipRect();
114
115        gmenu2x->drawScrollBar(SELECTOR_ELEMENTS,fl.size(),firstElement,42,175);
116        gmenu2x->s->flip();
117
118        switch (gmenu2x->input.waitForPressedButton()) {
119            case SETTINGS:
120                close = true;
121                result = false;
122                break;
123            case UP:
124                if (selected == 0) selected = fl.size() -1;
125                else selected -= 1;
126                selTick = SDL_GetTicks();
127                break;
128            case ALTLEFT:
129                if ((int)(selected-SELECTOR_ELEMENTS+1)<0) selected = 0;
130                else selected -= SELECTOR_ELEMENTS-1;
131                selTick = SDL_GetTicks();
132                break;
133            case DOWN:
134                if (selected+1>=fl.size()) selected = 0;
135                else selected += 1;
136                selTick = SDL_GetTicks();
137                break;
138            case ALTRIGHT:
139                if (selected+SELECTOR_ELEMENTS-1>=fl.size()) selected = fl.size()-1;
140                else selected += SELECTOR_ELEMENTS-1;
141                selTick = SDL_GetTicks();
142                break;
143            case CLEAR:
144                if (link->getSelectorBrowser()) {
145                    string::size_type p = dir.rfind("/", dir.size()-2);
146                    if (p==string::npos || dir.compare(0, 1, "/") != 0 || dir.length() < 2) {
147                        close = true;
148                        result = false;
149                    } else {
150                        dir = dir.substr(0,p+1);
151                        INFO("%s\n", dir.c_str());
152                        selected = 0;
153                        firstElement = 0;
154                        prepare(&fl,&screens,&titles);
155                    }
156                } else {
157                    close = true;
158                    result = false;
159                }
160                break;
161            case ACCEPT:
162                if (fl.isFile(selected)) {
163                    file = fl[selected];
164                    close = true;
165                } else {
166                    dir = dir+fl[selected]+"/";
167                    selected = 0;
168                    firstElement = 0;
169                    prepare(&fl,&screens,&titles);
170                }
171                break;
172            default:
173                break;
174        }
175
176        /*
177        gmenu2x->input.update();
178        if ( gmenu2x->input[ACTION_START] ) { close = true; result = false; }
179        if ( gmenu2x->input[ACTION_UP] ) {
180            if (selected==0) {
181                selected = fl.size()-1;
182            } else {
183                selected -= 1;
184            }
185            selTick = SDL_GetTicks();
186        }
187        if ( gmenu2x->input[ACTION_L] ) {
188            if ((int)(selected-SELECTOR_ELEMENTS+1)<0) {
189                selected = 0;
190            } else {
191                selected -= SELECTOR_ELEMENTS-1;
192            }
193            selTick = SDL_GetTicks();
194        }
195        if ( gmenu2x->input[ACTION_DOWN] ) {
196            if (selected+1>=fl.size()) {
197                selected = 0;
198            } else {
199                selected += 1;
200            }
201            selTick = SDL_GetTicks();
202        }
203        if ( gmenu2x->input[ACTION_R] ) {
204            if (selected+SELECTOR_ELEMENTS-1>=fl.size()) {
205                selected = fl.size()-1;
206            } else {
207                selected += SELECTOR_ELEMENTS-1;
208            }
209            selTick = SDL_GetTicks();
210        }
211        if ( gmenu2x->input[ACTION_X] ) {
212            if (link->getSelectorBrowser()) {
213                string::size_type p = dir.rfind("/", dir.size()-2);
214                if (p==string::npos || dir.compare(0, 1, "/") != 0 || dir.length() < 2) {
215                    close = true;
216                    result = false;
217                } else {
218                    dir = dir.substr(0,p+1);
219                    INFO("%s\n", dir.c_str());
220                    selected = 0;
221                    firstElement = 0;
222                    prepare(&fl,&screens,&titles);
223                }
224            } else {
225                close = true;
226                result = false;
227            }
228        }
229        if ( gmenu2x->input[ACTION_B] ) {
230            if (fl.isFile(selected)) {
231                file = fl[selected];
232                close = true;
233            } else {
234                dir = dir+fl[selected]+"/";
235                selected = 0;
236                firstElement = 0;
237                prepare(&fl,&screens,&titles);
238            }
239        }
240        */
241    }
242    gmenu2x->sc.defaultAlpha = true;
243    freeScreenshots(&screens);
244
245    return result ? (int)selected : -1;
246}
247
248void Selector::prepare(FileLister *fl, vector<string> *screens, vector<string> *titles) {
249    fl->setPath(dir);
250    freeScreenshots(screens);
251    screens->resize(fl->getFiles().size());
252    titles->resize(fl->getFiles().size());
253
254    string screendir = link->getSelectorScreens();
255    if (screendir != "" && screendir[screendir.length()-1]!='/') screendir += "/";
256
257    string noext;
258    string::size_type pos;
259    for (uint i=0; i<fl->getFiles().size(); i++) {
260        noext = fl->getFiles()[i];
261        pos = noext.rfind(".");
262        if (pos!=string::npos && pos>0)
263            noext = noext.substr(0, pos);
264        titles->at(i) = getAlias(noext);
265        if (titles->at(i)=="")
266            titles->at(i) = noext;
267
268        DEBUG("Searching for screen '%s%s.png'\n", screendir.c_str(), noext.c_str());
269
270        if (fileExists(screendir+noext+".png"))
271            screens->at(i) = screendir+noext+".png";
272        else if (fileExists(screendir+noext+".jpg"))
273            screens->at(i) = screendir+noext+".jpg";
274        else
275            screens->at(i) = "";
276    }
277}
278
279void Selector::freeScreenshots(vector<string> *screens) {
280    for (uint i=0; i<screens->size(); i++) {
281        if (screens->at(i) != "")
282            gmenu2x->sc.del(screens->at(i));
283    }
284}
285
286void Selector::loadAliases() {
287    aliases.clear();
288    if (fileExists(link->getAliasFile())) {
289        string line;
290        ifstream infile (link->getAliasFile().c_str(), ios_base::in);
291        while (getline(infile, line, '\n')) {
292            string::size_type position = line.find("=");
293            string name = trim(line.substr(0,position));
294            string value = trim(line.substr(position+1));
295            aliases[name] = value;
296        }
297        infile.close();
298    }
299}
300
301string Selector::getAlias(const string &key) {
302    unordered_map<string, string>::iterator i = aliases.find(key);
303    if (i == aliases.end())
304        return "";
305    else
306        return i->second;
307}
308

Archive Download this file



interactive