mirror of
https://github.com/fltk/fltk.git
synced 2026-05-21 06:21:26 +08:00
o Added draw_item_content() to Fl_Tree_Item,
a volatile method that can be overridden by
subclasses to take drawing control of tree item's content.
This replaces the old "item_draw_callback()" technique
added a few months ago as an ABI feature; turned out the
new technique is a better way to go.
o The examples/tree-custom-draw-items.cxx demo adjusted
accordingly.
o Added missing docs for some methods that had none,
including label_[xywh]().
o Added related methods needed to implement this, including:
Fl_Tree_Item_Array::replace()
Fl_Tree_Item::replace()
Fl_Tree::root(item)
Fl_Tree::add() variations
Fl_Tree_Item::drawbgcolor()/drawfgcolor()
o Carefully worked the FLTK_ABI_VERSION macros so as to be
ABI compatible with 1.3.0.
o Verified 1.3.0 ABI compatibility with ABI Compliance Checker 1.99.8.5:
http://ispras.linuxbase.org/index.php/ABI_compliance_checker
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@10071 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
+23
-12
@@ -372,11 +372,18 @@ public:
|
||||
///////////////////////
|
||||
void root_label(const char *new_label);
|
||||
Fl_Tree_Item* root();
|
||||
void root(Fl_Tree_Item *newitem);
|
||||
const Fl_Tree_Prefs& prefs() const { return _prefs; }
|
||||
|
||||
////////////////////////////////
|
||||
// Item creation/removal methods
|
||||
////////////////////////////////
|
||||
#if FLTK_ABI_VERSION >= 10303
|
||||
Fl_Tree_Item *add(const char *path, Fl_Tree_Item *newitem=0);
|
||||
#else
|
||||
Fl_Tree_Item *add(const char *path);
|
||||
Fl_Tree_Item *add(const char *path, Fl_Tree_Item *newitem);
|
||||
#endif
|
||||
Fl_Tree_Item* add(Fl_Tree_Item *parent_item, const char *name);
|
||||
Fl_Tree_Item *insert_above(Fl_Tree_Item *above, const char *name);
|
||||
Fl_Tree_Item* insert(Fl_Tree_Item *item, const char *name, int pos);
|
||||
@@ -407,7 +414,7 @@ public:
|
||||
Fl_Tree_Item *last_visible(); // deprecated in ABI 10303
|
||||
Fl_Tree_Item *last_visible_item();
|
||||
#if FLTK_ABI_VERSION >= 10303
|
||||
Fl_Tree_Item *next_visible_item(Fl_Tree_Item *start, int dir);
|
||||
Fl_Tree_Item *next_visible_item(Fl_Tree_Item *start, int dir); // made public in 1.3.3 ABI
|
||||
#endif
|
||||
Fl_Tree_Item *first_selected_item();
|
||||
Fl_Tree_Item *last_selected_item();
|
||||
@@ -444,16 +451,24 @@ public:
|
||||
int deselect_all(Fl_Tree_Item *item=0, int docallback=1);
|
||||
int select_only(Fl_Tree_Item *selitem, int docallback=1);
|
||||
int select_all(Fl_Tree_Item *item=0, int docallback=1);
|
||||
int extend_selection_dir(Fl_Tree_Item *from,
|
||||
Fl_Tree_Item *to,
|
||||
int dir,
|
||||
int val,
|
||||
bool visible);
|
||||
#if FLTK_ABI_VERSION >= 10303
|
||||
void extend_selection(Fl_Tree_Item *from, Fl_Tree_Item *to);
|
||||
int extend_selection(Fl_Tree_Item *from, Fl_Tree_Item *to, int dir, int val, bool visible);
|
||||
int extend_selection(Fl_Tree_Item *from, Fl_Tree_Item *to, int val, bool visible);
|
||||
int extend_selection(Fl_Tree_Item *from,
|
||||
Fl_Tree_Item *to,
|
||||
int val=1,
|
||||
bool visible=false);
|
||||
#else
|
||||
// Adding overload if not at least one overload breaks ABI, so avoid
|
||||
// See: http://www.ros.org/reps/rep-0009.html
|
||||
private:
|
||||
int extend_selection__(Fl_Tree_Item *from, Fl_Tree_Item *to, int dir, int val, bool visible);
|
||||
int extend_selection__(Fl_Tree_Item *from, Fl_Tree_Item *to, int val, bool visible);
|
||||
// Adding overload if not at least one overload breaks ABI, so avoid
|
||||
// by keeping private until we can break ABI. ref: http://www.ros.org/reps/rep-0009.html
|
||||
int extend_selection__(Fl_Tree_Item *from,
|
||||
Fl_Tree_Item *to,
|
||||
int val,
|
||||
bool visible);
|
||||
public:
|
||||
#endif
|
||||
void set_item_focus(Fl_Tree_Item *item);
|
||||
@@ -522,10 +537,6 @@ public:
|
||||
void item_draw_mode(int mode);
|
||||
#endif
|
||||
#if FLTK_ABI_VERSION >= 10303
|
||||
void item_draw_callback(Fl_Tree_Item_Draw_Callback *cb, void *data=0);
|
||||
Fl_Tree_Item_Draw_Callback* item_draw_callback() const;
|
||||
void* item_draw_user_data() const;
|
||||
void do_item_draw_callback(Fl_Tree_Item *o) const;
|
||||
void calc_dimensions();
|
||||
void calc_tree();
|
||||
#endif
|
||||
|
||||
+74
-24
@@ -52,6 +52,17 @@
|
||||
/// When you make changes to items, you'll need to tell the tree to redraw()
|
||||
/// for the changes to show up.
|
||||
///
|
||||
/// New 1.3.3 ABI feature:
|
||||
/// You can define custom items by either adding a custom widget to the item
|
||||
/// with Fl_Tree_Item::widget(), or override the draw_item_content() method
|
||||
/// if you want to just redefine how the label is drawn.
|
||||
///
|
||||
/// The following shows the Fl_Tree_Item's dimensions, useful when overriding
|
||||
/// the draw_item_content() method:
|
||||
///
|
||||
/// \image html Fl_Tree_Item-dimensions.png "Fl_Tree_Item's internal dimensions." width=6cm
|
||||
/// \image latex Fl_Tree_Item-dimensions.png "Fl_Tree_Item's internal dimensions." width=6cm
|
||||
///
|
||||
class Fl_Tree;
|
||||
class FL_EXPORT Fl_Tree_Item {
|
||||
#if FLTK_ABI_VERSION >= 10303
|
||||
@@ -96,6 +107,7 @@ class FL_EXPORT Fl_Tree_Item {
|
||||
Fl_Tree_Item *_prev_sibling; // previous sibling (same level)
|
||||
Fl_Tree_Item *_next_sibling; // next sibling (same level)
|
||||
#endif /*FLTK_ABI_VERSION*/
|
||||
// Protected methods
|
||||
protected:
|
||||
void _Init(const Fl_Tree_Prefs &prefs, Fl_Tree *tree);
|
||||
void show_widgets();
|
||||
@@ -103,6 +115,12 @@ protected:
|
||||
void draw_vertical_connector(int x, int y1, int y2, const Fl_Tree_Prefs &prefs);
|
||||
void draw_horizontal_connector(int x1, int x2, int y, const Fl_Tree_Prefs &prefs);
|
||||
void recalc_tree();
|
||||
int calc_item_height(const Fl_Tree_Prefs &prefs) const;
|
||||
#if FLTK_ABI_VERSION >= 10303
|
||||
Fl_Color drawfgcolor() const;
|
||||
Fl_Color drawbgcolor() const;
|
||||
#endif
|
||||
|
||||
public:
|
||||
Fl_Tree_Item(const Fl_Tree_Prefs &prefs); // CTOR -- backwards compatible
|
||||
#if FLTK_ABI_VERSION >= 10303
|
||||
@@ -110,20 +128,35 @@ public:
|
||||
#endif
|
||||
~Fl_Tree_Item(); // DTOR
|
||||
Fl_Tree_Item(const Fl_Tree_Item *o); // COPY CTOR
|
||||
/// The item's x position relative to the window
|
||||
int x() const { return(_xywh[0]); }
|
||||
/// The item's y position relative to the window
|
||||
int y() const { return(_xywh[1]); }
|
||||
/// The entire item's width to right edge of Fl_Tree's inner width
|
||||
/// within scrollbars.
|
||||
int w() const { return(_xywh[2]); }
|
||||
/// The item's height
|
||||
int h() const { return(_xywh[3]); }
|
||||
/// The item's label x position relative to the window
|
||||
/// \version 1.3.3
|
||||
int label_x() const { return(_label_xywh[0]); }
|
||||
/// The item's label y position relative to the window
|
||||
/// \version 1.3.3
|
||||
int label_y() const { return(_label_xywh[1]); }
|
||||
/// The item's maximum label width to right edge of Fl_Tree's inner width
|
||||
/// within scrollbars.
|
||||
/// \version 1.3.3
|
||||
int label_w() const { return(_label_xywh[2]); }
|
||||
/// The item's label height
|
||||
/// \version 1.3.3
|
||||
int label_h() const { return(_label_xywh[3]); }
|
||||
int calc_item_height(const Fl_Tree_Prefs &prefs) const;
|
||||
#if FLTK_ABI_VERSION >= 10303
|
||||
virtual int draw_item_content(int render);
|
||||
void draw(int X, int &Y, int W, Fl_Tree_Item *itemfocus,
|
||||
int &tree_item_xmax, int lastchild=1, int render=1);
|
||||
int &tree_item_xmax, int lastchild=1, int render=1);
|
||||
#else
|
||||
void draw(int X, int &Y, int W, Fl_Widget *tree, Fl_Tree_Item *itemfocus, const Fl_Tree_Prefs &prefs, int lastchild=1);
|
||||
void draw(int X, int &Y, int W, Fl_Widget *tree,
|
||||
Fl_Tree_Item *itemfocus, const Fl_Tree_Prefs &prefs, int lastchild=1);
|
||||
#endif
|
||||
void show_self(const char *indent = "") const;
|
||||
void label(const char *val);
|
||||
@@ -157,25 +190,27 @@ public:
|
||||
void labelfgcolor(Fl_Color val) {
|
||||
_labelfgcolor = val;
|
||||
}
|
||||
/// Set item's label text color.
|
||||
void labelcolor(Fl_Color val) {
|
||||
_labelfgcolor = val;
|
||||
}
|
||||
/// Return item's label text color.
|
||||
Fl_Color labelcolor() const {
|
||||
return(_labelfgcolor);
|
||||
}
|
||||
/// Return item's label foreground text color.
|
||||
Fl_Color labelfgcolor() const {
|
||||
return(_labelfgcolor);
|
||||
}
|
||||
/// Set item's label text color. Alias for labelfgcolor(Fl_Color)).
|
||||
void labelcolor(Fl_Color val) {
|
||||
labelfgcolor(val);
|
||||
}
|
||||
/// Return item's label text color. Alias for labelfgcolor() const).
|
||||
Fl_Color labelcolor() const {
|
||||
return labelfgcolor();
|
||||
}
|
||||
/// Set item's label background color.
|
||||
/// A special case is made for color 0xffffffff which is treated as 'transparent'.
|
||||
/// A special case is made for color 0xffffffff which uses the parent tree's bg color.
|
||||
void labelbgcolor(Fl_Color val) {
|
||||
_labelbgcolor = val;
|
||||
}
|
||||
/// Return item's background text color.
|
||||
/// If the color is 0xffffffff, it is 'transparent'.
|
||||
/// Return item's label background text color.
|
||||
/// If the color is 0xffffffff, the default behavior is the parent tree's
|
||||
/// bg color will be used. (An overloaded draw_item_content() can override
|
||||
/// this behavior.)
|
||||
Fl_Color labelbgcolor() const {
|
||||
return(_labelbgcolor);
|
||||
}
|
||||
@@ -209,15 +244,29 @@ public:
|
||||
void clear_children();
|
||||
void swap_children(int ax, int bx);
|
||||
int swap_children(Fl_Tree_Item *a, Fl_Tree_Item *b);
|
||||
const Fl_Tree_Item *find_child_item(char **arr) const; // const
|
||||
Fl_Tree_Item *find_child_item(char **arr); // non-const
|
||||
const Fl_Tree_Item *find_item(char **arr) const; // const
|
||||
Fl_Tree_Item *find_item(char **arr); // non-const
|
||||
const Fl_Tree_Item *find_child_item(const char *name) const;
|
||||
Fl_Tree_Item *find_child_item(const char *name);
|
||||
const Fl_Tree_Item *find_child_item(char **arr) const;
|
||||
Fl_Tree_Item *find_child_item(char **arr);
|
||||
const Fl_Tree_Item *find_item(char **arr) const;
|
||||
Fl_Tree_Item *find_item(char **arr);
|
||||
//////////////////
|
||||
// Adding items
|
||||
//////////////////
|
||||
Fl_Tree_Item *add(const Fl_Tree_Prefs &prefs, const char *new_label);
|
||||
Fl_Tree_Item *add(const Fl_Tree_Prefs &prefs, char **arr);
|
||||
Fl_Tree_Item *add(const Fl_Tree_Prefs &prefs,
|
||||
const char *new_label,
|
||||
Fl_Tree_Item *newitem);
|
||||
Fl_Tree_Item *add(const Fl_Tree_Prefs &prefs,
|
||||
const char *new_label);
|
||||
Fl_Tree_Item *add(const Fl_Tree_Prefs &prefs,
|
||||
char **arr,
|
||||
Fl_Tree_Item *newitem);
|
||||
Fl_Tree_Item *add(const Fl_Tree_Prefs &prefs,
|
||||
char **arr);
|
||||
#if FLTK_ABI_VERSION >= 10303
|
||||
Fl_Tree_Item *replace(Fl_Tree_Item *new_item);
|
||||
Fl_Tree_Item *replace_child(Fl_Tree_Item *olditem, Fl_Tree_Item *newitem);
|
||||
#endif
|
||||
Fl_Tree_Item *insert(const Fl_Tree_Prefs &prefs, const char *new_label, int pos=0);
|
||||
Fl_Tree_Item *insert_above(const Fl_Tree_Prefs &prefs, const char *new_label);
|
||||
int depth() const;
|
||||
@@ -246,6 +295,7 @@ public:
|
||||
_parent = val;
|
||||
}
|
||||
#if FLTK_ABI_VERSION >= 10303
|
||||
const Fl_Tree_Prefs& prefs() const;
|
||||
/// Return the tree for this item.
|
||||
const Fl_Tree *tree() const {
|
||||
return(_tree);
|
||||
@@ -323,9 +373,8 @@ public:
|
||||
/// Change the item's activation state to the optionally specified 'val'.
|
||||
///
|
||||
/// When deactivated, the item will be 'grayed out'; the callback()
|
||||
/// won't be invoked if the user clicks on the label. If the item
|
||||
/// has a widget() associated with the item, its activation state
|
||||
/// will be changed as well.
|
||||
/// won't be invoked if the user clicks on the label. If a widget()
|
||||
/// is associated with the item, its activation state will be changed as well.
|
||||
///
|
||||
/// If 'val' is not specified, the item will be activated.
|
||||
///
|
||||
@@ -350,7 +399,7 @@ public:
|
||||
char is_activated() const {
|
||||
return(is_flag(ACTIVE));
|
||||
}
|
||||
/// See if the item is activated.
|
||||
/// See if the item is activated. Alias for is_activated().
|
||||
char is_active() const {
|
||||
return(is_activated());
|
||||
}
|
||||
@@ -391,6 +440,7 @@ public:
|
||||
}
|
||||
|
||||
// Protected methods
|
||||
// TODO: move these to top 'protected:' section
|
||||
protected:
|
||||
#if FLTK_ABI_VERSION >= 10301
|
||||
/// Set a flag to an on or off value. val is 0 or 1.
|
||||
|
||||
@@ -87,6 +87,7 @@ public:
|
||||
void clear();
|
||||
void add(Fl_Tree_Item *val);
|
||||
void insert(int pos, Fl_Tree_Item *new_item);
|
||||
void replace(int pos, Fl_Tree_Item *new_item);
|
||||
void remove(int index);
|
||||
int remove(Fl_Tree_Item *item);
|
||||
#if FLTK_ABI_VERSION >= 10303
|
||||
|
||||
@@ -17,68 +17,159 @@
|
||||
// http://www.fltk.org/str.php
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <math.h> // sin(3)
|
||||
#include <time.h> /* ctime.. */
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/Fl_Double_Window.H>
|
||||
#include <FL/Fl_Tree.H>
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(a,b) ((a)>(b))?(a):(b)
|
||||
#endif
|
||||
|
||||
#if FLTK_ABI_VERSION >= 10303
|
||||
static void draw_item(Fl_Tree_Item *item, void *data) {
|
||||
Fl_Tree *tree = (Fl_Tree*)data;
|
||||
int X=item->label_x(), Y=item->label_y(),
|
||||
W=item->label_w(), H=item->label_h();
|
||||
// Draw the background
|
||||
fl_color(item->is_selected() ? tree->selection_color() : item->labelbgcolor());
|
||||
fl_rectf(X,Y,W,H);
|
||||
// Draw some red/grn/blu boxes
|
||||
int x = X + 5;
|
||||
fl_color(FL_RED); fl_rectf(x, Y+2, 10, H-4); x += 10;
|
||||
fl_color(FL_GREEN); fl_rectf(x, Y+2, 10, H-4); x += 10;
|
||||
fl_color(FL_BLUE); fl_rectf(x, Y+2, 10, H-4); x += 10;
|
||||
x += 5;
|
||||
// Draw text
|
||||
fl_font(item->labelfont(), item->labelsize());
|
||||
fl_color(item->labelfgcolor());
|
||||
char s[80];
|
||||
sprintf(s, "Custom: '%s'", item->label()?item->label():"---");
|
||||
fl_draw(s, x+tree->labelmarginleft(),Y,W,H, FL_ALIGN_LEFT);
|
||||
int fw=0,fh=0;
|
||||
fl_measure(s,fw,fh);
|
||||
x += fw + 10;
|
||||
// Draw a red sine wave past the text to end of xywh area
|
||||
fl_color(FL_RED);
|
||||
for ( float a=0.0; x<(X+W); x++,a+=.1) {
|
||||
int y = Y + sin(a) * ((H-2)/2) + (H/2);
|
||||
fl_point(x,y);
|
||||
// DERIVE CUSTOM CLASS FROM Fl_Tree_Item TO IMPLEMENT SHOWING THE TIME OF DAY
|
||||
// This demonstrates that item content can be dynamic and highly customized.
|
||||
//
|
||||
class MyTimeItem : public Fl_Tree_Item {
|
||||
const char *time_format;
|
||||
protected:
|
||||
// Remove trailing crlf
|
||||
const char* StripCrlf(char *s)
|
||||
{ char *ss = strchr(s, '\n'); if (ss) *ss = 0; return s; }
|
||||
const struct tm* GetTimeStruct() {
|
||||
time_t t = time(NULL);
|
||||
if ( strcmp(time_format, "Local") == 0 ) return localtime(&t);
|
||||
if ( strcmp(time_format, "GMT" ) == 0 ) return gmtime(&t);
|
||||
return 0;
|
||||
}
|
||||
public:
|
||||
MyTimeItem(Fl_Tree *tree, const char *time_format) : Fl_Tree_Item(tree) {
|
||||
label(time_format);
|
||||
this->time_format = time_format;
|
||||
}
|
||||
// Handle custom drawing of the item
|
||||
// Fl_Tree has already handled drawing everything to the left
|
||||
// of the label area, including any 'user icon', collapse buttons,
|
||||
// connector lines, etc.
|
||||
//
|
||||
// All we're responsible for is drawing the 'label' area of the item
|
||||
// and it's background. Fl_Tree gives us a hint as to what the
|
||||
// foreground and background colors should be via the fg/bg parameters,
|
||||
// and whether we're supposed to render anything or not.
|
||||
//
|
||||
// The only other thing we must do is return the maximum X position
|
||||
// of scrollable content, i.e. the right most X position of content
|
||||
// that we want the user to be able to use the horizontal scrollbar
|
||||
// to reach.
|
||||
//
|
||||
int draw_item_content(int render) {
|
||||
Fl_Color fg = drawfgcolor();
|
||||
Fl_Color bg = drawbgcolor();
|
||||
// Show the date and time as two small strings
|
||||
// one on top of the other in a single item.
|
||||
//
|
||||
// Our item's label dimensions
|
||||
int X = label_x(), Y = label_y(),
|
||||
W = label_w(), H = label_h();
|
||||
// Render background
|
||||
if ( render ) {
|
||||
if ( is_selected() ) { // Selected? Use selectbox() style
|
||||
fl_draw_box(prefs().selectbox(),X,Y,W,H,bg);
|
||||
} else { // Not Selected? use plain filled rectangle
|
||||
fl_color(bg); fl_rectf(X,Y,W,H);
|
||||
}
|
||||
}
|
||||
// Render the label
|
||||
if ( render ) {
|
||||
fl_color(fg);
|
||||
if ( label() ) fl_draw(label(), X,Y,W,H, FL_ALIGN_LEFT);
|
||||
}
|
||||
int lw=0, lh=0;
|
||||
if ( label() ) {
|
||||
lw=0; lh=0; fl_measure(label(), lw, lh);
|
||||
}
|
||||
X += lw + 8;
|
||||
// Draw some red/grn/blu boxes
|
||||
if ( render ) {
|
||||
fl_color(FL_RED); fl_rectf(X+0, Y+2, 10, H-4);
|
||||
fl_color(FL_GREEN); fl_rectf(X+10, Y+2, 10, H-4);
|
||||
fl_color(FL_BLUE); fl_rectf(X+20, Y+2, 10, H-4);
|
||||
}
|
||||
X += 35;
|
||||
// Render the date and time, one over the other
|
||||
fl_font(labelfont(), 8); // small font
|
||||
const struct tm *tm = GetTimeStruct();
|
||||
char s[80];
|
||||
sprintf(s, "Date: %02d/%02d/%02d", tm->tm_mon+1, tm->tm_mday, tm->tm_year % 100);
|
||||
lw=0, lh=0; fl_measure(s, lw, lh); // get box around text (including white space)
|
||||
if ( render ) fl_draw(s, X,Y+4,W,H, FL_ALIGN_LEFT|FL_ALIGN_TOP);
|
||||
sprintf(s, "Time: %02d:%02d:%02d", tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
if ( render ) fl_draw(s, X,Y+H/2,W,H/2, FL_ALIGN_LEFT|FL_ALIGN_TOP);
|
||||
int lw2=0, lh2=0; fl_measure(s, lw2, lh2);
|
||||
X += MAX(lw, lw2);
|
||||
return X; // return right most edge of what we've rendered
|
||||
}
|
||||
};
|
||||
|
||||
// TIMER TO HANDLE DYNAMIC CONTENT IN THE TREE
|
||||
void Timer_CB(void *data) {
|
||||
Fl_Tree *tree = (Fl_Tree*)data;
|
||||
tree->redraw(); // keeps time updated
|
||||
Fl::repeat_timeout(0.2, Timer_CB, data);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
Fl::scheme("gtk+");
|
||||
Fl_Double_Window *win = new Fl_Double_Window(250, 400, "Simple Tree");
|
||||
Fl_Double_Window *win = new Fl_Double_Window(350, 400, "Simple Tree");
|
||||
win->begin();
|
||||
{
|
||||
// Create the tree
|
||||
Fl_Tree *tree = new Fl_Tree(0, 0, win->w(), win->h());
|
||||
tree->showroot(0); // don't show root of tree
|
||||
tree->item_draw_callback(draw_item, (void*)tree); // setup a callback for the tree
|
||||
tree->showroot(0); // don't show root of tree
|
||||
tree->selectmode(FL_TREE_SELECT_MULTI); // multiselect
|
||||
|
||||
// Add some items
|
||||
tree->add("Flintstones/Fred");
|
||||
tree->add("Flintstones/Wilma");
|
||||
tree->add("Flintstones/Pebbles");
|
||||
tree->add("Simpsons/Homer");
|
||||
tree->add("Simpsons/Marge");
|
||||
tree->add("Simpsons/Bart");
|
||||
tree->add("Simpsons/Lisa");
|
||||
{
|
||||
MyTimeItem *myitem;
|
||||
myitem = new MyTimeItem(tree, "Local"); // create custom item
|
||||
myitem->labelsize(20);
|
||||
tree->add("Time Add Item/Local", myitem);
|
||||
|
||||
myitem = new MyTimeItem(tree, "GMT"); // create custom item
|
||||
myitem->labelsize(20);
|
||||
tree->add("Time Add Item/GMT", myitem);
|
||||
}
|
||||
// 'Replace' approach
|
||||
{
|
||||
Fl_Tree_Item *item;
|
||||
MyTimeItem *myitem;
|
||||
item = tree->add("Time Replace Item/Local Time");
|
||||
// Replace the 'Local' item with our own
|
||||
myitem = new MyTimeItem(tree, "Local"); // create custom item
|
||||
myitem->labelsize(20);
|
||||
item->replace(myitem); // replace normal item with custom
|
||||
|
||||
item = tree->add("Time Replace Item/GMT Time");
|
||||
// Replace the 'GMT' item with our own
|
||||
myitem = new MyTimeItem(tree, "GMT"); // create custom item
|
||||
myitem->labelsize(20);
|
||||
item->replace(myitem); // replace normal item with custom
|
||||
}
|
||||
tree->add("Superjail/Warden");
|
||||
tree->add("Superjail/Jared");
|
||||
tree->add("Superjail/Alice");
|
||||
tree->add("Superjail/Jailbot");
|
||||
|
||||
tree->show_self();
|
||||
|
||||
// Start with some items closed
|
||||
tree->close("Simpsons");
|
||||
tree->close("Superjail");
|
||||
|
||||
// Set up a timer to keep time in tree updated
|
||||
Fl::add_timeout(0.2, Timer_CB, (void*)tree);
|
||||
}
|
||||
win->end();
|
||||
win->resizable(win);
|
||||
|
||||
+96
-93
@@ -58,7 +58,7 @@ static char **parse_path(const char *path) {
|
||||
static void free_path(char **arr) {
|
||||
if ( arr ) {
|
||||
if ( arr[0] ) { delete[] arr[0]; } // deletes cp in parse_path
|
||||
delete[] arr; // deletes ptr array
|
||||
delete[] arr; // deletes ptr array
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,10 +128,15 @@ Fl_Tree::~Fl_Tree() {
|
||||
/// depending on direction \p 'dir', \p 'val', and \p 'visible'.
|
||||
///
|
||||
/// Efficient: does not walk entire tree; starts with \p 'from' and stops
|
||||
/// at \p 'to' while moving in direction \p 'dir'. Dir must be specified
|
||||
/// though; when not available (such as during SHIFT-click operations),
|
||||
/// the other method extend_selection(Fl_Tree_Item*,Fl_Tree_Item*,int,bool)
|
||||
/// should be used. Handles calling redraw() if anything changed.
|
||||
/// at \p 'to' while moving in direction \p 'dir'. Dir must be specified though.
|
||||
#if FLTK_ABI_VERSION >= 10303
|
||||
///
|
||||
/// If dir cannot be known in advance, such as during SHIFT-click operations,
|
||||
/// the method extend_selection(Fl_Tree_Item*,Fl_Tree_Item*,int,bool)
|
||||
/// should be used.
|
||||
#endif
|
||||
///
|
||||
/// Handles calling redraw() if anything changed.
|
||||
///
|
||||
/// \param[in] from Starting item
|
||||
/// \param[in] to Ending item
|
||||
@@ -140,15 +145,10 @@ Fl_Tree::~Fl_Tree() {
|
||||
/// \param[in] visible true=affect only open(), visible items,<br>
|
||||
/// false=affect open or closed items (default)
|
||||
/// \returns The number of items whose selection states were changed, if any.
|
||||
/// \version 1.3.3
|
||||
///
|
||||
#if FLTK_ABI_VERSION >= 10303
|
||||
int Fl_Tree::extend_selection(Fl_Tree_Item *from, Fl_Tree_Item *to,
|
||||
int dir, int val, bool visible ) {
|
||||
#else
|
||||
// Adding overload if not at least one overload breaks ABI, so avoid
|
||||
int Fl_Tree::extend_selection__(Fl_Tree_Item *from, Fl_Tree_Item *to,
|
||||
int dir, int val, bool visible ) {
|
||||
#endif
|
||||
int Fl_Tree::extend_selection_dir(Fl_Tree_Item *from, Fl_Tree_Item *to,
|
||||
int dir, int val, bool visible ) {
|
||||
int changed = 0;
|
||||
for (Fl_Tree_Item *item=from; item; item = next_item(item, dir, visible) ) {
|
||||
switch (val) {
|
||||
@@ -171,8 +171,8 @@ int Fl_Tree::extend_selection__(Fl_Tree_Item *from, Fl_Tree_Item *to,
|
||||
/// Extend a selection between \p 'from' and \p 'to' depending on \p 'visible'.
|
||||
///
|
||||
/// Similar to the more efficient
|
||||
/// extend_selection(Fl_Tree_Item*,Fl_Tree_Item*,int,int,bool) method,
|
||||
/// but direction (up or down) doesn't need to be known.<br>
|
||||
/// extend_selection_dir(Fl_Tree_Item*,Fl_Tree_Item*,int dir,int val,bool vis)
|
||||
/// method, but direction (up or down) doesn't need to be known.<br>
|
||||
/// We're less efficient because we search the tree for to/from, then operate
|
||||
/// on items in between. The more efficient method avoids the "search",
|
||||
/// but necessitates a direction to be specified to find \p 'to'.<br>
|
||||
@@ -185,12 +185,14 @@ int Fl_Tree::extend_selection__(Fl_Tree_Item *from, Fl_Tree_Item *to,
|
||||
/// \param[in] visible true=affect only open(), visible items,<br>
|
||||
/// false=affect open or closed items (default)
|
||||
/// \returns The number of items whose selection states were changed, if any.
|
||||
///
|
||||
#if FLTK_ABI_VERSION >= 10303
|
||||
/// \version 1.3.3 ABI feature
|
||||
int Fl_Tree::extend_selection(Fl_Tree_Item *from, Fl_Tree_Item *to,
|
||||
int val, bool visible) {
|
||||
#else
|
||||
/// \notes Made public in 1.3.3 ABI
|
||||
// Adding overload if not at least one overload breaks ABI, so avoid
|
||||
// by making a private function until ABI can change..
|
||||
int Fl_Tree::extend_selection__(Fl_Tree_Item *from, Fl_Tree_Item *to,
|
||||
int val, bool visible) {
|
||||
#endif
|
||||
@@ -237,13 +239,17 @@ int Fl_Tree::extend_selection__(Fl_Tree_Item *from, Fl_Tree_Item *to,
|
||||
}
|
||||
|
||||
#if FLTK_ABI_VERSION >= 10303
|
||||
// nothing
|
||||
// not needed, above overload handles this
|
||||
#else
|
||||
/// Extend a selection between \p 'from' and \p 'to'.
|
||||
/// Extends selection for items and all children, visible ('open') or not.
|
||||
/// Walks entire tree from top to bottom looking for \p 'from' and \p 'to'.
|
||||
/// \version 1.3.0
|
||||
///
|
||||
void Fl_Tree::extend_selection(Fl_Tree_Item *from, Fl_Tree_Item *to) {
|
||||
const int val = 1;
|
||||
const bool visible = false;
|
||||
extend_selection__(from, to, val, visible);
|
||||
const int val = 1; // 0=clr, 1=set, 2=toggle
|
||||
const bool visible = false; // true=only 'open' items, false='open' or 'closed'
|
||||
extend_selection__(from, to, val, visible); // use private method until we can release it
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -521,11 +527,7 @@ int Fl_Tree::handle(int e) {
|
||||
Fl_Tree_Item *to = item;
|
||||
int val = is_ctrl ? 2 : 1; // toggle_select() or just select()?
|
||||
bool visible = true;
|
||||
#if FLTK_ABI_VERSION >= 10303
|
||||
extend_selection(from, to, dir, val, visible);
|
||||
#else
|
||||
extend_selection__(from, to, dir, val, visible);
|
||||
#endif
|
||||
extend_selection_dir(from, to, dir, val, visible);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -850,6 +852,7 @@ int Fl_Tree::draw_tree() {
|
||||
/// Print the tree as 'ascii art' to stdout.
|
||||
/// Used mainly for debugging.
|
||||
/// \todo should be const
|
||||
/// \version 1.3.0
|
||||
///
|
||||
void Fl_Tree::show_self() {
|
||||
if ( ! _root ) return;
|
||||
@@ -870,9 +873,28 @@ Fl_Tree_Item* Fl_Tree::root() {
|
||||
return(_root);
|
||||
}
|
||||
|
||||
/// Sets the root item to \p 'newitem'.
|
||||
///
|
||||
/// If a root item already exists, clear() is first to clear it
|
||||
/// before replacing it with newitem.
|
||||
///
|
||||
#if FLTK_ABI_VERSION >= 10303
|
||||
/// Use this to install a custom item (derived from Fl_Tree_Item) as the root
|
||||
/// of the tree. This allows the derived class to implement custom drawing
|
||||
/// by overriding Fl_Tree_Item::draw_item_content().
|
||||
///
|
||||
#endif
|
||||
/// \version 1.3.3
|
||||
///
|
||||
void Fl_Tree::root(Fl_Tree_Item *newitem) {
|
||||
if ( _root ) clear();
|
||||
_root = newitem;
|
||||
}
|
||||
|
||||
/// Adds a new item, given a menu style \p 'path'.
|
||||
/// Any parent nodes that don't already exist are created automatically.
|
||||
/// Adds the item based on the value of sortorder().
|
||||
/// If \p 'item' is NULL, a new item is created.
|
||||
///
|
||||
/// To specify items or submenus that contain slashes ('/' or '\')
|
||||
/// use an escape character to protect them, e.g.
|
||||
@@ -881,10 +903,15 @@ Fl_Tree_Item* Fl_Tree::root() {
|
||||
/// tree->add("/Pathnames/c:\\\\Program Files\\\\MyApp"); // Adds item "c:\Program Files\MyApp"
|
||||
/// \endcode
|
||||
/// \param[in] path The path to the item, e.g. "Flintsone/Fred".
|
||||
/// \param[in] item The new item to be added.
|
||||
/// If NULL, a new item is created with
|
||||
/// a name that is the last element in \p 'path'.
|
||||
/// \returns The new item added, or 0 on error.
|
||||
/// \version 1.3.3
|
||||
///
|
||||
Fl_Tree_Item* Fl_Tree::add(const char *path) {
|
||||
if ( ! _root ) { // Create root if none
|
||||
Fl_Tree_Item* Fl_Tree::add(const char *path, Fl_Tree_Item *item) {
|
||||
// Tree has no root? make one
|
||||
if ( ! _root ) {
|
||||
#if FLTK_ABI_VERSION >= 10303
|
||||
_root = new Fl_Tree_Item(this);
|
||||
#else
|
||||
@@ -892,19 +919,36 @@ Fl_Tree_Item* Fl_Tree::add(const char *path) {
|
||||
#endif
|
||||
_root->parent(0);
|
||||
_root->label("ROOT");
|
||||
}
|
||||
}
|
||||
// Find parent item via path
|
||||
char **arr = parse_path(path);
|
||||
Fl_Tree_Item *item = _root->add(_prefs, arr);
|
||||
item = _root->add(_prefs, arr, item);
|
||||
free_path(arr);
|
||||
return(item);
|
||||
}
|
||||
|
||||
#if FLTK_ABI_VERSION >= 10303
|
||||
// do nothing here: add(path,item) where item defaults to 0 takes its place
|
||||
#else
|
||||
/// Adds a new item given a menu style \p 'path'.
|
||||
/// Same as calling add(path, NULL);
|
||||
/// \param[in] path The path to the item to be created, e.g. "Flintsone/Fred".
|
||||
/// \returns The new item added, or 0 on error.
|
||||
/// \see add(const char*,Fl_Tree_Item*)
|
||||
/// \version 1.3.0 release
|
||||
///
|
||||
Fl_Tree_Item* Fl_Tree::add(const char *path) {
|
||||
return add(path, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/// Add a new child item labeled \p 'name' to the specified \p 'parent_item'.
|
||||
///
|
||||
/// \param[in] parent_item The parent item the new child item will be added to.
|
||||
/// Must not be NULL.
|
||||
/// \param[in] name The label for the new item
|
||||
/// \returns The new item added.
|
||||
/// \version 1.3.0 release
|
||||
///
|
||||
Fl_Tree_Item* Fl_Tree::add(Fl_Tree_Item *parent_item, const char *name) {
|
||||
return(parent_item->add(_prefs, name));
|
||||
@@ -949,7 +993,7 @@ int Fl_Tree::remove(Fl_Tree_Item *item) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
/// Clear all children from the tree.
|
||||
/// Clear the entire tree's children, including the root.
|
||||
/// The tree will be left completely empty.
|
||||
///
|
||||
void Fl_Tree::clear() {
|
||||
@@ -987,7 +1031,7 @@ void Fl_Tree::clear_children(Fl_Tree_Item *item) {
|
||||
/// \see item_pathname()
|
||||
///
|
||||
Fl_Tree_Item *Fl_Tree::find_item(const char *path) {
|
||||
// I evoke "Effective C++, 3rd Ed", p.23. Sola fide, Amen.
|
||||
// "Effective C++, 3rd Ed", p.23. Sola fide, Amen.
|
||||
return(const_cast<Fl_Tree_Item*>(
|
||||
static_cast<const Fl_Tree&>(*this).find_item(path)));
|
||||
}
|
||||
@@ -1136,6 +1180,7 @@ Fl_Tree_Item* Fl_Tree::item_clicked() {
|
||||
/// \param[in] item The item above/below which we'll find the next visible item
|
||||
/// \param[in] dir The direction to search. Can be FL_Up or FL_Down.
|
||||
/// \returns The item found, or 0 if there's no visible items above/below the specified \p item.
|
||||
/// \version 1.3.3
|
||||
///
|
||||
Fl_Tree_Item *Fl_Tree::next_visible_item(Fl_Tree_Item *item, int dir) {
|
||||
return next_item(item, dir, true);
|
||||
@@ -1166,6 +1211,7 @@ Fl_Tree_Item* Fl_Tree::first_visible() {
|
||||
/// Returns the first open(), visible item in the tree, or 0 if none.
|
||||
/// \returns First visible item in tree, or 0 if none.
|
||||
/// \see first_visible_item(), last_visible_item(), next_visible_item()
|
||||
/// \version 1.3.3
|
||||
///
|
||||
Fl_Tree_Item* Fl_Tree::first_visible_item() {
|
||||
Fl_Tree_Item *i = showroot() ? first() : next(first());
|
||||
@@ -1234,7 +1280,7 @@ Fl_Tree_Item* Fl_Tree::last() {
|
||||
}
|
||||
|
||||
/// Returns the last open(), visible item in the tree.
|
||||
/// \deprecated in 1.3.3 ABI -- use last_visible_item() instead.
|
||||
/// \deprecated in 1.3.3 -- use last_visible_item() instead.
|
||||
///
|
||||
Fl_Tree_Item* Fl_Tree::last_visible() {
|
||||
return(last_visible_item());
|
||||
@@ -1243,6 +1289,7 @@ Fl_Tree_Item* Fl_Tree::last_visible() {
|
||||
/// Returns the last open(), visible item in the tree.
|
||||
/// \returns Last visible item in the tree, or 0 if none.
|
||||
/// \see first_visible_item(), last_visible_item(), next_visible_item()
|
||||
/// \version 1.3.3
|
||||
///
|
||||
Fl_Tree_Item* Fl_Tree::last_visible_item() {
|
||||
Fl_Tree_Item *item = last();
|
||||
@@ -1313,6 +1360,7 @@ Fl_Tree_Item *Fl_Tree::next_selected_item(Fl_Tree_Item *item) {
|
||||
///
|
||||
/// \returns The last selected item, or 0 if none.
|
||||
/// \see first_selected_item(), last_selected_item(), next_selected_item()
|
||||
/// \version 1.3.3
|
||||
///
|
||||
Fl_Tree_Item *Fl_Tree::last_selected_item() {
|
||||
return(next_selected_item(0, FL_Up));
|
||||
@@ -1325,13 +1373,13 @@ Fl_Tree_Item *Fl_Tree::last_selected_item() {
|
||||
/// If \p 'visible' is true, only items whose parents are open() will be returned.
|
||||
/// If \p 'visible' is false, even items whose parents are close()ed will be returned.
|
||||
///
|
||||
/// If \p item is 0, the return value will be:
|
||||
/// <pre>
|
||||
/// last_visible_item() - If \p visible=true and \p dir=FL_Up<br>
|
||||
/// first_visible_item() - If \p visible=true and \p dir=FL_Down<br>
|
||||
/// last() - If \p visible=false and \p dir=FL_Up<br>
|
||||
/// first() - If \p visible=false and \p dir=FL_Down
|
||||
/// </pre>
|
||||
/// If \p item is 0, the return value will be the result of this truth table:
|
||||
/// <PRE>
|
||||
/// visible=true visible=false
|
||||
/// ------------------- -------------
|
||||
/// dir=Fl_Up: last_visible_item() last()
|
||||
/// dir=Fl_Down: first_visible_item() first()
|
||||
/// </PRE>
|
||||
///
|
||||
/// \par Example use:
|
||||
/// \code
|
||||
@@ -1361,7 +1409,8 @@ Fl_Tree_Item *Fl_Tree::last_selected_item() {
|
||||
/// \see first(), last(), next(),<BR>
|
||||
/// first_visible_item(), last_visible_item(), next_visible_item(),<BR>
|
||||
/// first_selected_item(), last_selected_item(), next_selected_item()
|
||||
///
|
||||
/// \version 1.3.3
|
||||
///
|
||||
Fl_Tree_Item *Fl_Tree::next_item(Fl_Tree_Item *item, int dir, bool visible) {
|
||||
if ( ! item ) { // no start item?
|
||||
if ( visible ) {
|
||||
@@ -1408,6 +1457,7 @@ Fl_Tree_Item *Fl_Tree::next_item(Fl_Tree_Item *item, int dir, bool visible) {
|
||||
/// FL_Down for down the tree (default)
|
||||
/// \returns The next selected item, or 0 if there are no more selected items.
|
||||
/// \see first_selected_item(), last_selected_item(), next_selected_item()
|
||||
/// \version 1.3.3
|
||||
///
|
||||
Fl_Tree_Item *Fl_Tree::next_selected_item(Fl_Tree_Item *item, int dir) {
|
||||
switch (dir) {
|
||||
@@ -1451,6 +1501,7 @@ Fl_Tree_Item *Fl_Tree::next_selected_item(Fl_Tree_Item *item, int dir) {
|
||||
/// \param[out] ret_items The returned array of selected items.
|
||||
/// \returns The number of items in the returned array.
|
||||
/// \see first_selected_item(), next_selected_item()
|
||||
/// \version 1.3.3 ABI feature
|
||||
///
|
||||
int Fl_Tree::get_selected_items(Fl_Tree_Item_Array &ret_items) {
|
||||
ret_items.clear();
|
||||
@@ -2350,7 +2401,7 @@ void Fl_Tree::item_reselect_mode(Fl_Tree_Item_Reselect_Mode mode) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if FLTK_ABI_VERSION >= 10303
|
||||
#if FLTK_ABI_VERSION >= 10301
|
||||
/// Get the 'item draw mode' used for the tree
|
||||
Fl_Tree_Item_Draw_Mode Fl_Tree::item_draw_mode() const {
|
||||
return(_prefs.item_draw_mode());
|
||||
@@ -2373,54 +2424,6 @@ void Fl_Tree::item_draw_mode(Fl_Tree_Item_Draw_Mode mode) {
|
||||
void Fl_Tree::item_draw_mode(int mode) {
|
||||
_prefs.item_draw_mode(Fl_Tree_Item_Draw_Mode(mode));
|
||||
}
|
||||
|
||||
/// Set a callback to be invoked to handle drawing the Fl_Tree_Item
|
||||
/// instead of the default label drawing behavior. Lets one define
|
||||
/// custom drawing behavior for Fl_Tree_Item's. e.g.
|
||||
/// \code
|
||||
/// static void draw_item(Fl_Tree_Item *item, void *data) {
|
||||
/// Fl_Tree *tree = (Fl_Tree*)data;
|
||||
/// int X=item->label_x(), Y=item->label_y(),
|
||||
/// W=item->label_w(), H=item->label_h();
|
||||
/// // Draw the background
|
||||
/// fl_color(item->is_selected() ? tree->selection_color() : item->labelbgcolor());
|
||||
/// fl_rectf(X,Y,W,H);
|
||||
/// // Draw text
|
||||
/// fl_font(item->labelfont(), item->labelsize());
|
||||
/// fl_color(item->labelfgcolor());
|
||||
/// fl_draw("Some text", X+tree->labelmarginleft(),Y,W,H, FL_ALIGN_LEFT);
|
||||
/// }
|
||||
/// ..
|
||||
/// int main() {
|
||||
/// Fl_Tree *tree = new Fl_Tree(0,0,100,100);
|
||||
/// tree->item_draw_callback(draw_item, (void*)tree);
|
||||
/// [..]
|
||||
/// \endcode
|
||||
/// \param[in] cb The callback to use
|
||||
/// \param[in] data Optional item_draw_user_data() (default=NULL)
|
||||
/// \note This only affects the drawing of item's labels,
|
||||
/// it does not affect the drawing of widgets assigned with
|
||||
/// Fl_Tree_Item::widget().
|
||||
///
|
||||
void Fl_Tree::item_draw_callback(Fl_Tree_Item_Draw_Callback *cb, void *data) {
|
||||
_prefs.item_draw_callback(cb,data); // no recalc_tree() -- changes don't affect item geometry
|
||||
}
|
||||
|
||||
/// Get the current item draw callback. Returns 0 if none.
|
||||
Fl_Tree_Item_Draw_Callback* Fl_Tree::item_draw_callback() const {
|
||||
return(_prefs.item_draw_callback());
|
||||
}
|
||||
|
||||
/// Get the current item draw callback's user data.
|
||||
void* Fl_Tree::item_draw_user_data() const {
|
||||
return(_prefs.item_draw_user_data());
|
||||
}
|
||||
|
||||
/// Invoke the configured item_draw_callback().
|
||||
/// Do NOT call this if no item_draw_callback() was configured.
|
||||
void Fl_Tree::do_item_draw_callback(Fl_Tree_Item *o) const {
|
||||
_prefs.do_item_draw_callback(o);
|
||||
}
|
||||
#endif
|
||||
|
||||
/// See if \p 'item' is currently displayed on-screen (visible within the widget).
|
||||
@@ -2613,11 +2616,11 @@ int Fl_Tree::scrollbar_size() const {
|
||||
/// Normally you should not need this method, and should use the global
|
||||
/// Fl::scrollbar_size(int) instead to manage the size of ALL
|
||||
/// your widgets' scrollbars. This ensures your application
|
||||
/// has a consistent UI, is the default behavior, and is normally
|
||||
/// what you want.
|
||||
/// has a consistent UI, and is the default behavior. Normally
|
||||
/// this is what you want.
|
||||
///
|
||||
/// Only use THIS method if you really need to override just this
|
||||
/// widget instance's scrollbar size. (The need for this should be rare.)
|
||||
/// Only use this method if you really need to override just THIS
|
||||
/// instance of the widget's scrollbar size. (This need should be rare.)
|
||||
///
|
||||
/// Setting \p size to the special value of 0 causes the widget to
|
||||
/// track the global Fl::scrollbar_size(), which is the default.
|
||||
|
||||
+403
-148
File diff suppressed because it is too large
Load Diff
@@ -150,6 +150,29 @@ void Fl_Tree_Item_Array::add(Fl_Tree_Item *val) {
|
||||
insert(_total, val);
|
||||
}
|
||||
|
||||
/// Replace the item at \p index with \p newitem.
|
||||
///
|
||||
/// Old item at index position will be destroyed,
|
||||
/// and the new item will take it's place, and stitched into the linked list.
|
||||
///
|
||||
void Fl_Tree_Item_Array::replace(int index, Fl_Tree_Item *newitem) {
|
||||
if ( _items[index] ) { // delete if non-zero
|
||||
#if FLTK_ABI_VERSION >= 10303
|
||||
if ( _flags & MANAGE_ITEM )
|
||||
#endif
|
||||
// Destroy old item
|
||||
delete _items[index];
|
||||
}
|
||||
_items[index] = newitem; // install new item
|
||||
#if FLTK_ABI_VERSION >= 10303
|
||||
if ( _flags & MANAGE_ITEM )
|
||||
#endif
|
||||
{
|
||||
// Restitch into linked list
|
||||
_items[index]->update_prev_next(index);
|
||||
}
|
||||
}
|
||||
|
||||
/// Remove the item at \param[in] index from the array.
|
||||
///
|
||||
/// The item will be delete'd (if non-NULL), so its destructor will be called.
|
||||
|
||||
Reference in New Issue
Block a user