mirror of
https://github.com/fltk/fltk.git
synced 2026-08-17 16:43:10 +08:00
Fluid: remove three global state variables
* improves handling of class in class (still not recommended)
This commit is contained in:
+36
-13
@@ -474,10 +474,11 @@ void Code_Writer::write_c_indented(const std::string& codeblock, int additional_
|
||||
bool is_class_member(Node *t) {
|
||||
return dynamic_cast<Function_Node*>(t)
|
||||
|| dynamic_cast<Decl_Node*>(t)
|
||||
|| dynamic_cast<Data_Node*>(t);
|
||||
// || dynamic_cast<Class_Node*>(t) // FLUID can't handle a class inside a class
|
||||
// || dynamic_cast<Widget_Class_Node*>(t) // ???
|
||||
// || dynamic_cast<DeclBlock_Node*>(t) // Declaration blocks are generally not handled well
|
||||
|| dynamic_cast<Data_Node*>(t)
|
||||
|| dynamic_cast<Class_Node*>(t) // Caution, class in a class mostly untested
|
||||
|| dynamic_cast<Widget_Class_Node*>(t) // Caution, class in a class mostly untested
|
||||
// || dynamic_cast<DeclBlock_Node*>(t) // Declaration blocks are generally not handled well
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -537,8 +538,16 @@ Node* Code_Writer::write_code(Node* p) {
|
||||
}
|
||||
// recursively write the code of all children
|
||||
Node* q;
|
||||
if (p->is_widget() && p->is_class()) {
|
||||
// Handle widget classes specially
|
||||
if (dynamic_cast<Widget_Class_Node*>(p)) {
|
||||
// Legacy handling for Widget_Class_Node:
|
||||
// As the name suggests, these are widgets and classes at the same time.
|
||||
// The implementation is a class that generates a collection of widgets
|
||||
// in a Fl_Group of Fl_Window (or derived).
|
||||
// Problem is, widgets are created directly as children of Widget_Class_Node
|
||||
// instead of inside a constructor. So below we have to treat all children
|
||||
// that are widgets in write_code1(), and all children that are regular
|
||||
// class members (Methods, Variables) *after* write_code2().
|
||||
// \todo Widgets should be required to be in a constructor
|
||||
for (q = p->next; q && q->level > p->level;) {
|
||||
// note: maybe declaration blocks should be handled like comments in the context
|
||||
if (!is_class_member(q) && !is_comment_before_class_member(q)) {
|
||||
@@ -568,7 +577,7 @@ Node* Code_Writer::write_code(Node* p) {
|
||||
}
|
||||
|
||||
write_h("};\n");
|
||||
current_widget_class = nullptr;
|
||||
class_stack.pop_back();
|
||||
} else {
|
||||
for (q = p->next; q && q->level > p->level;) q = write_code(q);
|
||||
// write all code that come after the children
|
||||
@@ -788,12 +797,26 @@ int Code_Writer::flush()
|
||||
This avoids repeating these words if the mode is already set.
|
||||
\param[in] state 0 for private, 1 for public, 2 for protected
|
||||
*/
|
||||
void Code_Writer::write_public(int state) {
|
||||
if (!current_class && !current_widget_class) return;
|
||||
if (current_class && current_class->write_public_state == state) return;
|
||||
if (current_widget_class && current_widget_class->write_public_state == state) return;
|
||||
if (current_class) current_class->write_public_state = state;
|
||||
if (current_widget_class) current_widget_class->write_public_state = state;
|
||||
void Code_Writer::write_public(int state)
|
||||
{
|
||||
if (class_stack.empty()) {
|
||||
return;
|
||||
}
|
||||
auto* top = class_stack.back();
|
||||
auto* current_class = dynamic_cast<Class_Node*>(top);
|
||||
auto* current_widget_class = dynamic_cast<Widget_Class_Node*>(top);
|
||||
if (current_class) {
|
||||
if (current_class->write_public_state == state)
|
||||
return;
|
||||
current_class->write_public_state = state;
|
||||
} else if (current_widget_class) {
|
||||
if (current_widget_class->write_public_state == state)
|
||||
return;
|
||||
current_widget_class->write_public_state = state;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (state) {
|
||||
case 0: write_h("private:\n"); break;
|
||||
case 1: write_h("public:\n"); break;
|
||||
|
||||
@@ -130,6 +130,10 @@ public:
|
||||
/// (disables binary data blocks, for example)
|
||||
bool write_codeview { false };
|
||||
|
||||
/// Set while we are descending inside a Class or Widget Class node, so we can
|
||||
/// write public/private/protected keywords as needed.
|
||||
std::vector<Node*> class_stack { };
|
||||
|
||||
public:
|
||||
Code_Writer(Project &proj);
|
||||
Code_Writer(const Code_Writer &) = delete;
|
||||
|
||||
@@ -41,9 +41,6 @@ using namespace fluid;
|
||||
using namespace fluid::io;
|
||||
using namespace fluid::proj;
|
||||
|
||||
/// Set a current class, so that the code of the children is generated correctly.
|
||||
Class_Node *current_class = nullptr;
|
||||
|
||||
/**
|
||||
Check if the node tree has a top-level function with the given return type and signature.
|
||||
\param[in] return_type_regex regex for the return type of the function,
|
||||
@@ -1492,9 +1489,8 @@ void Class_Node::open() {
|
||||
Write the header code that declares this class.
|
||||
*/
|
||||
void Class_Node::write_code1(fluid::io::Code_Writer& f) {
|
||||
parent_class = current_class;
|
||||
current_class = this;
|
||||
write_public_state = 0;
|
||||
f.class_stack.push_back(this);
|
||||
write_public_state = 0; // private:
|
||||
f.write_h("\n");
|
||||
write_comment_h(f);
|
||||
if (!prefix().empty())
|
||||
@@ -1512,6 +1508,6 @@ void Class_Node::write_code1(fluid::io::Code_Writer& f) {
|
||||
*/
|
||||
void Class_Node::write_code2(fluid::io::Code_Writer& f) {
|
||||
f.write_h("};\n");
|
||||
current_class = parent_class;
|
||||
f.class_stack.pop_back();
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
extern class Class_Node *current_class;
|
||||
|
||||
bool has_toplevel_function(const std::string& return_type_regex, const std::string& function_sig_regex);
|
||||
|
||||
|
||||
@@ -109,10 +109,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// ---- global variables
|
||||
|
||||
Node *in_this_only; // set if menu popped-up in window
|
||||
|
||||
// ---- various functions
|
||||
|
||||
/**
|
||||
@@ -120,11 +116,6 @@ Node *in_this_only; // set if menu popped-up in window
|
||||
*/
|
||||
void select_all_cb(Fl_Widget *,void *) {
|
||||
Node *p = Fluid.proj.tree.current ? Fluid.proj.tree.current->parent : nullptr;
|
||||
if (in_this_only) {
|
||||
Node *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;
|
||||
@@ -147,11 +138,6 @@ void select_all_cb(Fl_Widget *,void *) {
|
||||
*/
|
||||
void select_none_cb(Fl_Widget *,void *) {
|
||||
Node *p = Fluid.proj.tree.current ? Fluid.proj.tree.current->parent : nullptr;
|
||||
if (in_this_only) {
|
||||
Node *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;
|
||||
|
||||
@@ -793,7 +793,6 @@ void toggle_restricted_cb(Fl_Check_Button *o, void *v) {
|
||||
extern void select(Node *,int);
|
||||
extern void select_only(Node *);
|
||||
extern void deselect();
|
||||
extern Node* in_this_only;
|
||||
extern void fix_group_size(Node *t);
|
||||
|
||||
extern Fl_Menu_Item New_Menu[];
|
||||
@@ -1003,7 +1002,6 @@ int Window_Node::handle(int event) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
in_this_only = this;
|
||||
popupx = Fl::event_x();
|
||||
popupy = Fl::event_y();
|
||||
// If the selected widget at dnd start and the drop target are the same,
|
||||
@@ -1022,7 +1020,6 @@ int Window_Node::handle(int event) {
|
||||
}
|
||||
popupx = 0x7FFFFFFF;
|
||||
popupy = 0x7FFFFFFF; // mark as invalid (MAXINT)
|
||||
in_this_only = nullptr;
|
||||
widget_browser->display(Fluid.proj.tree.current);
|
||||
widget_browser->rebuild();
|
||||
return 1;
|
||||
@@ -1033,13 +1030,11 @@ int Window_Node::handle(int event) {
|
||||
drag = dx = dy = 0;
|
||||
// test for popup menu:
|
||||
if (Fl::event_button() >= 3) {
|
||||
in_this_only = this; // modifies how some menu items work.
|
||||
static const Fl_Menu_Item* myprev;
|
||||
popupx = mx; popupy = my;
|
||||
const Fl_Menu_Item* m = New_Menu->popup(mx,my,"New",myprev);
|
||||
if (m && m->callback()) {myprev = m; m->do_callback(this->o);}
|
||||
popupx = 0x7FFFFFFF; popupy = 0x7FFFFFFF; // mark as invalid (MAXINT)
|
||||
in_this_only = nullptr;
|
||||
return 1;
|
||||
}
|
||||
// find the innermost item clicked on:
|
||||
@@ -1186,10 +1181,8 @@ int Window_Node::handle(int event) {
|
||||
}}
|
||||
|
||||
case FL_SHORTCUT: {
|
||||
in_this_only = this; // modifies how some menu items work.
|
||||
const Fl_Menu_Item* m = Fluid.main_menu->test_shortcut();
|
||||
if (m && m->callback()) m->do_callback(this->o);
|
||||
in_this_only = nullptr;
|
||||
return (m != nullptr);}
|
||||
|
||||
default:
|
||||
@@ -1314,8 +1307,6 @@ int Window_Node::read_fdesign(const char* propname, const char* value) {
|
||||
|
||||
Widget_Class_Node Widget_Class_Node::prototype;
|
||||
|
||||
Widget_Class_Node *current_widget_class = nullptr;
|
||||
|
||||
/**
|
||||
Create and add a new Widget Class node.
|
||||
\param[in] strategy add after current or as last child
|
||||
@@ -1386,9 +1377,8 @@ void Widget_Class_Node::write_code1(fluid::io::Code_Writer& f) {
|
||||
#if 0
|
||||
Widget_Node::write_code1(fluid::io::Code_Writer& f);
|
||||
#endif // 0
|
||||
|
||||
current_widget_class = this;
|
||||
write_public_state = 1;
|
||||
f.class_stack.push_back(this);
|
||||
write_public_state = 1; // public:, because the constructors follow.
|
||||
|
||||
std::string c = subclass();
|
||||
if (c.empty()) c = "Fl_Group";
|
||||
@@ -1487,6 +1477,7 @@ void Widget_Class_Node::write_code2(fluid::io::Code_Writer& f) {
|
||||
f.write_c(f.indent() + "resize(X, Y, W, H);\n");
|
||||
f.indent_less();
|
||||
f.write_c("}\n");
|
||||
//class_stack.pop_back(); is called in Code_Writer::write_code(Node* p)
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
class Widget_Class_Node;
|
||||
|
||||
extern Fl_Menu_Item window_type_menu[];
|
||||
extern Widget_Class_Node *current_widget_class;
|
||||
|
||||
void toggle_overlays(Fl_Widget *,void *);
|
||||
void toggle_guides(Fl_Widget *,void *);
|
||||
|
||||
@@ -2723,7 +2723,7 @@ static void cb_Reset(Fl_Button* o, void* v) {
|
||||
o->parent()->do_callback(o->parent(), LOAD);
|
||||
widget_browser->redraw();
|
||||
widget_browser->save_prefs();
|
||||
//fl ▲ ----------~=-=~==~~=~------------~-=~~~~-~~=~-~~=~~=~- ▲ fl//
|
||||
//fl ▲ ----------~=-=~==~~=~------------~~-~~~==~=-=-=-~-=--~ ▲ fl//
|
||||
}
|
||||
|
||||
static void cb_Close(Fl_Button*, void*) {
|
||||
|
||||
@@ -73,7 +73,6 @@ private:
|
||||
static void cb_6(Fl_Button*, void*);
|
||||
inline void cb_7_i(Fl_Button*, void*);
|
||||
static void cb_7(Fl_Button*, void*);
|
||||
public:
|
||||
void grid_child_cb(fluid::widget::Formula_Input* i, void* v, int what);
|
||||
};
|
||||
#endif // Grid_Child_Tab_h
|
||||
|
||||
Reference in New Issue
Block a user