1 /*
2 Copyright (C) 2009 Andrew Caudwell (acaudwell@gmail.com)
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version
7 3 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include "file.h"
19
20 float gGourceFileDiameter = 8.0;
21
22 std::vector<RFile*> gGourceRemovedFiles;
23
24 FXFont file_selected_font;
25 FXFont file_font;
26
RFile(const std::string & name,const vec3 & colour,const vec2 & pos,int tagid)27 RFile::RFile(const std::string & name, const vec3 & colour, const vec2 & pos, int tagid) : Pawn(name,pos,tagid) {
28 hidden = true;
29 size = gGourceFileDiameter * 1.05;
30 radius = size * 0.5;
31
32 setGraphic(gGourceSettings.file_graphic);
33
34 speed = 5.0;
35 nametime = gGourceSettings.filename_time;
36 name_interval = nametime;
37
38 namecol = vec3(1.0, 1.0, 1.0);
39 file_colour = colour;
40
41 last_action = 0.0f;
42 fade_start = -1.0f;
43 removed_timestamp = 0;
44 expired = false;
45 forced_removal = false;
46 removing = false;
47
48 shadow = true;
49
50 distance = 0;
51
52 setFilename(name);
53
54 if(!file_selected_font.initialized()) {
55 file_selected_font = fontmanager.grab(gGourceSettings.font_file, 18);
56 file_selected_font.dropShadow(true);
57 file_selected_font.roundCoordinates(false);
58 file_selected_font.setColour(vec4(gGourceSettings.selection_colour, 1.0f));
59 }
60
61 if(!file_font.initialized()) {
62 file_font = fontmanager.grab(gGourceSettings.font_file, gGourceSettings.filename_font_size);
63 file_font.dropShadow(true);
64 file_font.roundCoordinates(false);
65 file_font.setColour(vec4(gGourceSettings.filename_colour, 1.0f));
66 }
67
68 setSelected(false);
69
70 dir = 0;
71 }
72
~RFile()73 RFile::~RFile() {
74 }
75
remove(time_t removed_timestamp)76 void RFile::remove(time_t removed_timestamp) {
77 last_action = elapsed;
78 fade_start = elapsed;
79 removing = true;
80 this->removed_timestamp = removed_timestamp;
81 }
82
remove()83 void RFile::remove() {
84 forced_removal = true;
85 remove(0);
86 }
87
setDir(RDirNode * dir)88 void RFile::setDir(RDirNode* dir) {
89 this->dir = dir;
90 }
91
getDir() const92 RDirNode* RFile::getDir() const{
93 return dir;
94 }
95
getAbsolutePos() const96 vec2 RFile::getAbsolutePos() const{
97 return pos + dir->getPos();
98 }
99
overlaps(const vec2 & pos) const100 bool RFile::overlaps(const vec2& pos) const {
101
102 vec2 abs_pos = getAbsolutePos();
103
104 float halfsize_x = size * 0.5f;
105 vec2 halfsize ( halfsize_x, halfsize_x * graphic_ratio );
106
107 Bounds2D file_bounds(abs_pos - halfsize, abs_pos + halfsize);
108
109 return file_bounds.contains(pos);
110 }
111
setFilename(const std::string & abs_file_path)112 void RFile::setFilename(const std::string& abs_file_path) {
113
114 fullpath = abs_file_path;
115
116 size_t pos = fullpath.rfind('/');
117
118 if(pos != std::string::npos) {
119 path = name.substr(0,pos+1);
120 name = name.substr(pos+1, std::string::npos);
121 } else {
122 path = std::string("");
123 name = abs_file_path;
124 }
125
126 //trim name to just extension
127 size_t dotsep = name.rfind(".");
128
129 if(dotsep != std::string::npos && dotsep != name.size()-1) {
130 ext = name.substr(dotsep+1);
131 } else if(gGourceSettings.file_extension_fallback) {
132 ext = name;
133 }
134 }
135
colourize()136 void RFile::colourize() {
137 file_colour = ext.size() ? colourHash(ext) : vec3(1.0f, 1.0f, 1.0f);
138 }
139
getNameColour() const140 const vec3& RFile::getNameColour() const{
141 return selected ? gGourceSettings.selection_colour : namecol;
142 }
143
setFileColour(const vec3 & colour)144 void RFile::setFileColour(const vec3 & colour) {
145 file_colour = colour;
146 }
147
getFileColour() const148 const vec3 & RFile::getFileColour() const{
149 return file_colour;
150 }
151
getColour() const152 vec3 RFile::getColour() const{
153 if(selected) return vec3(1.0f);
154
155 float lc = elapsed - last_action;
156
157 if(lc<1.0f) {
158 return touch_colour * (1.0f-lc) + file_colour * lc;
159 }
160
161 return file_colour;
162 }
163
getAlpha() const164 float RFile::getAlpha() const{
165 float alpha = Pawn::getAlpha();
166
167 //user fades out if not doing anything
168 if(fade_start > 0.0f) {
169 alpha = 1.0 - glm::clamp(elapsed - fade_start, 0.0f, 1.0f);
170 }
171
172 return alpha;
173 }
174
logic(float dt)175 void RFile::logic(float dt) {
176 Pawn::logic(dt);
177
178 vec2 dest_pos = dest;
179 /*
180 if(dir->getParent() != 0 && dir->noDirs()) {
181 vec2 dirnorm = dir->getNodeNormal();
182 dest_pos = dirnorm + dest;
183 }*/
184
185 dest_pos = dest_pos * distance;
186
187 accel = dest_pos - pos;
188
189 // apply accel
190 vec2 accel2 = accel * speed * dt;
191
192 if(glm::length2(accel2) > glm::length2(accel)) {
193 accel2 = accel;
194 }
195
196 pos += accel2;
197
198 //files have no momentum
199 accel = vec2(0.0f, 0.0f);
200
201 if(fade_start < 0.0f && gGourceSettings.file_idle_time > 0.0f && (elapsed - last_action) > gGourceSettings.file_idle_time) {
202 fade_start = elapsed;
203 }
204
205 // has completely faded out
206 if(fade_start > 0.0f && !expired && (elapsed - fade_start) >= 1.0) {
207
208 expired = true;
209
210 bool found = false;
211 for(std::vector<RFile*>::iterator it = gGourceRemovedFiles.begin(); it != gGourceRemovedFiles.end(); it++) {
212 if((*it) == this) {
213 found = true;
214 break;
215 }
216 }
217
218 if(!found) {
219 gGourceRemovedFiles.push_back(this);
220 //fprintf(stderr, "expiring %s\n", fullpath.c_str());
221 }
222 }
223
224 if(isHidden() && !forced_removal) elapsed = 0.0;
225 }
226
touch(time_t touched_timestamp,const vec3 & colour)227 void RFile::touch(time_t touched_timestamp, const vec3 & colour) {
228 if(forced_removal || (removing && touched_timestamp < removed_timestamp)) return;
229
230 //fprintf(stderr, "touch %s\n", fullpath.c_str());
231
232 fade_start = -1.0f;
233 removing = false;
234 removed_timestamp = 0;
235 last_action = elapsed;
236 touch_colour = colour;
237
238 //un expire file if touched after being removed
239 if(expired) {
240 for(std::vector<RFile*>::iterator it = gGourceRemovedFiles.begin(); it != gGourceRemovedFiles.end(); it++) {
241 if((*it) == this) {
242 gGourceRemovedFiles.erase(it);
243 break;
244 }
245 }
246 expired=false;
247 }
248
249 showName();
250 setHidden(false);
251 dir->fileUpdated(true);
252 }
253
setHidden(bool hidden)254 void RFile::setHidden(bool hidden) {
255 if(this->hidden==true && hidden==false && dir !=0) {
256 dir->addVisible();
257 }
258
259 Pawn::setHidden(hidden);
260 }
261
calcScreenPos(GLint * viewport,GLdouble * modelview,GLdouble * projection)262 void RFile::calcScreenPos(GLint* viewport, GLdouble* modelview, GLdouble* projection) {
263
264 static GLdouble screen_x, screen_y, screen_z;
265
266 vec2 text_pos = getAbsolutePos();
267 text_pos.x += 5.5f;
268
269 if(selected)
270 text_pos.y -= 2.0f;
271 else
272 text_pos.y -= 1.0f;
273
274 gluProject( text_pos.x, text_pos.y, 0.0f, modelview, projection, viewport, &screen_x, &screen_y, &screen_z);
275 screen_y = (float)viewport[3] - screen_y;
276
277 screenpos.x = screen_x;
278 screenpos.y = screen_y;
279 }
280
drawNameText(float alpha)281 void RFile::drawNameText(float alpha) {
282 if(!selected && alpha <= 0.01) return;
283
284 float name_alpha = selected ? 1.0 : alpha;
285
286 if(selected) {
287 file_selected_font.draw(screenpos.x, screenpos.y, name);
288 } else {
289 file_font.setAlpha(name_alpha);
290 file_font.draw(screenpos.x, screenpos.y, gGourceSettings.file_extensions ? ext : name);
291 }
292 }
293
draw(float dt)294 void RFile::draw(float dt) {
295 Pawn::draw(dt);
296
297 glLoadName(0);
298 }
299