diff options
Diffstat (limited to 'fluid/Fl_Type.cxx')
| -rw-r--r-- | fluid/Fl_Type.cxx | 846 |
1 files changed, 240 insertions, 606 deletions
diff --git a/fluid/Fl_Type.cxx b/fluid/Fl_Type.cxx index 04b469b8d..68094850f 100644 --- a/fluid/Fl_Type.cxx +++ b/fluid/Fl_Type.cxx @@ -14,415 +14,201 @@ // https://www.fltk.org/bugs.php // -// Each object described by Fluid is one of these objects. They -// are all stored in a double-linked list. -// -// The "type" of the object is covered by the virtual functions. -// There will probably be a lot of these virtual functions. -// -// The type browser is also a list of these objects, but they -// are "factory" instances, not "real" ones. These objects exist -// only so the "make" method can be called on them. They are -// not in the linked list and are not written to files or -// copied or otherwise examined. - -#include <FL/Fl.H> -#include <FL/Fl_Browser_.H> -#include <FL/fl_draw.H> -#include <stdlib.h> -#include "../src/flstring.h" -#include <stdio.h> +/** \class Fl_Type +Each object described by Fluid is one of these objects. They +are all stored in a double-linked list. + +The "type" of the object is covered by the virtual functions. +There will probably be a lot of these virtual functions. + +The type browser is also a list of these objects, but they +are "factory" instances, not "real" ones. These objects exist +only so the "make" method can be called on them. They are +not in the linked list and are not written to files or +copied or otherwise examined. +*/ #include "Fl_Type.h" -#include "undo.h" +#include "fluid.h" +#include "Fl_Function_Type.h" +#include "Fl_Widget_Type.h" +#include "Fl_Window_Type.h" +#include "widget_browser.h" +#include "file.h" +#include "code.h" +#include "undo.h" #include "pixmaps.h" -extern int show_comments; - -//////////////////////////////////////////////////////////////// - -// Copy the given string str to buffer p with no more than maxl characters. -// Add "..." if string was truncated. -// If parameter quote is true (not 0) the string is quoted with "". -// Quote characters are NOT counted. -// The returned buffer (string) is terminated with a null byte. -// Returns pointer to end of string (before terminating null byte). -// Note: the buffer p must be large enough to hold (4 * (maxl+1) + 1) bytes -// or (4 * (maxl+1) + 3) bytes if quoted, e.g. "123..." because each UTF-8 -// character can consist of 4 bytes, "..." adds 3 bytes, quotes '""' add two -// bytes, and the terminating null byte adds another byte. -// This supports Unicode code points up to U+10FFFF (standard as of 10/2016). -// Sanity checks for illegal UTF-8 sequences are included. - -static char *copy_trunc(char *p, const char *str, int maxl, int quote) { - - int size = 0; // truncated string size in characters - int bs; // size of UTF-8 character in bytes - const char *end = str + strlen(str); // end of input string - if (quote) *p++ = '"'; // opening quote - while (size < maxl) { // maximum <maxl> characters - if (!(*str & (-32))) break; // end of string (0 or control char) - bs = fl_utf8len(*str); // size of next character - if (bs <= 0) break; // some error - leave - if (str + bs > end) break; // UTF-8 sequence beyond end of string - while (bs--) *p++ = *str++; // copy that character into the buffer - size++; // count copied characters - } - if (*str) { // string was truncated - strcpy(p,"..."); p += 3; - } - if (quote) *p++ = '"'; // closing quote - *p = 0; // terminating null byte - return p; -} - -//////////////////////////////////////////////////////////////// +#include <FL/Fl.H> +#include <FL/Fl_Browser_.H> +#include <FL/fl_draw.H> +#include "../src/flstring.h" -class Widget_Browser : public Fl_Browser_ { - friend class Fl_Type; +#include <stdlib.h> +#include <stdio.h> - // required routines for Fl_Browser_ subclass: - void *item_first() const ; - void *item_next(void *) const ; - void *item_prev(void *) const ; - int item_selected(void *) const ; - void item_select(void *,int); - int item_width(void *) const ; - int item_height(void *) const ; - void item_draw(void *,int,int,int,int) const ; - int incr_height() const ; +// ---- global variables -public: +Fl_Type *Fl_Type::first = NULL; +Fl_Type *Fl_Type::last = NULL; - int handle(int); - void callback(); - Widget_Browser(int,int,int,int,const char * =0); -}; +Fl_Type *in_this_only; // set if menu popped-up in window -static Widget_Browser *widget_browser; -Fl_Widget *make_widget_browser(int x,int y,int w,int h) { - return (widget_browser = new Widget_Browser(x,y,w,h)); -} +// ---- various functions -void redraw_widget_browser(Fl_Type *caller) -{ - if (caller) { - widget_browser->display(caller); +void select_all_cb(Fl_Widget *,void *) { + Fl_Type *p = Fl_Type::current ? Fl_Type::current->parent : 0; + if (in_this_only) { + Fl_Type *t = p; + for (; t && t != in_this_only; t = t->parent) {/*empty*/} + if (t != in_this_only) p = in_this_only; } - widget_browser->redraw(); -} - -void select(Fl_Type *o, int v) { - widget_browser->select(o,v,1); - // Fl_Type::current = o; -} - -void select_only(Fl_Type *o) { - widget_browser->select_only(o,1); -} - -void deselect() { - widget_browser->deselect(); - //Fl_Type::current = 0; // this breaks the paste & merge functions -} - -Fl_Type *Fl_Type::first; -Fl_Type *Fl_Type::last; - -static void Widget_Browser_callback(Fl_Widget *o,void *) { - ((Widget_Browser *)o)->callback(); -} - -Widget_Browser::Widget_Browser(int X,int Y,int W,int H,const char*l) -: Fl_Browser_(X,Y,W,H,l) { - type(FL_MULTI_BROWSER); - Fl_Widget::callback(Widget_Browser_callback); - when(FL_WHEN_RELEASE); -} - -void *Widget_Browser::item_first() const {return Fl_Type::first;} - -void *Widget_Browser::item_next(void *l) const {return ((Fl_Type*)l)->next;} - -void *Widget_Browser::item_prev(void *l) const {return ((Fl_Type*)l)->prev;} - -int Widget_Browser::item_selected(void *l) const {return ((Fl_Type*)l)->new_selected;} - -void Widget_Browser::item_select(void *l,int v) {((Fl_Type*)l)->new_selected = v;} - -int Widget_Browser::item_height(void *l) const { - Fl_Type *t = (Fl_Type*)l; - if (t->visible) { - if (show_comments && t->comment()) - return textsize()*2+4; - else - return textsize()+5; + for (;;) { + if (p) { + int foundany = 0; + for (Fl_Type *t = p->next; t && t->level>p->level; t = t->next) { + if (!t->new_selected) {widget_browser->select(t,1,0); foundany = 1;} + } + if (foundany) break; + p = p->parent; + } else { + for (Fl_Type *t = Fl_Type::first; t; t = t->next) + widget_browser->select(t,1,0); + break; + } } - return 0; -} - -int Widget_Browser::incr_height() const {return textsize()+2;} - -static Fl_Type* pushedtitle; - -// Generate a descriptive text for this item, to put in browser & window titles -const char* Fl_Type::title() { - const char* c = name(); if (c) return c; - return type_name(); + selection_changed(p); } -extern const char* subclassname(Fl_Type*); - - -/** - Draw an item in the widget browser. - - A browser line starts with a variable size space. This space directly - relates to the level of the type entry. - - If this type has the ability to store children, a triangle follows, - pointing right (closed) or pointing down (open, children shown). - - Next follows an icon that is specific to the type. This makes it easy to - spot certain types. - - Now follows some text. For classes and widgets, this is the type itself, - followed by the name of the object. Other objects show their content as - text, possibly abbreviated with an ellipsis. - - \param v v is a pointer to the actual widget type and can be cast safely - to Fl_Type - \param X,Y these give the position in window coordinates of the top left - corner of this line -*/ -void Widget_Browser::item_draw(void *v, int X, int Y, int, int) const { - // cast to a more general type - Fl_Type *l = (Fl_Type *)v; - - char buf[340]; // edit buffer: large enough to hold 80 UTF-8 chars + nul - - // calculate the horizontal start position of this item - // 3 is the edge of the browser - // 13 is the width of the arrow that indicates children for the item - // 18 is the width of the icon - // 12 is the indent per level - X += 3 + 13 + 18 + l->level * 12; - - // calculate the horizontal start position and width of the separator line - int x1 = X; - int w1 = w() - x1; - - // items can contain a comment. If they do, the comment gets a second text - // line inside this browser line - int comment_incr = 0; - if (show_comments && l->comment()) { - copy_trunc(buf, l->comment(), 80, 0); - comment_incr = textsize()-1; - if (l->new_selected) fl_color(fl_contrast(FL_DARK_GREEN,FL_SELECTION_COLOR)); - else fl_color(fl_contrast(FL_DARK_GREEN,color())); - fl_font(textfont()+FL_ITALIC, textsize()-2); - fl_draw(buf, X, Y+12); - Y += comment_incr/2; - comment_incr -= comment_incr/2; +void select_none_cb(Fl_Widget *,void *) { + Fl_Type *p = Fl_Type::current ? Fl_Type::current->parent : 0; + if (in_this_only) { + Fl_Type *t = p; + for (; t && t != in_this_only; t = t->parent) {/*empty*/} + if (t != in_this_only) p = in_this_only; } - - if (l->new_selected) fl_color(fl_contrast(FL_FOREGROUND_COLOR,FL_SELECTION_COLOR)); - else fl_color(FL_FOREGROUND_COLOR); - - // Width=10: Draw the triangle that indicates possible children - if (l->is_parent()) { - X = X - 18 - 13; - if (!l->next || l->next->level <= l->level) { - if (l->open_!=(l==pushedtitle)) { - // an outlined triangle to the right indicates closed item, no children - fl_loop(X,Y+7,X+5,Y+12,X+10,Y+7); - } else { - // an outlined triangle to the bottom indicates open item, no children - fl_loop(X+2,Y+2,X+7,Y+7,X+2,Y+12); + for (;;) { + if (p) { + int foundany = 0; + for (Fl_Type *t = p->next; t && t->level>p->level; t = t->next) { + if (t->new_selected) {widget_browser->select(t,0,0); foundany = 1;} } + if (foundany) break; + p = p->parent; } else { - if (l->open_!=(l==pushedtitle)) { - // a filled triangle to the right indicates closed item, with children - fl_polygon(X,Y+7,X+5,Y+12,X+10,Y+7); - } else { - // a filled triangle to the bottom indicates open item, with children - fl_polygon(X+2,Y+2,X+7,Y+7,X+2,Y+12); - } + for (Fl_Type *t = Fl_Type::first; t; t = t->next) + widget_browser->select(t,0,0); + break; } - X = X + 13 + 18; - } - - // Width=18: Draw the icon associated with the type. - Fl_Pixmap *pm = pixmap[l->pixmapID()]; - if (pm) pm->draw(X-18, Y); - - // Add tags on top of the icon for locked and protected types. - switch (l->is_public()) { - case 0: lock_pixmap->draw(X - 17, Y); break; - case 2: protected_pixmap->draw(X - 17, Y); break; } + selection_changed(p); +} - if ( l->is_widget() - && !l->is_window() - && ((Fl_Widget_Type*)l)->o - && !((Fl_Widget_Type*)l)->o->visible() - && (!l->parent || ( strcmp(l->parent->type_name(),"Fl_Tabs") - && strcmp(l->parent->type_name(),"Fl_Wizard")) ) - ) - { - invisible_pixmap->draw(X - 17, Y); +// move selected widgets in their parent's list: +void earlier_cb(Fl_Widget*,void*) { + Fl_Type *f; + int mod = 0; + for (f = Fl_Type::first; f; ) { + Fl_Type* nxt = f->next; + if (f->selected) { + Fl_Type* g; + for (g = f->prev; g && g->level > f->level; g = g->prev) {/*empty*/} + if (g && g->level == f->level && !g->selected) { + f->move_before(g); + mod = 1; + } + } + f = nxt; } + if (mod) set_modflag(1); +} - // Indent=12 per level: Now write the text that comes after the graphics representation - Y += comment_incr; - if (l->is_widget() || l->is_class()) { - const char* c = subclassname(l); - if (!strncmp(c,"Fl_",3)) c += 3; - fl_font(textfont(), textsize()); - fl_draw(c, X, Y+13); - X += int(fl_width(c)+fl_width('n')); - c = l->name(); - if (c) { - fl_font(textfont()|FL_BOLD, textsize()); - fl_draw(c, X, Y+13); - } else if ((c = l->label())) { - copy_trunc(buf, c, 20, 1); // quoted string - fl_draw(buf, X, Y+13); +void later_cb(Fl_Widget*,void*) { + Fl_Type *f; + int mod = 0; + for (f = Fl_Type::last; f; ) { + Fl_Type* prv = f->prev; + if (f->selected) { + Fl_Type* g; + for (g = f->next; g && g->level > f->level; g = g->next) {/*empty*/} + if (g && g->level == f->level && !g->selected) { + g->move_before(f); + mod = 1; + } } - } else { - copy_trunc(buf, l->title(), 55, 0); - fl_font(textfont() | (l->is_code_block() && (l->level==0 || l->parent->is_class())?0:FL_BOLD), textsize()); - fl_draw(buf, X, Y+13); + f = prv; } + if (mod) set_modflag(1); +} - // draw a thin line below the item if this item is not selected - // (if it is selected this additional line would look bad) - if (!l->new_selected) { - fl_color(fl_lighter(FL_GRAY)); - fl_line(x1,Y+16,x1+w1,Y+16); +static void delete_children(Fl_Type *p) { + Fl_Type *f; + for (f = p; f && f->next && f->next->level > p->level; f = f->next) {/*empty*/} + for (; f != p; ) { + Fl_Type *g = f->prev; + delete f; + f = g; } } -int Widget_Browser::item_width(void *v) const { - - char buf[340]; // edit buffer: large enough to hold 80 UTF-8 chars + nul - - Fl_Type *l = (Fl_Type *)v; - - if (!l->visible) return 0; - - int W = 3 + 13 + 18 + l->level * 12; - - if (l->is_widget() || l->is_class()) { - const char* c = l->type_name(); - if (!strncmp(c,"Fl_",3)) c += 3; - fl_font(textfont(), textsize()); - W += int(fl_width(c) + fl_width('n')); - c = l->name(); - if (c) { - fl_font(textfont()|FL_BOLD, textsize()); - W += int(fl_width(c)); - } else if (l->label()) { - copy_trunc(buf, l->label(), 20, 1); // quoted string - W += int(fl_width(buf)); - } - } else { - copy_trunc(buf, l->title(), 55, 0); - fl_font(textfont() | (l->is_code_block() && (l->level==0 || l->parent->is_class())?0:FL_BOLD), textsize()); - W += int(fl_width(buf)); +// object list operations: +void delete_all(int selected_only) { + for (Fl_Type *f = Fl_Type::first; f;) { + if (f->selected || !selected_only) { + delete_children(f); + Fl_Type *g = f->next; + delete f; + f = g; + } else f = f->next; + } + if(!selected_only) { + include_H_from_C=1; + use_FL_COMMAND=0; } - return W; -} - -void redraw_browser() { - widget_browser->redraw(); + selection_changed(0); } -void Widget_Browser::callback() { - selection_changed((Fl_Type*)selection()); +// update a string member: +// replace a string pointer with new value, strips leading/trailing blanks: +int storestring(const char *n, const char * & p, int nostrip) { + if (n == p) return 0; + undo_checkpoint(); + int length = 0; + if (n) { // see if blank, strip leading & trailing blanks + if (!nostrip) while (isspace((int)(unsigned char)*n)) n++; + const char *e = n + strlen(n); + if (!nostrip) while (e > n && isspace((int)(unsigned char)*(e-1))) e--; + length = int(e-n); + if (!length) n = 0; + } + if (n == p) return 0; + if (n && p && !strncmp(n,p,length) && !p[length]) return 0; + if (p) free((void *)p); + if (!n || !*n) { + p = 0; + } else { + char *q = (char *)malloc(length+1); + strlcpy(q,n,length+1); + p = q; + } + set_modflag(1); + return 1; } - -/** - Override the event handling for this browser. - - The vertical mouse position corresponds to an entry in the type tree. - The horizontal position has the following hot zones: - - 0-3 is the widget frame and ignored - - the next hot zone starts 12*indent pixels further to the right - - the next 13 pixels refer to the arrow that indicates children for the item - - 18 pixels follow for the icon - - the remaining part is filled with text - - \param[in] e the incoming event type - \return 0 if the event is not supported, and 1 if the event was "used up" -*/ -int Widget_Browser::handle(int e) { - static Fl_Type *title; - Fl_Type *l; - int X,Y,W,H; bbox(X,Y,W,H); - switch (e) { - case FL_PUSH: - if (!Fl::event_inside(X,Y,W,H)) break; - l = (Fl_Type*)find_item(Fl::event_y()); - if (l) { - X += 3 + 12*l->level - hposition(); - if (l->is_parent() && Fl::event_x()>X && Fl::event_x()<X+13) { - title = pushedtitle = l; - redraw_line(l); - return 1; - } - } - break; - case FL_DRAG: - if (!title) break; - l = (Fl_Type*)find_item(Fl::event_y()); - if (l) { - X += 3 + 12*l->level - hposition(); - if (l->is_parent() && Fl::event_x()>X && Fl::event_x()<X+13) ; - else l = 0; - } - if (l != pushedtitle) { - if (pushedtitle) redraw_line(pushedtitle); - if (l) redraw_line(l); - pushedtitle = l; - } - return 1; - case FL_RELEASE: - if (!title) { - l = (Fl_Type*)find_item(Fl::event_y()); - if (l && l->new_selected && (Fl::event_clicks() || Fl::event_state(FL_CTRL))) - l->open(); - break; - } - l = pushedtitle; - title = pushedtitle = 0; - if (l) { - if (l->open_) { - l->open_ = 0; - for (Fl_Type*k = l->next; k&&k->level>l->level; k = k->next) - k->visible = 0; - } else { - l->open_ = 1; - for (Fl_Type*k=l->next; k&&k->level>l->level;) { - k->visible = 1; - if (k->is_parent() && !k->open_) { - Fl_Type *j; - for (j = k->next; j && j->level>k->level; j = j->next) {/*empty*/} - k = j; - } else - k = k->next; - } - } - redraw(); - } - return 1; +void fixvisible(Fl_Type *p) { + Fl_Type *t = p; + for (;;) { + if (t->parent) t->visible = t->parent->visible && t->parent->open_; + else t->visible = 1; + t = t->next; + if (!t || t->level <= p->level) break; } - return Fl_Browser_::handle(e); } +// ---- implemenation of Fl_Type + Fl_Type::Fl_Type() { factory = 0; parent = 0; @@ -441,21 +227,28 @@ Fl_Type::Fl_Type() { code_position_end = header_position_end = -1; } -static void fixvisible(Fl_Type *p) { - Fl_Type *t = p; - for (;;) { - if (t->parent) t->visible = t->parent->visible && t->parent->open_; - else t->visible = 1; - t = t->next; - if (!t || t->level <= p->level) break; - } +Fl_Type::~Fl_Type() { + // warning: destructor only works for widgets that have been add()ed. + if (widget_browser) widget_browser->deleting(this); + if (prev) prev->next = next; else first = next; + if (next) next->prev = prev; else last = prev; + if (current == this) current = 0; + if (parent) parent->remove_child(this); + if (name_) free((void*)name_); + if (label_) free((void*)label_); + if (callback_) free((void*)callback_); + if (user_data_) free((void*)user_data_); + if (user_data_type_) free((void*)user_data_type_); + if (comment_) free((void*)comment_); } -// turn a click at x,y on this into the actual picked object: -Fl_Type* Fl_Type::click_test(int,int) {return 0;} -void Fl_Type::add_child(Fl_Type*, Fl_Type*) {} -void Fl_Type::move_child(Fl_Type*, Fl_Type*) {} -void Fl_Type::remove_child(Fl_Type*) {} +// Generate a descriptive text for this item, to put in browser & window titles +const char* Fl_Type::title() { + const char* c = name(); + if (c) + return c; + return type_name(); +} // add a list of widgets as a new child of p: void Fl_Type::add(Fl_Type *p) { @@ -516,8 +309,7 @@ void Fl_Type::insert(Fl_Type *g) { } // Return message number for I18N... -int -Fl_Type::msgnum() { +int Fl_Type::msgnum() { int count; Fl_Type *p; @@ -532,53 +324,34 @@ Fl_Type::msgnum() { return count; } - -// delete from parent: +/** + Remove this node and all its children from the parent node. + \return the node that follows this node after the operation; can be NULL + */ Fl_Type *Fl_Type::remove() { + // -- find the last child of this node Fl_Type *end = this; for (;;) { if (!end->next || end->next->level <= level) break; end = end->next; } + // -- unlink this node from the previous one if (prev) prev->next = end->next; else first = end->next; + // -- unlink the last child from their next node if (end->next) end->next->prev = prev; else last = prev; Fl_Type *r = end->next; prev = end->next = 0; + // -- allow the parent to update changes in the UI if (parent) parent->remove_child(this); parent = 0; + widget_browser->redraw_lines(); widget_browser->redraw(); selection_changed(0); return r; } -// update a string member: -int storestring(const char *n, const char * & p, int nostrip) { - if (n == p) return 0; - undo_checkpoint(); - int length = 0; - if (n) { // see if blank, strip leading & trailing blanks - if (!nostrip) while (isspace((int)(unsigned char)*n)) n++; - const char *e = n + strlen(n); - if (!nostrip) while (e > n && isspace((int)(unsigned char)*(e-1))) e--; - length = int(e-n); - if (!length) n = 0; - } - if (n == p) return 0; - if (n && p && !strncmp(n,p,length) && !p[length]) return 0; - if (p) free((void *)p); - if (!n || !*n) { - p = 0; - } else { - char *q = (char *)malloc(length+1); - strlcpy(q,n,length+1); - p = q; - } - set_modflag(1); - return 1; -} - void Fl_Type::name(const char *n) { int nostrip = is_comment(); if (storestring(n,name_,nostrip)) { @@ -615,125 +388,6 @@ void Fl_Type::open() { printf("Open of '%s' is not yet implemented\n",type_name()); } -void Fl_Type::setlabel(const char *) {} - -Fl_Type::~Fl_Type() { - // warning: destructor only works for widgets that have been add()ed. - if (widget_browser) widget_browser->deleting(this); - if (prev) prev->next = next; else first = next; - if (next) next->prev = prev; else last = prev; - if (current == this) current = 0; - if (parent) parent->remove_child(this); - if (name_) free((void*)name_); - if (label_) free((void*)label_); - if (callback_) free((void*)callback_); - if (user_data_) free((void*)user_data_); - if (user_data_type_) free((void*)user_data_type_); - if (comment_) free((void*)comment_); -} - -int Fl_Type::is_parent() const {return 0;} -int Fl_Type::is_widget() const {return 0;} -int Fl_Type::is_valuator() const {return 0;} -int Fl_Type::is_spinner() const {return 0;} -int Fl_Type::is_button() const {return 0;} -int Fl_Type::is_input() const {return 0;} -int Fl_Type::is_value_input() const {return 0;} -int Fl_Type::is_text_display() const {return 0;} -int Fl_Type::is_menu_item() const {return 0;} -int Fl_Type::is_menu_button() const {return 0;} -int Fl_Type::is_group() const {return 0;} -int Fl_Type::is_window() const {return 0;} -int Fl_Type::is_code() const {return 0;} -int Fl_Type::is_code_block() const {return 0;} -int Fl_Type::is_decl_block() const {return 0;} -int Fl_Type::is_comment() const {return 0;} -int Fl_Type::is_class() const {return 0;} -int Fl_Type::is_public() const {return 1;} - -int Fl_Code_Type::is_public()const { return -1; } -int Fl_CodeBlock_Type::is_public()const { return -1; } - - -//////////////////////////////////////////////////////////////// - -Fl_Type *in_this_only; // set if menu popped-up in window - -void select_all_cb(Fl_Widget *,void *) { - Fl_Type *p = Fl_Type::current ? Fl_Type::current->parent : 0; - if (in_this_only) { - Fl_Type *t = p; - for (; t && t != in_this_only; t = t->parent) {/*empty*/} - if (t != in_this_only) p = in_this_only; - } - for (;;) { - if (p) { - int foundany = 0; - for (Fl_Type *t = p->next; t && t->level>p->level; t = t->next) { - if (!t->new_selected) {widget_browser->select(t,1,0); foundany = 1;} - } - if (foundany) break; - p = p->parent; - } else { - for (Fl_Type *t = Fl_Type::first; t; t = t->next) - widget_browser->select(t,1,0); - break; - } - } - selection_changed(p); -} - -void select_none_cb(Fl_Widget *,void *) { - Fl_Type *p = Fl_Type::current ? Fl_Type::current->parent : 0; - if (in_this_only) { - Fl_Type *t = p; - for (; t && t != in_this_only; t = t->parent) {/*empty*/} - if (t != in_this_only) p = in_this_only; - } - for (;;) { - if (p) { - int foundany = 0; - for (Fl_Type *t = p->next; t && t->level>p->level; t = t->next) { - if (t->new_selected) {widget_browser->select(t,0,0); foundany = 1;} - } - if (foundany) break; - p = p->parent; - } else { - for (Fl_Type *t = Fl_Type::first; t; t = t->next) - widget_browser->select(t,0,0); - break; - } - } - selection_changed(p); -} - -static void delete_children(Fl_Type *p) { - Fl_Type *f; - for (f = p; f && f->next && f->next->level > p->level; f = f->next) {/*empty*/} - for (; f != p; ) { - Fl_Type *g = f->prev; - delete f; - f = g; - } -} - -void delete_all(int selected_only) { - for (Fl_Type *f = Fl_Type::first; f;) { - if (f->selected || !selected_only) { - delete_children(f); - Fl_Type *g = f->next; - delete f; - f = g; - } else f = f->next; - } - if(!selected_only) { - include_H_from_C=1; - use_FL_COMMAND=0; - } - - selection_changed(0); -} - // move f (and its children) into list before g: // returns pointer to whatever is after f & children void Fl_Type::move_before(Fl_Type* g) { @@ -756,45 +410,6 @@ void Fl_Type::move_before(Fl_Type* g) { } -// move selected widgets in their parent's list: -void earlier_cb(Fl_Widget*,void*) { - Fl_Type *f; - int mod = 0; - for (f = Fl_Type::first; f; ) { - Fl_Type* nxt = f->next; - if (f->selected) { - Fl_Type* g; - for (g = f->prev; g && g->level > f->level; g = g->prev) {/*empty*/} - if (g && g->level == f->level && !g->selected) { - f->move_before(g); - mod = 1; - } - } - f = nxt; - } - if (mod) set_modflag(1); -} - -void later_cb(Fl_Widget*,void*) { - Fl_Type *f; - int mod = 0; - for (f = Fl_Type::last; f; ) { - Fl_Type* prv = f->prev; - if (f->selected) { - Fl_Type* g; - for (g = f->next; g && g->level > f->level; g = g->next) {/*empty*/} - if (g && g->level == f->level && !g->selected) { - g->move_before(f); - mod = 1; - } - } - f = prv; - } - if (mod) set_modflag(1); -} - -//////////////////////////////////////////////////////////////// - // write a widget and all its children: void Fl_Type::write() { write_indent(level); @@ -871,21 +486,6 @@ void Fl_Type::read_property(const char *c) { int Fl_Type::read_fdesign(const char*, const char*) {return 0;} /** - Return 1 if the list contains a function with the given signature at the top level. - */ -int has_toplevel_function(const char *rtype, const char *sig) { - Fl_Type *child; - for (child = Fl_Type::first; child; child = child->next) { - if (!child->is_in_class() && strcmp(child->type_name(), "Function")==0) { - const Fl_Function_Type *fn = (const Fl_Function_Type*)child; - if (fn->has_signature(rtype, sig)) - return 1; - } - } - return 0; -} - -/** Write a comment into the header file. */ void Fl_Type::write_comment_h(const char *pre) @@ -963,25 +563,6 @@ void Fl_Type::write_comment_inline_c(const char *pre) } /** - Make sure that the given item is visible in the browser by opening - all parent groups and moving the item into the visible space. -*/ -void reveal_in_browser(Fl_Type *t) { - Fl_Type *p = t->parent; - if (p) { - for (;;) { - if (!p->open_) - p->open_ = 1; - if (!p->parent) break; - p = p->parent; - } - fixvisible(p); - } - widget_browser->display(t); - redraw_browser(); -} - -/** Build widgets and dataset needed in live mode. \return a widget pointer that the live mode initiator can 'show()' \see leave_live_mode() @@ -1019,3 +600,56 @@ int Fl_Type::user_defined(const char* cbname) const { return 1; return 0; } + +const char *Fl_Type::callback_name() { + if (is_name(callback())) return callback(); + return unique_id(this, "cb", name(), label()); +} + +const char* Fl_Type::class_name(const int need_nest) const { + Fl_Type* p = parent; + while (p) { + if (p->is_class()) { + // see if we are nested in another class, we must fully-qualify name: + // this is lame but works... + const char* q = 0; + if(need_nest) q=p->class_name(need_nest); + if (q) { + static char s[256]; + if (q != s) strlcpy(s, q, sizeof(s)); + strlcat(s, "::", sizeof(s)); + strlcat(s, p->name(), sizeof(s)); + return s; + } + return p->name(); + } + p = p->parent; + } + return 0; +} + +/** + If this Type resides inside a class, this function returns the class type, or null. + */ +const Fl_Class_Type *Fl_Type::is_in_class() const { + Fl_Type* p = parent; + while (p) { + if (p->is_class()) { + return (Fl_Class_Type*)p; + } + p = p->parent; + } + return 0; +} + +void Fl_Type::write_static() { +} + +void Fl_Type::write_code1() { + write_h("// Header for %s\n", title()); + write_c("// Code for %s\n", title()); +} + +void Fl_Type::write_code2() { +} + |
