From 9badcab8f0f5abf2c43bb324975a89089a27bd5c Mon Sep 17 00:00:00 2001 From: Matthias Melcher Date: Mon, 13 Jul 2026 23:38:14 +0200 Subject: [PATCH] Fluid: clean up Code_Writer --- fluid/io/Code_Writer.cxx | 301 +++++++++++++++++++------------- fluid/io/Code_Writer.h | 40 +++-- fluid/nodes/Node.h | 9 +- fluid/nodes/Tree.cxx | 12 +- fluid/panels/codeview_panel.cxx | 46 ++--- fluid/panels/codeview_panel.fl | 53 +++--- fluid/panels/codeview_panel.h | 2 +- fluid/panels/widget_panel.h | 2 +- 8 files changed, 278 insertions(+), 187 deletions(-) diff --git a/fluid/io/Code_Writer.cxx b/fluid/io/Code_Writer.cxx index f87ad3bcf..102111020 100644 --- a/fluid/io/Code_Writer.cxx +++ b/fluid/io/Code_Writer.cxx @@ -281,9 +281,9 @@ void Code_Writer::write_cstring(fluid::string_view text) { // A line break would be ok here. Do not put linebreak in front of // following characters (0b10......) if (linelength >= 78) { crc_puts(next_line); linelength = 0; } + linelength++; } crc_putc(c); - linelength++; break; } // otherwise we must print it as an octal constant: @@ -453,7 +453,7 @@ void Code_Writer::write_c_indented(const std::string& codeblock, int additional_ } /** - Return true if the type can be the member of a class. + Return true if the type can be a member of a class. Some types are treated differently if they are inside class. Especially within a Widget Class, children that are widgets are written as part of the @@ -481,7 +481,7 @@ bool is_class_member(Node *t) { \return false if it is followed by a widget or code \see is_class_member(Node *t) */ -bool is_comment_before_class_member(Node *q) { +static bool is_comment_before_class_member(Node *q) { if (dynamic_cast(q) && q->next && q->next->level==q->level) { if (dynamic_cast(q->next)) return is_comment_before_class_member(q->next); @@ -497,11 +497,9 @@ bool is_comment_before_class_member(Node *q) { \return pointer to the next sibling */ Node* Code_Writer::write_static(Node* p) { - if (write_codeview) p->header_static.start = header_pos(); - if (write_codeview) p->code_static.start = code_pos(); + mark_start(p->static_data); p->write_static(*this); - if (write_codeview) p->code_static.end = code_pos(); - if (write_codeview) p->header_static.end = header_pos(); + mark_end(p->static_data); Node* q; for (q = p->next; q && q->level > p->level;) { @@ -522,11 +520,9 @@ Node* Code_Writer::write_code(Node* p) { // write all code that comes before the children code // (but don't write the last comment until the very end) if (!(p==Fluid.proj.tree.last && dynamic_cast(p))) { - if (write_codeview) p->code1.start = code_pos(); - if (write_codeview) p->header1.start = header_pos(); + mark_start(p->setup_node); p->write_code1(*this); - if (write_codeview) p->code1.end = code_pos(); - if (write_codeview) p->header1.end = header_pos(); + mark_end(p->setup_node); } // recursively write the code of all children Node* q; @@ -545,11 +541,9 @@ Node* Code_Writer::write_code(Node* p) { } // write all code that come after the children - if (write_codeview) p->code2.start = code_pos(); - if (write_codeview) p->header2.start = header_pos(); + mark_start(p->finalize_node); p->write_code2(*this); - if (write_codeview) p->code2.end = code_pos(); - if (write_codeview) p->header2.end = header_pos(); + mark_end(p->finalize_node); for (q = p->next; q && q->level > p->level;) { if (is_class_member(q) || is_comment_before_class_member(q)) { @@ -567,17 +561,15 @@ Node* Code_Writer::write_code(Node* p) { } else { for (q = p->next; q && q->level > p->level;) q = write_code(q); // write all code that come after the children - if (write_codeview) p->code2.start = code_pos(); - if (write_codeview) p->header2.start = header_pos(); + mark_start(p->finalize_node); p->write_code2(*this); - if (write_codeview) p->code2.end = code_pos(); - if (write_codeview) p->header2.end = header_pos(); + mark_end(p->finalize_node); } return q; } /** - Write the source and header files for the current design. + Write source code and header files. If the files already exist, they will be overwritten only if the content has changed. This conservative approach helps reduce unnecessary recompilation. @@ -589,109 +581,92 @@ Node* Code_Writer::write_code(Node* p) { \return 0 if the operation failed, 1 if it was successful */ int Code_Writer::write_code(const std::string& code_arg, const std::string& header_arg, bool to_codeview) { + code_filename = code_arg; + header_filename = header_arg; write_codeview = to_codeview; - unique_id_list.clear(); - indentation = 0; - current_class = nullptr; - current_widget_class = nullptr; - - // Always use string stream buffers for output - code_buffer.str(""); - code_buffer.clear(); - header_buffer.str(""); - header_buffer.clear(); // Remember the last code file location for MergeBack - if (!code_arg.empty() && proj_.write_mergeback_data && !to_codeview) { - std::string filename = proj_.projectfile_path() + proj_.projectfile_name(); - int i, n = (int)filename.size(); - for (i=0; i(first_node)) { - if (write_codeview) { - first_node->code1.start = first_node->code2.start = code_pos(); - first_node->header1.start = first_node->header2.start = header_pos(); - } + mark_start(first_node->setup_node); + mark_start(first_node->finalize_node); // it is ok to write non-recursive code here, because comments have no children or code2 blocks first_node->write_code1(*this); - if (write_codeview) { - first_node->code1.end = first_node->code2.end = code_pos(); - first_node->header1.end = first_node->header2.end = header_pos(); - } + mark_end(first_node->setup_node); + mark_end(first_node->finalize_node); first_node = first_node->next; } + return first_node; +} +/** + Write the prologue of the source and header files, including the include guard + and any necessary includes. + */ +void Code_Writer::write_prologue() +{ char version[128]; fl_snprintf(version, sizeof(version), "// generated by Fast Light User Interface Designer (fluid) version %.4f\n\n", FL_VERSION); write_h(std::string(version)); crc_puts(version); - { - // Creating the include guard is more involved than it seems at first glance. - // The include guard is deduced from header filename. However, if the - // filename contains unicode characters, they need to be encoded using - // \Uxxxxxxxx or \\uxxxx encoding to form a valid macro identifier. - // - // But that approach is not portable. Windows does not normalize Unicode - // (ö is the letter \u00F6). macOS normalizes to NFD (ö is \u006F\u0308, - // o followed by a Combining Diaresis ¨). - // - // To make the include guard consistent across l=platforms, it can be - // explicitly set by the user in the Project Settings. - std::string macro_name_str = proj_.include_guard; - if (macro_name_str.empty()) { - std::ostringstream macro_name; - std::string header_name; - const char* a = nullptr; - if (write_codeview) { - header_name = proj_.headerfile_name(); - a = header_name.c_str(); - } else { - a = fl_filename_name(header_arg.c_str()); - } - const char* b = a + strlen(a); - int len = 0; - unsigned ucs = fl_utf8decode(a, b, &len); - if ((ucs > 127) || (!isalpha(ucs) && (ucs != '_'))) - macro_name << '_'; - while (a < b) { - ucs = fl_utf8decode(a, b, &len); - if (ucs > 0x0000ffff) { // large unicode character - macro_name << "\\U" << std::setw(8) << std::setfill('0') << std::hex << ucs; - } else if (ucs > 127) { // small unicode character or not an ASCI letter or digit - macro_name << "\\u" << std::setw(4) << std::setfill('0') << std::hex << ucs; - } else if (!isalnum(ucs)) { - macro_name << '_'; - } else { - macro_name << (char)ucs; - } - a += len; - } - macro_name_str = macro_name.str(); - } - write_h("#ifndef " + macro_name_str + "\n"); - write_h("#define " + macro_name_str + "\n"); - } + + std::string guard = header_guard_macro(); + write_h("#ifndef " + guard + "\n"); + write_h("#define " + guard + "\n"); if (proj_.avoid_early_includes==0) { write_h_once("#include "); } - if (!header_arg.empty() && proj_.include_H_from_C) { - if (to_codeview) { + if (!header_filename.empty() && proj_.include_H_from_C) { + if (write_codeview) { write_c("#include \"CodeView.h\"\n"); } else if (proj_.header_file_name[0] == '.' && strchr(proj_.header_file_name.c_str(), '/') == nullptr) { - write_c("#include \"" + fl_filename_name_str(header_arg) + "\"\n"); + write_c("#include \"" + fl_filename_name_str(header_filename) + "\"\n"); } else { write_c("#include \"" + proj_.header_file_name + "\"\n"); } } +} + +/** + Write the internationalization prologue, including any necessary includes and macros. + */ +void Code_Writer::write_i18n_prologue() +{ std::string loc_include, loc_conditional; if (proj_.i18n.type==fluid::I18n_Type::GNU) { loc_include = proj_.i18n.gnu_include; @@ -743,44 +718,53 @@ int Code_Writer::write_code(const std::string& code_arg, const std::string& head write_c("#endif\n"); } } - for (Node* p = first_node; p;) { - // write all static data for this & all children first - write_static(p); - // then write the nested code: - p = write_code(p); - } +} - write_h("#endif\n"); +/** + Write the epilogue of the source and header files, including the include guard. + */ +void Code_Writer::write_epilogue() +{ + std::string guard = header_guard_macro(); + write_h("#endif // " + guard + "\n"); +} +/** + If the last node in the project is a comment, emit it after the actual epilogue. + */ +void Code_Writer::write_epilogue_comment() { Node* last_node = Fluid.proj.tree.last; if (last_node && (last_node != Fluid.proj.tree.first) && dynamic_cast(last_node)) { - if (write_codeview) { - last_node->code1.start = last_node->code2.start = code_pos(); - last_node->header1.start = last_node->header2.start = header_pos(); - } + mark_start(last_node->setup_node); + mark_start(last_node->finalize_node); last_node->write_code1(*this); - if (write_codeview) { - last_node->code1.end = last_node->code2.end = code_pos(); - last_node->header1.end = last_node->header2.end = header_pos(); - } + mark_end(last_node->setup_node); + mark_end(last_node->finalize_node); } +} - // For codeview mode, strings are available via code_string() / header_string() - if (write_codeview) - return 1; +/** + Write the contents of code_buffer and header_buffer.. + If the files already exist, they will be overwritten only if the content + has changed. This conservative approach helps reduce unnecessary recompilation. + + \return 0 if the operation failed, 1 if it was successful + */ +int Code_Writer::flush() +{ // Write code output: to file if filename provided, to stdout otherwise bool code_ok = true; - if (!code_arg.empty()) { - code_ok = write_file_if_changed(code_arg, code_buffer.str()); + if (!code_filename.empty()) { + code_ok = write_file_if_changed(code_filename, code_buffer.str()); } else { fputs(code_buffer.str().c_str(), stdout); } // Write header output: to file if filename provided, to stdout otherwise bool header_ok = true; - if (!header_arg.empty()) { - header_ok = write_file_if_changed(header_arg, header_buffer.str()); + if (!header_filename.empty()) { + header_ok = write_file_if_changed(header_filename, header_buffer.str()); } else { fputs(header_buffer.str().c_str(), stdout); } @@ -788,7 +772,6 @@ int Code_Writer::write_code(const std::string& code_arg, const std::string& head return code_ok && header_ok ? 1 : 0; } - /** Write the public/private/protected keywords inside the class. This avoids repeating these words if the mode is already set. @@ -974,6 +957,90 @@ void fluid::CRC32::update(fluid::string_view block) { } } +/** + Return the macro name to use for the include guard in the header file. + + Creating the include guard is more involved than it seems at first glance. + The include guard is deduced from header filename. However, if the + filename contains unicode characters, they need to be encoded using + \Uxxxxxxxx or \\uxxxx encoding to form a valid macro identifier. + + But that approach is not portable. Windows does not normalize Unicode + (ö is the letter \u00F6). macOS normalizes to NFD (ö is \u006F\u0308, + o followed by a Combining Diaresis ¨). + + To make the include guard consistent across l=platforms, it can be + explicitly set by the user in the Project Settings. + */ +std::string Code_Writer::header_guard_macro() +{ + if (!header_guard_macro_.empty()) { + return header_guard_macro_; + } + header_guard_macro_ = proj_.include_guard; + if (header_guard_macro_.empty()) { + std::ostringstream macro_name; + std::string header_name; + const char* a = nullptr; + if (write_codeview) { + header_name = proj_.headerfile_name(); + a = header_name.c_str(); + } else { + a = fl_filename_name(header_filename.c_str()); + } + const char* b = a + strlen(a); + int len = 0; + unsigned ucs = fl_utf8decode(a, b, &len); + if ((ucs > 127) || (!isalpha(ucs) && (ucs != '_'))) + macro_name << '_'; + while (a < b) { + ucs = fl_utf8decode(a, b, &len); + if (ucs > 0x0000ffff) { // large unicode character + macro_name << "\\U" << std::setw(8) << std::setfill('0') << std::hex << ucs; + } else if (ucs > 127) { // small unicode character or not an ASCI letter or digit + macro_name << "\\u" << std::setw(4) << std::setfill('0') << std::hex << ucs; + } else if (!isalnum(ucs)) { + macro_name << '_'; + } else { + macro_name << (char)ucs; + } + a += len; + } + header_guard_macro_ = macro_name.str(); + } + return header_guard_macro_; +} + +/** + Remember the last code file location for MergeBack. + This is stored in the user preferences, so that the next time the project is + opened, the code file can be found and merged back into the project. + */ +void Code_Writer::remember_mergeback_paths() +{ + std::string filename = proj_.projectfile_path() + proj_.projectfile_name(); + int i, n = (int)filename.size(); + for (i=0; i unique_id_list { }; @@ -104,10 +110,11 @@ private: fluid::CRC32 crc_ { }; /// current level of source code indentation - int indentation = 0; + int indentation { 0 }; bool file_content_matches(const std::string& filename, const std::string& content); bool write_file_if_changed(const std::string& filename, const std::string& content); + int flush(); /// Return the current write position in the code output stream. int code_pos() { return (int)code_buffer.tellp(); } @@ -121,13 +128,13 @@ protected: public: /// set if we write abbreviated file for the source code previewer /// (disables binary data blocks, for example) - bool write_codeview = false; + bool write_codeview { false }; /// silly thing to prevent declaring unused variables: /// When this symbol is on, all attempts to write code don't write /// anything, but set a variable if it looks like the variable "o" is used: - int varused_test = 0; + int varused_test { 0 }; /// set to 1 if varused_test found that a variable is actually used - int varused = 0; + int varused { 0 }; public: Code_Writer(Project &proj); @@ -165,13 +172,26 @@ public: Node* write_code(Node* p); int write_code(const std::string& code_arg, const std::string& header_arg, bool to_codeview=false); + Node* write_prologue_comment(); + void write_prologue(); + void write_i18n_prologue(); + void write_epilogue(); + void write_epilogue_comment(); /// Return the generated source code as a string (valid after write_code() with to_codeview=true). std::string code_string() const { return code_buffer.str(); } /// Return the generated header code as a string (valid after write_code() with to_codeview=true). std::string header_string() const { return header_buffer.str(); } + /// Return the predefined header guard, or generate one based on the header filename if not set. + std::string header_guard_macro(); + /// Remember the last destination for later MergeBack calls. + void remember_mergeback_paths(); + void tag(proj::Mergeback::Tag prev_type, proj::Mergeback::Tag next_type, unsigned short uid); + + void mark_start(TextSpan2& span); + void mark_end(TextSpan2& span); }; } // namespace io diff --git a/fluid/nodes/Node.h b/fluid/nodes/Node.h index 13d088910..637f7c286 100644 --- a/fluid/nodes/Node.h +++ b/fluid/nodes/Node.h @@ -85,6 +85,10 @@ struct TextSpan { int start = -1, end = -1; }; +struct TextSpan2 { + TextSpan h, c; +}; + int storestring(const char *n, const char * & p, int nostrip=0); int storestring(const std::string& n, std::string& p, int nostrip=0); @@ -180,8 +184,9 @@ public: // things that should not be public: std::string callback_name(fluid::io::Code_Writer& f); // text positions of this type in code, header, and project file (see codeview) - TextSpan code_static, code1, code2; - TextSpan header1, header2, header_static; + TextSpan2 static_data; + TextSpan2 setup_node; + TextSpan2 finalize_node; TextSpan proj1, proj2; public: diff --git a/fluid/nodes/Tree.cxx b/fluid/nodes/Tree.cxx index cab0ae975..c35805d4a 100644 --- a/fluid/nodes/Tree.cxx +++ b/fluid/nodes/Tree.cxx @@ -107,14 +107,14 @@ Node *Tree::find_in_text(int text_type, int crsr) { for (auto node: all_nodes()) { switch (text_type) { case 0: - if (crsr >= node->code1.start && crsr < node->code1.end) return node; - if (crsr >= node->code2.start && crsr < node->code2.end) return node; - if (crsr >= node->code_static.start && crsr < node->code_static.end) return node; + if (crsr >= node->setup_node.c.start && crsr < node->setup_node.c.end) return node; + if (crsr >= node->finalize_node.c.start && crsr < node->finalize_node.c.end) return node; + if (crsr >= node->static_data.c.start && crsr < node->static_data.c.end) return node; break; case 1: - if (crsr >= node->header1.start && crsr < node->header1.end) return node; - if (crsr >= node->header2.start && crsr < node->header2.end) return node; - if (crsr >= node->header_static.start && crsr < node->header_static.end) return node; + if (crsr >= node->setup_node.h.start && crsr < node->setup_node.h.end) return node; + if (crsr >= node->finalize_node.h.start && crsr < node->finalize_node.h.end) return node; + if (crsr >= node->static_data.h.start && crsr < node->static_data.h.end) return node; break; case 2: if (crsr >= node->proj1.start && crsr < node->proj1.end) return node; diff --git a/fluid/panels/codeview_panel.cxx b/fluid/panels/codeview_panel.cxx index 8218bb946..20216cb50 100644 --- a/fluid/panels/codeview_panel.cxx +++ b/fluid/panels/codeview_panel.cxx @@ -50,24 +50,24 @@ void update_codeview_position() { if (cv_source->visible_r()) { switch (cv_code_choice) { case 0: // prolog: not yet (include statements) - pos0 = Fluid.proj.tree.current->code1.start; - pos1 = Fluid.proj.tree.current->code2.end; + pos0 = Fluid.proj.tree.current->setup_node.c.start; + pos1 = Fluid.proj.tree.current->finalize_node.c.end; break; case 1: // static: callbacks, menu declarations - pos0 = Fluid.proj.tree.current->code_static.start; - pos1 = Fluid.proj.tree.current->code_static.end; + pos0 = Fluid.proj.tree.current->static_data.c.start; + pos1 = Fluid.proj.tree.current->static_data.c.end; break; case 2: // code: entire implementation block including children - pos0 = Fluid.proj.tree.current->code1.start; - pos1 = Fluid.proj.tree.current->code2.end; + pos0 = Fluid.proj.tree.current->setup_node.c.start; + pos1 = Fluid.proj.tree.current->finalize_node.c.end; break; case 3: // code1: all implementation code before the children - pos0 = Fluid.proj.tree.current->code1.start; - pos1 = Fluid.proj.tree.current->code1.end; + pos0 = Fluid.proj.tree.current->setup_node.c.start; + pos1 = Fluid.proj.tree.current->setup_node.c.end; break; case 4: // code1: all implementation code before the children - pos0 = Fluid.proj.tree.current->code2.start; - pos1 = Fluid.proj.tree.current->code2.end; + pos0 = Fluid.proj.tree.current->finalize_node.c.start; + pos1 = Fluid.proj.tree.current->finalize_node.c.end; break; } if (pos0>=0) { @@ -82,20 +82,20 @@ void update_codeview_position() { switch (cv_code_choice) { case 0: // prolog: not yet (include statements) case 1: // static: callbacks, menu declarations - pos0 = Fluid.proj.tree.current->header_static.start; - pos1 = Fluid.proj.tree.current->header_static.end; + pos0 = Fluid.proj.tree.current->static_data.h.start; + pos1 = Fluid.proj.tree.current->static_data.h.end; break; case 2: // code: entire implementation block including children - pos0 = Fluid.proj.tree.current->header1.start; - pos1 = Fluid.proj.tree.current->header2.end; + pos0 = Fluid.proj.tree.current->setup_node.h.start; + pos1 = Fluid.proj.tree.current->finalize_node.h.end; break; case 3: // code1: all implementation code before the children - pos0 = Fluid.proj.tree.current->header1.start; - pos1 = Fluid.proj.tree.current->header1.end; + pos0 = Fluid.proj.tree.current->setup_node.h.start; + pos1 = Fluid.proj.tree.current->setup_node.h.end; break; case 4: // code1: all implementation code before the children - pos0 = Fluid.proj.tree.current->header2.start; - pos1 = Fluid.proj.tree.current->header2.end; + pos0 = Fluid.proj.tree.current->finalize_node.h.start; + pos1 = Fluid.proj.tree.current->finalize_node.h.end; break; } if (pos0>=0) { @@ -375,10 +375,10 @@ static void cb_cv_code_choice_w(Fl_Choice* o, void*) { Fl_Menu_Item menu_cv_code_choice_w[] = { {"prolog", 0, nullptr, (void*)(0), 16, (uchar)FL_NORMAL_LABEL, 0, 11, 0 }, - {"static", 0, nullptr, (void*)(1), 0, (uchar)FL_NORMAL_LABEL, 0, 11, 0 }, - {"code", 0, nullptr, (void*)(2), 0, (uchar)FL_NORMAL_LABEL, 0, 11, 0 }, - {"code 1", 0, nullptr, (void*)(3), 0, (uchar)FL_NORMAL_LABEL, 0, 11, 0 }, - {"code 2", 0, nullptr, (void*)(4), 0, (uchar)FL_NORMAL_LABEL, 0, 11, 0 }, + {"static data", 0, nullptr, (void*)(1), 0, (uchar)FL_NORMAL_LABEL, 0, 11, 0 }, + {"instantiate", 0, nullptr, (void*)(2), 0, (uchar)FL_NORMAL_LABEL, 0, 11, 0 }, + {"setup", 0, nullptr, (void*)(3), 0, (uchar)FL_NORMAL_LABEL, 0, 11, 0 }, + {"finalize", 0, nullptr, (void*)(4), 0, (uchar)FL_NORMAL_LABEL, 0, 11, 0 }, { nullptr, 0, nullptr, nullptr, 0, 0, 0, 0, 0 } }; @@ -517,7 +517,7 @@ Fl_Double_Window* make_codeview() { { cv_autoposition = new Fl_Light_Button(172, 485, 89, 20, "Auto-Position"); cv_autoposition->labelsize(11); } // Fl_Light_Button* cv_autoposition - { cv_code_choice_w = new Fl_Choice(265, 485, 70, 20); + { cv_code_choice_w = new Fl_Choice(265, 485, 90, 20); cv_code_choice_w->down_box(FL_BORDER_BOX); cv_code_choice_w->labelsize(11); cv_code_choice_w->textsize(11); diff --git a/fluid/panels/codeview_panel.fl b/fluid/panels/codeview_panel.fl index 77774848f..0bd010615 100644 --- a/fluid/panels/codeview_panel.fl +++ b/fluid/panels/codeview_panel.fl @@ -78,24 +78,24 @@ file.} open return_type void if (cv_source->visible_r()) { switch (cv_code_choice) { case 0: // prolog: not yet (include statements) - pos0 = Fluid.proj.tree.current->code1.start; - pos1 = Fluid.proj.tree.current->code2.end; + pos0 = Fluid.proj.tree.current->setup_node.c.start; + pos1 = Fluid.proj.tree.current->finalize_node.c.end; break; case 1: // static: callbacks, menu declarations - pos0 = Fluid.proj.tree.current->code_static.start; - pos1 = Fluid.proj.tree.current->code_static.end; + pos0 = Fluid.proj.tree.current->static_data.c.start; + pos1 = Fluid.proj.tree.current->static_data.c.end; break; case 2: // code: entire implementation block including children - pos0 = Fluid.proj.tree.current->code1.start; - pos1 = Fluid.proj.tree.current->code2.end; + pos0 = Fluid.proj.tree.current->setup_node.c.start; + pos1 = Fluid.proj.tree.current->finalize_node.c.end; break; case 3: // code1: all implementation code before the children - pos0 = Fluid.proj.tree.current->code1.start; - pos1 = Fluid.proj.tree.current->code1.end; + pos0 = Fluid.proj.tree.current->setup_node.c.start; + pos1 = Fluid.proj.tree.current->setup_node.c.end; break; case 4: // code1: all implementation code before the children - pos0 = Fluid.proj.tree.current->code2.start; - pos1 = Fluid.proj.tree.current->code2.end; + pos0 = Fluid.proj.tree.current->finalize_node.c.start; + pos1 = Fluid.proj.tree.current->finalize_node.c.end; break; } if (pos0>=0) { @@ -110,20 +110,20 @@ file.} open return_type void switch (cv_code_choice) { case 0: // prolog: not yet (include statements) case 1: // static: callbacks, menu declarations - pos0 = Fluid.proj.tree.current->header_static.start; - pos1 = Fluid.proj.tree.current->header_static.end; + pos0 = Fluid.proj.tree.current->static_data.h.start; + pos1 = Fluid.proj.tree.current->static_data.h.end; break; case 2: // code: entire implementation block including children - pos0 = Fluid.proj.tree.current->header1.start; - pos1 = Fluid.proj.tree.current->header2.end; + pos0 = Fluid.proj.tree.current->setup_node.h.start; + pos1 = Fluid.proj.tree.current->finalize_node.h.end; break; case 3: // code1: all implementation code before the children - pos0 = Fluid.proj.tree.current->header1.start; - pos1 = Fluid.proj.tree.current->header1.end; + pos0 = Fluid.proj.tree.current->setup_node.h.start; + pos1 = Fluid.proj.tree.current->setup_node.h.end; break; case 4: // code1: all implementation code before the children - pos0 = Fluid.proj.tree.current->header2.start; - pos1 = Fluid.proj.tree.current->header2.end; + pos0 = Fluid.proj.tree.current->finalize_node.h.start; + pos1 = Fluid.proj.tree.current->finalize_node.h.end; break; } if (pos0>=0) { @@ -224,8 +224,7 @@ if (cv_project->visible_r()) { } if (Fluid.proj.proj_filename) Fluid.proj.leave_project_dir(); -}} {selected - } +}} {} } Function {update_codeview_timer(void*)} { @@ -281,8 +280,8 @@ Function {make_codeview()} {open } { Fl_Window codeview_panel { label {Code View} - callback toggle_codeview_cb open - xywh {389 507 520 515} type Double align 80 resizable size_range {384 120 0 0} visible + callback toggle_codeview_cb open selected + xywh {518 271 520 515} type Double align 80 resizable size_range {384 120 0 0} visible } { Fl_Tabs cv_tab { callback update_codeview_position_cb open @@ -461,7 +460,7 @@ if (e) { Fl_Choice cv_code_choice_w { callback {cv_code_choice = (int)o->mvalue()->argument(); update_codeview_position();} open - xywh {265 485 70 20} down_box BORDER_BOX labelsize 11 textsize 11 + xywh {265 485 90 20} down_box BORDER_BOX labelsize 11 textsize 11 } { MenuItem {} { label prolog @@ -469,22 +468,22 @@ update_codeview_position();} open tooltip {Include statements in header or source code} xywh {0 0 100 20} labelsize 11 hide } MenuItem {} { - label static + label {static data} user_data 1 user_data_type long tooltip {static declarations in source code} xywh {10 10 100 20} labelsize 11 } MenuItem {} { - label code + label instantiate user_data 2 user_data_type long tooltip {widget code block including children} xywh {20 20 100 20} labelsize 11 } MenuItem {} { - label {code 1} + label setup user_data 3 user_data_type long tooltip {widget code block before children} xywh {30 30 100 20} labelsize 11 } MenuItem {} { - label {code 2} + label finalize user_data 4 user_data_type long tooltip {widget code block after children} xywh {40 40 100 20} labelsize 11 } diff --git a/fluid/panels/codeview_panel.h b/fluid/panels/codeview_panel.h index b4f96da4f..bf01eab20 100644 --- a/fluid/panels/codeview_panel.h +++ b/fluid/panels/codeview_panel.h @@ -54,6 +54,6 @@ extern Fl_Choice* cv_code_choice_w; extern void toggle_codeview_b_cb(Fl_Button*, void*); Fl_Double_Window* make_codeview(); extern Fl_Menu_Item menu_cv_code_choice_w[]; -#endif +#endif // codeview_panel_h // diff --git a/fluid/panels/widget_panel.h b/fluid/panels/widget_panel.h index 8321a3873..6060c86f3 100644 --- a/fluid/panels/widget_panel.h +++ b/fluid/panels/widget_panel.h @@ -151,4 +151,4 @@ extern Fl_Menu_Item menu_9[]; extern Fl_Menu_Item menu_a[]; extern Fl_Menu_Item menu_b[]; extern Fl_Menu_Item menu_c[]; -#endif +#endif // widget_panel_h