Root/
Source at commit 7b10f9448bb9965e94f9a37a59f0999e9c51e68f created 8 years 11 months ago. By Maarten ter Huurne, Suppress Clang analyzer warnings about dead assignments | |
---|---|
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 "selector.h" |
22 | |
23 | #include "debug.h" |
24 | #include "filelister.h" |
25 | #include "gmenu2x.h" |
26 | #include "linkapp.h" |
27 | #include "menu.h" |
28 | #include "surface.h" |
29 | #include "utilities.h" |
30 | |
31 | #include <SDL.h> |
32 | #include <algorithm> |
33 | |
34 | //for browsing the filesystem |
35 | #include <sys/stat.h> |
36 | #include <sys/types.h> |
37 | #include <dirent.h> |
38 | #include <fstream> |
39 | |
40 | using namespace std; |
41 | |
42 | Selector::Selector(GMenu2X& gmenu2x, LinkApp& link, const string &selectorDir) |
43 | : Dialog(gmenu2x) |
44 | , link(link) |
45 | { |
46 | dir = selectorDir.empty() ? link.getSelectorDir() : selectorDir; |
47 | if (dir[dir.length()-1]!='/') dir += "/"; |
48 | } |
49 | |
50 | int Selector::exec(int startSelection) { |
51 | const bool showDirectories = link.getSelectorBrowser(); |
52 | |
53 | FileLister fl; |
54 | fl.setShowDirectories(showDirectories); |
55 | fl.setFilter(link.getSelectorFilter()); |
56 | while (!prepare(fl) && showDirectories && dir != "/") { |
57 | // The given directory could not be opened; try parent. |
58 | dir = parentDir(dir); |
59 | } |
60 | |
61 | OffscreenSurface bg(*gmenu2x.bg); |
62 | drawTitleIcon(bg, link.getIconPath(), true); |
63 | writeTitle(bg, link.getTitle()); |
64 | writeSubTitle(bg, link.getDescription()); |
65 | |
66 | int x = 5; |
67 | if (fl.size() != 0) { |
68 | x = gmenu2x.drawButton(bg, "accept", gmenu2x.tr["Select"], x); |
69 | } |
70 | if (showDirectories) { |
71 | x = gmenu2x.drawButton(bg, "left", "", x); |
72 | x = gmenu2x.drawButton(bg, "cancel", gmenu2x.tr["Up one folder"], x); |
73 | } else { |
74 | x = gmenu2x.drawButton(bg, "cancel", "", x); |
75 | } |
76 | x = gmenu2x.drawButton(bg, "start", gmenu2x.tr["Exit"], x); |
77 | (void)x; |
78 | |
79 | unsigned int top, height; |
80 | tie(top, height) = gmenu2x.getContentArea(); |
81 | |
82 | auto folderIcon = gmenu2x.sc.skinRes("imgs/folder.png"); |
83 | |
84 | // Figure out how many items we can fit in the content area. |
85 | int lineHeight = gmenu2x.font->getLineSpacing(); |
86 | if (showDirectories && folderIcon) { |
87 | lineHeight = max(lineHeight, folderIcon->height() + 2); |
88 | } |
89 | unsigned int nb_elements = max(height / lineHeight, 1u); |
90 | // Redistribute any leftover space. |
91 | lineHeight = height / nb_elements; |
92 | top += (height - lineHeight * nb_elements) / 2; |
93 | |
94 | bg.convertToDisplayFormat(); |
95 | |
96 | unsigned int firstElement = 0; |
97 | unsigned int selected = constrain(startSelection, 0, fl.size() - 1); |
98 | |
99 | bool close = false, result = true; |
100 | while (!close) { |
101 | OutputSurface& s = *gmenu2x.s; |
102 | |
103 | bg.blit(s, 0, 0); |
104 | |
105 | if (fl.size() == 0) { |
106 | gmenu2x.font->write(s, "(" + gmenu2x.tr["no items"] + ")", |
107 | 4, top + lineHeight / 2, |
108 | Font::HAlignLeft, Font::VAlignMiddle); |
109 | } else { |
110 | if (selected >= firstElement + nb_elements) |
111 | firstElement = selected - nb_elements + 1; |
112 | if (selected < firstElement) |
113 | firstElement = selected; |
114 | |
115 | //Screenshot |
116 | if (fl.isFile(selected)) { |
117 | string path = screendir + trimExtension(fl[selected]) + ".png"; |
118 | auto screenshot = OffscreenSurface::loadImage(path, false); |
119 | if (screenshot) { |
120 | screenshot->blitRight(s, 320, 0, 320, 240, 128u); |
121 | } |
122 | } |
123 | |
124 | //Selection |
125 | int iY = top + (selected - firstElement) * lineHeight; |
126 | if (selected<fl.size()) |
127 | s.box(1, iY, 309, lineHeight, gmenu2x.skinConfColors[COLOR_SELECTION_BG]); |
128 | |
129 | //Files & Dirs |
130 | s.setClipRect(0, top, 311, height); |
131 | for (unsigned int i = firstElement; |
132 | i < fl.size() && i < firstElement + nb_elements; i++) { |
133 | iY = top + (i - firstElement) * lineHeight; |
134 | x = 4; |
135 | if (fl.isDirectory(i)) { |
136 | if (folderIcon) { |
137 | folderIcon->blit(s, |
138 | x, iY + (lineHeight - folderIcon->height()) / 2); |
139 | x += folderIcon->width() + 2; |
140 | } |
141 | gmenu2x.font->write(s, fl[i], |
142 | x, iY + lineHeight / 2, |
143 | Font::HAlignLeft, Font::VAlignMiddle); |
144 | } else { |
145 | gmenu2x.font->write(s, trimExtension(fl[i]), |
146 | x, iY + lineHeight / 2, |
147 | Font::HAlignLeft, Font::VAlignMiddle); |
148 | } |
149 | } |
150 | s.clearClipRect(); |
151 | } |
152 | |
153 | gmenu2x.drawScrollBar(nb_elements, fl.size(), firstElement); |
154 | s.flip(); |
155 | |
156 | switch (gmenu2x.input.waitForPressedButton()) { |
157 | case InputManager::SETTINGS: |
158 | close = true; |
159 | result = false; |
160 | break; |
161 | |
162 | case InputManager::UP: |
163 | if (selected == 0) selected = fl.size() -1; |
164 | else selected -= 1; |
165 | break; |
166 | |
167 | case InputManager::ALTLEFT: |
168 | if ((int)(selected - nb_elements + 1) < 0) |
169 | selected = 0; |
170 | else |
171 | selected -= nb_elements - 1; |
172 | break; |
173 | |
174 | case InputManager::DOWN: |
175 | if (selected+1>=fl.size()) selected = 0; |
176 | else selected += 1; |
177 | break; |
178 | |
179 | case InputManager::ALTRIGHT: |
180 | if (selected + nb_elements - 1 >= fl.size()) |
181 | selected = fl.size() - 1; |
182 | else |
183 | selected += nb_elements - 1; |
184 | break; |
185 | |
186 | case InputManager::CANCEL: |
187 | if (!showDirectories) { |
188 | close = true; |
189 | result = false; |
190 | break; |
191 | } |
192 | // ...fall through... |
193 | case InputManager::LEFT: |
194 | if (showDirectories) { |
195 | selected = goToParentDir(fl); |
196 | firstElement = 0; |
197 | } |
198 | break; |
199 | |
200 | case InputManager::ACCEPT: |
201 | if (fl.size() != 0) { |
202 | if (fl.isFile(selected)) { |
203 | file = fl[selected]; |
204 | close = true; |
205 | } else { |
206 | string subdir = fl[selected]; |
207 | if (subdir == "..") { |
208 | selected = goToParentDir(fl); |
209 | } else { |
210 | dir += subdir + '/'; |
211 | prepare(fl); |
212 | selected = 0; |
213 | } |
214 | firstElement = 0; |
215 | } |
216 | } |
217 | break; |
218 | |
219 | default: |
220 | break; |
221 | } |
222 | } |
223 | |
224 | return result ? (int)selected : -1; |
225 | } |
226 | |
227 | bool Selector::prepare(FileLister& fl) { |
228 | bool opened = fl.browse(dir); |
229 | |
230 | screendir = dir; |
231 | if (!screendir.empty() && screendir[screendir.length() - 1] != '/') { |
232 | screendir += "/"; |
233 | } |
234 | screendir += "previews/"; |
235 | |
236 | return opened; |
237 | } |
238 | |
239 | int Selector::goToParentDir(FileLister& fl) { |
240 | string oldDir = dir; |
241 | dir = parentDir(dir); |
242 | prepare(fl); |
243 | string oldName = oldDir.substr(dir.size(), oldDir.size() - dir.size() - 1); |
244 | auto& subdirs = fl.getDirectories(); |
245 | auto it = find(subdirs.begin(), subdirs.end(), oldName); |
246 | return it == subdirs.end() ? 0 : it - subdirs.begin(); |
247 | } |
248 |
Branches:
install_locations
master
opkrun
packages