summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Melcher <fltk@matthiasm.com>2008-12-26 21:20:38 +0000
committerMatthias Melcher <fltk@matthiasm.com>2008-12-26 21:20:38 +0000
commitfad309329b0ad830f3e423eaa5844e61d75e9210 (patch)
tree4e77f876791f203cfe93f262e41994e1ae192e51
parent459cd78a947693d7fb99bf6ed0f497f2ae5cc1a5 (diff)
STR #2113: added sorting and a few other functions to Fl_Browser_.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@6600 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
-rw-r--r--CHANGES1
-rw-r--r--FL/Fl_Browser.H4
-rw-r--r--FL/Fl_Browser_.H25
-rw-r--r--src/Fl_Browser.cxx6
-rw-r--r--src/Fl_Browser_.cxx37
-rw-r--r--test/browser.cxx16
6 files changed, 85 insertions, 4 deletions
diff --git a/CHANGES b/CHANGES
index 8dc593f1c..a740d8ee5 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,6 @@
CHANGES IN FLTK 1.3.0
+ - Added sorting to Fl_Browser_ (STR #2113)
- Added utf8 support for OS X copy and paste
- Improved handling of composed keys in OS X 10.5 and up
- Updated the bundled libpng to v1.2.33.
diff --git a/FL/Fl_Browser.H b/FL/Fl_Browser.H
index e0fa132c2..428bd20d2 100644
--- a/FL/Fl_Browser.H
+++ b/FL/Fl_Browser.H
@@ -86,6 +86,7 @@ protected:
void* item_first() const ;
void* item_next(void*) const ;
void* item_prev(void*) const ;
+ void* item_last()const ;
int item_selected(void*) const ;
void item_select(void*, int);
int item_height(void*) const ;
@@ -93,6 +94,9 @@ protected:
void item_draw(void*, int, int, int, int) const ;
int full_height() const ;
int incr_height() const ;
+ const char *item_text(void *item) const;
+ void item_swap(void *a, void *b) { swap((FL_BLINE*)a, (FL_BLINE*)b); }
+ void *item_at(int ix) const { return (void*)find_line(ix); }
FL_BLINE* find_line(int) const ;
FL_BLINE* _remove(int) ;
diff --git a/FL/Fl_Browser_.H b/FL/Fl_Browser_.H
index 30c62962c..f89383618 100644
--- a/FL/Fl_Browser_.H
+++ b/FL/Fl_Browser_.H
@@ -48,6 +48,9 @@
#define FL_HOLD_BROWSER 2 /**< type() of Fl_Hold_Browser */
#define FL_MULTI_BROWSER 3 /**< type() of Fl_Multi_Browser */
+#define FL_SORT_ASC 0 /**< sort browser items in ascending alphabetic order. */
+#define FL_SORT_DESC 1 /**< sort in descending order */
+
/**
This is the base for browsers. To be useful it must be
subclassed and several virtual functions defined. The Forms-compatible
@@ -94,6 +97,8 @@ protected:
virtual void *item_next(void *) const = 0;
/** This method must be provided by the subclass to return the item in the list before p. */
virtual void *item_prev(void *) const = 0;
+ /** This method can be provided by the subclass to return the ilast item in the list. */
+ virtual void *item_last() const { return 0L; }
/**
This method must be provided by the subclass to return the height of the
item p in pixels. Allow for two additional pixels for the list
@@ -113,6 +118,18 @@ protected:
and h.
*/
virtual void item_draw(void *,int,int,int,int) const = 0;
+ /**
+ This optional function returns a string that may be used for sorting.
+ */
+ virtual const char *item_text(void *item) const { return 0L; }
+ /**
+ This optional function is required for sorting browser items.
+ */
+ virtual void item_swap(void*, void*) { }
+ /**
+ Return the item a specified index.
+ */
+ virtual void *item_at(int) const { return 0L; }
// you don't have to provide these but it may help speed it up:
virtual int full_width() const ; // current width of all items
virtual int full_height() const ; // current height of all items
@@ -271,6 +288,14 @@ public:
*/
void scrollbar_left() {scrollbar.align(FL_ALIGN_LEFT);}
+ /**
+ Sort the items in the browser.
+ item_swap(void*, void*) and item_text(void*) must be implemented for this call.
+ \param[in] flags no flags were defined yet. Sorting in descending order and
+ sorting while ignoring case come to mind.
+ */
+ void sort(int flags=0);
+
};
#endif
diff --git a/src/Fl_Browser.cxx b/src/Fl_Browser.cxx
index 25561c633..d84cc9c7b 100644
--- a/src/Fl_Browser.cxx
+++ b/src/Fl_Browser.cxx
@@ -59,6 +59,8 @@ void* Fl_Browser::item_next(void* l) const {return ((FL_BLINE*)l)->next;}
void* Fl_Browser::item_prev(void* l) const {return ((FL_BLINE*)l)->prev;}
+void* Fl_Browser::item_last() const {return last;}
+
int Fl_Browser::item_selected(void* l) const {
return ((FL_BLINE*)l)->flags&SELECTED;}
@@ -67,6 +69,10 @@ void Fl_Browser::item_select(void* l, int v) {
else ((FL_BLINE*)l)->flags &= ~SELECTED;
}
+const char *Fl_Browser::item_text(void *item) const {
+ return ((FL_BLINE*)item)->txt;
+}
+
/**
Return entry for line number \a line.
*/
diff --git a/src/Fl_Browser_.cxx b/src/Fl_Browser_.cxx
index 32f2431d4..a9c17debd 100644
--- a/src/Fl_Browser_.cxx
+++ b/src/Fl_Browser_.cxx
@@ -902,6 +902,43 @@ Fl_Browser_::Fl_Browser_(int X, int Y, int W, int H, const char* l)
end();
}
+/*
+ * Simple bubble sort - pure lazyness on my side.
+ */
+void Fl_Browser_::sort(int flags) {
+ int i, j, n = -1, desc = ((flags&FL_SORT_DESC)==FL_SORT_DESC);
+ void *a =item_first(), *b, *c;
+ if (!a) return;
+ while (a) {
+ a = item_next(a);
+ n++;
+ }
+ for (i=n-1; i>0; i--) {
+ char swapped = 0;
+ a = item_first();
+ b = item_next(a);
+ for (j=0; j<i; j++) {
+ const char *ta = item_text(a);
+ const char *tb = item_text(b);
+ c = item_next(b);
+ if (desc) {
+ if (strcmp(ta, tb)<0) {
+ item_swap(a, b);
+ swapped = 1;
+ }
+ } else {
+ if (strcmp(ta, tb)>0) {
+ item_swap(a, b);
+ swapped = 1;
+ }
+ }
+ b = c; a = item_prev(b);
+ }
+ if (!swapped)
+ break;
+ }
+}
+
// Default versions of some of the virtual functions:
/**
diff --git a/test/browser.cxx b/test/browser.cxx
index 242b4caff..5e8b2927c 100644
--- a/test/browser.cxx
+++ b/test/browser.cxx
@@ -77,7 +77,8 @@ Fl_Button *top,
*bottom,
*middle,
*visible,
- *swap;
+ *swap,
+ *sort;
Fl_Int_Input *field;
void b_cb(Fl_Widget* o, void*) {
@@ -117,12 +118,16 @@ void swap_cb(Fl_Widget *, void *) {
browser->swap(a, b); // swap them
}
+void sort_cb(Fl_Widget *, void *) {
+ browser->sort(FL_SORT_ASC);
+}
+
int main(int argc, char **argv) {
int i;
if (!Fl::args(argc,argv,i)) Fl::fatal(Fl::help);
const char* fname = (i < argc) ? argv[i] : "browser.cxx";
- Fl_Window window(400,400,fname);
- browser = new Fl_Select_Browser(0,0,400,350,0);
+ Fl_Window window(480,400,fname);
+ browser = new Fl_Select_Browser(0,0,480,350,0);
browser->type(FL_MULTI_BROWSER);
//browser->type(FL_HOLD_BROWSER);
//browser->color(42);
@@ -155,7 +160,7 @@ int main(int argc, char **argv) {
}
browser->position(0);
- field = new Fl_Int_Input(50, 350, 350, 25, "Line #:");
+ field = new Fl_Int_Input(50, 350, 430, 25, "Line #:");
field->callback(show_cb);
top = new Fl_Button(0, 375, 80, 25, "Top");
@@ -174,6 +179,9 @@ int main(int argc, char **argv) {
swap->callback(swap_cb);
swap->tooltip("Swaps two selected lines\n(Use CTRL-click to select two lines)");
+ sort = new Fl_Button(400, 375, 80, 25, "Sort");
+ sort->callback(sort_cb);
+
window.resizable(browser);
window.show(argc,argv);
return Fl::run();