-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathEDE_Browser.h
217 lines (187 loc) · 6.08 KB
/
EDE_Browser.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
/*
* $Id$
*
* EDE Browser class
* Part of edelib.
* Copyright (c) 2005-2007 EDE Authors.
*
* This program is licenced under terms of the
* GNU General Public Licence version 2 or newer.
* See COPYING for details.
*/
#ifndef EDE_Browser_H
#define EDE_Browser_H
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <FL/Fl.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Tile.H>
#include <FL/Fl_Scroll.H>
#include <FL/Fl_Scrollbar.H>
#include <FL/Fl_Image.H>
#include <FL/fl_draw.H>
#include "Fl_Icon_Browser.h"
enum SortType {
NO_SORT = 0, ///< don't sort, items will be shown in order of adding
ALPHA_SORT = 1, ///< standard bibliographic sort
ALPHA_CASE_SORT = 2, ///< standard bibliographic sort ignoring the case
NUMERIC_SORT = 3, ///< items are converted to numbers and sorted by size
DATE_SORT = 4, ///< sort by date (depends on user locale)
FILE_SIZE_SORT = 5 ///< same as numeric, but also considering units such as kB, MB, GB
};
/**
* \class EDE_Browser
* \brief An improved version of Fl_Browser
*
* This is a (mostly compatible) version of Fl_Browser that adds
* following features:
* * sorting by column, using one of the several offered sort types,
* * optional header which enables resizing columns and sorting
* (by clicking the title of column that you wish to sort),
* * quick search (by pressing the first character of the item you
* are searching).
*
* The type of browser is set by default to FL_MULTI_BROWSER (call
* method type() to change).
*
* The class is based on Fl_Icon_Browser (which is just a Fl_Browser
* that can display icons) that I sincerelly hope will one day go
* upstream.
*
*/
class EDE_Browser : public Fl_Icon_Browser {
private:
// Button row height
static const int buttonheight=20;
// Subclass Fl_Group for handle()-ing button resizing and clicks
class Heading : public Fl_Group {
public:
Heading(int x, int y, int w, int h, const char *label = 0) : Fl_Group(x,y,w,h,label) {}
int handle(int e);
void draw() {
if (!visible()) return;
if (x() && y() && w() && h() && fl_not_clipped(x(),y(),w(),h())) fl_push_clip(x(),y(),w(),h());
Fl_Group::draw();
if (x() && y() && w() && h() && fl_not_clipped(x(),y(),w(),h())) fl_pop_clip();
}
} *heading;
Fl_Scrollbar *hscrollbar;
int totalwidth_; // total width of all columns
char *column_header_;
SortType *column_sort_types_;
// current sort:
int sort_column;
SortType sort_type;
bool sort_direction;
void cleanup_header();
void hide_header();
void show_header();
void mqsort(char *labels[], int beg, int end, SortType type); // my implementation of qsort
bool sortfn(char *,char*,SortType); // sort function, per type
Fl_Group* thegroup;
public:
EDE_Browser(int X,int Y,int W,int H,const char *L=0);
~EDE_Browser() {
delete[] column_sort_types_;
cleanup_header();
delete heading;
// delete scroll;
delete hscrollbar;
if (column_header_) free(column_header_); // this is a C-string
}
/**
* Get or set the column titles and display the header.
*
* \param c is formatted just like other items, e.g. it uses the same column_char()
* To hide the header, just call with a null pointer (this is the default value).
*/
void column_header(const char *c) {
free(column_header_);
if (c) {
column_header_=strdup(c);
show_header();
} else {
column_header_=0;
hide_header();
}
}
const char *column_header() { return column_header_; }
/**
* Sets the way various columns are sorted. By default all columns will use
* ALPHA_SORT e.g. classic bibliographic sort. Usually the programmer knows in
* advance what kind of data will be put into which column, so (s)he can set
* how each column will be sorted when the header buttons are clicked.
*
* \param l constant pointer to a sufficiently large array of SortType, corresponding
* to columns. Last value in this array must be 0 (NO_SORT) (there's no point for
* setting sort type of a column to NO_SORT; if you want to unsort the browser, just
* call sort(0, NO_SORT) ).
*/
void column_sort_types (const SortType *l) { for (int i=0; l[i]; i++) column_sort_types_[i]=l[i]; }
/**
* Sort items by column.
*
* \param column number of column to use for sorting
* \param type type of sorting to be used
* \param reverse if true, items will be sorted in reverse order
*/
void sort(int column, SortType type, bool reverse=false);
/**
* Sort items by column (toggle-type method). It will use the default sort type for
* given column, as set by column_sort_types(). If column is already sorted in normal
* order, this will resort in reverse - this method gives the same effect as clicking
* on column button.
*
* \param column number of column to use for sorting
*/
void sort(int column);
/**
* Set and get column widths.
* NOTE: *Unlike* Fl_Browser, you need to specify the width of the
* last column as well! If the sum of witdhs is larger than the
* Browser, a horizontal scrollbar will be shown. If it is smaller,
* there will be some unused space to the right.
*
* \param l array of column widths in pixels, ending with zero (please
* don't forget to set the last value of the array to 0). If you wish
* to make a column (practically) invisible, set width to 1 pixel.
*/
void column_widths(const int* l);
const int* column_widths() const;
// Overload handle for keyboard quick search
int handle(int e);
// Overload resize for show/hide horizontal scrollbar
void resize(int X, int Y, int W, int H);
// Overload hposition(), so that heading scrolls together with browser
void hposition(int X) {
if (heading->visible()) {
static int oldX=0;
// Move each button by X pixels
for(int i=0; i<heading->children(); i++) {
Fl_Widget* c = heading->child(i);
c->position(c->x()-X+oldX, c->y());
}
fl_push_clip(x(),y(),w(),h());
heading->redraw();
fl_pop_clip();
oldX=X;
}
Fl_Icon_Browser::hposition(X);
}
void hide() {
heading->hide();
thegroup->hide(); /* group */
Fl_Widget::hide();
}
void show() {
Fl_Widget::show();
heading->show();
thegroup->show();
}
};
#endif
//
// End of "$Id$".
//