|
fltk 1.3.0rc3
About: FLTK (Fast Light Tool Kit) is a cross-platform C++ GUI toolkit for UNIX/Linux (X11), Microsoft Windows, and MacOS X. Release candidate.
SfR Fresh Dox: fltk-1.3.0rc3-source.tar.gz ("inofficial" and yet experimental doxygen-generated source code documentation) ![]() |
00001 // 00002 // "$Id: Fl_File_Icon.cxx 7903 2010-11-28 21:06:39Z matt $" 00003 // 00004 // Fl_File_Icon routines. 00005 // 00006 // KDE icon code donated by Maarten De Boer. 00007 // 00008 // Copyright 1999-2010 by Michael Sweet. 00009 // 00010 // This library is free software; you can redistribute it and/or 00011 // modify it under the terms of the GNU Library General Public 00012 // License as published by the Free Software Foundation; either 00013 // version 2 of the License, or (at your option) any later version. 00014 // 00015 // This library is distributed in the hope that it will be useful, 00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 // Library General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Library General Public 00021 // License along with this library; if not, write to the Free Software 00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00023 // USA. 00024 // 00025 // Please report all bugs and problems on the following page: 00026 // 00027 // http://www.fltk.org/str.php 00028 // 00029 // Contents: 00030 // 00031 // Fl_File_Icon::Fl_File_Icon() - Create a new file icon. 00032 // Fl_File_Icon::~Fl_File_Icon() - Remove a file icon. 00033 // Fl_File_Icon::add() - Add data to an icon. 00034 // Fl_File_Icon::find() - Find an icon based upon a given file. 00035 // Fl_File_Icon::draw() - Draw an icon. 00036 // Fl_File_Icon::label() - Set the widgets label to an icon. 00037 // Fl_File_Icon::labeltype() - Draw the icon label. 00038 // 00039 00040 // 00041 // Include necessary header files... 00042 // 00043 00044 #include <stdio.h> 00045 #include <stdlib.h> 00046 #include <FL/fl_utf8.h> 00047 #include "flstring.h" 00048 #include <errno.h> 00049 #include <sys/types.h> 00050 #include <sys/stat.h> 00051 #if (defined(WIN32) && ! defined(__CYGWIN__)) || defined(__EMX__) 00052 # include <io.h> 00053 # define F_OK 0 00054 #else 00055 # include <unistd.h> 00056 #endif /* WIN32 || __EMX__ */ 00057 00058 #include <FL/Fl_File_Icon.H> 00059 #include <FL/Fl_Widget.H> 00060 #include <FL/fl_draw.H> 00061 #include <FL/filename.H> 00062 00063 00064 // 00065 // Define missing POSIX/XPG4 macros as needed... 00066 // 00067 00068 #ifndef S_ISDIR 00069 # define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) 00070 # define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) 00071 # define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) 00072 # define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) 00073 # define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) 00074 #endif /* !S_ISDIR */ 00075 00076 00077 // 00078 // Icon cache... 00079 // 00080 00081 Fl_File_Icon *Fl_File_Icon::first_ = (Fl_File_Icon *)0; 00082 00083 00091 Fl_File_Icon::Fl_File_Icon(const char *p, /* I - Filename pattern */ 00092 int t, /* I - File type */ 00093 int nd, /* I - Number of data values */ 00094 short *d) /* I - Data values */ 00095 { 00096 // Initialize the pattern and type... 00097 pattern_ = p; 00098 type_ = t; 00099 00100 // Copy icon data as needed... 00101 if (nd) 00102 { 00103 num_data_ = nd; 00104 alloc_data_ = nd + 1; 00105 data_ = (short *)calloc(sizeof(short), nd + 1); 00106 memcpy(data_, d, nd * sizeof(short)); 00107 } 00108 else 00109 { 00110 num_data_ = 0; 00111 alloc_data_ = 0; 00112 } 00113 00114 // And add the icon to the list of icons... 00115 next_ = first_; 00116 first_ = this; 00117 } 00118 00119 00124 Fl_File_Icon::~Fl_File_Icon() { 00125 Fl_File_Icon *current, // Current icon in list 00126 *prev; // Previous icon in list 00127 00128 00129 // Find the icon in the list... 00130 for (current = first_, prev = (Fl_File_Icon *)0; 00131 current != this && current != (Fl_File_Icon *)0; 00132 prev = current, current = current->next_); 00133 00134 // Remove the icon from the list as needed... 00135 if (current) 00136 { 00137 if (prev) 00138 prev->next_ = current->next_; 00139 else 00140 first_ = current->next_; 00141 } 00142 00143 // Free any memory used... 00144 if (alloc_data_) 00145 free(data_); 00146 } 00147 00148 00153 short * // O - Pointer to new data value 00154 Fl_File_Icon::add(short d) // I - Data to add 00155 { 00156 short *dptr; // Pointer to new data value 00157 00158 00159 // Allocate/reallocate memory as needed 00160 if ((num_data_ + 1) >= alloc_data_) 00161 { 00162 alloc_data_ += 128; 00163 00164 if (alloc_data_ == 128) 00165 dptr = (short *)malloc(sizeof(short) * alloc_data_); 00166 else 00167 dptr = (short *)realloc(data_, sizeof(short) * alloc_data_); 00168 00169 if (dptr == NULL) 00170 return (NULL); 00171 00172 data_ = dptr; 00173 } 00174 00175 // Store the new data value and return 00176 data_[num_data_++] = d; 00177 data_[num_data_] = END; 00178 00179 return (data_ + num_data_ - 1); 00180 } 00181 00182 00189 Fl_File_Icon * // O - Matching file icon or NULL 00190 Fl_File_Icon::find(const char *filename,// I - Name of file */ 00191 int filetype) // I - Enumerated file type 00192 { 00193 Fl_File_Icon *current; // Current file in list 00194 #ifndef WIN32 00195 struct stat fileinfo; // Information on file 00196 #endif // !WIN32 00197 const char *name; // Base name of filename 00198 00199 00200 // Get file information if needed... 00201 if (filetype == ANY) 00202 { 00203 #ifdef WIN32 00204 if (filename[strlen(filename) - 1] == '/') 00205 filetype = DIRECTORY; 00206 else if (fl_filename_isdir(filename)) 00207 filetype = DIRECTORY; 00208 else 00209 filetype = PLAIN; 00210 #else 00211 if (!fl_stat(filename, &fileinfo)) 00212 { 00213 if (S_ISDIR(fileinfo.st_mode)) 00214 filetype = DIRECTORY; 00215 # ifdef S_IFIFO 00216 else if (S_ISFIFO(fileinfo.st_mode)) 00217 filetype = FIFO; 00218 # endif // S_IFIFO 00219 # if defined(S_ICHR) && defined(S_IBLK) 00220 else if (S_ISCHR(fileinfo.st_mode) || S_ISBLK(fileinfo.st_mode)) 00221 filetype = DEVICE; 00222 # endif // S_ICHR && S_IBLK 00223 # ifdef S_ILNK 00224 else if (S_ISLNK(fileinfo.st_mode)) 00225 filetype = LINK; 00226 # endif // S_ILNK 00227 else 00228 filetype = PLAIN; 00229 } 00230 else 00231 filetype = PLAIN; 00232 #endif // WIN32 00233 } 00234 00235 // Look at the base name in the filename 00236 name = fl_filename_name(filename); 00237 00238 // Loop through the available file types and return any match that 00239 // is found... 00240 for (current = first_; current != (Fl_File_Icon *)0; current = current->next_) 00241 if ((current->type_ == filetype || current->type_ == ANY) && 00242 (fl_filename_match(filename, current->pattern_) || 00243 fl_filename_match(name, current->pattern_))) 00244 break; 00245 00246 // Return the match (if any)... 00247 return (current); 00248 } 00249 00256 void 00257 Fl_File_Icon::draw(int x, // I - Upper-lefthand X 00258 int y, // I - Upper-lefthand Y 00259 int w, // I - Width of bounding box 00260 int h, // I - Height of bounding box 00261 Fl_Color ic, // I - Icon color... 00262 int active) // I - Active or inactive? 00263 { 00264 Fl_Color c, // Current color 00265 oc; // Outline color 00266 short *d, // Pointer to data 00267 *dend; // End of data... 00268 short *prim; // Pointer to start of primitive... 00269 double scale; // Scale of icon 00270 00271 00272 // Don't try to draw a NULL array! 00273 if (num_data_ == 0) 00274 return; 00275 00276 // Setup the transform matrix as needed... 00277 scale = w < h ? w : h; 00278 00279 fl_push_matrix(); 00280 fl_translate((float)x + 0.5 * ((float)w - scale), 00281 (float)y + 0.5 * ((float)h + scale)); 00282 fl_scale(scale, -scale); 00283 00284 // Loop through the array until we see an unmatched END... 00285 d = data_; 00286 dend = data_ + num_data_; 00287 prim = NULL; 00288 c = ic; 00289 00290 if (active) 00291 fl_color(c); 00292 else 00293 fl_color(fl_inactive(c)); 00294 00295 while (d < dend) 00296 switch (*d) 00297 { 00298 case END : 00299 if (prim) 00300 switch (*prim) 00301 { 00302 case LINE : 00303 fl_end_line(); 00304 break; 00305 00306 case CLOSEDLINE : 00307 fl_end_loop(); 00308 break; 00309 00310 case POLYGON : 00311 fl_end_complex_polygon(); 00312 break; 00313 00314 case OUTLINEPOLYGON : 00315 fl_end_complex_polygon(); 00316 00317 oc = (Fl_Color)((((unsigned short *)prim)[1] << 16) | 00318 ((unsigned short *)prim)[2]); 00319 if (active) 00320 { 00321 if (oc == FL_ICON_COLOR) 00322 fl_color(ic); 00323 else 00324 fl_color(oc); 00325 } 00326 else 00327 { 00328 if (oc == FL_ICON_COLOR) 00329 fl_color(fl_inactive(ic)); 00330 else 00331 fl_color(fl_inactive(oc)); 00332 } 00333 00334 fl_begin_loop(); 00335 00336 prim += 3; 00337 while (*prim == VERTEX) 00338 { 00339 fl_vertex(prim[1] * 0.0001, prim[2] * 0.0001); 00340 prim += 3; 00341 } 00342 00343 fl_end_loop(); 00344 fl_color(c); 00345 break; 00346 } 00347 00348 prim = NULL; 00349 d ++; 00350 break; 00351 00352 case COLOR : 00353 c = (Fl_Color)((((unsigned short *)d)[1] << 16) | 00354 ((unsigned short *)d)[2]); 00355 00356 if (c == FL_ICON_COLOR) 00357 c = ic; 00358 00359 if (!active) 00360 c = fl_inactive(c); 00361 00362 fl_color(c); 00363 d += 3; 00364 break; 00365 00366 case LINE : 00367 prim = d; 00368 d ++; 00369 fl_begin_line(); 00370 break; 00371 00372 case CLOSEDLINE : 00373 prim = d; 00374 d ++; 00375 fl_begin_loop(); 00376 break; 00377 00378 case POLYGON : 00379 prim = d; 00380 d ++; 00381 fl_begin_complex_polygon(); 00382 break; 00383 00384 case OUTLINEPOLYGON : 00385 prim = d; 00386 d += 3; 00387 fl_begin_complex_polygon(); 00388 break; 00389 00390 case VERTEX : 00391 if (prim) 00392 fl_vertex(d[1] * 0.0001, d[2] * 0.0001); 00393 d += 3; 00394 break; 00395 00396 default : // Ignore invalid data... 00397 d ++; 00398 } 00399 00400 // If we still have an open primitive, close it... 00401 if (prim) 00402 switch (*prim) 00403 { 00404 case LINE : 00405 fl_end_line(); 00406 break; 00407 00408 case CLOSEDLINE : 00409 fl_end_loop(); 00410 break; 00411 00412 case POLYGON : 00413 fl_end_polygon(); 00414 break; 00415 00416 case OUTLINEPOLYGON : 00417 fl_end_polygon(); 00418 00419 oc = (Fl_Color)((((unsigned short *)prim)[1] << 16) | 00420 ((unsigned short *)prim)[2]); 00421 if (active) 00422 { 00423 if (oc == FL_ICON_COLOR) 00424 fl_color(ic); 00425 else 00426 fl_color(oc); 00427 } 00428 else 00429 { 00430 if (oc == FL_ICON_COLOR) 00431 fl_color(fl_inactive(ic)); 00432 else 00433 fl_color(fl_inactive(oc)); 00434 } 00435 00436 fl_begin_loop(); 00437 00438 prim += 3; 00439 while (*prim == VERTEX) 00440 { 00441 fl_vertex(prim[1] * 0.0001, prim[2] * 0.0001); 00442 prim += 3; 00443 } 00444 00445 fl_end_loop(); 00446 fl_color(c); 00447 break; 00448 } 00449 00450 // Restore the transform matrix 00451 fl_pop_matrix(); 00452 } 00453 00459 void Fl_File_Icon::label(Fl_Widget *w) // I - Widget to label 00460 { 00461 Fl::set_labeltype(_FL_ICON_LABEL, labeltype, 0); 00462 w->label(_FL_ICON_LABEL, (const char*)this); 00463 } 00464 00465 00472 void 00473 Fl_File_Icon::labeltype(const Fl_Label *o, // I - Label data 00474 int x, // I - X position of label 00475 int y, // I - Y position of label 00476 int w, // I - Width of label 00477 int h, // I - Height of label 00478 Fl_Align a) // I - Label alignment (not used) 00479 { 00480 Fl_File_Icon *icon; // Pointer to icon data 00481 00482 00483 (void)a; 00484 00485 icon = (Fl_File_Icon *)(o->value); 00486 if (icon) icon->draw(x, y, w, h, (Fl_Color)(o->color)); 00487 } 00488 00489 00490 // 00491 // End of "$Id: Fl_File_Icon.cxx 7903 2010-11-28 21:06:39Z matt $". 00492 //