2 // "$Id: Fl_File_Icon.cxx 7903 2010-11-28 21:06:39Z matt $"
4 // Fl_File_Icon routines.
6 // KDE icon code donated by Maarten De Boer.
8 // Copyright 1999-2010 by Michael Sweet.
10 // This library is free software; you can redistribute it and/or
11 // modify it under the terms of the GNU Library General Public
12 // License as published by the Free Software Foundation; either
13 // version 2 of the License, or (at your option) any later version.
15 // This library is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 // Library General Public License for more details.
20 // You should have received a copy of the GNU Library General Public
21 // License along with this library; if not, write to the Free Software
22 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
25 // Please report all bugs and problems on the following page:
27 // http://www.fltk.org/str.php
31 // Fl_File_Icon::Fl_File_Icon() - Create a new file icon.
32 // Fl_File_Icon::~Fl_File_Icon() - Remove a file icon.
33 // Fl_File_Icon::add() - Add data to an icon.
34 // Fl_File_Icon::find() - Find an icon based upon a given file.
35 // Fl_File_Icon::draw() - Draw an icon.
36 // Fl_File_Icon::label() - Set the widgets label to an icon.
37 // Fl_File_Icon::labeltype() - Draw the icon label.
41 // Include necessary header files...
46 #include <FL/fl_utf8.h>
49 #include <sys/types.h>
51 #if (defined(WIN32) && ! defined(__CYGWIN__)) || defined(__EMX__)
56 #endif /* WIN32 || __EMX__ */
58 #include <FL/Fl_File_Icon.H>
59 #include <FL/Fl_Widget.H>
60 #include <FL/fl_draw.H>
61 #include <FL/filename.H>
65 // Define missing POSIX/XPG4 macros as needed...
69 # define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
70 # define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
71 # define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
72 # define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
73 # define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
81 Fl_File_Icon
*Fl_File_Icon::first_
= (Fl_File_Icon
*)0;
85 Creates a new Fl_File_Icon with the specified information.
86 \param[in] p filename pattern
87 \param[in] t file type
88 \param[in] nd number of data values
89 \param[in] d data values
91 Fl_File_Icon::Fl_File_Icon(const char *p
, /* I - Filename pattern */
92 int t
, /* I - File type */
93 int nd
, /* I - Number of data values */
94 short *d
) /* I - Data values */
96 // Initialize the pattern and type...
100 // Copy icon data as needed...
104 alloc_data_
= nd
+ 1;
105 data_
= (short *)calloc(sizeof(short), nd
+ 1);
106 memcpy(data_
, d
, nd
* sizeof(short));
114 // And add the icon to the list of icons...
121 The destructor destroys the icon and frees all memory that has been
124 Fl_File_Icon::~Fl_File_Icon() {
125 Fl_File_Icon
*current
, // Current icon in list
126 *prev
; // Previous icon in list
129 // Find the icon in the list...
130 for (current
= first_
, prev
= (Fl_File_Icon
*)0;
131 current
!= this && current
!= (Fl_File_Icon
*)0;
132 prev
= current
, current
= current
->next_
);
134 // Remove the icon from the list as needed...
138 prev
->next_
= current
->next_
;
140 first_
= current
->next_
;
143 // Free any memory used...
150 Adds a keyword value to the icon array, returning a pointer to it.
151 \param[in] d data value
153 short * // O - Pointer to new data value
154 Fl_File_Icon::add(short d
) // I - Data to add
156 short *dptr
; // Pointer to new data value
159 // Allocate/reallocate memory as needed
160 if ((num_data_
+ 1) >= alloc_data_
)
164 if (alloc_data_
== 128)
165 dptr
= (short *)malloc(sizeof(short) * alloc_data_
);
167 dptr
= (short *)realloc(data_
, sizeof(short) * alloc_data_
);
175 // Store the new data value and return
176 data_
[num_data_
++] = d
;
177 data_
[num_data_
] = END
;
179 return (data_
+ num_data_
- 1);
184 Finds an icon that matches the given filename and file type.
185 \param[in] filename name of file
186 \param[in] filetype enumerated file type
187 \return matching file icon or NULL
189 Fl_File_Icon
* // O - Matching file icon or NULL
190 Fl_File_Icon::find(const char *filename
,// I - Name of file */
191 int filetype
) // I - Enumerated file type
193 Fl_File_Icon
*current
; // Current file in list
195 struct stat fileinfo
; // Information on file
197 const char *name
; // Base name of filename
200 // Get file information if needed...
204 if (filename
[strlen(filename
) - 1] == '/')
205 filetype
= DIRECTORY
;
206 else if (fl_filename_isdir(filename
))
207 filetype
= DIRECTORY
;
211 if (!fl_stat(filename
, &fileinfo
))
213 if (S_ISDIR(fileinfo
.st_mode
))
214 filetype
= DIRECTORY
;
216 else if (S_ISFIFO(fileinfo
.st_mode
))
219 # if defined(S_ICHR) && defined(S_IBLK)
220 else if (S_ISCHR(fileinfo
.st_mode
) || S_ISBLK(fileinfo
.st_mode
))
222 # endif // S_ICHR && S_IBLK
224 else if (S_ISLNK(fileinfo
.st_mode
))
235 // Look at the base name in the filename
236 name
= fl_filename_name(filename
);
238 // Loop through the available file types and return any match that
240 for (current
= first_
; current
!= (Fl_File_Icon
*)0; current
= current
->next_
)
241 if ((current
->type_
== filetype
|| current
->type_
== ANY
) &&
242 (fl_filename_match(filename
, current
->pattern_
) ||
243 fl_filename_match(name
, current
->pattern_
)))
246 // Return the match (if any)...
251 Draws an icon in the indicated area.
252 \param[in] x, y, w, h position and size
253 \param[in] ic icon color
254 \param[in] active status, default is active [non-zero]
257 Fl_File_Icon::draw(int x
, // I - Upper-lefthand X
258 int y
, // I - Upper-lefthand Y
259 int w
, // I - Width of bounding box
260 int h
, // I - Height of bounding box
261 Fl_Color ic
, // I - Icon color...
262 int active
) // I - Active or inactive?
264 Fl_Color c
, // Current color
266 short *d
, // Pointer to data
267 *dend
; // End of data...
268 short *prim
; // Pointer to start of primitive...
269 double scale
; // Scale of icon
272 // Don't try to draw a NULL array!
276 // Setup the transform matrix as needed...
277 scale
= w
< h
? w
: h
;
280 fl_translate((float)x
+ 0.5 * ((float)w
- scale
),
281 (float)y
+ 0.5 * ((float)h
+ scale
));
282 fl_scale(scale
, -scale
);
284 // Loop through the array until we see an unmatched END...
286 dend
= data_
+ num_data_
;
293 fl_color(fl_inactive(c
));
311 fl_end_complex_polygon();
314 case OUTLINEPOLYGON
:
315 fl_end_complex_polygon();
317 oc
= (Fl_Color
)((((unsigned short *)prim
)[1] << 16) |
318 ((unsigned short *)prim
)[2]);
321 if (oc
== FL_ICON_COLOR
)
328 if (oc
== FL_ICON_COLOR
)
329 fl_color(fl_inactive(ic
));
331 fl_color(fl_inactive(oc
));
337 while (*prim
== VERTEX
)
339 fl_vertex(prim
[1] * 0.0001, prim
[2] * 0.0001);
353 c
= (Fl_Color
)((((unsigned short *)d
)[1] << 16) |
354 ((unsigned short *)d
)[2]);
356 if (c
== FL_ICON_COLOR
)
381 fl_begin_complex_polygon();
384 case OUTLINEPOLYGON
:
387 fl_begin_complex_polygon();
392 fl_vertex(d
[1] * 0.0001, d
[2] * 0.0001);
396 default : // Ignore invalid data...
400 // If we still have an open primitive, close it...
416 case OUTLINEPOLYGON
:
419 oc
= (Fl_Color
)((((unsigned short *)prim
)[1] << 16) |
420 ((unsigned short *)prim
)[2]);
423 if (oc
== FL_ICON_COLOR
)
430 if (oc
== FL_ICON_COLOR
)
431 fl_color(fl_inactive(ic
));
433 fl_color(fl_inactive(oc
));
439 while (*prim
== VERTEX
)
441 fl_vertex(prim
[1] * 0.0001, prim
[2] * 0.0001);
450 // Restore the transform matrix
455 Applies the icon to the widget, registering the Fl_File_Icon
456 label type as needed.
457 \param[in] w widget for which this icon will become the label
459 void Fl_File_Icon::label(Fl_Widget
*w
) // I - Widget to label
461 Fl::set_labeltype(_FL_ICON_LABEL
, labeltype
, 0);
462 w
->label(_FL_ICON_LABEL
, (const char*)this);
468 \param[in] o label data
469 \param[in] x, y, w, h position and size of label
470 \param[in] a label alignment [not used]
473 Fl_File_Icon::labeltype(const Fl_Label
*o
, // I - Label data
474 int x
, // I - X position of label
475 int y
, // I - Y position of label
476 int w
, // I - Width of label
477 int h
, // I - Height of label
478 Fl_Align a
) // I - Label alignment (not used)
480 Fl_File_Icon
*icon
; // Pointer to icon data
485 icon
= (Fl_File_Icon
*)(o
->value
);
486 if (icon
) icon
->draw(x
, y
, w
, h
, (Fl_Color
)(o
->color
));
491 // End of "$Id: Fl_File_Icon.cxx 7903 2010-11-28 21:06:39Z matt $".