This commit was manufactured by cvs2svn to create branch 'branch-1.1'.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.1@1513 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
parent
4477e16640
commit
3cb5ebe0e8
37
FL/Fl_Export.H
Normal file
37
FL/Fl_Export.H
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
The following is only used when building DLLs under WIN32
|
||||
*/
|
||||
|
||||
#if defined(WIN32) && defined(FL_SHARED)
|
||||
# ifdef FL_LIBRARY
|
||||
# define FL_API __declspec(dllexport)
|
||||
# else
|
||||
# define FL_API __declspec(dllimport)
|
||||
# endif
|
||||
# ifdef FL_IMAGES_LIBRARY
|
||||
# define FL_IMAGES_API __declspec(dllexport)
|
||||
# else
|
||||
# define FL_IMAGES_API __declspec(dllimport)
|
||||
# endif
|
||||
# ifdef FL_GLUT_LIBRARY
|
||||
# define FL_GLUT_API __declspec(dllexport)
|
||||
# else
|
||||
# define FL_GLUT_API __declspec(dllimport)
|
||||
# endif
|
||||
# ifdef FL_FORMS_LIBRARY
|
||||
# define FL_FORMS_API __declspec(dllexport)
|
||||
# else
|
||||
# define FL_FORMS_API __declspec(dllimport)
|
||||
# endif
|
||||
# ifdef FL_GL_LIBRARY
|
||||
# define FL_GL_API __declspec(dllexport)
|
||||
# else
|
||||
# define FL_GL_API __declspec(dllimport)
|
||||
# endif
|
||||
#else
|
||||
# define FL_API
|
||||
# define FL_IMAGES_API
|
||||
# define FL_GLUT_API
|
||||
# define FL_FORMS_API
|
||||
# define FL_GL_API
|
||||
#endif
|
80
FL/Fl_FileBrowser.H
Normal file
80
FL/Fl_FileBrowser.H
Normal file
@ -0,0 +1,80 @@
|
||||
//
|
||||
// "$Id: Fl_FileBrowser.H,v 1.4 2000/01/16 07:44:20 robertk Exp $"
|
||||
//
|
||||
// Fl_FileBrowser definitions for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 1997-1999 by Easy Software Products.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA.
|
||||
//
|
||||
// Please report all bugs and problems to "fltk-bugs@easysw.com".
|
||||
//
|
||||
|
||||
//
|
||||
// Include necessary header files...
|
||||
//
|
||||
|
||||
#ifndef _FL_FILEBROWSER_H_
|
||||
# define _FL_FILEBROWSER_H_
|
||||
|
||||
# include <FL/Fl_Browser.H>
|
||||
# include <FL/Fl_FileIcon.H>
|
||||
|
||||
|
||||
//
|
||||
// Fl_FileBrowser class...
|
||||
//
|
||||
|
||||
class FL_API Fl_FileBrowser : public Fl_Browser
|
||||
{
|
||||
const char *directory_;
|
||||
uchar iconsize_;
|
||||
const char *pattern_;
|
||||
|
||||
int item_height(void *) const;
|
||||
int item_width(void *) const;
|
||||
void item_draw(void *, int, int, int, int) const;
|
||||
int incr_height() const { return (item_height(0)); }
|
||||
|
||||
public:
|
||||
Fl_FileBrowser(int, int, int, int, const char * = 0);
|
||||
|
||||
uchar iconsize() const { return (iconsize_); };
|
||||
void iconsize(uchar s) { iconsize_ = s; redraw(); };
|
||||
|
||||
void directory(const char *directory) { load(directory); }
|
||||
const char *directory(void) const { return (directory_); }
|
||||
|
||||
void filter(const char *pattern);
|
||||
const char *filter() const { return (pattern_); };
|
||||
|
||||
int load(const char *directory);
|
||||
|
||||
#ifdef FLTK_2
|
||||
unsigned textsize() const { return (Fl_Browser::text_size()); };
|
||||
void textsize(unsigned s) { Fl_Browser::text_size(s); };
|
||||
#else
|
||||
uchar textsize() const { return (Fl_Browser::textsize()); };
|
||||
void textsize(uchar s) { Fl_Browser::textsize(s); };
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#endif // !_FL_FILEBROWSER_H_
|
||||
|
||||
//
|
||||
// End of "$Id: Fl_FileBrowser.H,v 1.4 2000/01/16 07:44:20 robertk Exp $".
|
||||
//
|
80
FL/Fl_FileChooser.H
Normal file
80
FL/Fl_FileChooser.H
Normal file
@ -0,0 +1,80 @@
|
||||
// generated by Fast Light User Interface Designer (fluid) version 2.0000
|
||||
|
||||
#ifndef Fl_FileChooser_h
|
||||
#define Fl_FileChooser_h
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/Fl_Window.H>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <FL/Fl_Choice.H>
|
||||
#include <FL/Fl_Button.H>
|
||||
#include "filename.H"
|
||||
#include <FL/Fl_FileBrowser.H>
|
||||
#include <FL/Fl_FileInput.H>
|
||||
#include <FL/Fl_Return_Button.H>
|
||||
|
||||
class FL_API Fl_FileChooser {
|
||||
public:
|
||||
enum { SINGLE, MULTI, CREATE };
|
||||
Fl_FileChooser(const char *d, const char *p, int t, const char *title);
|
||||
Fl_Window *window;
|
||||
private:
|
||||
inline void cb_window_i(Fl_Window*, void*);
|
||||
static void cb_window(Fl_Window*, void*);
|
||||
Fl_Choice *dirMenu;
|
||||
inline void cb_dirMenu_i(Fl_Choice*, void*);
|
||||
static void cb_dirMenu(Fl_Choice*, void*);
|
||||
Fl_Button *upButton;
|
||||
inline void cb_upButton_i(Fl_Button*, void*);
|
||||
static void cb_upButton(Fl_Button*, void*);
|
||||
Fl_Button *newButton;
|
||||
inline void cb_newButton_i(Fl_Button*, void*);
|
||||
static void cb_newButton(Fl_Button*, void*);
|
||||
inline void cb__i(Fl_Button*, void*);
|
||||
static void cb_(Fl_Button*, void*);
|
||||
Fl_FileBrowser *fileList;
|
||||
inline void cb_fileList_i(Fl_FileBrowser*, void*);
|
||||
static void cb_fileList(Fl_FileBrowser*, void*);
|
||||
Fl_FileInput *fileName;
|
||||
inline void cb_fileName_i(Fl_FileInput*, void*);
|
||||
static void cb_fileName(Fl_FileInput*, void*);
|
||||
Fl_Return_Button *okButton;
|
||||
inline void cb_okButton_i(Fl_Return_Button*, void*);
|
||||
static void cb_okButton(Fl_Return_Button*, void*);
|
||||
inline void cb_Cancel_i(Fl_Button*, void*);
|
||||
static void cb_Cancel(Fl_Button*, void*);
|
||||
char directory_[1024];
|
||||
int type_;
|
||||
void fileListCB();
|
||||
void fileNameCB();
|
||||
void newdir();
|
||||
void up();
|
||||
public:
|
||||
void color(Fl_Color c);
|
||||
Fl_Color color();
|
||||
int count();
|
||||
void directory(const char *d);
|
||||
char * directory();
|
||||
void exec();
|
||||
void filter(const char *p);
|
||||
const char * filter();
|
||||
void hide();
|
||||
void iconsize(uchar s);
|
||||
uchar iconsize();
|
||||
void label(const char *l);
|
||||
const char * label();
|
||||
void rescan();
|
||||
void textcolor(Fl_Color c);
|
||||
Fl_Color textcolor();
|
||||
void textfont(Fl_Font f);
|
||||
Fl_Font textfont();
|
||||
void textsize(uchar s);
|
||||
uchar textsize();
|
||||
void type(int t);
|
||||
int type();
|
||||
const char *value(int f = 1);
|
||||
void value(const char *filename);
|
||||
int visible();
|
||||
};
|
||||
#endif
|
107
FL/Fl_FileIcon.H
Normal file
107
FL/Fl_FileIcon.H
Normal file
@ -0,0 +1,107 @@
|
||||
//
|
||||
// "$Id: Fl_FileIcon.H,v 1.1 2000/01/08 22:14:13 vincent Exp $"
|
||||
//
|
||||
// Fl_FileIcon definitions for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 1997-1999 by Easy Software Products.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA.
|
||||
//
|
||||
// Please report all bugs and problems to "fltk-bugs@easysw.com".
|
||||
//
|
||||
|
||||
//
|
||||
// Include necessary header files...
|
||||
//
|
||||
|
||||
#ifndef _FL_FILEICON_H_
|
||||
# define _FL_FILEICON_H_
|
||||
|
||||
# include <FL/Fl.H>
|
||||
|
||||
|
||||
//
|
||||
// Fl_FileIcon class...
|
||||
//
|
||||
|
||||
class FL_API Fl_FileIcon //// Icon data
|
||||
{
|
||||
static Fl_FileIcon *first_; // Pointer to first icon/filetype
|
||||
Fl_FileIcon *next_; // Pointer to next icon/filetype
|
||||
const char *pattern_; // Pattern string
|
||||
int type_; // Match only if directory or file?
|
||||
int num_data_; // Number of data elements
|
||||
int alloc_data_; // Number of allocated elements
|
||||
short *data_; // Icon data
|
||||
|
||||
public:
|
||||
|
||||
enum // File types
|
||||
{
|
||||
ANY, // Any kind of file
|
||||
PLAIN, // Only plain files
|
||||
FIFO, // Only named pipes
|
||||
DEVICE, // Only character and block devices
|
||||
LINK, // Only symbolic links
|
||||
DIR // Only directories
|
||||
};
|
||||
|
||||
enum // Data opcodes
|
||||
{
|
||||
END, // End of primitive/icon
|
||||
COLOR, // Followed by color index
|
||||
LINE, // Start of line
|
||||
CLOSEDLINE, // Start of closed line
|
||||
POLYGON, // Start of polygon
|
||||
OUTLINEPOLYGON, // Followed by outline color
|
||||
VERTEX // Followed by scaled X,Y
|
||||
};
|
||||
|
||||
Fl_FileIcon(const char *p, int t, int nd = 0, short *d = 0);
|
||||
~Fl_FileIcon();
|
||||
|
||||
short *add(short d);
|
||||
short *add_color(short c)
|
||||
{ short *d = add(COLOR); add(c); return (d); }
|
||||
short *add_vertex(int x, int y)
|
||||
{ short *d = add(VERTEX); add(x); add(y); return (d); }
|
||||
short *add_vertex(float x, float y)
|
||||
{ short *d = add(VERTEX); add((int)(x * 10000.0));
|
||||
add((int)(y * 10000.0)); return (d); }
|
||||
void clear() { num_data_ = 0; }
|
||||
void draw(int x, int y, int w, int h, Fl_Color ic, int active = 1);
|
||||
void label(Fl_Widget *w);
|
||||
// static void labeltype(const Fl_Label *o, int x, int y, int w, int h, Fl_Align a);
|
||||
void load(const char *f);
|
||||
void load_fti(const char *fti);
|
||||
void load_xpm(const char *xpm);
|
||||
const char *pattern() { return (pattern_); }
|
||||
int size() { return (num_data_); }
|
||||
int type() { return (type_); }
|
||||
short *value() { return (data_); }
|
||||
|
||||
static Fl_FileIcon *find(const char *filename, int filetype = ANY);
|
||||
static Fl_FileIcon *first() { return (first_); }
|
||||
static void load_system_icons(void);
|
||||
};
|
||||
|
||||
//#define _FL_ICON_LABEL FL_FREE_LABELTYPE
|
||||
|
||||
#endif // !_FL_FILEICON_H_
|
||||
|
||||
//
|
||||
// End of "$Id: Fl_FileIcon.H,v 1.1 2000/01/08 22:14:13 vincent Exp $".
|
||||
//
|
203
FL/Fl_Shared_Image.H
Normal file
203
FL/Fl_Shared_Image.H
Normal file
@ -0,0 +1,203 @@
|
||||
//
|
||||
// "$Id: Fl_Shared_Image.H,v 1.22 2001/07/16 19:38:17 robertk Exp $"
|
||||
//
|
||||
// Image file header file for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 1998-1999 by Bill Spitzak and others.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA.
|
||||
//
|
||||
// Please report all bugs and problems to "fltk-bugs@easysw.com".
|
||||
//
|
||||
|
||||
#ifndef Fl_Shared_Image_H
|
||||
#define Fl_Shared_Image_H
|
||||
|
||||
#include <FL/Fl_Image.H>
|
||||
#include <stddef.h>
|
||||
|
||||
struct FL_IMAGES_API Fl_Image_Type;
|
||||
|
||||
// Shared images class.
|
||||
class FL_IMAGES_API Fl_Shared_Image : public Fl_Image {
|
||||
protected:
|
||||
static const char* fl_shared_image_root;
|
||||
|
||||
static int image_used;
|
||||
static size_t mem_usage_limit;
|
||||
|
||||
static size_t mem_used;
|
||||
static int forbid_delete;
|
||||
|
||||
Fl_Shared_Image* l1; // Left leaf in the binary tree
|
||||
Fl_Shared_Image* l2; // Right leaf in the binary tree
|
||||
const char* name; // Used to indentify the image, and as filename
|
||||
const uchar* datas; // If non zero, pointers on inlined compressed datas
|
||||
unsigned int used; // Last time used, for cache handling purpose
|
||||
int refcount; // Number of time this image has been get
|
||||
|
||||
Fl_Shared_Image() { }; // Constructor is private on purpose,
|
||||
// use the get function rather
|
||||
~Fl_Shared_Image();
|
||||
|
||||
void find_less_used();
|
||||
static void check_mem_usage();
|
||||
|
||||
const char* get_filename();// Return the filename obtained from the concatenation
|
||||
// of the image root directory and this image name
|
||||
// WARNING : the returned pointer will be
|
||||
// available only until next call to get_filename
|
||||
|
||||
static const char* get_filename(const char*);
|
||||
|
||||
virtual void read() = 0;// decompress the image and create its pixmap
|
||||
|
||||
static void insert(Fl_Shared_Image*& p, Fl_Shared_Image* image);
|
||||
static Fl_Shared_Image* find(Fl_Shared_Image* image, const char* name);
|
||||
void remove_from_tree(Fl_Shared_Image*& p, Fl_Shared_Image* image);
|
||||
|
||||
|
||||
public:
|
||||
static Fl_Shared_Image *first_image;
|
||||
|
||||
// Return an Fl_Shared_Image, using the create function if an image with
|
||||
// the given name doesn't already exist. Use datas, or read from the
|
||||
// file with filename name if datas==0.
|
||||
static Fl_Shared_Image* get(Fl_Shared_Image* (*create)(),
|
||||
const char* name, const uchar* datas=0);
|
||||
|
||||
// Reload the image, useful if it has changed on disk, or if the datas
|
||||
// in memory have changed (you can also give a new pointer on datas)
|
||||
void reload(const uchar* datas=0);
|
||||
static void reload(const char* name, const uchar* datas=0);
|
||||
|
||||
// Remove an image from the database and delete it if its refcount has
|
||||
// fallen to zero
|
||||
// Each remove decrement the refcount, each get increment it
|
||||
// Return 1 if it has been really deleted.
|
||||
int remove();
|
||||
static int remove(const char* name);
|
||||
|
||||
// Clear the cache for this image and all of its children in the binary tree
|
||||
void clear_cache();
|
||||
|
||||
// Try to guess the filetype
|
||||
// Beware that calling this force you to link in all image types !
|
||||
static Fl_Image_Type* guess(const char* name, const uchar* datas=0);
|
||||
|
||||
// Set the position where images are looked for on disk
|
||||
static void set_root_directory(const char* d);
|
||||
|
||||
// Set the size of the cache (0 = unlimited is the default)
|
||||
static void set_cache_size(size_t l);
|
||||
|
||||
virtual void draw(int X, int Y, int W, int H, int cx, int cy);
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Description of a file format
|
||||
struct FL_IMAGES_API Fl_Image_Type {
|
||||
// Name of the filetype as it appear in the source code (uppercase)
|
||||
const char* name;
|
||||
// Function to test the filetype
|
||||
int (*test)(const uchar* datas, size_t size=0);
|
||||
// Function to get/create an image of this type
|
||||
Fl_Shared_Image* (*get)(const char* name, const uchar* datas=0);
|
||||
};
|
||||
extern FL_IMAGES_API Fl_Image_Type fl_image_filetypes[];
|
||||
|
||||
/* Specific image format functions. Add you own file format here. */
|
||||
|
||||
// PNG image class
|
||||
class FL_IMAGES_API Fl_PNG_Image : public Fl_Shared_Image {
|
||||
void read(); // Uncompress PNG datas
|
||||
Fl_PNG_Image() { }
|
||||
static Fl_Shared_Image* create() { return new Fl_PNG_Image; } // Instantiate
|
||||
public:
|
||||
// Check the given buffer if it is in PNG format
|
||||
static int test(const uchar* datas, size_t size=0);
|
||||
void measure(int& W, int& H); // Return width and heigth
|
||||
static Fl_Shared_Image* get(const char* name, const uchar* datas = 0) {
|
||||
return Fl_Shared_Image::get(create, name, datas);
|
||||
}
|
||||
};
|
||||
|
||||
class FL_IMAGES_API Fl_GIF_Image : public Fl_Shared_Image {
|
||||
void read();
|
||||
Fl_GIF_Image() { }
|
||||
static Fl_Shared_Image* create() { return new Fl_GIF_Image; }
|
||||
public:
|
||||
static int test(const uchar* datas, size_t size=0);
|
||||
void measure(int& W, int& H);
|
||||
static Fl_Shared_Image* get(const char* name, const uchar* datas = 0) {
|
||||
return Fl_Shared_Image::get(create, name, datas);
|
||||
}
|
||||
};
|
||||
|
||||
class FL_IMAGES_API Fl_XPM_Image : public Fl_Shared_Image {
|
||||
void read();
|
||||
Fl_XPM_Image() { }
|
||||
static Fl_Shared_Image* create() { return new Fl_XPM_Image; }
|
||||
public:
|
||||
static int test(const uchar* datas, size_t size=0);
|
||||
void measure(int& W, int& H);
|
||||
static Fl_Shared_Image* get(const char* name, const uchar* datas = 0) {
|
||||
return Fl_Shared_Image::get(create, name, datas);
|
||||
}
|
||||
};
|
||||
|
||||
class FL_IMAGES_API Fl_BMP_Image : public Fl_Shared_Image {
|
||||
void read();
|
||||
Fl_BMP_Image() { }
|
||||
static Fl_Shared_Image* create() { return new Fl_BMP_Image; }
|
||||
public:
|
||||
static int test(const uchar* datas, size_t size=0);
|
||||
void measure(int& W, int& H);
|
||||
static Fl_Shared_Image* get(const char* name, const uchar* datas = 0) {
|
||||
return Fl_Shared_Image::get(create, name, datas);
|
||||
}
|
||||
};
|
||||
|
||||
class FL_IMAGES_API Fl_JPEG_Image : public Fl_Shared_Image {
|
||||
void read();
|
||||
Fl_JPEG_Image() { }
|
||||
static Fl_Shared_Image* create() { return new Fl_JPEG_Image; }
|
||||
public:
|
||||
static int test(const uchar* datas, size_t size=0);
|
||||
void measure(int& W, int& H);
|
||||
static Fl_Shared_Image* get(const char* name, const uchar* datas = 0) {
|
||||
return Fl_Shared_Image::get(create, name, datas);
|
||||
}
|
||||
};
|
||||
|
||||
//class FL_API Fl_Bitmap;
|
||||
class Fl_Bitmap;
|
||||
extern FL_IMAGES_API Fl_Bitmap nosuch_bitmap;
|
||||
|
||||
class FL_IMAGES_API Fl_UNKNOWN_Image {
|
||||
public:
|
||||
static int test(const uchar*, size_t =0) { return 1; };
|
||||
static Fl_Shared_Image* get(const char*, const uchar* = 0) {
|
||||
return (Fl_Shared_Image*) &nosuch_bitmap;
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
// End of "$Id: Fl_Shared_Image.H,v 1.22 2001/07/16 19:38:17 robertk Exp $"
|
||||
//
|
241
FL/Fl_Text_Buffer.H
Normal file
241
FL/Fl_Text_Buffer.H
Normal file
@ -0,0 +1,241 @@
|
||||
//
|
||||
// "$Id: Fl_Text_Buffer.H,v 1.3 2001/02/21 06:15:44 clip Exp $"
|
||||
//
|
||||
// Header file for Fl_Text_Buffer class.
|
||||
//
|
||||
// Copyright Mark Edel. Permission to distribute under the LGPL for
|
||||
// the FLTK library granted by Mark Edel.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA.
|
||||
//
|
||||
// Please report all bugs and problems to "fltk-bugs@fltk.org".
|
||||
//
|
||||
|
||||
#ifndef FL_TEXT_BUFFER_H
|
||||
#define FL_TEXT_BUFFER_H
|
||||
|
||||
/* Maximum length in characters of a tab or control character expansion
|
||||
of a single buffer character */
|
||||
#define FL_TEXT_MAX_EXP_CHAR_LEN 20
|
||||
|
||||
#include <FL/Fl_Export.H>
|
||||
|
||||
class FL_API Fl_Text_Selection {
|
||||
friend class Fl_Text_Buffer;
|
||||
|
||||
public:
|
||||
void set(int start, int end);
|
||||
void set_rectangular(int start, int end, int rectStart, int rectEnd);
|
||||
void update(int pos, int nDeleted, int nInserted);
|
||||
char rectangular() { return mRectangular; }
|
||||
int start() { return mStart; }
|
||||
int end() { return mEnd; }
|
||||
int rect_start() { return mRectStart; }
|
||||
int rect_end() { return mRectEnd; }
|
||||
char selected() { return mSelected; }
|
||||
void selected(char b) { mSelected = b; }
|
||||
int includes(int pos, int lineStartPos, int dispIndex);
|
||||
int position(int* start, int* end);
|
||||
int position(int* start, int* end, int* isRect, int* rectStart, int* rectEnd);
|
||||
|
||||
|
||||
protected:
|
||||
char mSelected;
|
||||
char mRectangular;
|
||||
int mStart;
|
||||
int mEnd;
|
||||
int mRectStart;
|
||||
int mRectEnd;
|
||||
};
|
||||
|
||||
typedef void (*Fl_Text_Modify_Cb)(int pos, int nInserted, int nDeleted,
|
||||
int nRestyled, const char* deletedText,
|
||||
void* cbArg);
|
||||
|
||||
class FL_API Fl_Text_Buffer {
|
||||
public:
|
||||
Fl_Text_Buffer(int requestedSize = 0);
|
||||
~Fl_Text_Buffer();
|
||||
|
||||
int length() { return mLength; }
|
||||
const char* text();
|
||||
void text(const char* text);
|
||||
const char* text_range(int start, int end);
|
||||
char character(int pos);
|
||||
const char* text_in_rectangle(int start, int end, int rectStart, int rectEnd);
|
||||
void insert(int pos, const char* text);
|
||||
void append(const char* text) { insert(length(), text); }
|
||||
void remove(int start, int end);
|
||||
void replace(int start, int end, const char *text);
|
||||
void copy(Fl_Text_Buffer* fromBuf, int fromStart, int fromEnd, int toPos);
|
||||
int insertfile(const char *file, int pos, int buflen = 128*1024);
|
||||
int appendfile(const char *file, int buflen = 128*1024)
|
||||
{ return insertfile(file, length(), buflen); }
|
||||
int loadfile(const char *file, int buflen = 128*1024)
|
||||
{ select(0, length()); remove_selection(); return appendfile(file, buflen); }
|
||||
int outputfile(const char *file, int start, int end, int buflen = 128*1024);
|
||||
int savefile(const char *file, int buflen = 128*1024)
|
||||
{ return outputfile(file, 0, length(), buflen); }
|
||||
|
||||
void insert_column(int column, int startPos, const char* text,
|
||||
int* charsInserted, int* charsDeleted);
|
||||
|
||||
void replace_rectangular(int start, int end, int rectStart, int rectEnd,
|
||||
const char* text);
|
||||
|
||||
void overlay_rectangular(int startPos, int rectStart, int rectEnd,
|
||||
const char* text, int* charsInserted,
|
||||
int* charsDeleted);
|
||||
|
||||
void remove_rectangular(int start, int end, int rectStart, int rectEnd);
|
||||
void clear_rectangular(int start, int end, int rectStart, int rectEnd);
|
||||
int tab_distance() { return mTabDist; }
|
||||
void tab_distance(int tabDist);
|
||||
void select(int start, int end);
|
||||
int selected() { return mPrimary.selected(); }
|
||||
void unselect();
|
||||
void select_rectangular(int start, int end, int rectStart, int rectEnd);
|
||||
int selection_position(int* start, int* end);
|
||||
|
||||
int selection_position(int* start, int* end, int* isRect, int* rectStart,
|
||||
int* rectEnd);
|
||||
|
||||
const char* selection_text();
|
||||
void remove_selection();
|
||||
void replace_selection(const char* text);
|
||||
void secondary_select(int start, int end);
|
||||
void secondary_unselect();
|
||||
|
||||
void secondary_select_rectangular(int start, int end, int rectStart,
|
||||
int rectEnd);
|
||||
|
||||
int secondary_selection_position(int* start, int* end, int* isRect,
|
||||
int* rectStart, int* rectEnd);
|
||||
|
||||
const char* secondary_selection_text();
|
||||
void remove_secondary_selection();
|
||||
void replace_secondary_selection(const char* text);
|
||||
void highlight(int start, int end);
|
||||
void unhighlight();
|
||||
void highlight_rectangular(int start, int end, int rectStart, int rectEnd);
|
||||
|
||||
int highlight_position(int* start, int* end, int* isRect, int* rectStart,
|
||||
int* rectEnd);
|
||||
|
||||
const char* highlight_text();
|
||||
void add_modify_callback(Fl_Text_Modify_Cb bufModifiedCB, void* cbArg);
|
||||
void remove_modify_callback(Fl_Text_Modify_Cb bufModifiedCB, void* cbArg);
|
||||
|
||||
void call_modify_callbacks() { call_modify_callbacks(0, 0, 0, 0, 0); }
|
||||
|
||||
const char* line_text(int pos);
|
||||
int line_start(int pos);
|
||||
int line_end(int pos);
|
||||
int word_start(int pos);
|
||||
int word_end(int pos);
|
||||
int expand_character(int pos, int indent, char *outStr);
|
||||
|
||||
static int expand_character(char c, int indent, char* outStr, int tabDist,
|
||||
char nullSubsChar);
|
||||
|
||||
static int character_width(char c, int indent, int tabDist, char nullSubsChar);
|
||||
int count_displayed_characters(int lineStartPos, int targetPos);
|
||||
int skip_displayed_characters(int lineStartPos, int nChars);
|
||||
int count_lines(int startPos, int endPos);
|
||||
int skip_lines(int startPos, int nLines);
|
||||
int rewind_lines(int startPos, int nLines);
|
||||
int findchar_forward(int startPos, char searchChar, int* foundPos);
|
||||
int findchar_backward(int startPos, char searchChar, int* foundPos);
|
||||
int findchars_forward(int startPos, const char* searchChars, int* foundPos);
|
||||
int findchars_backward(int startPos, const char* searchChars, int* foundPos);
|
||||
|
||||
int search_forward(int startPos, const char* searchString, int* foundPos,
|
||||
int matchCase = 0);
|
||||
|
||||
int search_backward(int startPos, const char* searchString, int* foundPos,
|
||||
int matchCase = 0);
|
||||
|
||||
int substitute_null_characters(char* string, int length);
|
||||
void unsubstitute_null_characters(char* string);
|
||||
char null_substitution_character() { return mNullSubsChar; }
|
||||
Fl_Text_Selection* primary_selection() { return &mPrimary; }
|
||||
Fl_Text_Selection* secondary_selection() { return &mSecondary; }
|
||||
Fl_Text_Selection* highlight_selection() { return &mHighlight; }
|
||||
|
||||
protected:
|
||||
void call_modify_callbacks(int pos, int nDeleted, int nInserted,
|
||||
int nRestyled, const char* deletedText);
|
||||
|
||||
int insert_(int pos, const char* text);
|
||||
void remove_(int start, int end);
|
||||
|
||||
void remove_rectangular_(int start, int end, int rectStart, int rectEnd,
|
||||
int* replaceLen, int* endPos);
|
||||
|
||||
void insert_column_(int column, int startPos, const char* insText,
|
||||
int* nDeleted, int* nInserted, int* endPos);
|
||||
|
||||
void overlay_rectangular_(int startPos, int rectStart, int rectEnd,
|
||||
const char* insText, int* nDeleted,
|
||||
int* nInserted, int* endPos);
|
||||
|
||||
void redisplay_selection(Fl_Text_Selection* oldSelection,
|
||||
Fl_Text_Selection* newSelection);
|
||||
|
||||
void move_gap(int pos);
|
||||
void reallocate_with_gap(int newGapStart, int newGapLen);
|
||||
const char* selection_text_(Fl_Text_Selection* sel);
|
||||
void remove_selection_(Fl_Text_Selection* sel);
|
||||
void replace_selection_(Fl_Text_Selection* sel, const char* text);
|
||||
|
||||
void rectangular_selection_boundaries(int lineStartPos, int rectStart,
|
||||
int rectEnd, int* selStart,
|
||||
int* selEnd);
|
||||
|
||||
void update_selections(int pos, int nDeleted, int nInserted);
|
||||
|
||||
Fl_Text_Selection mPrimary; /* highlighted areas */
|
||||
Fl_Text_Selection mSecondary;
|
||||
Fl_Text_Selection mHighlight;
|
||||
int mLength; /* length of the text in the buffer (the length
|
||||
of the buffer itself must be calculated:
|
||||
gapEnd - gapStart + length) */
|
||||
char* mBuf; /* allocated memory where the text is stored */
|
||||
int mGapStart; /* points to the first character of the gap */
|
||||
int mGapEnd; /* points to the first char after the gap */
|
||||
// The hardware tab distance used by all displays for this buffer,
|
||||
// and used in computing offsets for rectangular selection operations.
|
||||
int mTabDist; /* equiv. number of characters in a tab */
|
||||
int mUseTabs; /* True if buffer routines are allowed to use
|
||||
tabs for padding in rectangular operations */
|
||||
int mNModifyProcs; /* number of modify-redisplay procs attached */
|
||||
Fl_Text_Modify_Cb* /* procedures to call when buffer is */
|
||||
mNodifyProcs; /* modified to redisplay contents */
|
||||
void** mCbArgs; /* caller arguments for modifyProcs above */
|
||||
int mCursorPosHint; /* hint for reasonable cursor position after
|
||||
a buffer modification operation */
|
||||
char mNullSubsChar; /* NEdit is based on C null-terminated strings,
|
||||
so ascii-nul characters must be substituted
|
||||
with something else. This is the else, but
|
||||
of course, things get quite messy when you
|
||||
use it */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
// End of "$Id: Fl_Text_Buffer.H,v 1.3 2001/02/21 06:15:44 clip Exp $".
|
||||
//
|
217
FL/Fl_Text_Display.H
Normal file
217
FL/Fl_Text_Display.H
Normal file
@ -0,0 +1,217 @@
|
||||
//
|
||||
// "$Id: Fl_Text_Display.H,v 1.4 2000/08/20 04:31:36 spitzak Exp $"
|
||||
//
|
||||
// Header file for Fl_Text_Display class.
|
||||
//
|
||||
// Copyright Mark Edel. Permission to distribute under the LGPL for
|
||||
// the FLTK library granted by Mark Edel.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA.
|
||||
//
|
||||
// Please report all bugs and problems to "fltk-bugs@fltk.org".
|
||||
//
|
||||
|
||||
#ifndef FL_TEXT_DISPLAY_H
|
||||
#define FL_TEXT_DISPLAY_H
|
||||
|
||||
#include <FL/fl_draw.H>
|
||||
#include <FL/Fl_Group.H>
|
||||
#include <FL/Fl_Widget.H>
|
||||
#include <FL/Fl_Scrollbar.H>
|
||||
#include <FL/Fl_Text_Buffer.H>
|
||||
|
||||
class FL_API Fl_Text_Display: public Fl_Group {
|
||||
public:
|
||||
enum {
|
||||
NORMAL_CURSOR, CARET_CURSOR, DIM_CURSOR,
|
||||
BLOCK_CURSOR, HEAVY_CURSOR
|
||||
};
|
||||
|
||||
enum {
|
||||
CURSOR_POS, CHARACTER_POS
|
||||
};
|
||||
|
||||
// drag types- they match Fl::event_clicks() so that single clicking to
|
||||
// start a collection selects by character, double clicking selects by
|
||||
// word and triple clicking selects by line.
|
||||
enum {
|
||||
DRAG_CHAR = 0, DRAG_WORD = 1, DRAG_LINE = 2
|
||||
};
|
||||
friend void fl_text_drag_me(int pos, Fl_Text_Display* d);
|
||||
|
||||
typedef void (*Unfinished_Style_Cb)();
|
||||
|
||||
struct FL_API Style_Table_Entry {
|
||||
Fl_Color color;
|
||||
Fl_Font font;
|
||||
int size;
|
||||
};
|
||||
|
||||
Fl_Text_Display(int X, int Y, int W, int H, const char *l = 0);
|
||||
~Fl_Text_Display();
|
||||
|
||||
virtual int handle(int e);
|
||||
void buffer(Fl_Text_Buffer* buf);
|
||||
void buffer(Fl_Text_Buffer& buf) { buffer(&buf); }
|
||||
Fl_Text_Buffer* buffer() { return mBuffer; }
|
||||
void redisplay_range(int start, int end);
|
||||
void scroll(int topLineNum, int horizOffset);
|
||||
void insert(const char* text);
|
||||
void overstrike(const char* text);
|
||||
void insert_position(int newPos);
|
||||
int insert_position() { return mCursorPos; }
|
||||
int in_selection(int x, int y);
|
||||
void show_insert_position();
|
||||
int move_right();
|
||||
int move_left();
|
||||
int move_up();
|
||||
int move_down();
|
||||
void next_word(void);
|
||||
void previous_word(void);
|
||||
void show_cursor(int b = 1);
|
||||
void hide_cursor() { show_cursor(0); }
|
||||
void cursor_style(int style);
|
||||
int scrollbar_width() { return scrollbar_width_; }
|
||||
Fl_Flags scrollbar_align() { return scrollbar_align_; }
|
||||
void scrollbar_width(int w) { scrollbar_width_ = w; }
|
||||
void scrollbar_align(Fl_Flags a) { scrollbar_align_ = a; }
|
||||
int word_start(int pos) { return buffer()->word_start(pos); }
|
||||
int word_end(int pos) { return buffer()->word_end(pos); }
|
||||
|
||||
void highlight_data(Fl_Text_Buffer *styleBuffer,
|
||||
Style_Table_Entry *styleTable,
|
||||
int nStyles, char unfinishedStyle,
|
||||
Unfinished_Style_Cb unfinishedHighlightCB,
|
||||
void *cbArg);
|
||||
|
||||
int position_style(int lineStartPos, int lineLen, int lineIndex,
|
||||
int dispIndex);
|
||||
|
||||
protected:
|
||||
// Most (all?) of this stuff should only be called from layout() or
|
||||
// draw().
|
||||
// Anything with "vline" indicates thats it deals with currently
|
||||
// visible lines.
|
||||
virtual void layout();
|
||||
|
||||
virtual void draw();
|
||||
void draw_text(int X, int Y, int W, int H);
|
||||
void draw_range(int start, int end);
|
||||
void draw_cursor(int, int);
|
||||
|
||||
void draw_string(int style, int x, int y, int toX, const char *string,
|
||||
int nChars);
|
||||
|
||||
void draw_vline(int visLineNum, int leftClip, int rightClip,
|
||||
int leftCharIndex, int rightCharIndex);
|
||||
|
||||
void clear_rect(int style, int x, int y, int width, int height);
|
||||
void display_insert();
|
||||
|
||||
void offset_line_starts(int newTopLineNum);
|
||||
|
||||
void calc_line_starts(int startLine, int endLine);
|
||||
|
||||
void update_line_starts(int pos, int charsInserted, int charsDeleted,
|
||||
int linesInserted, int linesDeleted, int *scrolled);
|
||||
|
||||
void calc_last_char();
|
||||
|
||||
int position_to_line( int pos, int* lineNum );
|
||||
int string_width(const char* string, int length, int style);
|
||||
|
||||
static void buffer_modified_cb(int pos, int nInserted, int nDeleted,
|
||||
int nRestyled, const char* deletedText,
|
||||
void* cbArg);
|
||||
|
||||
static void h_scrollbar_cb(Fl_Scrollbar* w, Fl_Text_Display* d);
|
||||
static void v_scrollbar_cb( Fl_Scrollbar* w, Fl_Text_Display* d);
|
||||
void update_v_scrollbar();
|
||||
void update_h_scrollbar();
|
||||
int measure_vline(int visLineNum);
|
||||
int longest_vline();
|
||||
int empty_vlines();
|
||||
int vline_length(int visLineNum);
|
||||
int xy_to_position(int x, int y, int PosType = CHARACTER_POS);
|
||||
|
||||
void xy_to_rowcol(int x, int y, int* row, int* column,
|
||||
int PosType = CHARACTER_POS);
|
||||
|
||||
int position_to_xy(int pos, int* x, int* y);
|
||||
int position_to_linecol(int pos, int* lineNum, int* column);
|
||||
void scroll_(int topLineNum, int horizOffset);
|
||||
|
||||
void extend_range_for_styles(int* start, int* end);
|
||||
|
||||
|
||||
int damage_range1_start, damage_range1_end;
|
||||
int damage_range2_start, damage_range2_end;
|
||||
int mCursorPos;
|
||||
int mCursorOn;
|
||||
int mCursorOldY; /* Y pos. of cursor for blanking */
|
||||
int mCursorToHint; /* Tells the buffer modified callback
|
||||
where to move the cursor, to reduce
|
||||
the number of redraw calls */
|
||||
int mCursorStyle; /* One of enum cursorStyles above */
|
||||
int mCursorPreferredCol; /* Column for vert. cursor movement */
|
||||
int mNVisibleLines; /* # of visible (displayed) lines */
|
||||
int mNBufferLines; /* # of newlines in the buffer */
|
||||
Fl_Text_Buffer* mBuffer; /* Contains text to be displayed */
|
||||
Fl_Text_Buffer* mStyleBuffer; /* Optional parallel buffer containing
|
||||
color and font information */
|
||||
int mFirstChar, mLastChar; /* Buffer positions of first and last
|
||||
displayed character (lastChar points
|
||||
either to a newline or one character
|
||||
beyond the end of the buffer) */
|
||||
int* mLineStarts;
|
||||
int mTopLineNum; /* Line number of top displayed line
|
||||
of file (first line of file is 1) */
|
||||
int mHorizOffset; /* Horizontal scroll pos. in pixels */
|
||||
int mTopLineNumHint; /* Line number of top displayed line
|
||||
of file (first line of file is 1) */
|
||||
int mHorizOffsetHint; /* Horizontal scroll pos. in pixels */
|
||||
int mVisibility; /* Window visibility (see XVisibility
|
||||
event) */
|
||||
int mNStyles; /* Number of entries in styleTable */
|
||||
Style_Table_Entry *mStyleTable; /* Table of fonts and colors for
|
||||
coloring/syntax-highlighting */
|
||||
char mUnfinishedStyle; /* Style buffer entry which triggers
|
||||
on-the-fly reparsing of region */
|
||||
Unfinished_Style_Cb mUnfinishedHighlightCB; /* Callback to parse "unfinished" */
|
||||
/* regions */
|
||||
void* mHighlightCBArg; /* Arg to unfinishedHighlightCB */
|
||||
|
||||
int mMaxsize;
|
||||
|
||||
int mFixedFontWidth; /* Font width if all current fonts are
|
||||
fixed and match in width, else -1 */
|
||||
|
||||
Fl_Color mCursor_color;
|
||||
|
||||
Fl_Scrollbar* mHScrollBar;
|
||||
Fl_Scrollbar* mVScrollBar;
|
||||
int scrollbar_width_;
|
||||
Fl_Flags scrollbar_align_;
|
||||
int dragPos, dragType, dragging;
|
||||
int display_insert_position_hint;
|
||||
struct { int x, y, w, h; } text_area;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
// End of "$Id: Fl_Text_Display.H,v 1.4 2000/08/20 04:31:36 spitzak Exp $".
|
||||
//
|
105
FL/Fl_Text_Editor.H
Normal file
105
FL/Fl_Text_Editor.H
Normal file
@ -0,0 +1,105 @@
|
||||
//
|
||||
// "$Id: Fl_Text_Editor.H,v 1.1 2000/08/04 10:21:59 clip Exp $"
|
||||
//
|
||||
// Header file for Fl_Text_Editor class.
|
||||
//
|
||||
// Copyright Mark Edel. Permission to distribute under the LGPL for
|
||||
// the FLTK library granted by Mark Edel.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA.
|
||||
//
|
||||
// Please report all bugs and problems to "fltk-bugs@fltk.org".
|
||||
//
|
||||
|
||||
|
||||
#ifndef FL_TEXT_EDITOR_H
|
||||
#define FL_TEXT_EDITOR_H
|
||||
|
||||
#include <FL/Fl_Text_Display.H>
|
||||
|
||||
// key will match in any state
|
||||
#define FL_TEXT_EDITOR_ANY_STATE (-1L)
|
||||
|
||||
class FL_API Fl_Text_Editor : public Fl_Text_Display {
|
||||
public:
|
||||
typedef int (*Key_Func)(int key, Fl_Text_Editor* editor);
|
||||
|
||||
struct FL_API Key_Binding {
|
||||
int key;
|
||||
int state;
|
||||
Key_Func function;
|
||||
Key_Binding* next;
|
||||
};
|
||||
|
||||
Fl_Text_Editor(int X, int Y, int W, int H, const char* l = 0);
|
||||
~Fl_Text_Editor() { remove_all_key_bindings(); }
|
||||
virtual int handle(int e);
|
||||
void insert_mode(int b) { insert_mode_ = b; }
|
||||
int insert_mode() { return insert_mode_; }
|
||||
|
||||
void add_key_binding(int key, int state, Key_Func f, Key_Binding** list);
|
||||
void add_key_binding(int key, int state, Key_Func f)
|
||||
{ add_key_binding(key, state, f, &key_bindings); }
|
||||
void remove_key_binding(int key, int state, Key_Binding** list);
|
||||
void remove_key_binding(int key, int state)
|
||||
{ remove_key_binding(key, state, &key_bindings); }
|
||||
void remove_all_key_bindings(Key_Binding** list);
|
||||
void remove_all_key_bindings() { remove_all_key_bindings(&key_bindings); }
|
||||
void add_default_key_bindings(Key_Binding** list);
|
||||
Key_Func bound_key_function(int key, int state, Key_Binding* list);
|
||||
Key_Func bound_key_function(int key, int state)
|
||||
{ return bound_key_function(key, state, key_bindings); }
|
||||
void default_key_function(Key_Func f) { default_key_function_ = f; }
|
||||
|
||||
// functions for the built in default bindings
|
||||
static int kf_default(int c, Fl_Text_Editor* e);
|
||||
static int kf_ignore(int c, Fl_Text_Editor* e);
|
||||
static int kf_backspace(int c, Fl_Text_Editor* e);
|
||||
static int kf_enter(int c, Fl_Text_Editor* e);
|
||||
static int kf_move(int c, Fl_Text_Editor* e);
|
||||
static int kf_shift_move(int c, Fl_Text_Editor* e);
|
||||
static int kf_ctrl_move(int c, Fl_Text_Editor* e);
|
||||
static int kf_c_s_move(int c, Fl_Text_Editor* e);
|
||||
static int kf_home(int, Fl_Text_Editor* e);
|
||||
static int kf_end(int c, Fl_Text_Editor* e);
|
||||
static int kf_left(int c, Fl_Text_Editor* e);
|
||||
static int kf_up(int c, Fl_Text_Editor* e);
|
||||
static int kf_right(int c, Fl_Text_Editor* e);
|
||||
static int kf_down(int c, Fl_Text_Editor* e);
|
||||
static int kf_page_up(int c, Fl_Text_Editor* e);
|
||||
static int kf_page_down(int c, Fl_Text_Editor* e);
|
||||
static int kf_insert(int c, Fl_Text_Editor* e);
|
||||
static int kf_delete(int c, Fl_Text_Editor* e);
|
||||
static int kf_copy(int c, Fl_Text_Editor* e);
|
||||
static int kf_cut(int c, Fl_Text_Editor* e);
|
||||
static int kf_paste(int c, Fl_Text_Editor* e);
|
||||
static int kf_select_all(int c, Fl_Text_Editor* e);
|
||||
|
||||
protected:
|
||||
int handle_key();
|
||||
|
||||
int insert_mode_;
|
||||
Key_Binding* key_bindings;
|
||||
static Key_Binding* global_key_bindings;
|
||||
Key_Func default_key_function_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
// End of "$Id: Fl_Text_Editor.H,v 1.1 2000/08/04 10:21:59 clip Exp $".
|
||||
//
|
||||
|
72
FL/Fl_Tooltip.H
Normal file
72
FL/Fl_Tooltip.H
Normal file
@ -0,0 +1,72 @@
|
||||
//
|
||||
// "$Id: Fl_Tooltip.H,v 1.16 2001/02/25 01:41:19 clip Exp $"
|
||||
//
|
||||
// Tooltip definitions for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 1998-1999 by Bill Spitzak and others.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA.
|
||||
//
|
||||
// Please report all bugs and problems to "fltk-bugs@easysw.com".
|
||||
//
|
||||
|
||||
#ifndef _FL_TOOLTIP_H_
|
||||
#define _FL_TOOLTIP_H_
|
||||
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/Fl_Widget.H>
|
||||
|
||||
class FL_API Fl_Tooltip {
|
||||
public:
|
||||
static float delay() { return delay_; }
|
||||
static void delay(float f) { delay_ = f; }
|
||||
static int enabled() { return enabled_; }
|
||||
static void enable(int b = 1) { enabled_ = b; }
|
||||
static void disable() { enable(0); }
|
||||
|
||||
// This is called when the pointer enters a widget,
|
||||
// Also enter(0) gets rid of any displayed or pending tooltip:
|
||||
static void (*enter)(Fl_Widget* w);
|
||||
|
||||
// A widget may also pop up tooltips for internal parts by calling this:
|
||||
static void (*enter_area)(Fl_Widget* w, int X, int Y, int W, int H, const char* tip);
|
||||
|
||||
// This is called when a widget is destroyed or hidden:
|
||||
static void (*exit)(Fl_Widget *w);
|
||||
|
||||
static Fl_Style* style() { return default_style; }
|
||||
static Fl_Font font() { return style()->label_font; }
|
||||
static void font(Fl_Font i) { style()->label_font = i; }
|
||||
static unsigned size() { return style()->label_size; }
|
||||
static void size(unsigned s) { style()->label_size = s; }
|
||||
static void color(Fl_Color c) { style()->color = c; }
|
||||
static Fl_Color color() { return style()->color; }
|
||||
static void textcolor(Fl_Color c) {style()->label_color = c; }
|
||||
static Fl_Color textcolor() { return style()->label_color; }
|
||||
static void boxtype(Fl_Boxtype b) {style()->box = b; }
|
||||
static Fl_Boxtype boxtype() { return style()->box; }
|
||||
|
||||
private:
|
||||
static Fl_Named_Style* default_style;
|
||||
static float delay_;
|
||||
static int enabled_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
// End of "$Id: Fl_Tooltip.H,v 1.16 2001/02/25 01:41:19 clip Exp $".
|
||||
//
|
142
documentation/Fl_Image.html
Normal file
142
documentation/Fl_Image.html
Normal file
@ -0,0 +1,142 @@
|
||||
<head><title>Fl_Image</title></head><body bgcolor=white>
|
||||
|
||||
<h1>class Fl_Image</h1>
|
||||
|
||||
This class holds an image, normally used to label a widget. The
|
||||
subclasses define how the data is interpreted, and usually store
|
||||
server-side cached versions of the image. All the current types
|
||||
define pixel arrays, but other types of images, such as vector
|
||||
graphics, can be defined.
|
||||
|
||||
<h2>Methods</h2>
|
||||
|
||||
<h4>ulong id, mask;<br>
|
||||
void _draw(int X, int Y, int W, int H, int cx, int cy);</h4>
|
||||
|
||||
Subclasses may use these <i>protected</i> members of the base class to
|
||||
draw a cached pixel array. They must first set <tt>id</tt> and
|
||||
<tt>mask</tt> to the color and transparency offscreen windows, using
|
||||
system-specific code. Then they can call <tt>_draw()</tt> to draw
|
||||
them.
|
||||
|
||||
<h4>int w,h</h4>
|
||||
|
||||
These members hold the width and height of the image. They are not
|
||||
correct until <tt>measure()</tt> is called. These are public instance
|
||||
variables for back comptability, but you should never set them.
|
||||
|
||||
<h4>virtual void Fl_Image::measure(int W, int H);</h4>
|
||||
|
||||
Measure how big the image will be if it is drawn inside a W,H
|
||||
rectangle and put the result into w,h. For most image types this does
|
||||
nothing and w,h are set by the constructor. This may be used to
|
||||
initialize the scaling for variable-sized images.
|
||||
|
||||
<h4>virtual void Fl_Image::draw(int x,int y,int w,int h, int cx,int
|
||||
cy);</h4>
|
||||
|
||||
Draw the image so the point <i>cx,cy</i> of the image is at
|
||||
<i>x,y</i>. The image may be scaled or clipped to fit in the <i>w,h</i>
|
||||
rectangle, but this is not necessary (although obeying the current
|
||||
fl_clip value is!).
|
||||
|
||||
<h4>void Fl_Image::draw(int x,int y,int w,int h, Fl_Flags align);</h4>
|
||||
|
||||
This <i>non-virtual</i> function uses <tt>measure()</tt> and the
|
||||
<i>align</i> flags to figure out <i>cx,cy</i> and call the normal draw
|
||||
function. This allows you to center or align any edge of the image
|
||||
with a bounding box.
|
||||
|
||||
<h4>virtual Fl_Image::~Fl_Image();</h4>
|
||||
|
||||
The destructor throws away any server-cached information, but in most
|
||||
cases does not destroy the local data passed to a constructor.
|
||||
|
||||
<H2><A name=Fl_Bitmap>class Fl_Bitmap : public Fl_Image</A></H2>
|
||||
This object encapsulates the width, height, and bits of an X bitmap
|
||||
(XBM), and allows you to make an <TT>Fl_Widget</TT> use a bitmap as a
|
||||
label, or to just draw the bitmap directly.
|
||||
|
||||
<H4>Fl_Bitmap(const char *bits, int W, int H)
|
||||
<BR> Fl_Bitmap(const uchar *bits, int W, int H)</H4>
|
||||
Construct using an X bitmap. The bits pointer is simply copied to the
|
||||
object, so it must point at persistent storage. The two constructors
|
||||
are provided because various X implementations disagree about the type
|
||||
of bitmap data. To use an XBM file use:
|
||||
<UL>
|
||||
<PRE>
|
||||
#include "foo.xbm"
|
||||
...
|
||||
Fl_Bitmap bitmap = new Fl_Bitmap(foo_bits, foo_width, foo_height);
|
||||
</PRE>
|
||||
</UL>
|
||||
<H4>~Fl_Bitmap()</H4>
|
||||
The destructor will destroy any X pixmap created. It does not do
|
||||
anything to the bits data.
|
||||
<H4>void draw(int x, int y, int w, int h, int ox = 0, int oy = 0)</H4>
|
||||
1 bits are drawn with the current color, 0 bits
|
||||
are unchanged.
|
||||
The image is clipped to the destination rectangle: the area
|
||||
<TT>ox,oy,w,h</TT> is copied to <TT>x,y,w,h</TT>.
|
||||
<H4>void draw(int x, int y)</H4>
|
||||
Draws the bitmap with the upper-left corner at <TT>x,y</TT>. This is
|
||||
the same as doing <TT>draw(x,y,this->w,this->h,0,0)</TT>.
|
||||
|
||||
<H2><A name=Fl_Pixmap>class Fl_Pixmap : public Fl_Image</A></H2>
|
||||
|
||||
This object encapsulates the data from an XPM image, and allows you to
|
||||
make an <TT>Fl_Widget</TT> use a pixmap as a label, or to just draw
|
||||
the pixmap directly.
|
||||
|
||||
<H4>Fl_Pixmap(char *const* data)</H4>
|
||||
Construct using XPM data. The data pointer is simply copied to the
|
||||
object, so it must point at persistent storage. To use an XPM file do:
|
||||
<UL>
|
||||
<PRE>
|
||||
#include <fltk/Fl_Pixmap.h>
|
||||
#include "foo.xpm"
|
||||
...
|
||||
Fl_Pixmap pixmap = new Fl_Pixmap(foo);
|
||||
</PRE>
|
||||
</UL>
|
||||
<H4>~Fl_Pixmap()</H4>
|
||||
The destructor will destroy any X pixmap created. It does not do
|
||||
anything to the data.
|
||||
|
||||
<H4>void draw(int x, int y, int w, int h, int ox = 0, int oy = 0)</H4>
|
||||
The image is clipped to the destination rectangle: the area
|
||||
<TT>ox,oy,w,h</TT> is copied to <TT>x,y,w,h</TT>. The current
|
||||
implementation converts the pixmap to 24-bit RGB data and uses <A
|
||||
href=#fl_draw_image><TT>fl_draw_image()</TT></A> to draw it. Thus you
|
||||
will get dithered colors on an 8 bit screen. </P>
|
||||
|
||||
<H4>void draw(int x, int y)</H4>
|
||||
Draws the image with the upper-left corner at <TT>x,y</TT>. This is
|
||||
the same as doing <TT>draw(x,y,this->w,this->h,0,0)</TT>.
|
||||
|
||||
<H2><A name=Fl_RGB_Image>class Fl_RGB_Image</A></H2>
|
||||
|
||||
This object encapsulates a full-color RGB image, and allows you to
|
||||
make an <TT>Fl_Widget</TT> use an image as a label, or to just draw the
|
||||
image directly.
|
||||
|
||||
<H4>Fl_RGB_Image(const uchar *data, int W, int H, int D = 3, int LD = 0)</H4>
|
||||
Construct using a pointer to RGB data. <TT>W</TT> and <TT>H</TT> are
|
||||
the size of the image in pixels. <TT>D</TT> is the delta between pixels
|
||||
(it may be more than 3 to skip alpha or other data, or negative to flip
|
||||
the image left/right). <TT>LD</TT> is the delta between lines (it may
|
||||
be more than <TT>D * W</TT> to crop images, or negative to flip the
|
||||
image vertically). The data pointer is simply copied to the object, so
|
||||
it must point at persistent storage.
|
||||
<H4>~Fl_RGB_Image()</H4>
|
||||
The destructor will destroy any X pixmap created. It does not do
|
||||
anything to the data.
|
||||
<H4>void draw(int x, int y, int w, int h, int ox = 0, int oy = 0)</H4>
|
||||
The image is clipped to the destination rectangle: the area
|
||||
<TT>ox,oy,w,h</TT> is copied to <TT>x,y,w,h</TT>.
|
||||
<H4>void draw(int x, int y)</H4>
|
||||
Draws the image with the upper-left corner at <TT>x,y</TT>. This is
|
||||
the same as doing <TT>draw(x,y,this->w,this->h,0,0)</TT>.
|
||||
|
||||
</body></html>
|
||||
|
446
src/Fl_FileBrowser.cxx
Normal file
446
src/Fl_FileBrowser.cxx
Normal file
@ -0,0 +1,446 @@
|
||||
//
|
||||
// "$Id: Fl_FileBrowser.cxx,v 1.13 2001/07/29 22:04:43 spitzak Exp $"
|
||||
//
|
||||
// Fl_FileBrowser routines for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 1997-1999 by Easy Software Products.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA.
|
||||
//
|
||||
// Please report all bugs and problems to "fltk-bugs@easysw.com".
|
||||
//
|
||||
// Contents:
|
||||
//
|
||||
// Fl_Fl_FileBrowser::item_width() - Return the width of a list item.
|
||||
// Fl_Fl_FileBrowser::item_draw() - Draw a list item.
|
||||
// Fl_Fl_FileBrowser::FileBrowser() - Create a FileBrowser widget.
|
||||
// Fl_Fl_FileBrowser::load() - Load a directory into the browser.
|
||||
// Fl_Fl_FileBrowser::filter() - Set the filename filter.
|
||||
//
|
||||
|
||||
//
|
||||
// Include necessary header files...
|
||||
//
|
||||
|
||||
#include <fltk/Fl_FileBrowser.h>
|
||||
#include <fltk/fl_draw.h>
|
||||
#include <fltk/filename.h>
|
||||
#include <fltk/vsnprintf.h>
|
||||
#include <stdlib.h>
|
||||
#include <config.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
# include <windows.h>
|
||||
# include <direct.h>
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#if defined(__EMX__)
|
||||
#define INCL_DOS
|
||||
#define INCL_DOSMISC
|
||||
#include <os2.h>
|
||||
#endif /* __EMX__ */
|
||||
|
||||
//
|
||||
// FL_BLINE definition from "Fl_Browser.cxx"...
|
||||
//
|
||||
|
||||
#define SELECTED 1
|
||||
#define NOTDISPLAYED 2
|
||||
|
||||
struct FL_BLINE // data is in a linked list of these
|
||||
{
|
||||
FL_BLINE *prev; // Previous item in list
|
||||
FL_BLINE *next; // Next item in list
|
||||
void *data; // Pointer to data (function)
|
||||
short length; // sizeof(txt)-1, may be longer than string
|
||||
char flags; // selected, displayed
|
||||
char txt[1]; // start of allocated array
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// 'Fl_FileBrowser::item_height()' - Return the height of a list item.
|
||||
//
|
||||
|
||||
int // O - Height in pixels
|
||||
Fl_FileBrowser::item_height(void *p) const // I - List item data
|
||||
{
|
||||
FL_BLINE *line; // Pointer to line
|
||||
char *text; // Pointer into text
|
||||
int height; // Width of line
|
||||
int textheight; // Height of text
|
||||
|
||||
|
||||
// Figure out the standard text height...
|
||||
textheight = fl_height(textfont(), textsize())+leading();
|
||||
|
||||
// We always have at least 1 line...
|
||||
height = textheight;
|
||||
|
||||
// Scan for newlines...
|
||||
line = (FL_BLINE *)p;
|
||||
|
||||
if (line != NULL)
|
||||
for (text = line->txt; *text != '\0'; text ++)
|
||||
if (*text == '\n')
|
||||
height += textheight;
|
||||
|
||||
// If we have enabled icons then add space for them...
|
||||
if (Fl_FileIcon::first() != NULL && height < iconsize_)
|
||||
height = iconsize_;
|
||||
|
||||
// Add space for the selection border..
|
||||
height += 2;
|
||||
|
||||
// Return the height
|
||||
return (height);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 'Fl_FileBrowser::item_width()' - Return the width of a list item.
|
||||
//
|
||||
|
||||
int // O - Width in pixels
|
||||
Fl_FileBrowser::item_width(void *p) const // I - List item data
|
||||
{
|
||||
FL_BLINE *line; // Pointer to line
|
||||
char *text, // Pointer into text
|
||||
*ptr, // Pointer into fragment
|
||||
fragment[10240]; // Fragment of text
|
||||
int width, // Width of line
|
||||
tempwidth; // Width of fragment
|
||||
int column; // Current column
|
||||
|
||||
|
||||
// Set the font and size...
|
||||
fl_font(text_font(), text_size());
|
||||
|
||||
// Scan for newlines...
|
||||
line = (FL_BLINE *)p;
|
||||
|
||||
if (strchr(line->txt, '\n') == NULL &&
|
||||
strchr(line->txt, '\t') == NULL)
|
||||
{
|
||||
// Do a fast width calculation...
|
||||
width = fl_width(line->txt);
|
||||
}
|
||||
else
|
||||
{
|
||||
// More than 1 line or have columns; find the maximum width...
|
||||
width = 0;
|
||||
tempwidth = 0;
|
||||
column = 0;
|
||||
|
||||
for (text = line->txt, ptr = fragment; *text != '\0'; text ++)
|
||||
if (*text == '\n')
|
||||
{
|
||||
// Newline - nul terminate this fragment and get the width...
|
||||
*ptr = '\0';
|
||||
|
||||
tempwidth += fl_width(fragment);
|
||||
|
||||
// Update the max width as needed...
|
||||
if (tempwidth > width)
|
||||
width = tempwidth;
|
||||
|
||||
// Point back to the start of the fragment...
|
||||
ptr = fragment;
|
||||
tempwidth = 0;
|
||||
}
|
||||
else if (*text == '\t')
|
||||
{
|
||||
// Advance to the next column...
|
||||
column ++;
|
||||
tempwidth = column * fl_width(" ");
|
||||
|
||||
if (tempwidth > width)
|
||||
width = tempwidth;
|
||||
|
||||
ptr = fragment;
|
||||
}
|
||||
else
|
||||
*ptr++ = *text;
|
||||
|
||||
if (ptr > fragment)
|
||||
{
|
||||
// Nul terminate this fragment and get the width...
|
||||
*ptr = '\0';
|
||||
|
||||
tempwidth += fl_width(fragment);
|
||||
|
||||
// Update the max width as needed...
|
||||
if (tempwidth > width)
|
||||
width = tempwidth;
|
||||
}
|
||||
}
|
||||
|
||||
// If we have enabled icons then add space for them...
|
||||
if (Fl_FileIcon::first() != NULL)
|
||||
width += iconsize_ + 8;
|
||||
|
||||
// Add space for the selection border..
|
||||
width += 2;
|
||||
|
||||
// Return the width
|
||||
return (width);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 'Fl_FileBrowser::item_draw()' - Draw a list item.
|
||||
//
|
||||
|
||||
void
|
||||
Fl_FileBrowser::item_draw(void *p, // I - List item data
|
||||
int x, // I - Upper-lefthand X coordinate
|
||||
int y, // I - Upper-lefthand Y coordinate
|
||||
int w, // I - Width of item
|
||||
int h) const // I - Height of item
|
||||
{
|
||||
Fl_Color c; // Color of text
|
||||
FL_BLINE *line; // Pointer to line
|
||||
|
||||
|
||||
puts("Fl_FileBrowser::item_draw()");
|
||||
// Draw the list item text...
|
||||
line = (FL_BLINE *)p;
|
||||
|
||||
fl_font(text_font(), text_size());
|
||||
if (line->flags & SELECTED)
|
||||
c = fl_contrast(text_color(), selection_color());
|
||||
else
|
||||
c = text_color();
|
||||
|
||||
if (active_r())
|
||||
fl_color(c);
|
||||
else
|
||||
fl_color(fl_inactive(c));
|
||||
|
||||
if (Fl_FileIcon::first() == NULL)
|
||||
{
|
||||
// No icons, just draw the text...
|
||||
fl_draw(line->txt, x + 1, y, w - 2, h, FL_ALIGN_LEFT);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Icons; draw the text offset to the right...
|
||||
fl_draw(line->txt, x + iconsize_ + 9, y, w - iconsize_ - 10, h,
|
||||
FL_ALIGN_LEFT);
|
||||
|
||||
// And then draw the icon if it is set...
|
||||
if (line->data)
|
||||
((Fl_FileIcon *)line->data)->draw(x, y, iconsize_, iconsize_,
|
||||
(line->flags & SELECTED) ? FL_YELLOW :
|
||||
FL_LIGHT2,
|
||||
active_r());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 'Fl_FileBrowser::Fl_FileBrowser()' - Create a Fl_FileBrowser widget.
|
||||
//
|
||||
|
||||
Fl_FileBrowser::Fl_FileBrowser(int x, // I - Upper-lefthand X coordinate
|
||||
int y, // I - Upper-lefthand Y coordinate
|
||||
int w, // I - Width in pixels
|
||||
int h, // I - Height in pixels
|
||||
const char *l) // I - Label text
|
||||
: Fl_Browser(x, y, w, h, l)
|
||||
{
|
||||
// Initialize the filter pattern, current directory, and icon size...
|
||||
pattern_ = "*";
|
||||
directory_ = "";
|
||||
iconsize_ = 20; // This looks best for the default icons, if loaded...
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 'Fl_FileBrowser::load()' - Load a directory into the browser.
|
||||
//
|
||||
|
||||
int // O - Number of files loaded
|
||||
Fl_FileBrowser::load(const char *directory)// I - Directory to load
|
||||
{
|
||||
int i; // Looping var
|
||||
int num_files; // Number of files in directory
|
||||
char filename[4096]; // Current file
|
||||
Fl_FileIcon *icon; // Icon to use
|
||||
|
||||
|
||||
clear();
|
||||
directory_ = directory;
|
||||
|
||||
if (directory_[0] == '\0')
|
||||
{
|
||||
//
|
||||
// No directory specified; for UNIX list all mount points. For DOS
|
||||
// list all valid drive letters...
|
||||
//
|
||||
|
||||
num_files = 0;
|
||||
icon = Fl_FileIcon::find("any", Fl_FileIcon::DEVICE);
|
||||
|
||||
if (icon == (Fl_FileIcon *)0)
|
||||
icon = Fl_FileIcon::find("any", Fl_FileIcon::DIR);
|
||||
|
||||
#if defined(_WIN32)
|
||||
DWORD drives; // Drive available bits
|
||||
|
||||
drives = GetLogicalDrives();
|
||||
for (i = 'A'; i <= 'Z'; i ++, drives >>= 1)
|
||||
if (drives & 1)
|
||||
{
|
||||
sprintf(filename, "%c:", i);
|
||||
add(filename, icon);
|
||||
|
||||
num_files ++;
|
||||
}
|
||||
#elif defined(__EMX__)
|
||||
ULONG curdrive; // Current drive
|
||||
ULONG drives; // Drive available bits
|
||||
int start = 3; // 'C' (MRS - dunno if this is correct!)
|
||||
|
||||
|
||||
DosQueryCurrentDisk(&curdrive, &drives);
|
||||
drives >>= start - 1;
|
||||
for (i = 'A'; i <= 'Z'; i ++, drives >>= 1)
|
||||
if (drives & 1)
|
||||
{
|
||||
sprintf(filename, "%c:", i);
|
||||
add(filename, icon);
|
||||
|
||||
num_files ++;
|
||||
}
|
||||
#else
|
||||
FILE *mtab; // /etc/mtab or /etc/mnttab file
|
||||
char line[1024]; // Input line
|
||||
|
||||
//
|
||||
// Open the file that contains a list of mounted filesystems...
|
||||
//
|
||||
# if defined(__hpux) || defined(__sun)
|
||||
mtab = fopen("/etc/mnttab", "r"); // Fairly standard
|
||||
# elif defined(__sgi) || defined(linux)
|
||||
mtab = fopen("/etc/mtab", "r"); // More standard
|
||||
# else
|
||||
mtab = fopen("/etc/fstab", "r"); // Otherwise fallback to full list
|
||||
if (mtab == NULL)
|
||||
mtab = fopen("/etc/vfstab", "r");
|
||||
# endif
|
||||
|
||||
if (mtab != NULL)
|
||||
{
|
||||
while (fgets(line, sizeof(line), mtab) != NULL)
|
||||
{
|
||||
if (line[0] == '#' || line[0] == '\n')
|
||||
continue;
|
||||
if (sscanf(line, "%*s%4095s", filename) != 1)
|
||||
continue;
|
||||
|
||||
add(filename, icon);
|
||||
num_files ++;
|
||||
}
|
||||
|
||||
fclose(mtab);
|
||||
}
|
||||
#endif // _WIN32
|
||||
}
|
||||
else
|
||||
{
|
||||
dirent **files; // Files in in directory
|
||||
|
||||
|
||||
//
|
||||
// Build the file list...
|
||||
//
|
||||
|
||||
#if defined(_WIN32) || defined(__EMX__)
|
||||
strncpy(filename, directory_, sizeof(filename) - 1);
|
||||
filename[sizeof(filename) - 1] = '\0';
|
||||
|
||||
i = strlen(filename) - 1;
|
||||
|
||||
if (i == 2 && filename[1] == ':' &&
|
||||
(filename[2] == '/' || filename[2] == '\\'))
|
||||
filename[2] = '/';
|
||||
else if (filename[i] != '/' && filename[i] != '\\')
|
||||
strcat(filename, "/");
|
||||
|
||||
num_files = filename_list(filename, &files);
|
||||
#else
|
||||
num_files = filename_list(directory_, &files);
|
||||
#endif /* _WIN32 || __EMX__ */
|
||||
|
||||
if (num_files <= 0)
|
||||
return (0);
|
||||
|
||||
// Add directories first...
|
||||
for (i = 0; i < num_files; i ++)
|
||||
if (strcmp(files[i]->d_name, ".") != 0 &&
|
||||
strcmp(files[i]->d_name, "..") != 0)
|
||||
{
|
||||
snprintf(filename, sizeof(filename), "%s/%s", directory_, files[i]->d_name);
|
||||
|
||||
if (filename_isdir(filename))
|
||||
add(files[i]->d_name, Fl_FileIcon::find(filename));
|
||||
}
|
||||
|
||||
for (i = 0; i < num_files; i ++)
|
||||
{
|
||||
if (strcmp(files[i]->d_name, ".") != 0 &&
|
||||
strcmp(files[i]->d_name, "..") != 0)
|
||||
{
|
||||
snprintf(filename, sizeof(filename), "%s/%s", directory_, files[i]->d_name);
|
||||
|
||||
if (!filename_isdir(filename) &&
|
||||
filename_match(files[i]->d_name, pattern_))
|
||||
add(files[i]->d_name, Fl_FileIcon::find(filename));
|
||||
}
|
||||
|
||||
free(files[i]);
|
||||
}
|
||||
|
||||
free(files);
|
||||
}
|
||||
|
||||
return (num_files);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 'Fl_FileBrowser::filter()' - Set the filename filter.
|
||||
//
|
||||
|
||||
void
|
||||
Fl_FileBrowser::filter(const char *pattern) // I - Pattern string
|
||||
{
|
||||
// If pattern is NULL set the pattern to "*"...
|
||||
if (pattern)
|
||||
pattern_ = pattern;
|
||||
else
|
||||
pattern_ = "*";
|
||||
|
||||
// Reload the current directory...
|
||||
load(directory_);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// End of "$Id: Fl_FileBrowser.cxx,v 1.13 2001/07/29 22:04:43 spitzak Exp $".
|
||||
//
|
248
src/Fl_FileChooser.cxx
Normal file
248
src/Fl_FileChooser.cxx
Normal file
@ -0,0 +1,248 @@
|
||||
// generated by Fast Light User Interface Designer (fluid) version 2.0000
|
||||
|
||||
#include <fltk/Fl_FileChooser.h>
|
||||
#include <fltk/vsnprintf.h>
|
||||
|
||||
inline void Fl_FileChooser::cb_window_i(Fl_Window*, void*) {
|
||||
fileList->deselect();
|
||||
fileName->value("");
|
||||
window->hide();
|
||||
}
|
||||
void Fl_FileChooser::cb_window(Fl_Window* o, void* v) {
|
||||
((Fl_FileChooser*)(o->user_data()))->cb_window_i(o,v);
|
||||
}
|
||||
|
||||
inline void Fl_FileChooser::cb_dirMenu_i(Fl_Choice*, void*) {
|
||||
if (dirMenu->value())
|
||||
directory(dirMenu->text(dirMenu->value()));
|
||||
else
|
||||
directory("");
|
||||
}
|
||||
void Fl_FileChooser::cb_dirMenu(Fl_Choice* o, void* v) {
|
||||
((Fl_FileChooser*)(o->parent()->user_data()))->cb_dirMenu_i(o,v);
|
||||
}
|
||||
|
||||
inline void Fl_FileChooser::cb_upButton_i(Fl_Button*, void*) {
|
||||
up();
|
||||
}
|
||||
void Fl_FileChooser::cb_upButton(Fl_Button* o, void* v) {
|
||||
((Fl_FileChooser*)(o->parent()->user_data()))->cb_upButton_i(o,v);
|
||||
}
|
||||
|
||||
#include <fltk/Fl_Bitmap.h>
|
||||
static unsigned char bits_up[] =
|
||||
"\0\0x\0\204\0\2\1""1\376y\200\375\200""1\200""1\200""1\200""1\200""1\200\1\
|
||||
\200\1\200\377\377\0\0";
|
||||
static Fl_Bitmap bitmap_up(bits_up, 16, 16);
|
||||
|
||||
inline void Fl_FileChooser::cb_newButton_i(Fl_Button*, void*) {
|
||||
newdir();
|
||||
}
|
||||
void Fl_FileChooser::cb_newButton(Fl_Button* o, void* v) {
|
||||
((Fl_FileChooser*)(o->parent()->user_data()))->cb_newButton_i(o,v);
|
||||
}
|
||||
|
||||
static unsigned char bits_new[] =
|
||||
"\0\0x\0\204\0\2\1\1\376\1\200""1\200""1\200\375\200\375\200""1\200""1\200\1\
|
||||
\200\1\200\377\377\0\0";
|
||||
static Fl_Bitmap bitmap_new(bits_new, 16, 16);
|
||||
|
||||
inline void Fl_FileChooser::cb__i(Fl_Button*, void*) {
|
||||
fileList->filter("*");;
|
||||
rescan();
|
||||
}
|
||||
void Fl_FileChooser::cb_(Fl_Button* o, void* v) {
|
||||
((Fl_FileChooser*)(o->parent()->user_data()))->cb__i(o,v);
|
||||
}
|
||||
|
||||
static unsigned char bits_allfiles[] =
|
||||
"\374?\4 \4 \4 \204!\244%\304#\364/\364/\304#\244%\204!\4 \4 \4 \374?";
|
||||
static Fl_Bitmap bitmap_allfiles(bits_allfiles, 16, 16);
|
||||
|
||||
inline void Fl_FileChooser::cb_fileList_i(Fl_FileBrowser*, void*) {
|
||||
fileListCB();
|
||||
}
|
||||
void Fl_FileChooser::cb_fileList(Fl_FileBrowser* o, void* v) {
|
||||
((Fl_FileChooser*)(o->parent()->user_data()))->cb_fileList_i(o,v);
|
||||
}
|
||||
|
||||
inline void Fl_FileChooser::cb_fileName_i(Fl_FileInput*, void*) {
|
||||
fileNameCB();
|
||||
}
|
||||
void Fl_FileChooser::cb_fileName(Fl_FileInput* o, void* v) {
|
||||
((Fl_FileChooser*)(o->parent()->user_data()))->cb_fileName_i(o,v);
|
||||
}
|
||||
|
||||
inline void Fl_FileChooser::cb_okButton_i(Fl_Return_Button*, void*) {
|
||||
char pathname[1024];
|
||||
|
||||
snprintf(pathname, sizeof(pathname), "%s/%s",
|
||||
fileList->directory(), fileName->value());
|
||||
if (filename_isdir(pathname))
|
||||
directory(pathname);
|
||||
else
|
||||
window->hide();
|
||||
}
|
||||
void Fl_FileChooser::cb_okButton(Fl_Return_Button* o, void* v) {
|
||||
((Fl_FileChooser*)(o->parent()->user_data()))->cb_okButton_i(o,v);
|
||||
}
|
||||
|
||||
inline void Fl_FileChooser::cb_Cancel_i(Fl_Button*, void*) {
|
||||
fileList->deselect();
|
||||
fileName->value("");
|
||||
window->hide();
|
||||
}
|
||||
void Fl_FileChooser::cb_Cancel(Fl_Button* o, void* v) {
|
||||
((Fl_FileChooser*)(o->parent()->user_data()))->cb_Cancel_i(o,v);
|
||||
}
|
||||
|
||||
Fl_FileChooser::Fl_FileChooser(const char *d, const char *p, int t, const char *title) {
|
||||
{ Fl_Window* o = window = new Fl_Window(375, 315, "Pick a File");
|
||||
o->callback((Fl_Callback*)cb_window, (void*)(this));
|
||||
((Fl_Window*)(o))->hotspot(o);
|
||||
{ Fl_Choice* o = dirMenu = new Fl_Choice(65, 10, 210, 25, "Directory:"); o->begin();
|
||||
o->callback((Fl_Callback*)cb_dirMenu);
|
||||
o->tooltip("Click to access directory tree.");
|
||||
o->set_flag(FL_ALIGN_LEFT | FL_ALIGN_RIGHT);
|
||||
o->align(FL_ALIGN_LEFT | FL_ALIGN_RIGHT);
|
||||
o->end();
|
||||
}
|
||||
{ Fl_Button* o = upButton = new Fl_Button(280, 10, 25, 25);
|
||||
o->image(bitmap_up);
|
||||
o->label_size(8);
|
||||
o->callback((Fl_Callback*)cb_upButton);
|
||||
o->tooltip("Click to display parent directory.");
|
||||
}
|
||||
{ Fl_Button* o = newButton = new Fl_Button(310, 10, 25, 25);
|
||||
o->image(bitmap_new);
|
||||
o->label_size(8);
|
||||
o->callback((Fl_Callback*)cb_newButton);
|
||||
o->tooltip("Click to create a new directory.");
|
||||
}
|
||||
{ Fl_Button* o = new Fl_Button(340, 10, 25, 25);
|
||||
o->image(bitmap_allfiles);
|
||||
o->label_color((Fl_Color)4);
|
||||
o->label_size(28);
|
||||
o->callback((Fl_Callback*)cb_);
|
||||
o->align(FL_ALIGN_CENTER|FL_ALIGN_INSIDE);
|
||||
o->tooltip("Click to show all files.");
|
||||
}
|
||||
{ Fl_FileBrowser* o = fileList = new Fl_FileBrowser(10, 45, 355, 180);
|
||||
o->callback((Fl_Callback*)cb_fileList);
|
||||
Fl_Group::current()->resizable(o);
|
||||
o->tooltip("Double-click to change directories.");
|
||||
}
|
||||
{ Fl_FileInput* o = fileName = new Fl_FileInput(10, 245, 355, 25, "Filename:");
|
||||
o->callback((Fl_Callback*)cb_fileName);
|
||||
o->align(FL_ALIGN_TOP | FL_ALIGN_LEFT);
|
||||
o->when(FL_WHEN_ENTER_KEY);
|
||||
o->tooltip("Type a filename or directory name here.");
|
||||
fileName->when(FL_WHEN_CHANGED | FL_WHEN_ENTER_KEY_ALWAYS);
|
||||
}
|
||||
{ Fl_Return_Button* o = okButton = new Fl_Return_Button(240, 280, 55, 25, "OK");
|
||||
o->shortcut(0xff0d);
|
||||
o->callback((Fl_Callback*)cb_okButton);
|
||||
}
|
||||
{ Fl_Button* o = new Fl_Button(300, 280, 65, 25, "Cancel");
|
||||
o->callback((Fl_Callback*)cb_Cancel);
|
||||
}
|
||||
if (title) window->label(title);
|
||||
o->set_modal();
|
||||
o->end();
|
||||
}
|
||||
window->size_range(345, 270, 345);
|
||||
fileList->filter(p);
|
||||
type(t);
|
||||
value(d);
|
||||
}
|
||||
|
||||
void Fl_FileChooser::color(Fl_Color c) {
|
||||
fileList->color(c);
|
||||
}
|
||||
|
||||
Fl_Color Fl_FileChooser::color() {
|
||||
return (fileList->color());
|
||||
}
|
||||
|
||||
char * Fl_FileChooser::directory() {
|
||||
return directory_;
|
||||
}
|
||||
|
||||
void Fl_FileChooser::filter(const char *p) {
|
||||
fileList->filter(p);
|
||||
rescan();
|
||||
}
|
||||
|
||||
const char * Fl_FileChooser::filter() {
|
||||
return (fileList->filter());
|
||||
}
|
||||
|
||||
void Fl_FileChooser::hide() {
|
||||
window->hide();
|
||||
}
|
||||
|
||||
void Fl_FileChooser::iconsize(uchar s) {
|
||||
fileList->iconsize(s);
|
||||
}
|
||||
|
||||
uchar Fl_FileChooser::iconsize() {
|
||||
return (fileList->iconsize());
|
||||
}
|
||||
|
||||
void Fl_FileChooser::label(const char *l) {
|
||||
window->label(l);
|
||||
}
|
||||
|
||||
const char * Fl_FileChooser::label() {
|
||||
return (window->label());
|
||||
}
|
||||
|
||||
void Fl_FileChooser::exec() {
|
||||
window->exec();
|
||||
fileList->deselect();
|
||||
}
|
||||
|
||||
void Fl_FileChooser::textcolor(Fl_Color c) {
|
||||
fileList->textcolor(c);
|
||||
fileList->text_color(c);
|
||||
}
|
||||
|
||||
Fl_Color Fl_FileChooser::textcolor() {
|
||||
return (fileList->textcolor());
|
||||
}
|
||||
|
||||
void Fl_FileChooser::textfont(Fl_Font f) {
|
||||
fileList->text_font(f);
|
||||
}
|
||||
|
||||
Fl_Font Fl_FileChooser::textfont() {
|
||||
return (fileList->text_font());
|
||||
}
|
||||
|
||||
void Fl_FileChooser::textsize(uchar s) {
|
||||
fileList->text_size(s);
|
||||
}
|
||||
|
||||
uchar Fl_FileChooser::textsize() {
|
||||
return (fileList->textsize());
|
||||
}
|
||||
|
||||
void Fl_FileChooser::type(int t) {
|
||||
type_ = t;
|
||||
if (t == MULTI)
|
||||
fileList->type(FL_MULTI_BROWSER);
|
||||
else
|
||||
fileList->type(FL_HOLD_BROWSER);
|
||||
if (t != CREATE)
|
||||
newButton->deactivate();
|
||||
else
|
||||
newButton->activate();
|
||||
}
|
||||
|
||||
int Fl_FileChooser::type() {
|
||||
return (type_);
|
||||
}
|
||||
|
||||
int Fl_FileChooser::visible() {
|
||||
return window->visible();
|
||||
}
|
208
src/Fl_FileChooser.fl
Normal file
208
src/Fl_FileChooser.fl
Normal file
@ -0,0 +1,208 @@
|
||||
# data file for the FLTK User Interface Designer (FLUID)
|
||||
version 2.0000
|
||||
images_dir ./
|
||||
do_not_include_H_from_C
|
||||
header_name {.H}
|
||||
code_name {.cxx}
|
||||
gridx 5
|
||||
gridy 5
|
||||
snap 3
|
||||
decl {\#include <fltk/Fl_FileChooser.h>} {}
|
||||
|
||||
decl {\#include <config.h>} {}
|
||||
|
||||
class Fl_FileChooser {open
|
||||
} {
|
||||
decl {enum { SINGLE, MULTI, CREATE };} {public
|
||||
}
|
||||
Function {Fl_FileChooser(const char *d, const char *p, int t, const char *title)} {open
|
||||
} {
|
||||
Fl_Window window {
|
||||
label {Pick a File}
|
||||
callback {fileList->deselect();
|
||||
fileName->value("");
|
||||
window->hide();} open
|
||||
xywh {269 372 375 315} resizable hotspot
|
||||
code0 {if (title) window->label(title);}
|
||||
code1 {\#include <stdio.h>}
|
||||
code2 {\#include <stdlib.h>}
|
||||
code3 {\#include <string.h>} modal visible
|
||||
} {
|
||||
Fl_Choice dirMenu {
|
||||
label {Directory:}
|
||||
callback {if (dirMenu->value())
|
||||
directory(dirMenu->text(dirMenu->value()));
|
||||
else
|
||||
directory("");} open
|
||||
tooltip {Click to access directory tree.}
|
||||
private xywh {65 10 210 25}
|
||||
code0 {o->set_flag(FL_ALIGN_LEFT | FL_ALIGN_RIGHT);
|
||||
o->align(FL_ALIGN_LEFT | FL_ALIGN_RIGHT);}
|
||||
} {}
|
||||
Fl_Button upButton {
|
||||
callback {up();}
|
||||
tooltip {Click to display parent directory.}
|
||||
private xywh {280 10 25 25} image not_inlined {up.xbm} labelsize 8
|
||||
}
|
||||
Fl_Button newButton {
|
||||
callback {newdir();}
|
||||
tooltip {Click to create a new directory.}
|
||||
private xywh {310 10 25 25} image not_inlined {new.xbm} labelsize 8
|
||||
}
|
||||
Fl_Button {} {
|
||||
callback {fileList->filter("*");;
|
||||
rescan();}
|
||||
tooltip {Click to show all files.}
|
||||
private xywh {340 10 25 25} align 524304 image not_inlined {allfiles.xbm} labelcolor 4 labelsize 28
|
||||
}
|
||||
Fl_Browser fileList {
|
||||
callback {fileListCB();}
|
||||
tooltip {Double-click to change directories.}
|
||||
private xywh {10 45 355 180} resizable
|
||||
code0 {\#include "filename.H"}
|
||||
code1 {\#include <fltk/Fl_FileBrowser.h>}
|
||||
class Fl_FileBrowser
|
||||
}
|
||||
Fl_Input fileName {
|
||||
label {Filename:}
|
||||
callback {fileNameCB();} selected
|
||||
tooltip {Type a filename or directory name here.}
|
||||
private xywh {10 245 355 25} align 5 when 8
|
||||
code0 {fileName->when(FL_WHEN_CHANGED | FL_WHEN_ENTER_KEY_ALWAYS);}
|
||||
code1 {\#include <fltk/Fl_FileInput.h>}
|
||||
class Fl_FileInput
|
||||
}
|
||||
Fl_Return_Button okButton {
|
||||
label OK
|
||||
callback {char pathname[1024];
|
||||
|
||||
snprintf(pathname, sizeof(pathname), "%s/%s",
|
||||
fileList->directory(), fileName->value());
|
||||
if (filename_isdir(pathname))
|
||||
directory(pathname);
|
||||
else
|
||||
window->hide();}
|
||||
private xywh {240 280 55 25} shortcut 0xff0d
|
||||
}
|
||||
Fl_Button {} {
|
||||
label Cancel
|
||||
callback {fileList->deselect();
|
||||
fileName->value("");
|
||||
window->hide();}
|
||||
private xywh {300 280 65 25}
|
||||
}
|
||||
}
|
||||
code {window->size_range(345, 270, 345);
|
||||
fileList->filter(p);
|
||||
type(t);
|
||||
value(d);} {}
|
||||
}
|
||||
decl {char directory_[1024];} {}
|
||||
decl {int type_;} {}
|
||||
decl {void fileListCB();} {}
|
||||
decl {void fileNameCB();} {}
|
||||
decl {void newdir();} {}
|
||||
decl {void up();} {}
|
||||
Function {color(Fl_Color c)} {} {
|
||||
code {fileList->color(c);} {}
|
||||
}
|
||||
Function {color()} {return_type Fl_Color
|
||||
} {
|
||||
code {return (fileList->color());} {}
|
||||
}
|
||||
decl {int count();} {public
|
||||
}
|
||||
decl {void directory(const char *d);} {public
|
||||
}
|
||||
Function {directory()} {return_type {char *}
|
||||
} {
|
||||
code {return directory_;} {}
|
||||
}
|
||||
Function {filter(const char *p)} {return_type void
|
||||
} {
|
||||
code {fileList->filter(p);
|
||||
rescan();} {}
|
||||
}
|
||||
Function {filter()} {return_type {const char *}
|
||||
} {
|
||||
code {return (fileList->filter());} {}
|
||||
}
|
||||
Function {hide()} {return_type void
|
||||
} {
|
||||
code {window->hide();} {}
|
||||
}
|
||||
Function {iconsize(uchar s)} {return_type void
|
||||
} {
|
||||
code {fileList->iconsize(s);} {}
|
||||
}
|
||||
Function {iconsize()} {return_type uchar
|
||||
} {
|
||||
code {return (fileList->iconsize());} {}
|
||||
}
|
||||
Function {label(const char *l)} {return_type void
|
||||
} {
|
||||
code {window->label(l);} {}
|
||||
}
|
||||
Function {label()} {return_type {const char *}
|
||||
} {
|
||||
code {return (window->label());} {}
|
||||
}
|
||||
decl {void rescan();} {public
|
||||
}
|
||||
Function {exec()} {return_type void
|
||||
} {
|
||||
code {window->exec();
|
||||
fileList->deselect();} {}
|
||||
}
|
||||
Function {textcolor(Fl_Color c)} {return_type void
|
||||
} {
|
||||
code {fileList->textcolor(c);
|
||||
fileList->text_color(c);} {}
|
||||
}
|
||||
Function {textcolor()} {return_type Fl_Color
|
||||
} {
|
||||
code {return (fileList->textcolor());
|
||||
return (fileList->textcolor());} {}
|
||||
}
|
||||
Function {textfont(Fl_Font f)} {return_type void
|
||||
} {
|
||||
code {fileList->text_font(f);} {}
|
||||
}
|
||||
Function {textfont()} {return_type Fl_Font
|
||||
} {
|
||||
code {return (fileList->text_font());
|
||||
return (fileList->textfont());} {}
|
||||
}
|
||||
Function {textsize(uchar s)} {return_type void
|
||||
} {
|
||||
code {fileList->text_size(s);} {}
|
||||
}
|
||||
Function {textsize()} {return_type uchar
|
||||
} {
|
||||
code {return (fileList->textsize());} {}
|
||||
}
|
||||
Function {type(int t)} {return_type void
|
||||
} {
|
||||
code {type_ = t;
|
||||
if (t == MULTI)
|
||||
fileList->type(FL_MULTI_BROWSER);
|
||||
else
|
||||
fileList->type(FL_HOLD_BROWSER);
|
||||
if (t != CREATE)
|
||||
newButton->deactivate();
|
||||
else
|
||||
newButton->activate();} {}
|
||||
}
|
||||
Function {type()} {return_type int
|
||||
} {
|
||||
code {return (type_);} {}
|
||||
}
|
||||
decl {const char *value(int f = 1);} {public
|
||||
}
|
||||
decl {void value(const char *filename);} {public
|
||||
}
|
||||
Function {visible()} {return_type int
|
||||
} {
|
||||
code {return window->visible();} {}
|
||||
}
|
||||
}
|
669
src/Fl_FileChooser2.cxx
Normal file
669
src/Fl_FileChooser2.cxx
Normal file
@ -0,0 +1,669 @@
|
||||
//
|
||||
// "$Id: Fl_FileChooser2.cxx,v 1.15 2001/07/29 22:04:43 spitzak Exp $"
|
||||
//
|
||||
// More Fl_FileChooser routines for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 1997-2000 by Easy Software Products.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA.
|
||||
//
|
||||
// Please report all bugs and problems to "fltk-bugs@easysw.com".
|
||||
//
|
||||
// Contents:
|
||||
//
|
||||
// Fl_FileChooser::directory() - Set the directory in the file chooser.
|
||||
// Fl_FileChooser::count() - Return the number of selected files.
|
||||
// Fl_FileChooser::value() - Return a selected filename.
|
||||
// Fl_FileChooser::up() - Go up one directory.
|
||||
// Fl_FileChooser::newdir() - Make a new directory.
|
||||
// Fl_FileChooser::rescan() - Rescan the current directory.
|
||||
// Fl_FileChooser::fileListCB() - Handle clicks (and double-clicks) in the
|
||||
// FileBrowser.
|
||||
// Fl_FileChooser::fileNameCB() - Handle text entry in the FileBrowser.
|
||||
//
|
||||
|
||||
//
|
||||
// Include necessary headers.
|
||||
//
|
||||
|
||||
#include <fltk/Fl_FileChooser.h>
|
||||
#include <fltk/filename.h>
|
||||
#include <fltk/fl_ask.h>
|
||||
#include <fltk/vsnprintf.h>
|
||||
#include <fltk/x.h>
|
||||
#include <config.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
# include <direct.h>
|
||||
# include <io.h>
|
||||
#else
|
||||
# include <unistd.h>
|
||||
# include <pwd.h>
|
||||
#endif /* _WIN32 */
|
||||
|
||||
//
|
||||
// 'Fl_FileChooser::directory()' - Set the directory in the file chooser.
|
||||
//
|
||||
|
||||
void
|
||||
Fl_FileChooser::directory(const char *d) // I - Directory to change to
|
||||
{
|
||||
char pathname[1024], // Full path of directory
|
||||
*pathptr, // Pointer into full path
|
||||
*dirptr; // Pointer into directory
|
||||
int levels; // Number of levels in directory
|
||||
|
||||
|
||||
// NULL == current directory
|
||||
if (d == NULL)
|
||||
d = ".";
|
||||
|
||||
if (d[0] != '\0')
|
||||
{
|
||||
// Make the directory absolute...
|
||||
#if defined(_WIN32) || defined(__EMX__)
|
||||
if (d[0] != '/' && d[0] != '\\' && d[1] != ':')
|
||||
#else
|
||||
if (d[0] != '/' && d[0] != '\\')
|
||||
#endif /* _WIN32 || __EMX__ */
|
||||
filename_absolute(directory_, d);
|
||||
else
|
||||
{
|
||||
strncpy(directory_, d, sizeof(directory_) - 1);
|
||||
directory_[sizeof(directory_) - 1] = '\0';
|
||||
}
|
||||
|
||||
// Strip any trailing slash and/or period...
|
||||
dirptr = directory_ + strlen(directory_) - 1;
|
||||
if (*dirptr == '.')
|
||||
*dirptr-- = '\0';
|
||||
if ((*dirptr == '/' || *dirptr == '\\') && dirptr > directory_)
|
||||
*dirptr = '\0';
|
||||
}
|
||||
else
|
||||
directory_[0] = '\0';
|
||||
|
||||
// Clear the directory menu and fill it as needed...
|
||||
dirMenu->clear();
|
||||
#if defined(_WIN32) || defined(__EMX__)
|
||||
dirMenu->add("My Computer");
|
||||
#else
|
||||
dirMenu->add("File Systems");
|
||||
#endif /* _WIN32 || __EMX__ */
|
||||
|
||||
levels = 0;
|
||||
for (dirptr = directory_, pathptr = pathname; *dirptr != '\0';)
|
||||
{
|
||||
if (*dirptr == '/' || *dirptr == '\\')
|
||||
{
|
||||
// Need to quote the slash first, and then add it to the menu...
|
||||
*pathptr++ = '\\';
|
||||
*pathptr++ = '/';
|
||||
*pathptr = '\0';
|
||||
dirptr ++;
|
||||
|
||||
dirMenu->add(pathname);
|
||||
levels ++;
|
||||
}
|
||||
else
|
||||
*pathptr++ = *dirptr++;
|
||||
}
|
||||
|
||||
if (pathptr > pathname)
|
||||
{
|
||||
*pathptr = '\0';
|
||||
dirMenu->add(pathname);
|
||||
levels ++;
|
||||
}
|
||||
|
||||
dirMenu->value(levels);
|
||||
dirMenu->redraw();
|
||||
|
||||
// Rescan the directory...
|
||||
rescan();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 'Fl_FileChooser::count()' - Return the number of selected files.
|
||||
//
|
||||
|
||||
int // O - Number of selected files
|
||||
Fl_FileChooser::count()
|
||||
{
|
||||
int i; // Looping var
|
||||
int count; // Number of selected files
|
||||
const char *filename; // Filename in input field or list
|
||||
char pathname[1024]; // Full path to file
|
||||
|
||||
|
||||
if (type_ != MULTI)
|
||||
{
|
||||
// Check to see if the file name input field is blank...
|
||||
filename = fileName->value();
|
||||
if (filename == NULL || filename[0] == '\0')
|
||||
return (0);
|
||||
|
||||
// Is the file name a directory?
|
||||
if (directory_[0] != '\0')
|
||||
snprintf(pathname, sizeof(pathname), "%s/%s", directory_, filename);
|
||||
else
|
||||
{
|
||||
strncpy(pathname, filename, sizeof(pathname) - 1);
|
||||
pathname[sizeof(pathname) - 1] = '\0';
|
||||
}
|
||||
|
||||
if (filename_isdir(pathname))
|
||||
return (0);
|
||||
else
|
||||
return (1);
|
||||
}
|
||||
|
||||
for (i = 0, count = 0; i < fileList->size(); i ++)
|
||||
if (fileList->selected(i))
|
||||
{
|
||||
// See if this file is a directory...
|
||||
filename = (char *)fileList->text(i);
|
||||
if (directory_[0] != '\0')
|
||||
snprintf(pathname, sizeof(pathname), "%s/%s", directory_, filename);
|
||||
else
|
||||
{
|
||||
strncpy(pathname, filename, sizeof(pathname) - 1);
|
||||
pathname[sizeof(pathname) - 1] = '\0';
|
||||
}
|
||||
|
||||
if (!filename_isdir(pathname))
|
||||
count ++;
|
||||
}
|
||||
|
||||
return (count);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 'Fl_FileChooser::value()' - Return a selected filename.
|
||||
//
|
||||
|
||||
const char * // O - Filename or NULL
|
||||
Fl_FileChooser::value(int f) // I - File number
|
||||
{
|
||||
int i; // Looping var
|
||||
int count; // Number of selected files
|
||||
const char *name; // Current filename
|
||||
static char pathname[1024]; // Filename + directory
|
||||
|
||||
|
||||
if (type_ != MULTI)
|
||||
{
|
||||
name = fileName->value();
|
||||
if (name[0] == '\0')
|
||||
return (NULL);
|
||||
|
||||
snprintf(pathname, sizeof(pathname), "%s/%s", directory_, name);
|
||||
return ((const char *)pathname);
|
||||
}
|
||||
|
||||
for (i = 0, count = 0; i < fileList->size(); i ++)
|
||||
if (fileList->selected(i))
|
||||
{
|
||||
// See if this file is a directory...
|
||||
name = fileList->text(i);
|
||||
snprintf(pathname, sizeof(pathname), "%s/%s", directory_, name);
|
||||
|
||||
if (!filename_isdir(pathname))
|
||||
{
|
||||
// Nope, see if this this is "the one"...
|
||||
count ++;
|
||||
if (count == f)
|
||||
return ((const char *)pathname);
|
||||
}
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 'Fl_FileChooser::value()' - Set the current filename.
|
||||
//
|
||||
|
||||
void
|
||||
Fl_FileChooser::value(const char *filename) // I - Filename + directory
|
||||
{
|
||||
int i, // Looping var
|
||||
count; // Number of items in list
|
||||
char *slash; // Directory separator
|
||||
char pathname[1024]; // Local copy of filename
|
||||
|
||||
|
||||
// See if the filename is actually a directory...
|
||||
if (filename == NULL || filename_isdir(filename))
|
||||
{
|
||||
// Yes, just change the current directory...
|
||||
directory(filename);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!filename[0])
|
||||
{
|
||||
// Just show the current directory...
|
||||
directory(NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
// Switch to single-selection mode as needed
|
||||
if (type_ == MULTI)
|
||||
type(SINGLE);
|
||||
|
||||
// See if there is a directory in there...
|
||||
strncpy(pathname, filename, sizeof(pathname) - 1);
|
||||
pathname[sizeof(pathname) - 1] = '\0';
|
||||
|
||||
if ((slash = strrchr(pathname, '/')) == NULL)
|
||||
slash = strrchr(pathname, '\\');
|
||||
|
||||
if (slash != NULL)
|
||||
{
|
||||
// Yes, change the display to the directory...
|
||||
*slash++ = '\0';
|
||||
directory(pathname);
|
||||
}
|
||||
else
|
||||
{
|
||||
directory(NULL);
|
||||
slash = pathname;
|
||||
}
|
||||
|
||||
// Set the input field to the remaining portion
|
||||
fileName->value(slash);
|
||||
fileName->position(0, strlen(slash));
|
||||
okButton->activate();
|
||||
|
||||
// Then find the file in the file list and select it...
|
||||
count = fileList->size();
|
||||
|
||||
for (i = 0; i < count; i ++)
|
||||
if (strcmp(fileList->text(i), slash) == 0)
|
||||
{
|
||||
fileList->select(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 'Fl_FileChooser::up()' - Go up one directory.
|
||||
//
|
||||
|
||||
void
|
||||
Fl_FileChooser::up()
|
||||
{
|
||||
char *slash; // Trailing slash
|
||||
|
||||
|
||||
if ((slash = strrchr(directory_, '/')) == NULL)
|
||||
slash = strrchr(directory_, '\\');
|
||||
|
||||
if (directory_[0] != '\0')
|
||||
dirMenu->value(dirMenu->value() - 1);
|
||||
|
||||
if (slash != NULL)
|
||||
*slash = '\0';
|
||||
else
|
||||
{
|
||||
upButton->deactivate();
|
||||
directory_[0] = '\0';
|
||||
}
|
||||
|
||||
rescan();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 'Fl_FileChooser::newdir()' - Make a new directory.
|
||||
//
|
||||
|
||||
void
|
||||
Fl_FileChooser::newdir()
|
||||
{
|
||||
const char *dir; // New directory name
|
||||
char pathname[1024]; // Full path of directory
|
||||
|
||||
|
||||
// Get a directory name from the user
|
||||
if ((dir = fl_input("New Directory?")) == NULL)
|
||||
return;
|
||||
|
||||
// Make it relative to the current directory as needed...
|
||||
#if defined(_WIN32) || defined(__EMX__)
|
||||
if (dir[0] != '/' && dir[0] != '\\' && dir[1] != ':')
|
||||
#else
|
||||
if (dir[0] != '/' && dir[0] != '\\')
|
||||
#endif /* _WIN32 || __EMX__ */
|
||||
snprintf(pathname, sizeof(pathname), "%s/%s", directory_, dir);
|
||||
else
|
||||
{
|
||||
strncpy(pathname, dir, sizeof(pathname) - 1);
|
||||
pathname[sizeof(pathname) - 1] = '\0';
|
||||
}
|
||||
|
||||
// Create the directory; ignore EEXIST errors...
|
||||
#if defined(_WIN32)
|
||||
if (mkdir(pathname))
|
||||
#else
|
||||
if (mkdir(pathname, 0777))
|
||||
#endif /* _WIN32 || __EMX__ */
|
||||
if (errno != EEXIST)
|
||||
{
|
||||
fl_alert("Unable to create directory!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Show the new directory...
|
||||
directory(pathname);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 'Fl_FileChooser::rescan()' - Rescan the current directory.
|
||||
//
|
||||
|
||||
void
|
||||
Fl_FileChooser::rescan()
|
||||
{
|
||||
// Clear the current filename
|
||||
fileName->value("");
|
||||
okButton->deactivate();
|
||||
|
||||
// Build the file list...
|
||||
fileList->load(directory_);
|
||||
fileList->redraw();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 'Fl_FileChooser::fileListCB()' - Handle clicks (and double-clicks) in the
|
||||
// FileBrowser.
|
||||
//
|
||||
|
||||
void
|
||||
Fl_FileChooser::fileListCB()
|
||||
{
|
||||
char filename[1024], // New filename
|
||||
pathname[1024]; // Full pathname to file
|
||||
|
||||
|
||||
strncpy(filename, fileList->text(fileList->value()), sizeof(filename) - 1);
|
||||
filename[sizeof(filename) - 1] = '\0';
|
||||
|
||||
#if defined(_WIN32) || defined(__EMX__)
|
||||
if (directory_[0] != '\0' && filename[0] != '/' && filename[0] != '\\' &&
|
||||
!(isalpha(filename[0]) && filename[1] == ':'))
|
||||
snprintf(pathname, sizeof(pathname), "%s/%s", directory_, filename);
|
||||
else
|
||||
{
|
||||
strncpy(pathname, filename, sizeof(pathname) - 1);
|
||||
pathname[sizeof(pathname) - 1] = '\0';
|
||||
}
|
||||
#else
|
||||
if (directory_[0] != '\0' && filename[0] != '/')
|
||||
snprintf(pathname, sizeof(pathname), "%s/%s", directory_, filename);
|
||||
else
|
||||
{
|
||||
strncpy(pathname, filename, sizeof(pathname) - 1);
|
||||
pathname[sizeof(pathname) - 1] = '\0';
|
||||
}
|
||||
#endif /* _WIN32 || __EMX__ */
|
||||
|
||||
if (Fl::event_clicks() || Fl::event_key() == FL_Enter)
|
||||
{
|
||||
puts("double-click");
|
||||
if (filename_isdir(pathname))
|
||||
{
|
||||
puts("directory");
|
||||
directory(pathname);
|
||||
upButton->activate();
|
||||
}
|
||||
else
|
||||
window->hide();
|
||||
}
|
||||
else
|
||||
{
|
||||
fileName->value(filename);
|
||||
okButton->activate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 'Fl_FileChooser::fileNameCB()' - Handle text entry in the FileBrowser.
|
||||
//
|
||||
|
||||
void
|
||||
Fl_FileChooser::fileNameCB()
|
||||
{
|
||||
char *filename, // New filename
|
||||
*slash, // Pointer to trailing slash
|
||||
pathname[1024]; // Full pathname to file
|
||||
int i, // Looping var
|
||||
min_match, // Minimum number of matching chars
|
||||
max_match, // Maximum number of matching chars
|
||||
num_files, // Number of files in directory
|
||||
first_line; // First matching line
|
||||
const char *file; // File from directory
|
||||
|
||||
|
||||
// Get the filename from the text field...
|
||||
filename = (char *)fileName->value();
|
||||
|
||||
if (filename == NULL || filename[0] == '\0')
|
||||
{
|
||||
okButton->deactivate();
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(_WIN32) || defined(__EMX__)
|
||||
if (directory_[0] != '\0' && filename[0] != '/' && filename[0] != '\\' &&
|
||||
!(isalpha(filename[0]) && filename[1] == ':'))
|
||||
snprintf(pathname, sizeof(pathname), "%s/%s", directory_, filename);
|
||||
else
|
||||
{
|
||||
strncpy(pathname, filename, sizeof(pathname) - 1);
|
||||
pathname[sizeof(pathname) - 1] = '\0';
|
||||
}
|
||||
#else
|
||||
if (filename[0] == '~')
|
||||
{
|
||||
// Lookup user...
|
||||
struct passwd *pwd;
|
||||
|
||||
if (!filename[1] || filename[1] == '/')
|
||||
pwd = getpwuid(getuid());
|
||||
else
|
||||
{
|
||||
strncpy(pathname, filename + 1, sizeof(pathname) - 1);
|
||||
pathname[sizeof(pathname) - 1] = '\0';
|
||||
|
||||
i = strlen(pathname) - 1;
|
||||
if (pathname[i] == '/')
|
||||
pathname[i] = '\0';
|
||||
|
||||
pwd = getpwnam(pathname);
|
||||
}
|
||||
|
||||
if (pwd)
|
||||
{
|
||||
strncpy(pathname, pwd->pw_dir, sizeof(pathname) - 1);
|
||||
pathname[sizeof(pathname) - 1] = '\0';
|
||||
|
||||
if (filename[strlen(filename) - 1] == '/')
|
||||
strncat(pathname, "/", sizeof(pathname) - strlen(pathname) - 1);
|
||||
}
|
||||
else
|
||||
snprintf(pathname, sizeof(pathname), "%s/%s", directory_, filename);
|
||||
|
||||
endpwent();
|
||||
}
|
||||
else if (directory_[0] != '\0' && filename[0] != '/')
|
||||
snprintf(pathname, sizeof(pathname), "%s/%s", directory_, filename);
|
||||
else
|
||||
{
|
||||
strncpy(pathname, filename, sizeof(pathname) - 1);
|
||||
pathname[sizeof(pathname) - 1] = '\0';
|
||||
}
|
||||
#endif /* _WIN32 || __EMX__ */
|
||||
|
||||
if (Fl::event_key() == FL_Enter)
|
||||
{
|
||||
// Enter pressed - select or change directory...
|
||||
if (filename_isdir(pathname))
|
||||
directory(pathname);
|
||||
else if (type_ == CREATE || access(pathname, 0) == 0)
|
||||
{
|
||||
// New file or file exists... If we are in multiple selection mode,
|
||||
// switch to single selection mode...
|
||||
if (type_ == MULTI)
|
||||
type(SINGLE);
|
||||
|
||||
// Hide the window to signal things are done...
|
||||
window->hide();
|
||||
}
|
||||
else
|
||||
{
|
||||
// File doesn't exist, so alert the user...
|
||||
fl_alert("Please choose an existing file!");
|
||||
}
|
||||
}
|
||||
else if (Fl::event_key() != FL_Delete)
|
||||
{
|
||||
// Check to see if the user has entered a directory...
|
||||
if ((slash = strrchr(filename, '/')) == NULL)
|
||||
slash = strrchr(filename, '\\');
|
||||
|
||||
if (slash != NULL)
|
||||
{
|
||||
// Yes, change directories and update the file name field...
|
||||
if ((slash = strrchr(pathname, '/')) == NULL)
|
||||
slash = strrchr(pathname, '\\');
|
||||
|
||||
if (slash > pathname) // Special case for "/"
|
||||
*slash++ = '\0';
|
||||
else
|
||||
slash++;
|
||||
|
||||
if (strcmp(filename, "../") == 0) // Special case for "../"
|
||||
up();
|
||||
else
|
||||
directory(pathname);
|
||||
|
||||
// If the string ended after the slash, we're done for now...
|
||||
if (*slash == '\0')
|
||||
return;
|
||||
|
||||
// Otherwise copy the remainder and proceed...
|
||||
fileName->value(slash);
|
||||
fileName->position(strlen(slash));
|
||||
filename = slash;
|
||||
}
|
||||
|
||||
// Other key pressed - do filename completion as possible...
|
||||
num_files = fileList->size();
|
||||
min_match = strlen(filename);
|
||||
max_match = 100000;
|
||||
first_line = 0;
|
||||
|
||||
for (i = 0; i < num_files && max_match > min_match; i ++)
|
||||
{
|
||||
file = fileList->text(i);
|
||||
|
||||
#if defined(_WIN32) || defined(__EMX__)
|
||||
if (strnicmp(filename, file, min_match) == 0)
|
||||
#else
|
||||
if (strncmp(filename, file, min_match) == 0)
|
||||
#endif // _WIN32 || __EMX__
|
||||
{
|
||||
// OK, this one matches; check against the previous match
|
||||
if (max_match == 100000)
|
||||
{
|
||||
// First match; copy stuff over...
|
||||
strncpy(pathname, file, sizeof(pathname) - 1);
|
||||
pathname[sizeof(pathname) - 1] = '\0';
|
||||
max_match = strlen(pathname);
|
||||
|
||||
// And then make sure that the item is visible
|
||||
fileList->topline(i);
|
||||
first_line = i;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Succeeding match; compare to find maximum string match...
|
||||
while (max_match > min_match)
|
||||
#if defined(_WIN32) || defined(__EMX__)
|
||||
if (strnicmp(file, pathname, max_match) == 0)
|
||||
#else
|
||||
if (strncmp(file, pathname, max_match) == 0)
|
||||
#endif // _WIN32 || __EMX__
|
||||
break;
|
||||
else
|
||||
max_match --;
|
||||
|
||||
// Truncate the string as needed...
|
||||
pathname[max_match] = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fileList->deselect(0);
|
||||
fileList->redraw();
|
||||
|
||||
// If we have any matches, add them to the input field...
|
||||
if (first_line > 0 && min_match == max_match &&
|
||||
max_match == (int)strlen(fileList->text(first_line)))
|
||||
fileList->select(first_line);
|
||||
else if (max_match > min_match && max_match != 100000)
|
||||
{
|
||||
// Add the matching portion...
|
||||
fileName->replace(0, min_match, pathname, strlen(pathname));
|
||||
|
||||
// Highlight it; if the user just pressed the backspace
|
||||
// key, position the cursor at the start of the selection.
|
||||
// Otherwise, put the cursor at the end of the selection so
|
||||
// s/he can press the right arrow to accept the selection
|
||||
// (Tab and End also do this for both cases.)
|
||||
if (Fl::event_key() == FL_BackSpace)
|
||||
fileName->position(min_match - 1, max_match);
|
||||
else
|
||||
fileName->position(max_match, min_match);
|
||||
}
|
||||
|
||||
// See if we need to enable the OK button...
|
||||
snprintf(pathname, sizeof(pathname), "%s/%s", directory_, fileName->value());
|
||||
|
||||
if (type_ == CREATE || access(pathname, 0) == 0)
|
||||
okButton->activate();
|
||||
else
|
||||
okButton->deactivate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// End of "$Id: Fl_FileChooser2.cxx,v 1.15 2001/07/29 22:04:43 spitzak Exp $".
|
||||
//
|
329
src/Fl_FileIcon.cxx
Normal file
329
src/Fl_FileIcon.cxx
Normal file
@ -0,0 +1,329 @@
|
||||
//
|
||||
// "$Id: Fl_FileIcon.cxx,v 1.10 2001/07/29 22:04:43 spitzak Exp $"
|
||||
//
|
||||
// Fl_FileIcon routines for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 1997-1999 by Easy Software Products.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA.
|
||||
//
|
||||
// Please report all bugs and problems to "fltk-bugs@easysw.com".
|
||||
//
|
||||
// Contents:
|
||||
//
|
||||
// Fl_FileIcon::Fl_FileIcon() - Create a new file icon.
|
||||
// Fl_FileIcon::~Fl_FileIcon() - Remove a file icon.
|
||||
// Fl_FileIcon::add() - Add data to an icon.
|
||||
// Fl_FileIcon::find() - Find an icon based upon a given file.
|
||||
// Fl_FileIcon::draw() - Draw an icon.
|
||||
//
|
||||
|
||||
//
|
||||
// Include necessary header files...
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#ifdef _WIN32
|
||||
# include <io.h>
|
||||
# define F_OK 0
|
||||
#else
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <fltk/Fl_FileIcon.h>
|
||||
#include <fltk/Fl_Widget.h>
|
||||
#include <fltk/fl_draw.h>
|
||||
#include <fltk/filename.h>
|
||||
|
||||
|
||||
//
|
||||
// Define missing POSIX/XPG4 macros as needed...
|
||||
//
|
||||
|
||||
#ifndef S_ISDIR
|
||||
# define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
|
||||
# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
|
||||
# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
|
||||
# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
|
||||
# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
|
||||
#endif /* !S_ISDIR */
|
||||
|
||||
|
||||
//
|
||||
// Icon cache...
|
||||
//
|
||||
|
||||
Fl_FileIcon *Fl_FileIcon::first_ = (Fl_FileIcon *)0;
|
||||
|
||||
|
||||
//
|
||||
// 'Fl_FileIcon::Fl_FileIcon()' - Create a new file icon.
|
||||
//
|
||||
|
||||
Fl_FileIcon::Fl_FileIcon(const char *p, /* I - Filename pattern */
|
||||
int t, /* I - File type */
|
||||
int nd, /* I - Number of data values */
|
||||
short *d) /* I - Data values */
|
||||
{
|
||||
// Initialize the pattern and type...
|
||||
pattern_ = p;
|
||||
type_ = t;
|
||||
|
||||
// Copy icon data as needed...
|
||||
if (nd)
|
||||
{
|
||||
num_data_ = nd;
|
||||
alloc_data_ = nd + 1;
|
||||
data_ = (short *)calloc(sizeof(short), nd + 1);
|
||||
memcpy(data_, d, nd * sizeof(short));
|
||||
}
|
||||
else
|
||||
{
|
||||
num_data_ = 0;
|
||||
alloc_data_ = 0;
|
||||
}
|
||||
|
||||
// And add the icon to the list of icons...
|
||||
next_ = first_;
|
||||
first_ = this;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 'Fl_FileIcon::~Fl_FileIcon()' - Remove a file icon.
|
||||
//
|
||||
|
||||
Fl_FileIcon::~Fl_FileIcon()
|
||||
{
|
||||
Fl_FileIcon *current, // Current icon in list
|
||||
*prev; // Previous icon in list
|
||||
|
||||
|
||||
// Find the icon in the list...
|
||||
for (current = first_, prev = (Fl_FileIcon *)0;
|
||||
current != this && current != (Fl_FileIcon *)0;
|
||||
prev = current, current = current->next_);
|
||||
|
||||
// Remove the icon from the list as needed...
|
||||
if (current)
|
||||
{
|
||||
if (prev)
|
||||
prev->next_ = current->next_;
|
||||
else
|
||||
first_ = current->next_;
|
||||
}
|
||||
|
||||
// Free any memory used...
|
||||
if (alloc_data_)
|
||||
free(data_);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 'Fl_FileIcon::add()' - Add data to an icon.
|
||||
//
|
||||
|
||||
short * // O - Pointer to new data value
|
||||
Fl_FileIcon::add(short d) // I - Data to add
|
||||
{
|
||||
short *dptr; // Pointer to new data value
|
||||
|
||||
|
||||
// Allocate/reallocate memory as needed
|
||||
if ((num_data_ + 1) >= alloc_data_)
|
||||
{
|
||||
alloc_data_ += 128;
|
||||
|
||||
if (alloc_data_ == 128)
|
||||
dptr = (short *)malloc(sizeof(short) * alloc_data_);
|
||||
else
|
||||
dptr = (short *)realloc(data_, sizeof(short) * alloc_data_);
|
||||
|
||||
if (dptr == NULL)
|
||||
return (NULL);
|
||||
|
||||
data_ = dptr;
|
||||
}
|
||||
|
||||
// Store the new data value and return
|
||||
data_[num_data_++] = d;
|
||||
data_[num_data_] = END;
|
||||
|
||||
return (data_ + num_data_ - 1);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 'Fl_FileIcon::find()' - Find an icon based upon a given file.
|
||||
//
|
||||
|
||||
Fl_FileIcon * // O - Matching file icon or NULL
|
||||
Fl_FileIcon::find(const char *filename, // I - Name of file */
|
||||
int filetype) // I - Enumerated file type
|
||||
{
|
||||
Fl_FileIcon *current; // Current file in list
|
||||
struct stat fileinfo; // Information on file
|
||||
|
||||
|
||||
// Get file information if needed...
|
||||
if (filetype == ANY)
|
||||
if (!stat(filename, &fileinfo))
|
||||
{
|
||||
if (S_ISDIR(fileinfo.st_mode))
|
||||
filetype = DIR;
|
||||
#ifdef S_IFIFO
|
||||
else if (S_ISFIFO(fileinfo.st_mode))
|
||||
filetype = FIFO;
|
||||
#endif // S_IFIFO
|
||||
#if defined(S_ICHR) && defined(S_IBLK)
|
||||
else if (S_ISCHR(fileinfo.st_mode) || S_ISBLK(fileinfo.st_mode))
|
||||
filetype = DEVICE;
|
||||
#endif // S_ICHR && S_IBLK
|
||||
#ifdef S_ILNK
|
||||
else if (S_ISLNK(fileinfo.st_mode))
|
||||
filetype = LINK;
|
||||
#endif // S_ILNK
|
||||
else
|
||||
filetype = PLAIN;
|
||||
}
|
||||
|
||||
// Loop through the available file types and return any match that
|
||||
// is found...
|
||||
for (current = first_; current != (Fl_FileIcon *)0; current = current->next_)
|
||||
if ((current->type_ == filetype || current->type_ == ANY) &&
|
||||
filename_match(filename, current->pattern_))
|
||||
break;
|
||||
|
||||
// Return the match (if any)...
|
||||
return (current);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 'Fl_FileIcon::draw()' - Draw an icon.
|
||||
//
|
||||
|
||||
void
|
||||
Fl_FileIcon::draw(int x, // I - Upper-lefthand X
|
||||
int y, // I - Upper-lefthand Y
|
||||
int w, // I - Width of bounding box
|
||||
int h, // I - Height of bounding box
|
||||
Fl_Color ic, // I - Icon color...
|
||||
int active) // I - Active or inactive?
|
||||
{
|
||||
Fl_Color c; // Current color
|
||||
short *d; // Pointer to data
|
||||
short *prim; // Pointer to start of primitive...
|
||||
double scale; // Scale of icon
|
||||
|
||||
|
||||
// Don't try to draw a NULL array!
|
||||
if (num_data_ == 0)
|
||||
return;
|
||||
|
||||
// Setup the transform matrix as needed...
|
||||
scale = w < h ? w : h;
|
||||
|
||||
fl_push_matrix();
|
||||
fl_translate((float)x + 0.5 * ((float)w - scale),
|
||||
(float)y + 0.5 * ((float)h + scale));
|
||||
fl_scale(scale, -scale);
|
||||
|
||||
// Loop through the array until we see an unmatched END...
|
||||
d = data_;
|
||||
prim = NULL;
|
||||
c = ic;
|
||||
|
||||
if (active)
|
||||
fl_color(c);
|
||||
else
|
||||
fl_color(fl_inactive(c));
|
||||
|
||||
while (*d != END || prim)
|
||||
switch (*d)
|
||||
{
|
||||
case END :
|
||||
switch (*prim)
|
||||
{
|
||||
case LINE :
|
||||
fl_stroke();
|
||||
break;
|
||||
|
||||
case CLOSEDLINE :
|
||||
fl_closepath();
|
||||
fl_stroke();
|
||||
break;
|
||||
|
||||
case POLYGON :
|
||||
fl_fill();
|
||||
break;
|
||||
|
||||
case OUTLINEPOLYGON : {
|
||||
Fl_Color color = prim[1]==256 ? ic : (Fl_Color)prim[1];
|
||||
if (!active) color = fl_inactive(color);
|
||||
fl_fill_stroke(color);
|
||||
break;}
|
||||
}
|
||||
|
||||
prim = NULL;
|
||||
d ++;
|
||||
break;
|
||||
|
||||
case COLOR :
|
||||
if (d[1] == 256)
|
||||
c = ic;
|
||||
else
|
||||
c = (Fl_Color)d[1];
|
||||
|
||||
if (!active)
|
||||
c = fl_inactive(c);
|
||||
|
||||
fl_color(c);
|
||||
d += 2;
|
||||
break;
|
||||
|
||||
case LINE :
|
||||
case CLOSEDLINE :
|
||||
case POLYGON :
|
||||
prim = d;
|
||||
d ++;
|
||||
break;
|
||||
|
||||
case OUTLINEPOLYGON :
|
||||
prim = d;
|
||||
d += 2;
|
||||
break;
|
||||
|
||||
case VERTEX :
|
||||
if (prim)
|
||||
fl_vertex(d[1] * 0.0001, d[2] * 0.0001);
|
||||
d += 3;
|
||||
break;
|
||||
}
|
||||
|
||||
// Restore the transform matrix
|
||||
fl_pop_matrix();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// End of "$Id: Fl_FileIcon.cxx,v 1.10 2001/07/29 22:04:43 spitzak Exp $".
|
||||
//
|
2287
src/Fl_Text_Buffer.cxx
Normal file
2287
src/Fl_Text_Buffer.cxx
Normal file
File diff suppressed because it is too large
Load Diff
1947
src/Fl_Text_Display.cxx
Normal file
1947
src/Fl_Text_Display.cxx
Normal file
File diff suppressed because it is too large
Load Diff
446
src/Fl_Text_Editor.cxx
Normal file
446
src/Fl_Text_Editor.cxx
Normal file
@ -0,0 +1,446 @@
|
||||
//
|
||||
// "$Id: Fl_Text_Editor.cxx,v 1.9 2001/07/23 09:50:05 spitzak Exp $"
|
||||
//
|
||||
// Copyright Mark Edel. Permission to distribute under the LGPL for
|
||||
// the FLTK library granted by Mark Edel.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA.
|
||||
//
|
||||
// Please report all bugs and problems to "fltk-bugs@fltk.org".
|
||||
//
|
||||
|
||||
|
||||
#include <fltk/Fl.h>
|
||||
#include <fltk/Fl_Text_Editor.h>
|
||||
#include <fltk/Fl_Style.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
static void revert(Fl_Style*) {}
|
||||
static Fl_Named_Style style("Text_Editor", revert, &Fl_Text_Editor::default_style);
|
||||
Fl_Named_Style* Fl_Text_Editor::default_style = &::style;
|
||||
|
||||
Fl_Text_Editor::Fl_Text_Editor(int X, int Y, int W, int H, const char* l)
|
||||
: Fl_Text_Display(X, Y, W, H, l) {
|
||||
style(default_style);
|
||||
mCursorOn = 1;
|
||||
insert_mode_ = 1;
|
||||
key_bindings = 0;
|
||||
|
||||
// handle the default key bindings
|
||||
add_default_key_bindings(&key_bindings);
|
||||
|
||||
// handle everything else
|
||||
default_key_function(kf_default);
|
||||
}
|
||||
|
||||
Fl_Text_Editor::Key_Binding* Fl_Text_Editor::global_key_bindings = 0;
|
||||
|
||||
static int ctrl_a(int, Fl_Text_Editor* e);
|
||||
|
||||
// These are the default key bindings every widget should start with
|
||||
static struct {
|
||||
int key;
|
||||
int state;
|
||||
Fl_Text_Editor::Key_Func func;
|
||||
} default_key_bindings[] = {
|
||||
{ FL_Escape, FL_TEXT_EDITOR_ANY_STATE, Fl_Text_Editor::kf_ignore },
|
||||
{ FL_Enter, FL_TEXT_EDITOR_ANY_STATE, Fl_Text_Editor::kf_enter },
|
||||
{ FL_KP_Enter, FL_TEXT_EDITOR_ANY_STATE, Fl_Text_Editor::kf_enter },
|
||||
{ FL_BackSpace, FL_TEXT_EDITOR_ANY_STATE, Fl_Text_Editor::kf_backspace },
|
||||
{ FL_Insert, FL_TEXT_EDITOR_ANY_STATE, Fl_Text_Editor::kf_insert },
|
||||
{ FL_Delete, FL_TEXT_EDITOR_ANY_STATE, Fl_Text_Editor::kf_delete },
|
||||
{ FL_Home, 0, Fl_Text_Editor::kf_move },
|
||||
{ FL_End, 0, Fl_Text_Editor::kf_move },
|
||||
{ FL_Left, 0, Fl_Text_Editor::kf_move },
|
||||
{ FL_Up, 0, Fl_Text_Editor::kf_move },
|
||||
{ FL_Right, 0, Fl_Text_Editor::kf_move },
|
||||
{ FL_Down, 0, Fl_Text_Editor::kf_move },
|
||||
{ FL_Page_Up, 0, Fl_Text_Editor::kf_move },
|
||||
{ FL_Page_Down, 0, Fl_Text_Editor::kf_move },
|
||||
{ FL_Home, FL_SHIFT, Fl_Text_Editor::kf_shift_move },
|
||||
{ FL_End, FL_SHIFT, Fl_Text_Editor::kf_shift_move },
|
||||
{ FL_Left, FL_SHIFT, Fl_Text_Editor::kf_shift_move },
|
||||
{ FL_Up, FL_SHIFT, Fl_Text_Editor::kf_shift_move },
|
||||
{ FL_Right, FL_SHIFT, Fl_Text_Editor::kf_shift_move },
|
||||
{ FL_Down, FL_SHIFT, Fl_Text_Editor::kf_shift_move },
|
||||
{ FL_Page_Up, FL_SHIFT, Fl_Text_Editor::kf_shift_move },
|
||||
{ FL_Page_Down, FL_SHIFT, Fl_Text_Editor::kf_shift_move },
|
||||
{ FL_Home, FL_CTRL, Fl_Text_Editor::kf_ctrl_move },
|
||||
{ FL_End, FL_CTRL, Fl_Text_Editor::kf_ctrl_move },
|
||||
{ FL_Left, FL_CTRL, Fl_Text_Editor::kf_ctrl_move },
|
||||
{ FL_Up, FL_CTRL, Fl_Text_Editor::kf_ctrl_move },
|
||||
{ FL_Right, FL_CTRL, Fl_Text_Editor::kf_ctrl_move },
|
||||
{ FL_Down, FL_CTRL, Fl_Text_Editor::kf_ctrl_move },
|
||||
{ FL_Page_Up, FL_CTRL, Fl_Text_Editor::kf_ctrl_move },
|
||||
{ FL_Page_Down, FL_CTRL, Fl_Text_Editor::kf_ctrl_move },
|
||||
{ FL_Home, FL_CTRL|FL_SHIFT, Fl_Text_Editor::kf_c_s_move },
|
||||
{ FL_End, FL_CTRL|FL_SHIFT, Fl_Text_Editor::kf_c_s_move },
|
||||
{ FL_Left, FL_CTRL|FL_SHIFT, Fl_Text_Editor::kf_c_s_move },
|
||||
{ FL_Up, FL_CTRL|FL_SHIFT, Fl_Text_Editor::kf_c_s_move },
|
||||
{ FL_Right, FL_CTRL|FL_SHIFT, Fl_Text_Editor::kf_c_s_move },
|
||||
{ FL_Down, FL_CTRL|FL_SHIFT, Fl_Text_Editor::kf_c_s_move },
|
||||
{ FL_Page_Up, FL_CTRL|FL_SHIFT, Fl_Text_Editor::kf_c_s_move },
|
||||
{ FL_Page_Down, FL_CTRL|FL_SHIFT, Fl_Text_Editor::kf_c_s_move },
|
||||
//{ FL_Clear, 0, Fl_Text_Editor::delete_to_eol },
|
||||
//{ 'z', FL_CTRL, Fl_Text_Editor::undo },
|
||||
//{ '/', FL_CTRL, Fl_Text_Editor::undo },
|
||||
{ 'x', FL_CTRL, Fl_Text_Editor::kf_cut },
|
||||
{ 'c', FL_CTRL, Fl_Text_Editor::kf_copy },
|
||||
{ 'v', FL_CTRL, Fl_Text_Editor::kf_paste },
|
||||
{ 'a', FL_CTRL, ctrl_a },
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
void Fl_Text_Editor::add_default_key_bindings(Key_Binding** list) {
|
||||
for (int i = 0; default_key_bindings[i].key; i++) {
|
||||
add_key_binding(default_key_bindings[i].key,
|
||||
default_key_bindings[i].state,
|
||||
default_key_bindings[i].func,
|
||||
list);
|
||||
}
|
||||
}
|
||||
|
||||
Fl_Text_Editor::Key_Func
|
||||
Fl_Text_Editor::bound_key_function(int key, int state, Key_Binding* list) {
|
||||
Key_Binding* current;
|
||||
for (current = list; current; current = current->next)
|
||||
if (current->key == key)
|
||||
if (current->state == FL_TEXT_EDITOR_ANY_STATE || current->state == state)
|
||||
break;
|
||||
if (!current) return 0;
|
||||
return current->function;
|
||||
}
|
||||
|
||||
void
|
||||
Fl_Text_Editor::remove_all_key_bindings(Key_Binding** list) {
|
||||
Key_Binding *current, *next;
|
||||
for (current = *list; current; current = next) {
|
||||
next = current->next;
|
||||
delete current;
|
||||
}
|
||||
*list = 0;
|
||||
}
|
||||
|
||||
void
|
||||
Fl_Text_Editor::remove_key_binding(int key, int state, Key_Binding** list) {
|
||||
Key_Binding *current, *last = 0;
|
||||
for (current = *list; current; last = current, current = current->next)
|
||||
if (current->key == key && current->state == state) break;
|
||||
if (!current) return;
|
||||
if (last) last->next = current->next;
|
||||
else *list = current->next;
|
||||
delete current;
|
||||
}
|
||||
|
||||
void
|
||||
Fl_Text_Editor::add_key_binding(int key, int state, Key_Func function,
|
||||
Key_Binding** list) {
|
||||
Key_Binding* kb = new Key_Binding;
|
||||
kb->key = key;
|
||||
kb->state = state;
|
||||
kb->function = function;
|
||||
kb->next = *list;
|
||||
*list = kb;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
#define NORMAL_INPUT_MOVE 0
|
||||
|
||||
static void kill_selection(Fl_Text_Editor* e) {
|
||||
if (e->buffer()->selected()) {
|
||||
e->insert_position(e->buffer()->primary_selection()->start());
|
||||
e->buffer()->remove_selection();
|
||||
}
|
||||
}
|
||||
|
||||
int Fl_Text_Editor::kf_default(int c, Fl_Text_Editor* e) {
|
||||
if (!c || (!isprint(c) && c != '\t')) return 0;
|
||||
char s[2] = "\0";
|
||||
s[0] = (char)c;
|
||||
kill_selection(e);
|
||||
if (e->insert_mode()) e->insert(s);
|
||||
else e->overstrike(s);
|
||||
e->show_insert_position();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Fl_Text_Editor::kf_ignore(int, Fl_Text_Editor*) {
|
||||
return 0; // don't handle
|
||||
}
|
||||
|
||||
int Fl_Text_Editor::kf_backspace(int, Fl_Text_Editor* e) {
|
||||
if (!e->buffer()->selected() && e->move_left())
|
||||
e->buffer()->select(e->insert_position(), e->insert_position()+1);
|
||||
kill_selection(e);
|
||||
e->show_insert_position();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Fl_Text_Editor::kf_enter(int, Fl_Text_Editor* e) {
|
||||
kill_selection(e);
|
||||
e->insert("\n");
|
||||
e->show_insert_position();
|
||||
return 1;
|
||||
}
|
||||
|
||||
extern void fl_text_drag_me(int pos, Fl_Text_Display* d);
|
||||
|
||||
int Fl_Text_Editor::kf_move(int c, Fl_Text_Editor* e) {
|
||||
int i;
|
||||
int selected = e->buffer()->selected();
|
||||
if (!selected)
|
||||
e->dragPos = e->insert_position();
|
||||
e->buffer()->unselect();
|
||||
switch (c) {
|
||||
case FL_Home:
|
||||
e->insert_position(e->buffer()->line_start(e->insert_position()));
|
||||
break;
|
||||
case FL_End:
|
||||
e->insert_position(e->buffer()->line_end(e->insert_position()));
|
||||
break;
|
||||
case FL_Left:
|
||||
e->move_left();
|
||||
break;
|
||||
case FL_Right:
|
||||
e->move_right();
|
||||
break;
|
||||
case FL_Up:
|
||||
e->move_up();
|
||||
break;
|
||||
case FL_Down:
|
||||
e->move_down();
|
||||
break;
|
||||
case FL_Page_Up:
|
||||
for (i = 0; i < e->mNVisibleLines - 1; i++) e->move_up();
|
||||
break;
|
||||
case FL_Page_Down:
|
||||
for (i = 0; i < e->mNVisibleLines - 1; i++) e->move_down();
|
||||
break;
|
||||
}
|
||||
e->show_insert_position();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Fl_Text_Editor::kf_shift_move(int c, Fl_Text_Editor* e) {
|
||||
kf_move(c, e);
|
||||
fl_text_drag_me(e->insert_position(), e);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Fl_Text_Editor::kf_ctrl_move(int c, Fl_Text_Editor* e) {
|
||||
if (!e->buffer()->selected())
|
||||
e->dragPos = e->insert_position();
|
||||
if (c != FL_Up && c != FL_Down) {
|
||||
e->buffer()->unselect();
|
||||
e->show_insert_position();
|
||||
}
|
||||
switch (c) {
|
||||
case FL_Home:
|
||||
e->insert_position(0);
|
||||
break;
|
||||
case FL_End:
|
||||
e->insert_position(e->buffer()->length());
|
||||
break;
|
||||
case FL_Left:
|
||||
e->previous_word();
|
||||
break;
|
||||
case FL_Right:
|
||||
e->next_word();
|
||||
break;
|
||||
case FL_Up:
|
||||
e->scroll(e->mTopLineNum-1, e->mHorizOffset);
|
||||
break;
|
||||
case FL_Down:
|
||||
e->scroll(e->mTopLineNum+1, e->mHorizOffset);
|
||||
break;
|
||||
case FL_Page_Up:
|
||||
e->insert_position(e->mLineStarts[0]);
|
||||
break;
|
||||
case FL_Page_Down:
|
||||
e->insert_position(e->mLineStarts[e->mNVisibleLines-2]);
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Fl_Text_Editor::kf_c_s_move(int c, Fl_Text_Editor* e) {
|
||||
kf_ctrl_move(c, e);
|
||||
fl_text_drag_me(e->insert_position(), e);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ctrl_a(int, Fl_Text_Editor* e) {
|
||||
// make 2+ ^A's in a row toggle select-all:
|
||||
int i = e->buffer()->line_start(e->insert_position());
|
||||
if (i != e->insert_position())
|
||||
return Fl_Text_Editor::kf_move(FL_Home, e);
|
||||
else {
|
||||
if (e->buffer()->selected())
|
||||
e->buffer()->unselect();
|
||||
else
|
||||
Fl_Text_Editor::kf_select_all(0, e);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Fl_Text_Editor::kf_home(int, Fl_Text_Editor* e) {
|
||||
return kf_move(FL_Home, e);
|
||||
}
|
||||
|
||||
int Fl_Text_Editor::kf_end(int, Fl_Text_Editor* e) {
|
||||
return kf_move(FL_End, e);
|
||||
}
|
||||
|
||||
int Fl_Text_Editor::kf_left(int, Fl_Text_Editor* e) {
|
||||
return kf_move(FL_Left, e);
|
||||
}
|
||||
|
||||
int Fl_Text_Editor::kf_up(int, Fl_Text_Editor* e) {
|
||||
return kf_move(FL_Up, e);
|
||||
}
|
||||
|
||||
int Fl_Text_Editor::kf_right(int, Fl_Text_Editor* e) {
|
||||
return kf_move(FL_Right, e);
|
||||
}
|
||||
|
||||
int Fl_Text_Editor::kf_down(int, Fl_Text_Editor* e) {
|
||||
return kf_move(FL_Down, e);
|
||||
}
|
||||
|
||||
int Fl_Text_Editor::kf_page_up(int, Fl_Text_Editor* e) {
|
||||
return kf_move(FL_Page_Up, e);
|
||||
}
|
||||
|
||||
int Fl_Text_Editor::kf_page_down(int, Fl_Text_Editor* e) {
|
||||
return kf_move(FL_Page_Down, e);
|
||||
}
|
||||
|
||||
|
||||
int Fl_Text_Editor::kf_insert(int, Fl_Text_Editor* e) {
|
||||
e->insert_mode(e->insert_mode() ? 0 : 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Fl_Text_Editor::kf_delete(int, Fl_Text_Editor* e) {
|
||||
if (!e->buffer()->selected())
|
||||
e->buffer()->select(e->insert_position(), e->insert_position()+1);
|
||||
kill_selection(e);
|
||||
e->show_insert_position();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Fl_Text_Editor::kf_copy(int, Fl_Text_Editor* e) {
|
||||
if (!e->buffer()->selected()) return 1;
|
||||
const char *copy = e->buffer()->selection_text();
|
||||
if (*copy) Fl::copy(copy, strlen(copy), true);
|
||||
free((void*)copy);
|
||||
e->show_insert_position();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Fl_Text_Editor::kf_cut(int c, Fl_Text_Editor* e) {
|
||||
kf_copy(c, e);
|
||||
kill_selection(e);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Fl_Text_Editor::kf_paste(int, Fl_Text_Editor* e) {
|
||||
kill_selection(e);
|
||||
Fl::paste(*e,true);
|
||||
e->show_insert_position();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Fl_Text_Editor::kf_select_all(int, Fl_Text_Editor* e) {
|
||||
e->buffer()->select(0, e->buffer()->length());
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Fl_Text_Editor::handle_key() {
|
||||
|
||||
// Call fltk's rules to try to turn this into a printing character.
|
||||
// This uses the right-hand ctrl key as a "compose prefix" and returns
|
||||
// the changes that should be made to the text, as a number of
|
||||
// bytes to delete and a string to insert:
|
||||
int del;
|
||||
if (Fl::compose(del)) {
|
||||
if (del) buffer()->select(insert_position()-del, insert_position());
|
||||
kill_selection(this);
|
||||
if (Fl::event_length()) {
|
||||
if (insert_mode()) insert(Fl::event_text());
|
||||
else overstrike(Fl::event_text());
|
||||
}
|
||||
show_insert_position();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int key = Fl::event_key(), state = Fl::event_state(), c = Fl::event_text()[0];
|
||||
state &= FL_SHIFT|FL_CTRL|FL_ALT|FL_META; // only care about these states
|
||||
Key_Func f;
|
||||
f = bound_key_function(key, state, global_key_bindings);
|
||||
if (!f) f = bound_key_function(key, state, key_bindings);
|
||||
|
||||
if (f) return f(key, this);
|
||||
if (default_key_function_ && !state) return default_key_function_(c, this);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Fl_Text_Editor::handle(int event) {
|
||||
if (!buffer()) return 0;
|
||||
|
||||
if (event == FL_PUSH && Fl::event_button() == 2) {
|
||||
dragType = -1;
|
||||
Fl::paste(*this,false);
|
||||
Fl::focus(this);
|
||||
return 1;
|
||||
}
|
||||
|
||||
switch (event) {
|
||||
case FL_FOCUS:
|
||||
show_cursor(mCursorOn); // redraws the cursor
|
||||
return 1;
|
||||
|
||||
case FL_UNFOCUS:
|
||||
show_cursor(mCursorOn); // redraws the cursor
|
||||
return 1;
|
||||
|
||||
case FL_KEYBOARD:
|
||||
return handle_key();
|
||||
|
||||
case FL_PASTE:
|
||||
buffer()->remove_selection();
|
||||
if (insert_mode()) insert(Fl::event_text());
|
||||
else overstrike(Fl::event_text());
|
||||
show_insert_position();
|
||||
return 1;
|
||||
|
||||
// CET - FIXME - this will clobber the window's current cursor state!
|
||||
// case FL_ENTER:
|
||||
// case FL_MOVE:
|
||||
// case FL_LEAVE:
|
||||
// if (Fl::event_inside(text_area)) fl_cursor(FL_CURSOR_INSERT);
|
||||
// else fl_cursor(FL_CURSOR_DEFAULT);
|
||||
}
|
||||
|
||||
return Fl_Text_Display::handle(event);
|
||||
}
|
||||
|
||||
//
|
||||
// End of "$Id: Fl_Text_Editor.cxx,v 1.9 2001/07/23 09:50:05 spitzak Exp $".
|
||||
//
|
157
src/Fl_Tooltip.cxx
Normal file
157
src/Fl_Tooltip.cxx
Normal file
@ -0,0 +1,157 @@
|
||||
//
|
||||
// "$Id: Fl_Tooltip.cxx,v 1.38 2001/07/23 09:50:05 spitzak Exp $"
|
||||
//
|
||||
// Tooltip code for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 1998-1999 by Bill Spitzak and others.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA.
|
||||
//
|
||||
// Please report all bugs and problems to "fltk-bugs@easysw.com".
|
||||
//
|
||||
|
||||
#include <fltk/Fl_Tooltip.h>
|
||||
#include <fltk/fl_draw.h>
|
||||
#include <fltk/Fl_Menu_Window.h>
|
||||
|
||||
float Fl_Tooltip::delay_ = 0.5f;
|
||||
int Fl_Tooltip::enabled_ = 1;
|
||||
|
||||
#define MAX_WIDTH 400
|
||||
|
||||
class Fl_TooltipBox : public Fl_Menu_Window {
|
||||
public:
|
||||
Fl_TooltipBox() : Fl_Menu_Window(0, 0, 0, 0) {
|
||||
style(Fl_Tooltip::default_style);}
|
||||
void draw();
|
||||
void layout();
|
||||
};
|
||||
|
||||
static const char* tip;
|
||||
static Fl_Widget* widget;
|
||||
static Fl_TooltipBox *window = 0;
|
||||
static int X,Y,W,H;
|
||||
|
||||
void Fl_TooltipBox::layout() {
|
||||
fl_font(label_font(), label_size());
|
||||
int ww, hh;
|
||||
ww = MAX_WIDTH;
|
||||
fl_measure(tip, ww, hh, FL_ALIGN_LEFT|FL_ALIGN_WRAP|FL_ALIGN_INSIDE);
|
||||
ww += 6; hh += 6;
|
||||
|
||||
// find position on the screen of the widget:
|
||||
int ox = Fl::event_x_root()+5;
|
||||
//int ox = X+W/2;
|
||||
int oy = Y + H+2;
|
||||
for (Fl_Widget* p = widget; p; p = p->parent()) {
|
||||
//ox += p->x();
|
||||
oy += p->y();
|
||||
}
|
||||
if (ox+ww > Fl::w()) ox = Fl::w() - ww;
|
||||
if (ox < 0) ox = 0;
|
||||
if (H > 30) {
|
||||
oy = Fl::event_y_root()+13;
|
||||
if (oy+hh > Fl::h()) oy -= 23+hh;
|
||||
} else {
|
||||
if (oy+hh > Fl::h()) oy -= (4+hh+H);
|
||||
}
|
||||
if (oy < 0) oy = 0;
|
||||
|
||||
resize(ox, oy, ww, hh);
|
||||
Fl_Menu_Window::layout();
|
||||
}
|
||||
|
||||
void Fl_TooltipBox::draw() {
|
||||
draw_box();
|
||||
draw_label(3, 3, w()-6, h()-6, FL_ALIGN_LEFT|FL_ALIGN_WRAP|FL_ALIGN_INSIDE);
|
||||
}
|
||||
|
||||
|
||||
static void tooltip_timeout(void*) {
|
||||
if (Fl::grab()) return;
|
||||
|
||||
if (window) delete window;
|
||||
Fl_Group* saveCurrent = Fl_Group::current();
|
||||
Fl_Group::current(0);
|
||||
window = new Fl_TooltipBox;
|
||||
window->set_override();
|
||||
window->end();
|
||||
Fl_Group::current(saveCurrent);
|
||||
|
||||
// this cast bypasses the normal Fl_Window label() code:
|
||||
((Fl_Widget*)window)->label(tip);
|
||||
window->relayout();
|
||||
window->show();
|
||||
}
|
||||
|
||||
static int cheesy_flag = 0;
|
||||
|
||||
static void
|
||||
tt_exit(Fl_Widget *w) {
|
||||
if (!w || w != widget) return;
|
||||
widget = 0;
|
||||
Fl::remove_timeout((Fl_Timeout_Handler)tooltip_timeout);
|
||||
if (window) {
|
||||
// This flag makes sure that tootip_enter() isn't executed because of
|
||||
// this destroy() which could cause unwanted recursion in tooltip_enter()
|
||||
cheesy_flag = 1;
|
||||
window->destroy();
|
||||
cheesy_flag = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tt_enter_area(Fl_Widget* w, int X, int Y, int W, int H, const char* t) {
|
||||
if (cheesy_flag) return;
|
||||
if (w == widget && X == ::X && Y == ::Y && W == ::W && H == ::H && t == tip)
|
||||
return;
|
||||
tt_exit(widget);
|
||||
widget = w; ::X = X; ::Y = Y; ::W = W; ::H = H; tip = t;
|
||||
if (!t || !Fl_Tooltip::enabled()) return;
|
||||
float d = Fl_Tooltip::delay();
|
||||
if (d < .01f) d = .01f;
|
||||
Fl::add_timeout(d, (Fl_Timeout_Handler)tooltip_timeout);
|
||||
}
|
||||
|
||||
static void
|
||||
tt_enter(Fl_Widget* w) {
|
||||
if (cheesy_flag || w == widget) return;
|
||||
if (!w || w == window) { tt_exit(widget); widget = 0; return; }
|
||||
tt_enter_area(w, 0, 0, w->w(), w->h(), w->tooltip());
|
||||
}
|
||||
|
||||
void Fl_Widget::tooltip(const char *tt) {
|
||||
static int do_once = 0;
|
||||
if (!do_once) {
|
||||
do_once = 1;
|
||||
Fl_Tooltip::enter = tt_enter;
|
||||
Fl_Tooltip::enter_area = tt_enter_area;
|
||||
Fl_Tooltip::exit = tt_exit;
|
||||
}
|
||||
tooltip_ = tt;
|
||||
}
|
||||
|
||||
static void revert(Fl_Style* s) {
|
||||
s->box = FL_BORDER_BOX;
|
||||
s->color = (Fl_Color)215;
|
||||
s->label_color = FL_BLACK;
|
||||
}
|
||||
static Fl_Named_Style style("Tooltip", revert, &Fl_Tooltip::default_style);
|
||||
Fl_Named_Style* Fl_Tooltip::default_style = &::style;
|
||||
|
||||
//
|
||||
// End of "$Id: Fl_Tooltip.cxx,v 1.38 2001/07/23 09:50:05 spitzak Exp $".
|
||||
//
|
145
src/Fl_lock.cxx
Normal file
145
src/Fl_lock.cxx
Normal file
@ -0,0 +1,145 @@
|
||||
/* Fl_Lock.cxx
|
||||
|
||||
I would prefer that fltk contain the minimal amount of extra stuff
|
||||
for doing threads. There are other portable thread wrapper libraries
|
||||
out there and fltk should not be providing another. This file
|
||||
is an attempt to make minimal additions and make them self-contained
|
||||
in this source file.
|
||||
|
||||
Fl::lock() - recursive lock. Plus you must call this before the
|
||||
first call to Fl::wait()/run() to initialize the thread system.
|
||||
The lock is locked all the time except when Fl::wait() is waiting
|
||||
for events.
|
||||
|
||||
Fl::unlock() - release the recursive lock.
|
||||
|
||||
Fl::awake(void*) - Causes Fl::wait() to return (with the lock locked)
|
||||
even if there are no events ready.
|
||||
|
||||
Fl::thread_message() - returns an argument sent to an Fl::awake call,
|
||||
or returns null if none. Warning: the current implementation only
|
||||
has a one-entry queue and only returns the most recent value!
|
||||
|
||||
See also the Fl_Threads.h header file, which provides convienence
|
||||
functions so you can create your own threads and mutexes.
|
||||
*/
|
||||
|
||||
#include <fltk/Fl.h>
|
||||
#include <config.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
#if defined(_WIN32)
|
||||
|
||||
#include <windows.h>
|
||||
#include <process.h>
|
||||
|
||||
// these pointers are in Fl_win32.cxx:
|
||||
extern void (*fl_lock_function)();
|
||||
extern void (*fl_unlock_function)();
|
||||
|
||||
static DWORD main_thread;
|
||||
|
||||
CRITICAL_SECTION cs;
|
||||
|
||||
static void unlock_function() {
|
||||
LeaveCriticalSection(&cs);
|
||||
}
|
||||
|
||||
static void lock_function() {
|
||||
EnterCriticalSection(&cs);
|
||||
}
|
||||
|
||||
void Fl::lock() {
|
||||
if (!main_thread)
|
||||
InitializeCriticalSection(&cs);
|
||||
lock_function();
|
||||
if (!main_thread) {
|
||||
fl_lock_function = lock_function;
|
||||
fl_unlock_function = unlock_function;
|
||||
main_thread = GetCurrentThreadId();
|
||||
}
|
||||
}
|
||||
|
||||
void Fl::unlock() {
|
||||
unlock_function();
|
||||
}
|
||||
|
||||
// when called from a thread, it causes FLTK to awake from Fl::wait()
|
||||
void Fl::awake(void* msg) {
|
||||
PostThreadMessage( main_thread, WM_USER, (WPARAM)msg, 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
#elif HAVE_PTHREAD
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
|
||||
// Linux supports recursive locks, use them directly:
|
||||
|
||||
static pthread_mutex_t fltk_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
|
||||
|
||||
static void lock_function() {
|
||||
pthread_mutex_lock(&fltk_mutex);
|
||||
}
|
||||
|
||||
void Fl::unlock() {
|
||||
pthread_mutex_unlock(&fltk_mutex);
|
||||
}
|
||||
|
||||
// this is needed for the Fl_Mutex constructor:
|
||||
pthread_mutexattr_t Fl_Mutex_attrib = {PTHREAD_MUTEX_RECURSIVE_NP};
|
||||
|
||||
#else
|
||||
// Make a recursive lock out of the pthread mutex:
|
||||
|
||||
static pthread_mutex_t fltk_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_t owner;
|
||||
static int counter;
|
||||
|
||||
static void lock_function() {
|
||||
if (!counter || owner != pthread_self()) {
|
||||
pthread_mutex_lock(&fltk_mutex); owner = pthread_self();
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
|
||||
void Fl::unlock() {
|
||||
if (!--counter) pthread_mutex_unlock(&fltk_mutex);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static int thread_filedes[2];
|
||||
|
||||
// these pointers are in Fl_x.cxx:
|
||||
extern void (*fl_lock_function)();
|
||||
extern void (*fl_unlock_function)();
|
||||
|
||||
static void* thread_message_;
|
||||
void* Fl::thread_message() {
|
||||
void* r = thread_message_;
|
||||
thread_message_ = 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
static void thread_awake_cb(int fd, void*) {
|
||||
read(fd, &thread_message_, sizeof(void*));
|
||||
}
|
||||
|
||||
void Fl::lock() {
|
||||
lock_function();
|
||||
if (!thread_filedes[1]) { // initialize the mt support
|
||||
// Init threads communication pipe to let threads awake FLTK from wait
|
||||
pipe(thread_filedes);
|
||||
Fl::add_fd(thread_filedes[0], FL_READ, thread_awake_cb);
|
||||
fl_lock_function = lock_function;
|
||||
fl_unlock_function = Fl::unlock;
|
||||
}
|
||||
}
|
||||
|
||||
void Fl::awake(void* msg) {
|
||||
write(thread_filedes[1], &msg, sizeof(void*));
|
||||
}
|
||||
|
||||
#endif
|
6
src/allfiles.xbm
Normal file
6
src/allfiles.xbm
Normal file
@ -0,0 +1,6 @@
|
||||
#define allfiles_width 16
|
||||
#define allfiles_height 16
|
||||
static unsigned char allfiles_bits[] = {
|
||||
0xfc, 0x3f, 0x04, 0x20, 0x04, 0x20, 0x04, 0x20, 0x84, 0x21, 0xa4, 0x25,
|
||||
0xc4, 0x23, 0xf4, 0x2f, 0xf4, 0x2f, 0xc4, 0x23, 0xa4, 0x25, 0x84, 0x21,
|
||||
0x04, 0x20, 0x04, 0x20, 0x04, 0x20, 0xfc, 0x3f};
|
34
src/fl_dnd.cxx
Normal file
34
src/fl_dnd.cxx
Normal file
@ -0,0 +1,34 @@
|
||||
//
|
||||
// "$Id: fl_dnd.cxx,v 1.3 2001/07/29 22:04:44 spitzak Exp $"
|
||||
//
|
||||
// Drag & Drop code for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 1998-1999 by Bill Spitzak and others.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA.
|
||||
//
|
||||
// Please report all bugs and problems to "fltk-bugs@easysw.com".
|
||||
//
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "fl_dnd_win32.cxx"
|
||||
#else
|
||||
#include "fl_dnd_x.cxx"
|
||||
#endif
|
||||
|
||||
//
|
||||
// End of "$Id: fl_dnd.cxx,v 1.3 2001/07/29 22:04:44 spitzak Exp $".
|
||||
//
|
170
src/fl_dnd_x.cxx
Normal file
170
src/fl_dnd_x.cxx
Normal file
@ -0,0 +1,170 @@
|
||||
//
|
||||
// "$Id: fl_dnd_x.cxx,v 1.5 2001/07/23 09:50:05 spitzak Exp $"
|
||||
//
|
||||
// Drag & Drop code for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 1998-1999 by Bill Spitzak and others.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA.
|
||||
//
|
||||
// Please report all bugs and problems to "fltk-bugs@easysw.com".
|
||||
//
|
||||
|
||||
#include <fltk/Fl.h>
|
||||
#include <fltk/Fl_Window.h>
|
||||
#include <fltk/x.h>
|
||||
|
||||
extern Atom fl_XdndAware;
|
||||
extern Atom fl_XdndSelection;
|
||||
extern Atom fl_XdndEnter;
|
||||
extern Atom fl_XdndTypeList;
|
||||
extern Atom fl_XdndPosition;
|
||||
extern Atom fl_XdndLeave;
|
||||
extern Atom fl_XdndDrop;
|
||||
extern Atom fl_XdndStatus;
|
||||
extern Atom fl_XdndActionCopy;
|
||||
extern Atom fl_XdndFinished;
|
||||
//extern Atom fl_XdndProxy;
|
||||
|
||||
extern char fl_i_own_selection;
|
||||
|
||||
void fl_sendClientMessage(Window window, Atom message,
|
||||
unsigned long d0,
|
||||
unsigned long d1=0,
|
||||
unsigned long d2=0,
|
||||
unsigned long d3=0,
|
||||
unsigned long d4=0);
|
||||
|
||||
// return version # of Xdnd this window supports. Also change the
|
||||
// window the the proxy if it uses a proxy:
|
||||
static int dnd_aware(Window& window) {
|
||||
Atom actual; int format; unsigned long count, remaining;
|
||||
unsigned char *data = 0;
|
||||
XGetWindowProperty(fl_display, window, fl_XdndAware,
|
||||
0, 4, False, XA_ATOM,
|
||||
&actual, &format,
|
||||
&count, &remaining, &data);
|
||||
if (actual == XA_ATOM && format==32 && count && data)
|
||||
return int(*(Atom*)data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool grabfunc(int event) {
|
||||
if (event == FL_RELEASE) Fl::pushed(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
extern bool (*fl_local_grab)(int); // in Fl.cxx
|
||||
|
||||
// send an event to an fltk window belonging to this program:
|
||||
static bool local_handle(int event, Fl_Window* window) {
|
||||
fl_local_grab = 0;
|
||||
Fl::e_x = Fl::e_x_root-window->x();
|
||||
Fl::e_y = Fl::e_y_root-window->y();
|
||||
int ret = Fl::handle(event,window);
|
||||
fl_local_grab = grabfunc;
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool Fl::dnd() {
|
||||
Fl::first_window()->cursor((Fl_Cursor)21);
|
||||
Window source_window = fl_xid(Fl::first_window());
|
||||
fl_local_grab = grabfunc;
|
||||
Window target_window = 0;
|
||||
Fl_Window* local_window = 0;
|
||||
int version = 4; int dest_x, dest_y;
|
||||
XSetSelectionOwner(fl_display, fl_XdndSelection, fl_message_window, fl_event_time);
|
||||
|
||||
while (Fl::pushed()) {
|
||||
|
||||
// figure out what window we are pointing at:
|
||||
Window new_window = 0; int new_version = 0;
|
||||
Fl_Window* new_local_window = 0;
|
||||
for (Window child = RootWindow(fl_display, fl_screen);;) {
|
||||
Window root; unsigned int junk3;
|
||||
XQueryPointer(fl_display, child, &root, &child,
|
||||
&e_x_root, &e_y_root, &dest_x, &dest_y, &junk3);
|
||||
if (!child) {
|
||||
if (!new_window && (new_version = dnd_aware(root))) new_window = root;
|
||||
break;
|
||||
}
|
||||
new_window = child;
|
||||
if ((new_local_window = fl_find(child))) break;
|
||||
if ((new_version = dnd_aware(new_window))) break;
|
||||
}
|
||||
|
||||
if (new_window != target_window) {
|
||||
if (local_window) {
|
||||
local_handle(FL_DND_LEAVE, local_window);
|
||||
} else if (version) {
|
||||
fl_sendClientMessage(target_window, fl_XdndLeave, source_window);
|
||||
}
|
||||
version = new_version;
|
||||
target_window = new_window;
|
||||
local_window = new_local_window;
|
||||
if (local_window) {
|
||||
local_handle(FL_DND_ENTER, local_window);
|
||||
} else if (version) {
|
||||
fl_sendClientMessage(target_window, fl_XdndEnter, source_window,
|
||||
version<<24, XA_STRING, 0, 0);
|
||||
}
|
||||
}
|
||||
if (local_window) {
|
||||
local_handle(FL_DND_DRAG, local_window);
|
||||
} else if (version) {
|
||||
fl_sendClientMessage(target_window, fl_XdndPosition, source_window,
|
||||
0, (e_x_root<<16)|e_y_root, fl_event_time,
|
||||
fl_XdndActionCopy);
|
||||
}
|
||||
Fl::wait();
|
||||
}
|
||||
|
||||
if (local_window) {
|
||||
fl_i_own_selection = 1;
|
||||
if (local_handle(FL_DND_RELEASE, local_window)) paste(*belowmouse(),false);
|
||||
} else if (version) {
|
||||
fl_sendClientMessage(target_window, fl_XdndDrop, source_window,
|
||||
0, fl_event_time);
|
||||
} else if (target_window) {
|
||||
// fake a drop by clicking the middle mouse button:
|
||||
XButtonEvent msg;
|
||||
msg.type = ButtonPress;
|
||||
msg.window = target_window;
|
||||
msg.root = RootWindow(fl_display, fl_screen);
|
||||
msg.subwindow = 0;
|
||||
msg.time = fl_event_time+1;
|
||||
msg.x = dest_x;
|
||||
msg.y = dest_y;
|
||||
msg.x_root = Fl::e_x_root;
|
||||
msg.y_root = Fl::e_y_root;
|
||||
msg.state = 0x0;
|
||||
msg.button = Button2;
|
||||
XSendEvent(fl_display, target_window, False, 0L, (XEvent*)&msg);
|
||||
msg.time++;
|
||||
msg.state = 0x200;
|
||||
msg.type = ButtonRelease;
|
||||
XSendEvent(fl_display, target_window, False, 0L, (XEvent*)&msg);
|
||||
}
|
||||
|
||||
fl_local_grab = 0;
|
||||
Fl::first_window()->cursor(FL_CURSOR_DEFAULT);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// End of "$Id: fl_dnd_x.cxx,v 1.5 2001/07/23 09:50:05 spitzak Exp $".
|
||||
//
|
6
src/new.xbm
Normal file
6
src/new.xbm
Normal file
@ -0,0 +1,6 @@
|
||||
#define new_width 16
|
||||
#define new_height 16
|
||||
static unsigned char new_bits[] = {
|
||||
0x00, 0x00, 0x78, 0x00, 0x84, 0x00, 0x02, 0x01, 0x01, 0xfe, 0x01, 0x80,
|
||||
0x31, 0x80, 0x31, 0x80, 0xfd, 0x80, 0xfd, 0x80, 0x31, 0x80, 0x31, 0x80,
|
||||
0x01, 0x80, 0x01, 0x80, 0xff, 0xff, 0x00, 0x00};
|
6
src/up.xbm
Normal file
6
src/up.xbm
Normal file
@ -0,0 +1,6 @@
|
||||
#define up_width 16
|
||||
#define up_height 16
|
||||
static unsigned char up_bits[] = {
|
||||
0x00, 0x00, 0x78, 0x00, 0x84, 0x00, 0x02, 0x01, 0x31, 0xfe, 0x79, 0x80,
|
||||
0xfd, 0x80, 0x31, 0x80, 0x31, 0x80, 0x31, 0x80, 0x31, 0x80, 0x31, 0x80,
|
||||
0x01, 0x80, 0x01, 0x80, 0xff, 0xff, 0x00, 0x00};
|
85
test/tabs.cxx
Normal file
85
test/tabs.cxx
Normal file
@ -0,0 +1,85 @@
|
||||
// generated by Fast Light User Interface Designer (fluid) version 2.0001
|
||||
|
||||
#include "tabs.h"
|
||||
|
||||
Fl_Window *foo_window=(Fl_Window *)0;
|
||||
|
||||
static void cb_cancel(Fl_Button*, void*) {
|
||||
exit(1);
|
||||
|
||||
}
|
||||
|
||||
static void cb_OK(Fl_Return_Button*, void*) {
|
||||
exit(0);
|
||||
|
||||
}
|
||||
|
||||
int main (int argc, char **argv) {
|
||||
|
||||
Fl_Window* w;
|
||||
{ Fl_Window* o = foo_window = new Fl_Window(321, 324);
|
||||
w = o;
|
||||
{ Fl_Tabs* o = new Fl_Tabs(10, 10, 300, 200);
|
||||
o->color((Fl_Color)47);
|
||||
o->selection_color((Fl_Color)15);
|
||||
{ Fl_Group* o = new Fl_Group(0, 20, 300, 180, "Label1");
|
||||
o->hide();
|
||||
new Fl_Input(50, 20, 240, 40, "input:");
|
||||
new Fl_Input(50, 60, 240, 30, "input2:");
|
||||
new Fl_Input(50, 90, 240, 80, "input3:");
|
||||
o->end();
|
||||
Fl_Group::current()->resizable(o);
|
||||
}
|
||||
{ Fl_Group* o = new Fl_Group(0, 20, 300, 180, "tab2");
|
||||
o->hide();
|
||||
new Fl_Button(10, 30, 100, 30, "button1");
|
||||
new Fl_Input(130, 70, 100, 30, "input in box2");
|
||||
new Fl_Button(20, 110, 260, 30, "This is stuff inside the Fl_Group \"tab2\"");
|
||||
o->end();
|
||||
}
|
||||
{ Fl_Group* o = new Fl_Group(0, 20, 300, 180, "tab3");
|
||||
o->hide();
|
||||
new Fl_Button(10, 30, 60, 80, "button2");
|
||||
new Fl_Button(70, 30, 60, 80, "button");
|
||||
new Fl_Button(130, 30, 60, 80, "button");
|
||||
o->end();
|
||||
}
|
||||
{ Fl_Group* o = new Fl_Group(0, 20, 300, 180, "tab4");
|
||||
o->label_font(fl_fonts+2);
|
||||
o->hide();
|
||||
new Fl_Button(10, 20, 60, 110, "button2");
|
||||
new Fl_Button(70, 20, 60, 110, "button");
|
||||
new Fl_Button(130, 20, 60, 110, "button");
|
||||
o->end();
|
||||
}
|
||||
{ Fl_Group* o = new Fl_Group(0, 20, 300, 180, " tab5 ");
|
||||
o->label_type(FL_ENGRAVED_LABEL);
|
||||
new Fl_Button(10, 50, 60, 80, "button2");
|
||||
new Fl_Button(80, 60, 60, 80, "button");
|
||||
{ Fl_Clock* o = new Fl_Clock(150, 20, 100, 100, "Make sure this clock does not use processor time when this tab is hidden or w\
|
||||
indow is iconized");
|
||||
o->box(FL_OSHADOW_BOX);
|
||||
o->label_font(fl_fonts+8);
|
||||
o->color((Fl_Color)238);
|
||||
o->label_size(10);
|
||||
o->align(130);
|
||||
}
|
||||
o->end();
|
||||
}
|
||||
o->end();
|
||||
Fl_Group::current()->resizable(o);
|
||||
}
|
||||
new Fl_Input(60, 220, 130, 30, "inputA:");
|
||||
new Fl_Input(60, 250, 250, 30, "inputB:");
|
||||
{ Fl_Button* o = new Fl_Button(180, 290, 60, 30, "cancel");
|
||||
o->callback((Fl_Callback*)cb_cancel);
|
||||
}
|
||||
{ Fl_Return_Button* o = new Fl_Return_Button(250, 290, 60, 30, "OK");
|
||||
o->shortcut(0xff0d);
|
||||
o->callback((Fl_Callback*)cb_OK);
|
||||
}
|
||||
o->end();
|
||||
}
|
||||
w->show(argc, argv);
|
||||
return Fl::run();
|
||||
}
|
65
test/threads.cxx
Normal file
65
test/threads.cxx
Normal file
@ -0,0 +1,65 @@
|
||||
#include <fltk/Fl.h>
|
||||
#include <fltk/Fl_Window.h>
|
||||
#include <fltk/Fl_Browser.h>
|
||||
#include <fltk/Fl_Threads.h>
|
||||
#include <stdio.h>
|
||||
|
||||
Fl_Thread prime_thread;
|
||||
|
||||
Fl_Browser *browser1, *browser2;
|
||||
|
||||
void* prime_func(void* p)
|
||||
{
|
||||
Fl_Browser* browser = (Fl_Browser*) p;
|
||||
|
||||
// very loosy prime number calculator !
|
||||
for (int n=1000000; ; n++) {
|
||||
int p;
|
||||
for (p=2; p<n; p++) if ( n%p == 0 ) break;
|
||||
if (p == n) {
|
||||
char s[128];
|
||||
sprintf(s, "%d", n);
|
||||
Fl::lock();
|
||||
browser->add(s);
|
||||
Fl::unlock();
|
||||
Fl::awake((void*) (browser == browser1? p:0)); // Cause the browser to redraw ...
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
Fl_Window* w = new Fl_Window(200, 300, "Multithread test");
|
||||
browser1 = new Fl_Browser(0, 0, 200, 300);
|
||||
w->end();
|
||||
w->show();
|
||||
w = new Fl_Window(200, 300, "Multithread test");
|
||||
browser2 = new Fl_Browser(0, 0, 200, 300);
|
||||
w->end();
|
||||
w->show();
|
||||
|
||||
browser1->add("Prime numbers :");
|
||||
browser2->add("Prime numbers :");
|
||||
|
||||
Fl::lock(); // you must do this before creating any threads!
|
||||
|
||||
// One thread displaying in one browser
|
||||
fl_create_thread(prime_thread, prime_func, browser1);
|
||||
// Several threads displaying in another browser
|
||||
fl_create_thread(prime_thread, prime_func, browser2);
|
||||
fl_create_thread(prime_thread, prime_func, browser2);
|
||||
fl_create_thread(prime_thread, prime_func, browser2);
|
||||
fl_create_thread(prime_thread, prime_func, browser2);
|
||||
fl_create_thread(prime_thread, prime_func, browser2);
|
||||
fl_create_thread(prime_thread, prime_func, browser2);
|
||||
|
||||
// Fl::run();
|
||||
while (w->visible()) {
|
||||
Fl::wait();
|
||||
void* m = Fl::thread_message();
|
||||
if (m) printf("Recieved message: %d\n", int(m));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user