summaryrefslogtreecommitdiff
path: root/fluid
diff options
context:
space:
mode:
Diffstat (limited to 'fluid')
-rw-r--r--fluid/Fd_Snap_Action.cxx4
-rw-r--r--fluid/Fl_Function_Type.cxx2
-rw-r--r--fluid/Fl_Function_Type.h4
-rw-r--r--fluid/Fl_Group_Type.cxx2
-rw-r--r--fluid/Fl_Group_Type.h1
-rw-r--r--fluid/Fl_Type.cxx13
-rw-r--r--fluid/Fl_Type.h55
-rw-r--r--fluid/Fl_Widget_Type.cxx11
-rw-r--r--fluid/Fl_Window_Type.cxx8
-rw-r--r--fluid/Fl_Window_Type.h1
-rw-r--r--fluid/factory.cxx4
-rw-r--r--fluid/fluid.cxx4
12 files changed, 68 insertions, 41 deletions
diff --git a/fluid/Fd_Snap_Action.cxx b/fluid/Fd_Snap_Action.cxx
index 3602256f8..e0597a8f9 100644
--- a/fluid/Fd_Snap_Action.cxx
+++ b/fluid/Fd_Snap_Action.cxx
@@ -935,7 +935,7 @@ static bool in_window(Fd_Snap_Data &d) {
}
static bool in_group(Fd_Snap_Data &d) {
- return (d.wgt && d.wgt->parent && d.wgt->parent->is_group() && d.wgt->parent != d.win);
+ return (d.wgt && d.wgt->parent && d.wgt->parent->is_a(Fl_Type::ID_Group) && d.wgt->parent != d.win);
}
static bool in_tabs(Fd_Snap_Data &d) {
@@ -1448,7 +1448,7 @@ public:
clr();
best_match = NULL;
if (!d.wgt) return;
- if (!d.wgt->parent->is_group()) return;
+ if (!d.wgt->parent->is_a(Fl_Type::ID_Group)) return;
int dsib_min = 1024;
Fl_Group_Type *gt = (Fl_Group_Type*)d.wgt->parent;
Fl_Group *g = (Fl_Group*)gt->o;
diff --git a/fluid/Fl_Function_Type.cxx b/fluid/Fl_Function_Type.cxx
index b6790a524..f88a6f9b1 100644
--- a/fluid/Fl_Function_Type.cxx
+++ b/fluid/Fl_Function_Type.cxx
@@ -1979,7 +1979,7 @@ void Fl_Class_Type::write_code2(Fd_Code_Writer& f) {
/**
Return 1 if this class contains a function with the given signature.
*/
-int Fl_Class_Type::has_function(const char *rtype, const char *sig) const {
+int Fl_Type::has_function(const char *rtype, const char *sig) const {
Fl_Type *child;
for (child = next; child && child->level > level; child = child->next) {
if (child->level == level+1 && child->is_a(Fl_Type::ID_Function)) {
diff --git a/fluid/Fl_Function_Type.h b/fluid/Fl_Function_Type.h
index 1af161374..478606b43 100644
--- a/fluid/Fl_Function_Type.h
+++ b/fluid/Fl_Function_Type.h
@@ -34,7 +34,7 @@
#include <stdarg.h>
#include <stdlib.h>
-extern Fl_Class_Type *current_class;
+extern class Fl_Class_Type *current_class;
int has_toplevel_function(const char *rtype, const char *sig);
@@ -89,7 +89,6 @@ public:
void open() FL_OVERRIDE;
const char *type_name() FL_OVERRIDE {return "code";}
int is_code_block() const FL_OVERRIDE {return 0;}
- int is_code() const FL_OVERRIDE {return 1;}
ID id() const FL_OVERRIDE { return ID_Code; }
bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Code) ? true : super::is_a(inID); }
int is_public() const FL_OVERRIDE { return -1; }
@@ -249,7 +248,6 @@ public:
// class prefix attribute access
void prefix(const char* p);
const char* prefix() const {return class_prefix;}
- int has_function(const char*, const char*) const;
};
#endif // _FLUID_FL_FUNCTION_TYPE_H
diff --git a/fluid/Fl_Group_Type.cxx b/fluid/Fl_Group_Type.cxx
index c0e7526e3..1b63aa033 100644
--- a/fluid/Fl_Group_Type.cxx
+++ b/fluid/Fl_Group_Type.cxx
@@ -61,7 +61,7 @@ Fl_Type *Fl_Group_Type::make(Strategy strategy) {
\brief Enlarge the group size, so all children fit within.
*/
void fix_group_size(Fl_Type *tt) {
- if (!tt || !tt->is_group()) return;
+ if (!tt || !tt->is_a(Fl_Type::ID_Group)) return;
Fl_Group_Type* t = (Fl_Group_Type*)tt;
int X = t->o->x();
int Y = t->o->y();
diff --git a/fluid/Fl_Group_Type.h b/fluid/Fl_Group_Type.h
index 6f104fb80..67791f981 100644
--- a/fluid/Fl_Group_Type.h
+++ b/fluid/Fl_Group_Type.h
@@ -53,7 +53,6 @@ public:
void move_child(Fl_Type*, Fl_Type*) FL_OVERRIDE;
void remove_child(Fl_Type*) FL_OVERRIDE;
int is_parent() const FL_OVERRIDE {return 1;}
- int is_group() const FL_OVERRIDE {return 1;}
ID id() const FL_OVERRIDE { return ID_Group; }
bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Group) ? true : super::is_a(inID); }
Fl_Widget *enter_live_mode(int top=0) FL_OVERRIDE;
diff --git a/fluid/Fl_Type.cxx b/fluid/Fl_Type.cxx
index 379c4cb90..4732b00e0 100644
--- a/fluid/Fl_Type.cxx
+++ b/fluid/Fl_Type.cxx
@@ -427,7 +427,7 @@ Fl_Group_Type *Fl_Type::group() {
if (!is_widget())
return NULL;
for (Fl_Type *t = this; t; t=t->parent)
- if (t->is_group())
+ if (t->is_a(Fl_Type::ID_Group))
return (Fl_Group_Type*)t;
return NULL;
}
@@ -882,17 +882,16 @@ const char* Fl_Type::class_name(const int need_nest) const {
}
/**
- If this Type resides inside a class, this function returns the class type, or null.
+ Check if this is inside a Fl_Class_Type or Fl_Widget_Class_Type.
+ \return true if any of the parents is Fl_Class_Type or Fl_Widget_Class_Type
*/
-const Fl_Class_Type *Fl_Type::is_in_class() const {
+bool Fl_Type::is_in_class() const {
Fl_Type* p = parent;
while (p) {
- if (p->is_class()) {
- return (Fl_Class_Type*)p;
- }
+ if (p->is_class()) return true;
p = p->parent;
}
- return 0;
+ return false;
}
void Fl_Type::write_static(Fd_Code_Writer&) {
diff --git a/fluid/Fl_Type.h b/fluid/Fl_Type.h
index ad8edff01..ec30e5735 100644
--- a/fluid/Fl_Type.h
+++ b/fluid/Fl_Type.h
@@ -43,27 +43,55 @@ void select_none_cb(Fl_Widget *,void *);
void earlier_cb(Fl_Widget*,void*);
void later_cb(Fl_Widget*,void*);
-class Fl_Type {
+/**
+ \brief This is the base class for all elements in the project tree.
+
+ All widgets and other types in the project are derived from Fl_Types. They
+ are organized in a doubly linked list. Every Type also has depth information
+ to create a pseudo tree structure. To make walking up the tree faster, Type
+ also holds a pointer to the `parent` Type.
+
+ Types can be identified using the builtin ID system that works like RTTI. The
+ method `id()` returns the exact type, and the method `is_a(ID)` returns true
+ if this is the exact type or derived from the type, and a dynamic cast will
+ work reliably.
+
+ \todo it would be nice if we can handle multiple independent trees. To do that
+ we must remove static members like `first` and `last`.
- friend class Widget_Browser;
- friend Fl_Widget *make_type_browser(int,int,int,int,const char *);
- friend class Fl_Window_Type;
+ \todo add virtual methods to handle events, draw widgets, and draw overlays.
+ It may also make sense to have a virtual method that returns a boolean if
+ a specific type can be added as a child.
+ \todo it may make sense to have a readable iterator class instead of relying
+ on pointer manipulation. Or use std in future releases.
+ */
+class Fl_Type {
+ /** Copy the label text to Widgets and Windows, does nothing in Type. */
virtual void setlabel(const char *) { } // virtual part of label(char*)
protected:
Fl_Type();
+ /** Name of a widget, or code some non-widget Types. */
const char *name_;
+ /** Label text of a widget. */
const char *label_;
+ /** If it is just a word, it's the name of the callback function. Otherwise
+ it is the full callback C++ code. Can be NULL. */
const char *callback_;
+ /** Widget user data field as C++ text. */
const char *user_data_;
+ /** Widget user data type as C++ text, usually `void*` or `long`. */
const char *user_data_type_;
+ /** Optional comment for every node in the graph. Visible in browser and
+ panels, and will also be copied to the source code. */
const char *comment_;
public: // things that should not be public:
+ /** Quick link to the parent Type instead of walking up the linked list. */
Fl_Type *parent;
char new_selected; // browser highlight
char selected; // copied here by selection_changed()
@@ -149,6 +177,7 @@ public:
void comment(const char *);
virtual Fl_Type* click_test(int,int) { return NULL; }
+
virtual void add_child(Fl_Type*, Fl_Type* beforethis) { }
virtual void move_child(Fl_Type*, Fl_Type* beforethis) { }
virtual void remove_child(Fl_Type*) { }
@@ -181,27 +210,31 @@ public:
// get message number for I18N
int msgnum();
- // fake rtti:
- /** Return 1 if the Type chn have children. */
+ /** Return 1 if the Type can have children. */
virtual int is_parent() const {return 0;}
/** Return 1 if the type is a widget or menu item. */
virtual int is_widget() const {return 0;}
/** Return 1 if the type is a widget but not a menu item. */
virtual int is_true_widget() const {return 0;}
- /** Return 1 if a type behaves like a button (Fl_Button and Fl_Menu_Item and derived. */
+ /** Return 1 if a type behaves like a button (Fl_Button and Fl_Menu_Item and derived, but not Fl_Submenu_Type. */
virtual int is_button() const {return 0;}
- virtual int is_group() const {return 0;}
- virtual int is_code() const {return 0;}
+ /** Return 1 if this is a Fl_Widget_Class_Type, Fl_CodeBlock_Type, or Fl_Function_Type */
virtual int is_code_block() const {return 0;}
+ /** Return 1 if this is a Fl_Widget_Class_Type, Fl_Class_Type, or Fl_DeclBlock_Type */
virtual int is_decl_block() const {return 0;}
+ /** Return 1 if this is a Fl_Class_Type or Fl_Widget_Class_Type. */
virtual int is_class() const {return 0;}
+ /** Return 1 if the type browser shall draw a padlock over the icon. */
virtual int is_public() const {return 1;}
-
+ /** Return the type ID for this Type. */
virtual ID id() const { return ID_Base_; }
+ /** Check if this Type is of the give type ID or derived from that type ID. */
virtual bool is_a(ID inID) const { return (inID==ID_Base_); }
const char* class_name(const int need_nest) const;
- const class Fl_Class_Type* is_in_class() const;
+ bool is_in_class() const;
+
+ int has_function(const char*, const char*) const;
};
#endif // _FLUID_FL_TYPE_H
diff --git a/fluid/Fl_Widget_Type.cxx b/fluid/Fl_Widget_Type.cxx
index 40de78306..868cd735b 100644
--- a/fluid/Fl_Widget_Type.cxx
+++ b/fluid/Fl_Widget_Type.cxx
@@ -91,7 +91,7 @@ Fl_Type *Fl_Widget_Type::make(Strategy strategy) {
Fl_Widget_Type* q = (Fl_Widget_Type*)qq;
// find the parent widget:
Fl_Widget_Type* p = q;
- if ((force_parent || !p->is_group()) && p->parent && p->parent->is_widget())
+ if ((force_parent || !p->is_a(Fl_Type::ID_Group)) && p->parent && p->parent->is_widget())
p = (Fl_Widget_Type*)(p->parent);
force_parent = 0;
@@ -107,7 +107,7 @@ Fl_Type *Fl_Widget_Type::make(Strategy strategy) {
// Figure out a position and size for the widget
int X,Y,W,H;
- if (is_group()) { // fill the parent with the widget
+ if (is_a(Fl_Type::ID_Group)) { // fill the parent with the widget
X = ULX+B;
W = p->o->w()-B;
Y = ULY+B;
@@ -2786,10 +2786,9 @@ void Fl_Widget_Type::write_static(Fd_Code_Writer& f) {
}
if (callback() && is_name(callback())) {
int write_extern_declaration = 1;
- const Fl_Class_Type *cc = is_in_class();
char buf[1024]; snprintf(buf, 1023, "%s(*)", callback());
- if (cc) {
- if (cc->has_function("static void", buf))
+ if (is_in_class()) {
+ if (has_function("static void", buf))
write_extern_declaration = 0;
} else {
if (has_toplevel_function(0L, buf))
@@ -3165,7 +3164,7 @@ void Fl_Widget_Type::write_widget_code(Fd_Code_Writer& f) {
f.write_c("%s%s->hide();\n", f.indent(), var);
if (!o->active())
f.write_c("%s%s->deactivate();\n", f.indent(), var);
- if (!is_group() && resizable())
+ if (!is_a(Fl_Type::ID_Group) && resizable())
f.write_c("%sFl_Group::current()->resizable(%s);\n", f.indent(), var);
if (hotspot()) {
if (is_class())
diff --git a/fluid/Fl_Window_Type.cxx b/fluid/Fl_Window_Type.cxx
index aae3a43d3..65d3a3114 100644
--- a/fluid/Fl_Window_Type.cxx
+++ b/fluid/Fl_Window_Type.cxx
@@ -530,7 +530,7 @@ void Fl_Window_Type::draw_out_of_bounds() {
draw_out_of_bounds(this, 0, 0, o->w(), o->h());
for (Fl_Type *q=next; q && q->level>level; q = q->next) {
// don't do this for Fl_Scroll (which we currently can't handle in FLUID anyway)
- if (q->is_group() && !q->is_a(ID_Scroll)) {
+ if (q->is_a(Fl_Type::ID_Group) && !q->is_a(ID_Scroll)) {
Fl_Widget_Type *w = (Fl_Widget_Type*)q;
draw_out_of_bounds(w, w->o->x(), w->o->y(), w->o->w(), w->o->h());
}
@@ -699,7 +699,7 @@ void check_redraw_corresponding_parent(Fl_Type *s) {
Fl_Widget_Type * prev_parent = 0;
if( !s || !s->selected || !s->is_widget()) return;
for (Fl_Type *i=s; i && i->parent; i=i->parent) {
- if (i->is_group() && prev_parent) {
+ if (i->is_a(Fl_Type::ID_Group) && prev_parent) {
if (i->is_a(Fl_Type::ID_Tabs)) {
((Fl_Tabs*)((Fl_Widget_Type*)i)->o)->value(prev_parent->o);
return;
@@ -709,7 +709,7 @@ void check_redraw_corresponding_parent(Fl_Type *s) {
return;
}
}
- if (i->is_group() && s->is_widget())
+ if (i->is_a(Fl_Type::ID_Group) && s->is_widget())
prev_parent = (Fl_Widget_Type*)i;
}
}
@@ -876,7 +876,7 @@ int Fl_Window_Type::handle(int event) {
// find the innermost item clicked on:
selection = this;
for (Fl_Type* i=next; i && i->level>level; i=i->next)
- if (i->is_group()) {
+ if (i->is_a(Fl_Type::ID_Group)) {
Fl_Widget_Type* myo = (Fl_Widget_Type*)i;
if (Fl::event_inside(myo->o) && myo->o->visible_r()) {
selection = myo;
diff --git a/fluid/Fl_Window_Type.h b/fluid/Fl_Window_Type.h
index a7a43eaf3..758ae2402 100644
--- a/fluid/Fl_Window_Type.h
+++ b/fluid/Fl_Window_Type.h
@@ -114,7 +114,6 @@ public:
void remove_child(Fl_Type*) FL_OVERRIDE;
int is_parent() const FL_OVERRIDE {return 1;}
- int is_group() const FL_OVERRIDE {return 1;}
Fl_Widget *enter_live_mode(int top=0) FL_OVERRIDE;
void leave_live_mode() FL_OVERRIDE;
diff --git a/fluid/factory.cxx b/fluid/factory.cxx
index 8e6164aa1..d9c53465a 100644
--- a/fluid/factory.cxx
+++ b/fluid/factory.cxx
@@ -1272,7 +1272,7 @@ Fl_Type *add_new_widget_from_user(const char *inName, Strategy strategy) {
*/
static void cbf(Fl_Widget *, void *v) {
Fl_Type *t = NULL;
- if (Fl_Type::current && Fl_Type::current->is_group())
+ if (Fl_Type::current && Fl_Type::current->is_a(Fl_Type::ID_Group))
t = ((Fl_Type*)v)->make(kAddAsLastChild);
else
t = ((Fl_Type*)v)->make(kAddAfterCurrent);
@@ -1284,7 +1284,7 @@ static void cbf(Fl_Widget *, void *v) {
*/
static void cb(Fl_Widget *, void *v) {
Fl_Type *t = NULL;
- if (Fl_Type::current && Fl_Type::current->is_group())
+ if (Fl_Type::current && Fl_Type::current->is_a(Fl_Type::ID_Group))
t = add_new_widget_from_user((Fl_Type*)v, kAddAsLastChild);
else
t = add_new_widget_from_user((Fl_Type*)v, kAddAfterCurrent);
diff --git a/fluid/fluid.cxx b/fluid/fluid.cxx
index 5b0666d08..db069063c 100644
--- a/fluid/fluid.cxx
+++ b/fluid/fluid.cxx
@@ -607,7 +607,7 @@ static void external_editor_timer(void*) {
// Walk tree looking for files modified by external editors.
int modified = 0;
for (Fl_Type *p = Fl_Type::first; p; p = p->next) {
- if ( p->is_code() ) {
+ if ( p->is_a(Fl_Type::ID_Code) ) {
Fl_Code_Type *code = (Fl_Code_Type*)p;
// Code changed by external editor?
if ( code->handle_editor_changes() ) { // updates ram, file size/mtime
@@ -1368,7 +1368,7 @@ void paste_cb(Fl_Widget*, void*) {
undo_checkpoint();
undo_suspend();
Strategy strategy = kAddAfterCurrent;
- if (Fl_Type::current && Fl_Type::current->is_group())
+ if (Fl_Type::current && Fl_Type::current->is_a(Fl_Type::ID_Group))
strategy = kAddAsLastChild;
if (!read_file(cutfname(), 1, strategy)) {
widget_browser->rebuild();