summaryrefslogtreecommitdiff
path: root/src/Fl_Menu_add.cxx
diff options
context:
space:
mode:
authorBill Spitzak <spitzak@gmail.com>1999-02-03 08:43:35 +0000
committerBill Spitzak <spitzak@gmail.com>1999-02-03 08:43:35 +0000
commit8009fef12cb88c5d4944bdad9a1e641c282df303 (patch)
tree9c3cacadf5121dba5ee5ab42327ba6a9ab79402a /src/Fl_Menu_add.cxx
parent0434a826d57f5de3ef258532cc090717db574d4e (diff)
Put Fl::grab() into it's own source file. Rewritten as suggested so that
it takes a window pointer, and grab(0) releases. You can now call grab repeatedly with the same or different values without it failing. The old Fl::grab() and Fl::release() are emulated in inline functions in Fl.H Added Fl_Menu_::copy(Fl_Menu_Item*), which will be useful for fluid, although that use is nyi. Fixes and cleanup to the code for Fl_Menu_::add(...). git-svn-id: file:///fltk/svn/fltk/trunk@268 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src/Fl_Menu_add.cxx')
-rw-r--r--src/Fl_Menu_add.cxx120
1 files changed, 62 insertions, 58 deletions
diff --git a/src/Fl_Menu_add.cxx b/src/Fl_Menu_add.cxx
index cb6b91b4d..0b50ec3fd 100644
--- a/src/Fl_Menu_add.cxx
+++ b/src/Fl_Menu_add.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_Menu_add.cxx,v 1.6 1999/01/29 16:56:48 carl Exp $"
+// "$Id: Fl_Menu_add.cxx,v 1.7 1999/02/03 08:43:33 bill Exp $"
//
// Menu utilities for the Fast Light Tool Kit (FLTK).
//
@@ -41,20 +41,44 @@
// always allocate this much initially:
#define INITIAL_MENU_SIZE 15
-// as menu array size passes through each power of two, the memory
-// array allocated is doubled in size:
-static Fl_Menu_Item* incr_array(Fl_Menu_Item* array, int size) {
- if (size < INITIAL_MENU_SIZE) return array;
- if ((size+1) & size) return array; // not a power of 2
- Fl_Menu_Item* newarray = new Fl_Menu_Item[size*2+1];
- for (int i = 0; i <= size; i++) newarray[i] = array[i];
- delete[] array;
- return newarray;
-}
-
// if this local pointer is set, array is reallocated and put here:
static Fl_Menu_Item** alloc;
+// Insert a single Fl_Menu_Item into an array at offset n. If ::alloc
+// is not zero, the array may be reallocated. This is done each time
+// it's size passes through a power of 2. The new (or old) array is
+// returned.
+// Notice that size does not count the trailing null item, so one more
+// item than you think must be copied.
+static Fl_Menu_Item* insert(
+ Fl_Menu_Item* array, int size,
+ int n,
+ const char *text,
+ int flags) {
+ // If new size is a power of two, we reallocate to the next power
+ // of two:
+ if (alloc && size >= INITIAL_MENU_SIZE && !((size+1)&size)) {
+ Fl_Menu_Item* newarray = new Fl_Menu_Item[(size+1)*2];
+ memcpy(newarray, array, (size+1)*sizeof(Fl_Menu_Item));
+ delete[] array;
+ *alloc = array = newarray;
+ }
+ // move all the later items:
+ memmove(array+n+1, array+n, sizeof(Fl_Menu_Item)*(size-n+1));
+ // create the new item:
+ Fl_Menu_Item* m = array+n;
+ m->text = text ? strdup(text) : 0;
+ m->shortcut_ = 0;
+ m->callback_ = 0;
+ m->user_data_ = 0;
+ m->flags = flags;
+ m->labeltype_ = m->labelfont_ = m->labelsize_ = m->labelcolor_ = 0;
+ return array;
+}
+
+// Add an item. The text is split at '/' characters to automatically
+// produce submenus (actually a totally unnecessary feature as you can
+// now add submenu titles directly by setting SUBMENU in the flags):
int Fl_Menu_Item::add(
const char *text,
int shortcut,
@@ -85,27 +109,17 @@ int Fl_Menu_Item::add(
/* find a matching menu title: */
for (; m->text; m = m->next())
- if (m->flags&FL_SUBMENU && !strcmp(item,m->text)) break;
+ if (m->flags&FL_SUBMENU && !strcmp(item, m->text)) break;
if (!m->text) { /* create a new menu */
- if (alloc) {
- int n = m-array;
- array = incr_array(array,size);
- array = incr_array(array,size+1);
- *alloc = array;
- m = array+n;
- }
- memmove(m+2,m,sizeof(Fl_Menu_Item)*(array+size-m));
- m->text = strdup(item);
- m->shortcut_ = 0;
- m->callback_ = 0;
- m->user_data_ = 0;
- m->flags = FL_SUBMENU|flags1;
- m->labeltype_ = m->labelfont_ = m->labelsize_ = m->labelcolor_ = 0;
- (m+1)->text = 0;
- size += 2;
+ int n = m-array;
+ array = insert(array, size, n, item, FL_SUBMENU|flags1);
+ size++;
+ array = insert(array, size, n+1, 0, 0);
+ size++;
+ m = array+n;
}
- m++; /* go into the menu */
+ m++; /* go into the submenu */
flags1 = 0;
}
@@ -114,22 +128,20 @@ int Fl_Menu_Item::add(
if (!strcmp(m->text,item)) break;
if (!m->text) { /* add a new menu item */
- if (alloc) {
- int n = m-array;
- *alloc = array = incr_array(array,size);
- m = array+n;
- }
- memmove(m+1,m,sizeof(Fl_Menu_Item)*(array+size-m));
+ int n = m-array;
+ array = insert(array, size, n, item, flags|flags1);
size++;
- m->text = strdup(item);
+ if (flags & FL_SUBMENU) { // add submenu delimiter
+ array = insert(array, size, n+1, 0, 0);
+ size++;
+ }
+ m = array+n;
}
/* fill it in */
m->shortcut_ = shortcut;
m->callback_ = cb;
m->user_data_ = data;
- m->flags = flags|flags1;
- m->labeltype_ = m->labelfont_ = m->labelsize_ = m->labelcolor_ = 0;
return m-array;
}
@@ -137,8 +149,8 @@ int Fl_Menu_Item::add(
int Fl_Menu_::add(const char *t, int s, Fl_Callback *c,void *v,int f) {
int n = value_ ? value_ - menu_ : 0;
if (!menu_) {
- alloc = 1;
- menu_ = new Fl_Menu_Item[INITIAL_MENU_SIZE];
+ alloc = 2; // indicates that the strings can be freed
+ menu_ = new Fl_Menu_Item[INITIAL_MENU_SIZE+1];
menu_[0].text = 0;
}
if (alloc) ::alloc = &menu_;
@@ -148,6 +160,8 @@ int Fl_Menu_::add(const char *t, int s, Fl_Callback *c,void *v,int f) {
return r;
}
+// This is a Forms (and SGI GL library) compatable add function, it
+// adds strings of the form "name\tshortcut|name\tshortcut|..."
int Fl_Menu_::add(const char *str) {
char buf[128];
int r = 0;
@@ -167,30 +181,20 @@ int Fl_Menu_::add(const char *str) {
void Fl_Menu_::replace(int i, const char *str) {
if (i<0 || i>=size()) return;
- if (alloc) free((void *)menu_[i].text);
- menu_[i].text = strdup(str);
+ if (alloc > 1) {
+ free((void *)menu_[i].text);
+ str = strdup(str);
+ }
+ menu_[i].text = str;
}
void Fl_Menu_::remove(int i) {
int n = size();
if (i<0 || i>=n) return;
- if (alloc) free((void *)menu_[i].text);
+ if (alloc > 1) free((void *)menu_[i].text);
memmove(&menu_[i],&menu_[i+1],(n-i)*sizeof(Fl_Menu_Item));
}
-void Fl_Menu_::clear() {
- for (int i = size(); i--;)
- if (menu_[i].text) free((void*)menu_[i].text);
- if (alloc) {
- delete[] menu_;
- menu_ = 0;
- alloc = 0;
- } else if (menu_) {
- menu_[0].text = 0;
- value_ = menu_;
- }
-}
-
//
-// End of "$Id: Fl_Menu_add.cxx,v 1.6 1999/01/29 16:56:48 carl Exp $".
+// End of "$Id: Fl_Menu_add.cxx,v 1.7 1999/02/03 08:43:33 bill Exp $".
//