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