2007-07-16 11:35:32 +04:00
|
|
|
/*
|
|
|
|
* $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>
|
2007-08-01 22:04:35 +04:00
|
|
|
#include <FL/fl_draw.H>
|
2007-07-16 11:35:32 +04:00
|
|
|
|
|
|
|
#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);
|
2007-08-01 22:04:35 +04:00
|
|
|
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();
|
|
|
|
}
|
2007-07-16 11:35:32 +04:00
|
|
|
} *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;
|
|
|
|
|
2007-07-27 12:36:05 +04:00
|
|
|
void cleanup_header();
|
2007-07-16 11:35:32 +04:00
|
|
|
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
|
|
|
|
|
|
|
|
public:
|
|
|
|
EDE_Browser(int X,int Y,int W,int H,const char *L=0);
|
|
|
|
|
|
|
|
~EDE_Browser() {
|
|
|
|
delete[] column_sort_types_;
|
2007-07-27 12:36:05 +04:00
|
|
|
cleanup_header();
|
2007-07-16 11:35:32 +04:00
|
|
|
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
|
2007-08-01 22:04:35 +04:00
|
|
|
void hposition(int X) {
|
2007-07-16 11:35:32 +04:00
|
|
|
if (heading->visible()) {
|
2007-08-01 22:04:35 +04:00
|
|
|
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());
|
2007-07-16 11:35:32 +04:00
|
|
|
heading->redraw();
|
2007-08-01 22:04:35 +04:00
|
|
|
fl_pop_clip();
|
|
|
|
oldX=X;
|
2007-07-16 11:35:32 +04:00
|
|
|
}
|
2007-08-01 22:04:35 +04:00
|
|
|
Fl_Icon_Browser::hposition(X);
|
2007-07-16 11:35:32 +04:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
//
|
|
|
|
// End of "$Id$".
|
|
|
|
//
|
|
|
|
|