1 #include "key.h"
2
3
4 // File Key Entry
5 // a string for the file ext and a colour
6
FileKeyEntry(const FXFont & font,const std::string & ext,const vec3 & colour)7 FileKeyEntry::FileKeyEntry(const FXFont& font, const std::string& ext, const vec3& colour) {
8 this->ext = ext;
9 this->colour = colour;
10 this->pos_y = -1.0f;
11
12 this->font = font;
13 this->font.dropShadow(false);
14
15 shadow = vec2(3.0, 3.0);
16
17 width = 90.0f;
18 height = 18.0f;
19 left_margin = 20.0f;
20 count = 0;
21 brightness = 1.0f;
22 alpha = 0.0f;
23
24 move_elapsed = 1.0f;
25 src_y = -1.0f;
26 dest_y = -1.0f;
27
28 show = true;
29
30 display_ext = ext;
31
32 bool truncated = false;
33
34 while(font.getWidth(display_ext) > width - 15.0f) {
35 display_ext.resize(display_ext.size()-1);
36 truncated = true;
37 }
38
39 if(truncated) {
40 display_ext += std::string("...");
41 }
42 }
43
getColour() const44 const vec3& FileKeyEntry::getColour() const {
45 return colour;
46 }
47
getExt() const48 const std::string& FileKeyEntry::getExt() const {
49 return ext;
50 }
51
setShow(bool show)52 void FileKeyEntry::setShow(bool show) {
53 this->show = show;
54 }
55
isFinished() const56 bool FileKeyEntry::isFinished() const {
57 return (count<=0 && alpha <= 0.0f);
58 }
59
colourize()60 void FileKeyEntry::colourize() {
61 colour = ext.empty() ? vec3(1.0f, 1.0f, 1.0f) : colourHash(ext);
62 }
63
inc()64 void FileKeyEntry::inc() {
65 count++;
66 }
67
dec()68 void FileKeyEntry::dec() {
69 count--;
70 }
71
getCount() const72 int FileKeyEntry::getCount() const {
73 return count;
74 }
75
setCount(int count)76 void FileKeyEntry::setCount(int count) {
77 this->count = count;
78 }
79
setDestY(float dest_y)80 void FileKeyEntry::setDestY(float dest_y) {
81 if(dest_y == this->dest_y) return;
82
83 this->dest_y = dest_y;
84
85 src_y = pos_y;
86 move_elapsed = 0.0f;
87 }
88
89
logic(float dt)90 void FileKeyEntry::logic(float dt) {
91
92 if(count<=0 || !show) {
93 alpha = std::max(0.0f, alpha - dt);
94 } else if(alpha < 1.0f) {
95 alpha = std::min(1.0f, alpha + dt);
96 }
97
98 //move towards dest
99 if(pos_y != dest_y) {
100 //initialize pos from dest if new
101 if(pos_y < 0.0f) pos_y = dest_y;
102 else {
103 move_elapsed += dt;
104
105 if(move_elapsed >= 1.0f) pos_y = dest_y;
106 else pos_y = src_y + (dest_y - src_y) * move_elapsed;
107 }
108 }
109
110 pos = vec2(alpha * left_margin, pos_y);
111 }
112
draw()113 void FileKeyEntry::draw() {
114 if(isFinished()) return;
115 //label.draw();
116
117 glDisable(GL_TEXTURE_2D);
118 glEnable(GL_BLEND);
119 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
120
121 glColor4f(0.0f, 0.0f, 0.0f, alpha * 0.333f);
122
123 glPushMatrix();
124 glTranslatef(shadow.x, shadow.y, 0.0f);
125
126 glBegin(GL_QUADS);
127 glVertex2f(pos.x, pos.y);
128 glVertex2f(pos.x, pos.y + height);
129 glVertex2f(pos.x+width, pos.y + height);
130 glVertex2f(pos.x+width, pos.y);
131 glEnd();
132 glPopMatrix();
133
134 glBegin(GL_QUADS);
135 glColor4f(colour.x * 0.5f, colour.y * 0.5f, colour.z * 0.5f, alpha);
136 glVertex2f(pos.x, pos.y);
137 glVertex2f(pos.x, pos.y + height);
138 glColor4f(colour.x, colour.y, colour.z, alpha);
139 glVertex2f(pos.x + width, pos.y + height);
140 glVertex2f(pos.x + width, pos.y);
141 glEnd();
142
143 glEnable(GL_TEXTURE_2D);
144
145 font.setColour(vec4(1.0f, 1.0f, 1.0f, alpha));
146
147 font.dropShadow(false);
148 font.draw((int)pos.x+2, (int)pos.y+3, display_ext.c_str());
149
150 font.dropShadow(true);
151 font.print((int)pos.x+width+4, (int)pos.y+3, "%d", count);
152 }
153
154 // Key
155
156 //maintain a key of all the current file types, updated periodically.
157 //new entries slide in and out / fade in fade out
158
FileKey()159 FileKey::FileKey() {
160
161 }
162
FileKey(float update_interval)163 FileKey::FileKey(float update_interval) {
164 this->update_interval = update_interval;
165 interval_remaining = 1.0f;
166 font = fontmanager.grab(gGourceSettings.font_file, 16);
167 font.dropShadow(false);
168 font.roundCoordinates(false);
169 show = true;
170 }
171
~FileKey()172 FileKey::~FileKey() {
173 active_keys.clear();
174
175 for(std::map<std::string, FileKeyEntry*>::iterator it = keymap.begin(); it != keymap.end(); it++) {
176 FileKeyEntry* entry = it->second;
177 delete entry;
178 }
179 keymap.clear();
180
181 }
182
setShow(bool show)183 void FileKey::setShow(bool show) {
184 this->show = show;
185
186 for(std::vector<FileKeyEntry*>::iterator it = active_keys.begin(); it != active_keys.end(); it++) {
187
188 FileKeyEntry* entry = *it;
189
190 entry->setShow(show);
191 }
192 interval_remaining = 0.0f;
193 }
194
colourize()195 void FileKey::colourize() {
196 for(std::vector<FileKeyEntry*>::iterator it = active_keys.begin(); it != active_keys.end(); it++) {
197 FileKeyEntry* entry = *it;
198 entry->colourize();
199 }
200 }
201
clear()202 void FileKey::clear() {
203
204 for(std::vector<FileKeyEntry*>::iterator it = active_keys.begin(); it != active_keys.end(); it++) {
205 FileKeyEntry* entry = *it;
206 entry->setCount(0);
207 }
208
209 interval_remaining = 0.0f;
210 }
211
inc(RFile * file)212 void FileKey::inc(RFile* file) {
213
214 FileKeyEntry* entry = 0;
215
216 std::map<std::string, FileKeyEntry*>::iterator result = keymap.find(file->ext);
217
218 if(result != keymap.end()) {
219 entry = result->second;
220 } else {
221 entry = new FileKeyEntry(font, file->ext, file->getFileColour());
222 keymap[file->ext] = entry;
223 }
224
225 entry->inc();
226 }
227
228
229 //decrement count of extension. if drops to zero, mark it for removal
dec(RFile * file)230 void FileKey::dec(RFile* file) {
231
232 std::map<std::string, FileKeyEntry*>::iterator result = keymap.find(file->ext);
233
234 if(result == keymap.end()) return;
235
236 FileKeyEntry* entry = result->second;
237
238 entry->dec();
239 }
240
file_key_entry_sort(const FileKeyEntry * a,const FileKeyEntry * b)241 bool file_key_entry_sort (const FileKeyEntry* a, const FileKeyEntry* b) {
242
243 //sort by count
244 if(a->getCount() != b->getCount())
245 return (a->getCount() > b->getCount());
246
247 //then by name (tie breaker)
248 return a->getExt().compare(b->getExt()) < 0;
249 }
250
logic(float dt)251 void FileKey::logic(float dt) {
252
253 interval_remaining -= dt;
254
255 //recalculate active_keys
256 if(interval_remaining <= 0.0f) {
257
258 if(show) {
259 active_keys.clear();
260 std::vector<FileKeyEntry*> finished_keys;
261
262 for(std::map<std::string, FileKeyEntry*>::iterator it = keymap.begin(); it != keymap.end(); it++) {
263 FileKeyEntry* entry = it->second;
264
265 if(!entry->isFinished()) {
266 active_keys.push_back(entry);
267 } else {
268 finished_keys.push_back(entry);
269 }
270 }
271
272 //sort
273 std::sort(active_keys.begin(), active_keys.end(), file_key_entry_sort);
274
275 //limit to entries we can put onto the screen
276 int max_visible_entries = std::max(0, (int)((display.height - 150.0f) / 20.0f));
277
278 if (active_keys.size() > max_visible_entries) {
279 active_keys.resize(max_visible_entries);
280 }
281
282 //set position
283
284 float key_y = 20.0f;
285
286 for(std::vector<FileKeyEntry*>::iterator it = active_keys.begin(); it != active_keys.end(); it++) {
287 FileKeyEntry* entry = *it;
288 if(entry->getCount()>0) {
289 entry->setDestY(key_y);
290 }
291 key_y += 20.0f;
292 }
293
294 //remove and delete finished entries
295 for(std::vector<FileKeyEntry*>::iterator it = finished_keys.begin(); it != finished_keys.end(); it++) {
296 FileKeyEntry* entry = *it;
297 keymap.erase(entry->getExt());
298 delete entry;
299 }
300 }
301
302 interval_remaining = update_interval;
303 }
304
305 for(std::vector<FileKeyEntry*>::iterator it = active_keys.begin(); it != active_keys.end(); it++) {
306
307 FileKeyEntry* entry = *it;
308
309 entry->logic(dt);
310 }
311 }
312
draw()313 void FileKey::draw() {
314
315 for(std::vector<FileKeyEntry*>::iterator it = active_keys.begin(); it != active_keys.end(); it++) {
316 FileKeyEntry* entry = *it;
317
318 entry->draw();
319 }
320
321 }
322