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)  

Fl_File_Icon.cxx

Go to the documentation of this file.
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 //