summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Ercolano <erco@seriss.com>2010-04-16 17:55:45 +0000
committerGreg Ercolano <erco@seriss.com>2010-04-16 17:55:45 +0000
commitcba451be455e16ab1be718ae9a6a067ba346b74e (patch)
treef6c45708bc636c61973edc8378b36ad5598f0db4
parent4d22e65e539d9258718768ee914bc4af5de935d0 (diff)
Doc sync.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@7517 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
-rw-r--r--CHANGES2
-rw-r--r--FL/Fl_Menu_.H14
-rw-r--r--FL/Fl_Menu_Item.H1
-rw-r--r--src/Fl_Menu_.cxx138
-rw-r--r--src/Fl_Menu_add.cxx118
5 files changed, 231 insertions, 42 deletions
diff --git a/CHANGES b/CHANGES
index cc402681f..b91781f95 100644
--- a/CHANGES
+++ b/CHANGES
@@ -157,6 +157,8 @@ CHANGES IN FLTK 1.3.0
- hide() and show() methods are now virtual from Fl_Widget,
was only virtual since Fl_Window derived classes before.
So now widget->hide() will work if widget is a window.
+ - New widgets: Fl_Tree, Fl_Table, Fl_Native_File_Chooser
+ - added Fl_Menu_ methods: insert(), find_index(), clear_submenu()
CHANGES IN FLTK 1.1.9
diff --git a/FL/Fl_Menu_.H b/FL/Fl_Menu_.H
index 5daec157d..8f3b64449 100644
--- a/FL/Fl_Menu_.H
+++ b/FL/Fl_Menu_.H
@@ -66,6 +66,9 @@ public:
const Fl_Menu_Item* picked(const Fl_Menu_Item*);
const Fl_Menu_Item* find_item(const char *name);
const Fl_Menu_Item* find_item(Fl_Callback*);
+ int find_index(const char *name) const;
+ int find_index(const Fl_Menu_Item *item) const;
+ int find_index(Fl_Callback *cb) const;
const Fl_Menu_Item* test_shortcut() {return picked(menu()->test_shortcut());}
void global();
@@ -77,14 +80,21 @@ public:
const Fl_Menu_Item *menu() const {return menu_;}
void menu(const Fl_Menu_Item *m);
void copy(const Fl_Menu_Item *m, void* user_data = 0);
+ int insert(int index, const char*, int shortcut, Fl_Callback*, void* = 0, int = 0);
int add(const char*, int shortcut, Fl_Callback*, void* = 0, int = 0);
- /** See int Fl_Menu_::add(const char* label, int shortcut, Fl_Callback*, void *user_data=0, int flags=0)*/
+ /** See int Fl_Menu_::add(const char* label, int shortcut, Fl_Callback*, void *user_data=0, int flags=0) */
int add(const char* a, const char* b, Fl_Callback* c, void* d = 0, int e = 0) {
- return add(a,fl_old_shortcut(b),c,d,e);}
+ return add(a,fl_old_shortcut(b),c,d,e);
+ }
+ /** See int Fl_Menu_::insert(const char* label, int shortcut, Fl_Callback*, void *user_data=0, int flags=0) */
+ int insert(int index, const char* a, const char* b, Fl_Callback* c, void* d = 0, int e = 0) {
+ return insert(index,a,fl_old_shortcut(b),c,d,e);
+ }
int add(const char *);
int size() const ;
void size(int W, int H) { Fl_Widget::size(W, H); }
void clear();
+ int clear_submenu(int index);
void replace(int,const char *);
void remove(int);
/** Changes the shortcut of item i to n. */
diff --git a/FL/Fl_Menu_Item.H b/FL/Fl_Menu_Item.H
index 0ea5c792f..31620e16f 100644
--- a/FL/Fl_Menu_Item.H
+++ b/FL/Fl_Menu_Item.H
@@ -386,6 +386,7 @@ struct FL_EXPORT Fl_Menu_Item {
/** back compatibility only \deprecated. */
void uncheck() {flags &= ~FL_MENU_VALUE;}
+ int insert(int,const char*,int,Fl_Callback*,void* =0, int =0);
int add(const char*, int shortcut, Fl_Callback*, void* =0, int = 0);
/** See int add(const char*, int shortcut, Fl_Callback*, void*, int) */
diff --git a/src/Fl_Menu_.cxx b/src/Fl_Menu_.cxx
index ce417bfa9..2e3405885 100644
--- a/src/Fl_Menu_.cxx
+++ b/src/Fl_Menu_.cxx
@@ -100,11 +100,13 @@ int Fl_Menu_::item_pathname(char *name, int namelen, const Fl_Menu_Item *findite
}
/**
- Find menu item index, given a menu pathname such as "Edit/Copy".
+ Find the menu item for a given menu \p pathname, such as "Edit/Copy".
- This method finds a menu item in a menu array, also traversing submenus, but
+ This method finds a menu item in the menu array, also traversing submenus, but
not submenu pointers.
+ To get the menu item's index, use find_index(const char*)
+
\b Example:
\code
Fl_Menu_Bar *menubar = new Fl_Menu_Bar(..);
@@ -120,25 +122,84 @@ int Fl_Menu_::item_pathname(char *name, int namelen, const Fl_Menu_Item *findite
item->labelcolor(FL_GREEN);
}
\endcode
- \returns The item found, or NULL if not found.
- \see
- \param name path and name of the menu item
- \return NULL if not found
- \see Fl_Menu_::find_item(Fl_Callback*), item_pathname()
+ \param pathname The path and name of the menu item
+ \returns The item found, or NULL if not found
+ \see find_index(const char*), find_item(Fl_Callback*), item_pathname()
*/
-const Fl_Menu_Item * Fl_Menu_::find_item(const char *name) {
- char menupath[1024] = ""; // File/Export
+const Fl_Menu_Item * Fl_Menu_::find_item(const char *pathname) {
+ int i = find_index(pathname);
+ return( (i==-1) ? 0 : (const Fl_Menu_Item*)(menu_+i));
+}
+/**
+ Find the index the menu array for given \p item.
+
+ A way to convert a menu item pointer into an index.
+
+ Current implementation is fast and not expensive.
+
+ \code
+ // Convert an index-to-item
+ int index = 12;
+ const Fl_Menu_Item *item = mymenu->menu() + index;
+
+ // Convert an item-to-index
+ int index = mymenu->find_index(item);
+ if ( index == -1 ) { ..error.. }
+ \endcode
+
+ \param item The *item to be found
+ \returns The index of the item, or -1 if not found.
+ \see menu()
+*/
+int Fl_Menu_::find_index(const Fl_Menu_Item *item) const {
+ Fl_Menu_Item *max = menu_+size();
+ if (item<menu_ || item>=max) return(-1);
+ return(item-menu_);
+}
+
+/**
+ Find the index into the menu array for a given callback \p cb.
+
+ This method finds a menu item's index position, also traversing submenus, but
+ not submenu pointers. This is useful if an application uses internationalisation
+ and a menu item can not be found using its label. This search is also much faster.
+
+ \param cb Find the first item with this callback
+ \returns The index of the item with the specific callback, or -1 if not found
+ \see find_index(const char*)
+ */
+int Fl_Menu_::find_index(Fl_Callback *cb) const {
+ for ( int t=0; t < size(); t++ )
+ if (menu_[t].callback_==cb)
+ return(t);
+ return(-1);
+}
+
+/**
+ Find the menu item index for a given menu \p pathname, such as "Edit/Copy".
+
+ This method finds a menu item's index position for the given menu pathname,
+ also traversing submenus, but not submenu pointers.
+
+ To get the menu item pointer for a pathname, use find_item()
+
+ \param pathname The path and name of the menu item index to find
+ \returns The index of the matching item, or -1 if not found.
+ \see item_pathname()
+
+*/
+int Fl_Menu_::find_index(const char *pathname) const {
+ char menupath[1024] = ""; // File/Export
for ( int t=0; t < size(); t++ ) {
Fl_Menu_Item *m = menu_ + t;
-
if (m->flags&FL_SUBMENU) {
// IT'S A SUBMENU
// we do not support searches through FL_SUBMENU_POINTER links
if (menupath[0]) strlcat(menupath, "/", sizeof(menupath));
strlcat(menupath, m->label(), sizeof(menupath));
- if (!strcmp(menupath, name)) return m;
+ if (!strcmp(menupath, pathname)) return(t);
} else {
if (!m->label()) {
// END OF SUBMENU? Pop back one level.
@@ -147,21 +208,19 @@ const Fl_Menu_Item * Fl_Menu_::find_item(const char *name) {
else menupath[0] = '\0';
continue;
}
-
// IT'S A MENU ITEM
char itempath[1024]; // eg. Edit/Copy
strcpy(itempath, menupath);
if (itempath[0]) strlcat(itempath, "/", sizeof(itempath));
strlcat(itempath, m->label(), sizeof(itempath));
- if (!strcmp(itempath, name)) return m;
+ if (!strcmp(itempath, pathname)) return(t);
}
}
-
- return (const Fl_Menu_Item *)0;
+ return(-1);
}
/**
- Find menu item index given a callback.
+ Find the menu item for the given callback \p cb.
This method finds a menu item in a menu array, also traversing submenus, but
not submenu pointers. This is useful if an application uses
@@ -169,8 +228,8 @@ const Fl_Menu_Item * Fl_Menu_::find_item(const char *name) {
search is also much faster.
\param cb find the first item with this callback
- \return NULL if not found
- \see Fl_Menu_::find_item(const char*)
+ \returns The item found, or NULL if not found
+ \see find_item(const char*)
*/
const Fl_Menu_Item * Fl_Menu_::find_item(Fl_Callback *cb) {
for ( int t=0; t < size(); t++ ) {
@@ -286,7 +345,7 @@ void Fl_Menu_::menu(const Fl_Menu_Item* m) {
/**
Sets the menu array pointer with a copy of m that will be automatically deleted.
- If ud is not NULL, then all user data pointers are changed in the menus as well.
+ If userdata \p ud is not NULL, then all user data pointers are changed in the menus as well.
See void Fl_Menu_::menu(const Fl_Menu_Item* m).
*/
void Fl_Menu_::copy(const Fl_Menu_Item* m, void* ud) {
@@ -330,6 +389,47 @@ void Fl_Menu_::clear() {
}
}
+/**
+ Clears the specified submenu pointed to by \p index of all menu items.
+
+ This method is useful for clearing a submenu so that it can be
+ re-populated with new items. Example: a "File/Recent Files/..." submenu
+ that shows the last few files that have been opened.
+
+ The specified \p index must point to a submenu.
+
+ The submenu is cleared with remove().
+ If the menu array was directly set with menu(x), then copy()
+ is done to make a private array.
+
+ \warning Since this method can change the internal menu array, any menu
+ item pointers or indecies the application may have cached can become
+ stale, and should be recalculated/refreshed.
+
+ \b Example:
+ \code
+ int index = menubar->find_index("File/Recent"); // get index of "File/Recent" submenu
+ if ( index != -1 ) menubar->clear_submenu(index); // clear the submenu
+ menubar->add("File/Recent/Aaa");
+ menubar->add("File/Recent/Bbb");
+ [..]
+ \endcode
+
+ \param index The index of the submenu to be cleared
+ \returns 0 on success, -1 if the index is out of range or not a submenu
+ \see remove(int)
+ */
+int Fl_Menu_::clear_submenu(int index) {
+ if ( index < 0 || index >= size() ) return(-1);
+ if ( ! (menu_[index].flags & FL_SUBMENU) ) return(-1);
+ ++index; // advance to first item in submenu
+ while ( index < size() ) { // keep remove()ing top item until end is reached
+ if ( menu_[index].text == 0 ) break; // end of this submenu? done
+ remove(index); // remove items/submenus
+ }
+ return(0);
+}
+
//
// End of "$Id$".
//
diff --git a/src/Fl_Menu_add.cxx b/src/Fl_Menu_add.cxx
index 96f4a443c..036fc2d0d 100644
--- a/src/Fl_Menu_add.cxx
+++ b/src/Fl_Menu_add.cxx
@@ -53,11 +53,12 @@ extern Fl_Menu_* fl_menu_array_owner; // in Fl_Menu_.cxx
// Insert a single Fl_Menu_Item into an array of size at offset n,
// if this is local_array it will be reallocated if needed.
-static Fl_Menu_Item* insert(
- Fl_Menu_Item* array, int size,
- int n,
- const char *text,
- int flags
+static Fl_Menu_Item* array_insert(
+ Fl_Menu_Item* array, // array to modify
+ int size, // size of array
+ int n, // index of new insert position
+ const char *text, // text of new item (copy is made)
+ int flags // flags for new item
) {
if (array == local_array && size >= local_array_alloc) {
local_array_alloc = 2*size;
@@ -107,6 +108,27 @@ int Fl_Menu_Item::add(
void *data,
int myflags
) {
+ return(insert(-1,mytext,sc,cb,data,myflags)); // -1: append
+}
+
+/** Inserts an item at position \p index.
+
+ If \p index is -1, the item is added the same way as Fl_Menu_Item::add().
+
+ If 'mytext' contains any un-escaped front slashes (/), it's assumed
+ a menu pathname is being specified, and the value of \p index
+ will be ignored.
+
+ In all other aspects, the behavior of insert() is the same as add().
+*/
+int Fl_Menu_Item::insert(
+ int index,
+ const char *mytext,
+ int sc,
+ Fl_Callback *cb,
+ void *data,
+ int myflags
+) {
Fl_Menu_Item *array = this;
Fl_Menu_Item *m = this;
const char *p;
@@ -133,17 +155,18 @@ int Fl_Menu_Item::add(
item = buf;
if (*p != '/') break; /* not a menu title */
- mytext = p+1; /* point at item title */
+ index = -1; /* any submenu specified overrides insert position */
+ mytext = p+1; /* point at item title */
/* find a matching menu title: */
for (; m->text; m = m->next())
if (m->flags&FL_SUBMENU && !compare(item, m->text)) break;
if (!m->text) { /* create a new menu */
- int n = m-array;
- array = insert(array, msize, n, item, FL_SUBMENU|flags1);
+ int n = (index==-1) ? m-array : index;
+ array = array_insert(array, msize, n, item, FL_SUBMENU|flags1);
msize++;
- array = insert(array, msize, n+1, 0, 0);
+ array = array_insert(array, msize, n+1, 0, 0);
msize++;
m = array+n;
}
@@ -156,11 +179,11 @@ int Fl_Menu_Item::add(
if (!(m->flags&FL_SUBMENU) && !compare(m->text,item)) break;
if (!m->text) { /* add a new menu item */
- int n = m-array;
- array = insert(array, msize, n, item, myflags|flags1);
+ int n = (index==-1) ? m-array : index;
+ array = array_insert(array, msize, n, item, myflags|flags1);
msize++;
if (myflags & FL_SUBMENU) { // add submenu delimiter
- array = insert(array, msize, n+1, 0, 0);
+ array = array_insert(array, msize, n+1, 0, 0);
msize++;
}
m = array+n;
@@ -179,17 +202,21 @@ int Fl_Menu_Item::add(
/**
Adds a new menu item.
- \param[in] label The text label for the menu item.
+ \param[in] label The text label for the menu item.
\param[in] shortcut Optional keyboard shortcut that can be an int or string; (FL_CTRL+'a') or "^a". Default 0 if none.
\param[in] callback Optional callback invoked when user clicks the item. Default 0 if none.
\param[in] userdata Optional user data passed as an argument to the callback. Default 0 if none.
- \param[in] flags Optional flags that control the type of menu item; see below. Default is 0 for none.
- \returns The index into the menu() array, where the entry was added.
+ \param[in] flags Optional flags that control the type of menu item; see below. Default is 0 for none.
+ \returns The index into the menu() array, where the entry was added.
\par Description
If the menu array was directly set with menu(x), then copy() is done
to make a private array.
\par
+ Since this method can change the internal menu array, any menu item
+ pointers or indecies the application may have cached can become stale,
+ and should be recalculated/refreshed.
+ \par
A menu item's callback must not add() items to its parent menu during the callback.
<B>Detailed Description of Parameters</B>
@@ -219,23 +246,32 @@ int Fl_Menu_Item::add(
\par
This parameter is optional, and defaults to 0 to indicate no shortcut.
\par
- Shortcut can be 0L, or either a modifier/key combination (for example
- FL_CTRL+'A') or a string describing the shortcut in one of two ways:
+ The shortcut can either be a raw integer value (eg. FL_CTRL+'A')
+ or a string (eg. "^c" or "^97").
+ \par
+ Raw integer shortcuts can be a combination of keyboard chars (eg. 'A')
+ and optional keyboard modifiers (see Fl::event_state(), e.g. FL_SHIFT, etc).
+ \par
+ String shortcuts can be specified in one of two ways:
+ \par
\verbatim
[#+^]<ascii_value> e.g. "97", "^97", "+97", "#97"
[#+^]<ascii_char> e.g. "a", "^a", "+a", "#a"
\endverbatim
+ \par
..where \<ascii_value\> is a decimal value representing an
- ascii character (eg. 97 is the ascii for 'a'), and the optional
+ ascii character (eg. 97 is the ascii code for 'a'), and the optional
prefixes enhance the value that follows. Multiple prefixes must
appear in the above order.
+ \par
\verbatim
# - Alt
+ - Shift
^ - Control
\endverbatim
- Text shortcuts are converted to integer shortcut by calling
- unsigned int fl_old_shortcut(const char*).
+ \par
+ Internally, the text shortcuts are converted to integer values using
+ fl_old_shortcut(const char*).
\par callback
The callback to invoke when this menu item is selected.
@@ -264,8 +300,48 @@ int Fl_Menu_Item::add(
FL_MENU_DIVIDER // Creates divider line below this item. Also ends a group of radio buttons.
\endcode
+ \todo Raw integer shortcut needs examples.
+ Dependent on responses to http://fltk.org/newsgroups.php?gfltk.development+v:10086 and results of STR#2344
*/
int Fl_Menu_::add(const char *label,int shortcut,Fl_Callback *callback,void *userdata,int flags) {
+ return(insert(-1,label,shortcut,callback,userdata,flags)); // -1: append
+}
+
+/**
+ Inserts a new menu item at the specified \p index position.
+
+ If \p index is -1, the menu item is appended; same behavior as add().
+
+ The value of \p index will be ignored if \p label contains un-escaped
+ front-slashes (/) indicating a menu pathname as the point of insertion.
+ A menu pathname will override the value of \p index.
+
+ For more details, see add(). Except for the \p index parameter, add()
+ has more detailed information on parameters and behavior, and is
+ functionally equivalent,
+
+ \param[in] index The menu array's index position where the new item
+ is inserted. If -1, behavior is the same as add().
+ \param[in] label The text label for the menu item.
+ \param[in] shortcut Optional keyboard shortcut. Can be an int (FL_CTRL+'a')
+ or a string ("^a"). Default is 0.
+ \param[in] callback Optional callback invoked when user clicks the item.
+ Default 0 if none.
+ \param[in] userdata Optional user data passed as an argument to the callback.
+ Default 0 if none.
+ \param[in] flags Optional flags that control the type of menu item;
+ see add() for more info. Default is 0 for none.
+ \returns The index into the menu() array, where the entry was added.
+
+ */
+int Fl_Menu_::insert(
+ int index,
+ const char *label,
+ int shortcut,
+ Fl_Callback *callback,
+ void *userdata,
+ int flags
+) {
// make this widget own the local array:
if (this != fl_menu_array_owner) {
if (fl_menu_array_owner) {
@@ -299,7 +375,7 @@ int Fl_Menu_::add(const char *label,int shortcut,Fl_Callback *callback,void *use
}
fl_menu_array_owner = this;
}
- int r = menu_->add(label,shortcut,callback,userdata,flags);
+ int r = menu_->insert(index,label,shortcut,callback,userdata,flags);
// if it rellocated array we must fix the pointer:
int value_offset = value_-menu_;
menu_ = local_array; // in case it reallocated it