summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael R Sweet <michael.r.sweet@gmail.com>1998-12-02 16:15:12 +0000
committerMichael R Sweet <michael.r.sweet@gmail.com>1998-12-02 16:15:12 +0000
commitaadcb29e900bc702dce23108c82b2749153dbe31 (patch)
treee71236b5a7258d391813708dd2faf8b872c7d6e7
parent892664ca26ebe8d03c2acd701124a9f8fcbdab5f (diff)
Menu update from Bill - dynamic allocation of items...
git-svn-id: file:///fltk/svn/fltk/trunk@116 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
-rw-r--r--src/Fl_Menu_add.cxx59
1 files changed, 44 insertions, 15 deletions
diff --git a/src/Fl_Menu_add.cxx b/src/Fl_Menu_add.cxx
index 69f6fd8df..e46bc87a2 100644
--- a/src/Fl_Menu_add.cxx
+++ b/src/Fl_Menu_add.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_Menu_add.cxx,v 1.3 1998/10/21 14:20:13 mike Exp $"
+// "$Id: Fl_Menu_add.cxx,v 1.4 1998/12/02 16:15:12 mike Exp $"
//
// Menu utilities for the Fast Light Tool Kit (FLTK).
//
@@ -47,6 +47,23 @@ int fl_old_shortcut(const char* s) {
return n | *s;
}
+// 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;
+
int Fl_Menu_Item::add(
const char *text,
int shortcut,
@@ -54,17 +71,15 @@ int Fl_Menu_Item::add(
void *data,
int flags)
{
- Fl_Menu_Item *m;
+ Fl_Menu_Item *array = this;
+ Fl_Menu_Item *m = this;
const char *p;
char *q;
char buf[1024];
- int size = this->size();
+ int size = array->size();
int flags1 = 0;
char* item;
-
- m = this;
-
for (;;) { /* do all the supermenus: */
/* fill in the buf with name, changing \x to x: */
@@ -82,7 +97,14 @@ int Fl_Menu_Item::add(
if (m->flags&FL_SUBMENU && !strcmp(item,m->text)) break;
if (!m->text) { /* create a new menu */
- memmove(m+2,m,sizeof(Fl_Menu_Item)*(this+size-m));
+ 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;
@@ -101,7 +123,12 @@ int Fl_Menu_Item::add(
if (!strcmp(m->text,item)) break;
if (!m->text) { /* add a new menu item */
- memmove(m+1,m,sizeof(Fl_Menu_Item)*(this+size-m));
+ 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));
size++;
m->text = strdup(item);
}
@@ -113,19 +140,21 @@ int Fl_Menu_Item::add(
m->flags = flags|flags1;
m->labeltype_ = m->labelfont_ = m->labelsize_ = m->labelcolor_ = 0;
- return m-this;
+ return m-array;
}
-// this is really lame, it will crash if this many items are added:
-#define FL_MENU_MAXITEMS 128
-
int Fl_Menu_::add(const char *t, int s, Fl_Callback *c,void *v,int f) {
+ int n = value_ ? value_ - menu_ : 0;
if (!menu_) {
- value_ = menu_ = new Fl_Menu_Item[FL_MENU_MAXITEMS+1];
alloc = 1;
+ menu_ = new Fl_Menu_Item[INITIAL_MENU_SIZE];
menu_[0].text = 0;
}
- return menu_->add(t,s,c,v,f);
+ if (alloc) ::alloc = &menu_;
+ int r = menu_->add(t,s,c,v,f);
+ ::alloc = 0;
+ if (value_) value_ = menu_+n;
+ return r;
}
int Fl_Menu_::add(const char *str) {
@@ -172,5 +201,5 @@ void Fl_Menu_::clear() {
}
//
-// End of "$Id: Fl_Menu_add.cxx,v 1.3 1998/10/21 14:20:13 mike Exp $".
+// End of "$Id: Fl_Menu_add.cxx,v 1.4 1998/12/02 16:15:12 mike Exp $".
//