summaryrefslogtreecommitdiff
path: root/fluid/nodes
diff options
context:
space:
mode:
authorMatthias Melcher <github@matthiasm.com>2025-03-16 17:16:12 -0400
committerGitHub <noreply@github.com>2025-03-16 17:16:12 -0400
commit51a55bc73660f64e8f4b32b8b4d3858f2a786f7b (patch)
tree122ad9f838fcf8f61ed7cf5fa031e8ed69817e10 /fluid/nodes
parent13a7073a1e007ce5b71ef70bced1a9b15158820d (diff)
Fluid: restructuring and rejuvenation of the source code.
* Add classes for application and project * Removed all globals from Fluid.h * Extracting args and project history into their own classes * Moving globals into Application class * Initialize values inside headers for some classes. * Undo functionality wrapped in a class inside Project. * File reader and writer are now linked to a project. * Avoid global project access * Nodes (former Types) will be managed by a new Tree class. * Removed static members (hidden globals) form Node/Fl_Type. * Adding Tree iterator. * Use nullptr instead of 0, NULL, or 0L * Renamed Fl_..._Type to ..._Node, FL_OVERRIDE -> override * Renaming ..._type to ...::prototype * Splitting Widget Panel into multiple files. * Moved callback code into widget panel file. * Cleaning up Fluid_Image -> Image_asset * Moving Fd_Snap_Action into new namespace fld::app::Snap_Action etc. * Moved mergeback into proj folder. * `enum ID` is now `enum class Type`.
Diffstat (limited to 'fluid/nodes')
-rw-r--r--fluid/nodes/Button_Node.cxx166
-rw-r--r--fluid/nodes/Button_Node.h149
-rw-r--r--fluid/nodes/Fl_Button_Type.cxx227
-rw-r--r--fluid/nodes/Fl_Button_Type.h46
-rw-r--r--fluid/nodes/Fl_Function_Type.h259
-rw-r--r--fluid/nodes/Fl_Grid_Type.h82
-rw-r--r--fluid/nodes/Fl_Group_Type.h242
-rw-r--r--fluid/nodes/Fl_Menu_Type.h287
-rw-r--r--fluid/nodes/Fl_Widget_Type.cxx3939
-rw-r--r--fluid/nodes/Fl_Window_Type.h157
-rw-r--r--fluid/nodes/Function_Node.cxx (renamed from fluid/nodes/Fl_Function_Type.cxx)489
-rw-r--r--fluid/nodes/Function_Node.h277
-rw-r--r--fluid/nodes/Grid_Node.cxx (renamed from fluid/nodes/Fl_Grid_Type.cxx)333
-rw-r--r--fluid/nodes/Grid_Node.h82
-rw-r--r--fluid/nodes/Group_Node.cxx (renamed from fluid/nodes/Fl_Group_Type.cxx)334
-rw-r--r--fluid/nodes/Group_Node.h261
-rw-r--r--fluid/nodes/Menu_Node.cxx (renamed from fluid/nodes/Fl_Menu_Type.cxx)384
-rw-r--r--fluid/nodes/Menu_Node.h310
-rw-r--r--fluid/nodes/Node.cxx (renamed from fluid/nodes/Fl_Type.cxx)596
-rw-r--r--fluid/nodes/Node.h (renamed from fluid/nodes/Fl_Type.h)156
-rw-r--r--fluid/nodes/Tree.cxx128
-rw-r--r--fluid/nodes/Tree.h106
-rw-r--r--fluid/nodes/Widget_Node.cxx2438
-rw-r--r--fluid/nodes/Widget_Node.h (renamed from fluid/nodes/Fl_Widget_Type.h)85
-rw-r--r--fluid/nodes/Window_Node.cxx (renamed from fluid/nodes/Fl_Window_Type.cxx)575
-rw-r--r--fluid/nodes/Window_Node.h163
-rw-r--r--fluid/nodes/callbacks.cxx18
-rw-r--r--fluid/nodes/callbacks.h23
-rw-r--r--fluid/nodes/factory.cxx1286
-rw-r--r--fluid/nodes/factory.h18
30 files changed, 6088 insertions, 7528 deletions
diff --git a/fluid/nodes/Button_Node.cxx b/fluid/nodes/Button_Node.cxx
new file mode 100644
index 000000000..c1ac26e95
--- /dev/null
+++ b/fluid/nodes/Button_Node.cxx
@@ -0,0 +1,166 @@
+//
+// Button Node code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2025 by Bill Spitzak and others.
+//
+// This library is free software. Distribution and use rights are outlined in
+// the file "COPYING" which should have been included with this file. If this
+// file is missing or damaged, see the license at:
+//
+// https://www.fltk.org/COPYING.php
+//
+// Please see the following page on how to report bugs and issues:
+//
+// https://www.fltk.org/bugs.php
+//
+
+/**
+ \file Bottun_Node.cxx
+
+ Node prototypes for Fl_Button based classes. Those are used by the Node
+ Factory to generate the scene from project files or user input.
+ */
+
+#include "nodes/Button_Node.h"
+
+#include "Fluid.h"
+#include "app/Snap_Action.h"
+#include "io/Project_Reader.h"
+#include "io/Project_Writer.h"
+
+#include <FL/Fl.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Check_Button.H>
+#include <FL/Fl_Menu_Item.H>
+#include <FL/Fl_Return_Button.H>
+#include <FL/Fl_Repeat_Button.H>
+#include <FL/Fl_Round_Button.H>
+
+#include <stdlib.h>
+
+// ---- Button Nodes --------------------------------------------------- MARK: -
+
+
+// ---- Button ----
+
+Button_Node Button_Node::prototype;
+
+static Fl_Menu_Item buttontype_menu[] = {
+ {"Normal", 0, nullptr, (void*)nullptr},
+ {"Toggle", 0, nullptr, (void*)FL_TOGGLE_BUTTON},
+ {"Radio", 0, nullptr, (void*)FL_RADIO_BUTTON},
+ {nullptr}
+};
+
+Fl_Menu_Item *Button_Node::subtypes() {
+ return buttontype_menu;
+}
+
+void Button_Node::ideal_size(int &w, int &h) {
+ auto layout = Fluid.proj.layout;
+ h = layout->labelsize + 8;
+ w = layout->labelsize * 4 + 8;
+ fld::app::Snap_Action::better_size(w, h);
+}
+
+Fl_Widget *Button_Node::widget(int x, int y, int w, int h) {
+ return new Fl_Button(x, y, w, h, "Button");
+}
+
+void Button_Node::write_properties(fld::io::Project_Writer &f) {
+ Widget_Node::write_properties(f);
+ Fl_Button *btn = (Fl_Button*)o;
+ if (btn->compact()) {
+ f.write_string("compact");
+ f.write_string("%d", btn->compact());
+ }
+}
+
+void Button_Node::read_property(fld::io::Project_Reader &f, const char *c) {
+ Fl_Button *btn = (Fl_Button*)o;
+ if (!strcmp(c, "compact")) {
+ btn->compact((uchar)atol(f.read_word()));
+ } else {
+ Widget_Node::read_property(f, c);
+ }
+}
+
+void Button_Node::copy_properties() {
+ Widget_Node::copy_properties();
+ Fl_Button *s = (Fl_Button*)o, *d = (Fl_Button*)live_widget;
+ d->compact(s->compact());
+}
+
+
+// ---- Return Button ----
+
+void Return_Button_Node::ideal_size(int &w, int &h) {
+ auto layout = Fluid.proj.layout;
+ h = layout->labelsize + 8;
+ w = layout->labelsize * 4 + 8 + h; // make room for the symbol
+ fld::app::Snap_Action::better_size(w, h);
+}
+
+Fl_Widget *Return_Button_Node::widget(int x, int y, int w, int h) {
+ return new Fl_Return_Button(x, y, w, h, "Button");
+}
+
+Return_Button_Node Return_Button_Node::prototype;
+
+
+// ---- Repeat Button ----
+
+Fl_Widget *Repeat_Button_Node::widget(int x, int y, int w, int h) {
+ return new Fl_Repeat_Button(x, y, w, h, "Button");
+}
+
+Repeat_Button_Node Repeat_Button_Node::prototype;
+
+
+// ---- Light Button ----
+
+void Light_Button_Node::ideal_size(int &w, int &h) {
+ auto layout = Fluid.proj.layout;
+ h = layout->labelsize + 8;
+ w = layout->labelsize * 4 + 8 + layout->labelsize; // make room for the light
+ fld::app::Snap_Action::better_size(w, h);
+}
+
+Fl_Widget *Light_Button_Node::widget(int x, int y, int w, int h) {
+ return new Fl_Light_Button(x, y, w, h, "Button");
+}
+
+Light_Button_Node Light_Button_Node::prototype;
+
+
+// ---- Check Button ----
+
+void Check_Button_Node::ideal_size(int &w, int &h) {
+ auto layout = Fluid.proj.layout;
+ h = layout->labelsize + 8;
+ w = layout->labelsize * 4 + 8 + layout->labelsize; // make room for the symbol
+ fld::app::Snap_Action::better_size(w, h);
+}
+
+Fl_Widget *Check_Button_Node::widget(int x, int y, int w, int h) {
+ return new Fl_Check_Button(x, y, w, h, "Button");
+}
+
+Check_Button_Node Check_Button_Node::prototype;
+
+
+// ---- Round Button ----
+
+void Round_Button_Node::ideal_size(int &w, int &h) {
+ auto layout = Fluid.proj.layout;
+ h = layout->labelsize + 8;
+ w = layout->labelsize * 4 + 8 + layout->labelsize; // make room for the symbol
+ fld::app::Snap_Action::better_size(w, h);
+}
+
+Fl_Widget *Round_Button_Node::widget(int x, int y, int w, int h) {
+ return new Fl_Round_Button(x, y, w, h, "Button");
+}
+
+Round_Button_Node Round_Button_Node::prototype;
+
diff --git a/fluid/nodes/Button_Node.h b/fluid/nodes/Button_Node.h
new file mode 100644
index 000000000..ecdc8cc24
--- /dev/null
+++ b/fluid/nodes/Button_Node.h
@@ -0,0 +1,149 @@
+//
+// Button Node header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2025 by Bill Spitzak and others.
+//
+// This library is free software. Distribution and use rights are outlined in
+// the file "COPYING" which should have been included with this file. If this
+// file is missing or damaged, see the license at:
+//
+// https://www.fltk.org/COPYING.php
+//
+// Please see the following page on how to report bugs and issues:
+//
+// https://www.fltk.org/bugs.php
+//
+
+#ifndef FLUID_NODES_BUTTON_NODE_H
+#define FLUID_NODES_BUTTON_NODE_H
+
+#include "nodes/Widget_Node.h"
+
+/**
+ \brief A handler for the simple push button and a base class for all other buttons.
+ */
+class Button_Node : public Widget_Node
+{
+public:
+ typedef Widget_Node super;
+ static Button_Node prototype;
+private:
+ Fl_Menu_Item *subtypes() override;
+public:
+ void ideal_size(int &w, int &h) override;
+ const char *type_name() override { return "Fl_Button"; }
+ const char *alt_type_name() override { return "fltk::Button"; }
+ Fl_Widget *widget(int x, int y, int w, int h) override;
+ Widget_Node *_make() override { return new Button_Node(); }
+ int is_button() const override { return 1; }
+ Type type() const override { return Type::Button; }
+ bool is_a(Type inType) const override { return (inType==Type::Button) ? true : super::is_a(inType); }
+ void write_properties(fld::io::Project_Writer &f) override;
+ void read_property(fld::io::Project_Reader &f, const char *) override;
+ void copy_properties() override;
+};
+
+// ---- Return Button ----
+
+/**
+ \brief The Return Button is simply a Button with the return key as a hotkey.
+ */
+class Return_Button_Node : public Button_Node
+{
+public:
+ typedef Button_Node super;
+ static Return_Button_Node prototype;
+public:
+ void ideal_size(int &w, int &h) override;
+ const char *type_name() override { return "Fl_Return_Button"; }
+ const char *alt_type_name() override { return "fltk::ReturnButton"; }
+ Fl_Widget *widget(int x, int y, int w, int h) override;
+ Widget_Node *_make() override { return new Return_Button_Node(); }
+ Type type() const override { return Type::Return_Button; }
+ bool is_a(Type inType) const override { return (inType==Type::Return_Button) ? true : super::is_a(inType); }
+};
+
+// ---- Repeat Button ----
+
+/**
+ \brief Handler for Fl_Repeat_Button.
+ \note Even though Fl_Repeat_Button is somewhat limited compared to Fl_Button,
+ and some settings may not make much sense, it is still derived from it,
+ so the wrapper should be as well.
+ */
+class Repeat_Button_Node : public Button_Node
+{
+public:
+ typedef Button_Node super;
+ static Repeat_Button_Node prototype;
+public:
+ const char *type_name() override { return "Fl_Repeat_Button"; }
+ const char *alt_type_name() override { return "fltk::RepeatButton"; }
+ Fl_Widget *widget(int x, int y, int w, int h) override;
+ Widget_Node *_make() override { return new Repeat_Button_Node(); }
+ Type type() const override { return Type::Repeat_Button; }
+ bool is_a(Type inType) const override { return (inType==Type::Repeat_Button) ? true : super::is_a(inType); }
+};
+
+// ---- Light Button ----
+
+/**
+ \brief A handler for a toggle button with an indicator light.
+ */
+class Light_Button_Node : public Button_Node
+{
+public:
+ typedef Button_Node super;
+ static Light_Button_Node prototype;
+public:
+ void ideal_size(int &w, int &h) override;
+ const char *type_name() override { return "Fl_Light_Button"; }
+ const char *alt_type_name() override { return "fltk::LightButton"; }
+ Fl_Widget *widget(int x, int y, int w, int h) override;
+ Widget_Node *_make() override { return new Light_Button_Node(); }
+ Type type() const override { return Type::Light_Button; }
+ bool is_a(Type inType) const override { return (inType==Type::Light_Button) ? true : super::is_a(inType); }
+};
+
+// ---- Check Button ----
+
+/**
+ \brief Manage buttons with a check mark on its left.
+ */
+class Check_Button_Node : public Button_Node
+{
+public:
+ typedef Button_Node super;
+ static Check_Button_Node prototype;
+public:
+ void ideal_size(int &w, int &h) override;
+ const char *type_name() override { return "Fl_Check_Button"; }
+ const char *alt_type_name() override { return "fltk::CheckButton"; }
+ Fl_Widget *widget(int x, int y, int w, int h) override;
+ Widget_Node *_make() override { return new Check_Button_Node(); }
+ Type type() const override { return Type::Check_Button; }
+ bool is_a(Type inType) const override { return (inType==Type::Check_Button) ? true : super::is_a(inType); }
+};
+
+// ---- Round Button ----
+
+/**
+ \brief Manage buttons with a round indicator on its left.
+ */
+class Round_Button_Node : public Button_Node
+{
+public:
+ typedef Button_Node super;
+ static Round_Button_Node prototype;
+public:
+ void ideal_size(int &w, int &h) override;
+ const char *type_name() override { return "Fl_Round_Button"; }
+ const char *alt_type_name() override { return "fltk::RadioButton"; }
+ Fl_Widget *widget(int x, int y, int w, int h) override;
+ Widget_Node *_make() override { return new Round_Button_Node(); }
+ Type type() const override { return Type::Round_Button; }
+ bool is_a(Type inType) const override { return (inType==Type::Round_Button) ? true : super::is_a(inType); }
+};
+
+
+#endif // FLUID_NODES_BUTTON_NODE_H
diff --git a/fluid/nodes/Fl_Button_Type.cxx b/fluid/nodes/Fl_Button_Type.cxx
deleted file mode 100644
index 2d3b7f31f..000000000
--- a/fluid/nodes/Fl_Button_Type.cxx
+++ /dev/null
@@ -1,227 +0,0 @@
-//
-// Button type factory code for the Fast Light Tool Kit (FLTK).
-//
-// Type classes for most of the fltk widgets. Most of the work
-// is done by code in Fl_Widget_Type.C. Also a factory instance
-// of each of these type classes.
-//
-// This file also contains the "new" menu, which has a pointer
-// to a factory instance for every class (both the ones defined
-// here and ones in other files)
-//
-// Copyright 1998-2023 by Bill Spitzak and others.
-//
-// This library is free software. Distribution and use rights are outlined in
-// the file "COPYING" which should have been included with this file. If this
-// file is missing or damaged, see the license at:
-//
-// https://www.fltk.org/COPYING.php
-//
-// Please see the following page on how to report bugs and issues:
-//
-// https://www.fltk.org/bugs.php
-//
-
-#include "nodes/Fl_Button_Type.h"
-
-#include "app/Fd_Snap_Action.h"
-#include "io/Project_Reader.h"
-#include "io/Project_Writer.h"
-
-#include <FL/Fl.H>
-#include <FL/Fl_Button.H>
-#include <FL/Fl_Check_Button.H>
-#include <FL/Fl_Menu_Item.H>
-#include <FL/Fl_Return_Button.H>
-#include <FL/Fl_Repeat_Button.H>
-#include <FL/Fl_Round_Button.H>
-
-#include <stdlib.h>
-
-
-
-// ---- Button Types --------------------------------------------------- MARK: -
-
-
-// ---- Button ----
-
-static Fl_Menu_Item buttontype_menu[] = {
- {"Normal", 0, 0, (void*)0},
- {"Toggle", 0, 0, (void*)FL_TOGGLE_BUTTON},
- {"Radio", 0, 0, (void*)FL_RADIO_BUTTON},
- {0}
-};
-
-Fl_Menu_Item *Fl_Button_Type::subtypes() {
- return buttontype_menu;
-}
-
-void Fl_Button_Type::ideal_size(int &w, int &h) {
- h = layout->labelsize + 8;
- w = layout->labelsize * 4 + 8;
- Fd_Snap_Action::better_size(w, h);
-}
-
-Fl_Widget *Fl_Button_Type::widget(int x, int y, int w, int h) {
- return new Fl_Button(x, y, w, h, "Button");
-}
-
-void Fl_Button_Type::write_properties(fld::io::Project_Writer &f) {
- Fl_Widget_Type::write_properties(f);
- Fl_Button *btn = (Fl_Button*)o;
- if (btn->compact()) {
- f.write_string("compact");
- f.write_string("%d", btn->compact());
- }
-}
-
-void Fl_Button_Type::read_property(fld::io::Project_Reader &f, const char *c) {
- Fl_Button *btn = (Fl_Button*)o;
- if (!strcmp(c, "compact")) {
- btn->compact((uchar)atol(f.read_word()));
- } else {
- Fl_Widget_Type::read_property(f, c);
- }
-}
-
-void Fl_Button_Type::copy_properties() {
- Fl_Widget_Type::copy_properties();
- Fl_Button *s = (Fl_Button*)o, *d = (Fl_Button*)live_widget;
- d->compact(s->compact());
-}
-
-Fl_Button_Type Fl_Button_type;
-
-
-// ---- Return Button ----
-
-/**
- \brief The Return Button is simply a Button with the return key as a hotkey.
- */
-class Fl_Return_Button_Type : public Fl_Button_Type
-{
- typedef Fl_Button_Type super;
-public:
- void ideal_size(int &w, int &h) FL_OVERRIDE {
- h = layout->labelsize + 8;
- w = layout->labelsize * 4 + 8 + h; // make room for the symbol
- Fd_Snap_Action::better_size(w, h);
- }
- const char *type_name() FL_OVERRIDE { return "Fl_Return_Button"; }
- const char *alt_type_name() FL_OVERRIDE { return "fltk::ReturnButton"; }
- Fl_Widget *widget(int x, int y, int w, int h) FL_OVERRIDE {
- return new Fl_Return_Button(x, y, w, h, "Button");
- }
- Fl_Widget_Type *_make() FL_OVERRIDE { return new Fl_Return_Button_Type(); }
- ID id() const FL_OVERRIDE { return ID_Return_Button; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Return_Button) ? true : super::is_a(inID); }
-};
-
-Fl_Return_Button_Type Fl_Return_Button_type;
-
-
-// ---- Repeat Button ----
-
-/**
- \brief Handler for Fl_Repeat_Button.
- \note Even though Fl_Repeat_Button is somewhat limited compared to Fl_Button,
- and some settings may not make much sense, it is still derived from it,
- so the wrapper should be as well.
- */
-class Fl_Repeat_Button_Type : public Fl_Button_Type
-{
- typedef Fl_Button_Type super;
-public:
- const char *type_name() FL_OVERRIDE { return "Fl_Repeat_Button"; }
- const char *alt_type_name() FL_OVERRIDE { return "fltk::RepeatButton"; }
- Fl_Widget *widget(int x, int y, int w, int h) FL_OVERRIDE {
- return new Fl_Repeat_Button(x, y, w, h, "Button");
- }
- Fl_Widget_Type *_make() FL_OVERRIDE { return new Fl_Repeat_Button_Type(); }
- ID id() const FL_OVERRIDE { return ID_Repeat_Button; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Repeat_Button) ? true : super::is_a(inID); }
-};
-
-Fl_Repeat_Button_Type Fl_Repeat_Button_type;
-
-
-// ---- Light Button ----
-
-/**
- \brief A handler for a toggle button with an indicator light.
- */
-class Fl_Light_Button_Type : public Fl_Button_Type
-{
- typedef Fl_Button_Type super;
-public:
- void ideal_size(int &w, int &h) FL_OVERRIDE {
- h = layout->labelsize + 8;
- w = layout->labelsize * 4 + 8 + layout->labelsize; // make room for the light
- Fd_Snap_Action::better_size(w, h);
- }
- const char *type_name() FL_OVERRIDE { return "Fl_Light_Button"; }
- const char *alt_type_name() FL_OVERRIDE { return "fltk::LightButton"; }
- Fl_Widget *widget(int x, int y, int w, int h) FL_OVERRIDE {
- return new Fl_Light_Button(x, y, w, h, "Button");
- }
- Fl_Widget_Type *_make() FL_OVERRIDE { return new Fl_Light_Button_Type(); }
- ID id() const FL_OVERRIDE { return ID_Light_Button; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Light_Button) ? true : super::is_a(inID); }
-};
-
-Fl_Light_Button_Type Fl_Light_Button_type;
-
-
-// ---- Check Button ----
-
-/**
- \brief Manage buttons with a check mark on its left.
- */
-class Fl_Check_Button_Type : public Fl_Button_Type
-{
- typedef Fl_Button_Type super;
-public:
- void ideal_size(int &w, int &h) FL_OVERRIDE {
- h = layout->labelsize + 8;
- w = layout->labelsize * 4 + 8 + layout->labelsize; // make room for the symbol
- Fd_Snap_Action::better_size(w, h);
- }
- const char *type_name() FL_OVERRIDE { return "Fl_Check_Button"; }
- const char *alt_type_name() FL_OVERRIDE { return "fltk::CheckButton"; }
- Fl_Widget *widget(int x, int y, int w, int h) FL_OVERRIDE {
- return new Fl_Check_Button(x, y, w, h, "Button");
- }
- Fl_Widget_Type *_make() FL_OVERRIDE { return new Fl_Check_Button_Type(); }
- ID id() const FL_OVERRIDE { return ID_Check_Button; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Check_Button) ? true : super::is_a(inID); }
-};
-
-Fl_Check_Button_Type Fl_Check_Button_type;
-
-
-// ---- Round Button ----
-
-/**
- \brief Manage buttons with a round indicator on its left.
- */
-class Fl_Round_Button_Type : public Fl_Button_Type
-{
- typedef Fl_Button_Type super;
-public:
- void ideal_size(int &w, int &h) FL_OVERRIDE {
- h = layout->labelsize + 8;
- w = layout->labelsize * 4 + 8 + layout->labelsize; // make room for the symbol
- Fd_Snap_Action::better_size(w, h);
- }
- const char *type_name() FL_OVERRIDE { return "Fl_Round_Button"; }
- const char *alt_type_name() FL_OVERRIDE { return "fltk::RadioButton"; }
- Fl_Widget *widget(int x, int y, int w, int h) FL_OVERRIDE {
- return new Fl_Round_Button(x, y, w, h, "Button");
- }
- Fl_Widget_Type *_make() FL_OVERRIDE { return new Fl_Round_Button_Type(); }
- ID id() const FL_OVERRIDE { return ID_Round_Button; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Round_Button) ? true : super::is_a(inID); }
-};
-
-Fl_Round_Button_Type Fl_Round_Button_type;
-
diff --git a/fluid/nodes/Fl_Button_Type.h b/fluid/nodes/Fl_Button_Type.h
deleted file mode 100644
index 4229ac82d..000000000
--- a/fluid/nodes/Fl_Button_Type.h
+++ /dev/null
@@ -1,46 +0,0 @@
-//
-// Button type header file for the Fast Light Tool Kit (FLTK).
-//
-// Copyright 1998-2023 by Bill Spitzak and others.
-//
-// This library is free software. Distribution and use rights are outlined in
-// the file "COPYING" which should have been included with this file. If this
-// file is missing or damaged, see the license at:
-//
-// https://www.fltk.org/COPYING.php
-//
-// Please see the following page on how to report bugs and issues:
-//
-// https://www.fltk.org/bugs.php
-//
-
-#ifndef _FL_BUTTON_TYPE_H
-#define _FL_BUTTON_TYPE_H
-
-#include "nodes/Fl_Widget_Type.h"
-
-/**
- \brief A handler for the simple push button and a base class for all other buttons.
- */
-class Fl_Button_Type : public Fl_Widget_Type
-{
- typedef Fl_Widget_Type super;
- Fl_Menu_Item *subtypes() FL_OVERRIDE;
-public:
- void ideal_size(int &w, int &h) FL_OVERRIDE;
- const char *type_name() FL_OVERRIDE { return "Fl_Button"; }
- const char *alt_type_name() FL_OVERRIDE { return "fltk::Button"; }
- Fl_Widget *widget(int x, int y, int w, int h) FL_OVERRIDE;
- Fl_Widget_Type *_make() FL_OVERRIDE { return new Fl_Button_Type(); }
- int is_button() const FL_OVERRIDE { return 1; }
- ID id() const FL_OVERRIDE { return ID_Button; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Button) ? true : super::is_a(inID); }
- void write_properties(fld::io::Project_Writer &f) FL_OVERRIDE;
- void read_property(fld::io::Project_Reader &f, const char *) FL_OVERRIDE;
- void copy_properties() FL_OVERRIDE;
-};
-
-extern Fl_Button_Type Fl_Button_type;
-
-
-#endif // _FL_BUTTON_TYPE_H
diff --git a/fluid/nodes/Fl_Function_Type.h b/fluid/nodes/Fl_Function_Type.h
deleted file mode 100644
index 4c2319aee..000000000
--- a/fluid/nodes/Fl_Function_Type.h
+++ /dev/null
@@ -1,259 +0,0 @@
-//
-// C function type header file for the Fast Light Tool Kit (FLTK).
-//
-// Copyright 1998-2021 by Bill Spitzak and others.
-//
-// This library is free software. Distribution and use rights are outlined in
-// the file "COPYING" which should have been included with this file. If this
-// file is missing or damaged, see the license at:
-//
-// https://www.fltk.org/COPYING.php
-//
-// Please see the following page on how to report bugs and issues:
-//
-// https://www.fltk.org/bugs.php
-//
-
-#ifndef _FLUID_FL_FUNCTION_TYPE_H
-#define _FLUID_FL_FUNCTION_TYPE_H
-
-#include "nodes/Fl_Type.h"
-
-#include "app/Fluid_Image.h"
-#ifdef _WIN32
-#include "tools/ExternalCodeEditor_WIN32.h"
-#else
-#include "tools/ExternalCodeEditor_UNIX.h"
-#endif
-
-#include <FL/Fl_Widget.H>
-#include <FL/Fl_Menu.H>
-#include <FL/fl_draw.H>
-#include <FL/fl_attr.h>
-
-#include <stdarg.h>
-#include <stdlib.h>
-
-extern class Fl_Class_Type *current_class;
-
-int has_toplevel_function(const char *rtype, const char *sig);
-
-const char *c_check(const char *c, int type = 0);
-
-// ---- Fl_Function_Type declaration
-
-class Fl_Function_Type : public Fl_Type
-{
- typedef Fl_Type super;
- const char* return_type;
- char public_, cdecl_, constructor, havewidgets;
-
-public:
- Fl_Function_Type();
- ~Fl_Function_Type();
- Fl_Type *make(Strategy strategy) FL_OVERRIDE;
- void write_code1(fld::io::Code_Writer& f) FL_OVERRIDE;
- void write_code2(fld::io::Code_Writer& f) FL_OVERRIDE;
- void open() FL_OVERRIDE;
- int ismain() {return name_ == 0;}
- const char *type_name() FL_OVERRIDE {return "Function";}
- const char *title() FL_OVERRIDE {
- return name() ? name() : "main()";
- }
- int can_have_children() const FL_OVERRIDE {return 1;}
- int is_code_block() const FL_OVERRIDE {return 1;}
- int is_public() const FL_OVERRIDE;
- ID id() const FL_OVERRIDE { return ID_Function; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Function) ? true : super::is_a(inID); }
- void write_properties(fld::io::Project_Writer &f) FL_OVERRIDE;
- void read_property(fld::io::Project_Reader &f, const char *) FL_OVERRIDE;
- int has_signature(const char *, const char*) const;
-};
-
-// ---- Fl_Code_Type declaration
-
-class Fl_Code_Type : public Fl_Type
-{
- typedef Fl_Type super;
- ExternalCodeEditor editor_;
- int cursor_position_;
- int code_input_scroll_row;
- int code_input_scroll_col;
-
-public:
- Fl_Code_Type();
- Fl_Type *make(Strategy strategy) FL_OVERRIDE;
- void write(fld::io::Project_Writer &f) FL_OVERRIDE;
- void write_code1(fld::io::Code_Writer& f) FL_OVERRIDE;
- void write_code2(fld::io::Code_Writer& f) FL_OVERRIDE { }
- void open() FL_OVERRIDE;
- const char *type_name() FL_OVERRIDE {return "code";}
- int is_code_block() const FL_OVERRIDE {return 0;}
- 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; }
- int is_editing();
- int reap_editor();
- int handle_editor_changes();
-};
-
-// ---- Fl_CodeBlock_Type declaration
-
-class Fl_CodeBlock_Type : public Fl_Type
-{
- typedef Fl_Type super;
- const char* after;
-
-public:
- Fl_CodeBlock_Type();
- ~Fl_CodeBlock_Type();
- Fl_Type *make(Strategy strategy) FL_OVERRIDE;
- void write_code1(fld::io::Code_Writer& f) FL_OVERRIDE;
- void write_code2(fld::io::Code_Writer& f) FL_OVERRIDE;
- void open() FL_OVERRIDE;
- const char *type_name() FL_OVERRIDE {return "codeblock";}
- int is_code_block() const FL_OVERRIDE {return 1;}
- int can_have_children() const FL_OVERRIDE {return 1;}
- int is_public() const FL_OVERRIDE { return -1; }
- ID id() const FL_OVERRIDE { return ID_CodeBlock; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_CodeBlock) ? true : super::is_a(inID); }
- void write_properties(fld::io::Project_Writer &f) FL_OVERRIDE;
- void read_property(fld::io::Project_Reader &f, const char *) FL_OVERRIDE;
-};
-
-// ---- Fl_Decl_Type declaration
-
-class Fl_Decl_Type : public Fl_Type
-{
- typedef Fl_Type super;
-
-protected:
- char public_;
- char static_;
-
-public:
- Fl_Decl_Type();
- Fl_Type *make(Strategy strategy) FL_OVERRIDE;
- void write_code1(fld::io::Code_Writer& f) FL_OVERRIDE;
- void write_code2(fld::io::Code_Writer& f) FL_OVERRIDE { }
- void open() FL_OVERRIDE;
- const char *type_name() FL_OVERRIDE {return "decl";}
- void write_properties(fld::io::Project_Writer &f) FL_OVERRIDE;
- void read_property(fld::io::Project_Reader &f, const char *) FL_OVERRIDE;
- int is_public() const FL_OVERRIDE;
- ID id() const FL_OVERRIDE { return ID_Decl; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Decl) ? true : super::is_a(inID); }
-};
-
-// ---- Fl_Data_Type declaration
-
-class Fl_Data_Type : public Fl_Decl_Type
-{
- typedef Fl_Decl_Type super;
- const char *filename_;
- int text_mode_;
-
-public:
- Fl_Data_Type();
- ~Fl_Data_Type();
- Fl_Type *make(Strategy strategy) FL_OVERRIDE;
- void write_code1(fld::io::Code_Writer& f) FL_OVERRIDE;
- void write_code2(fld::io::Code_Writer& f) FL_OVERRIDE {}
- void open() FL_OVERRIDE;
- const char *type_name() FL_OVERRIDE {return "data";}
- void write_properties(fld::io::Project_Writer &f) FL_OVERRIDE;
- void read_property(fld::io::Project_Reader &f, const char *) FL_OVERRIDE;
- ID id() const FL_OVERRIDE { return ID_Data; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Data) ? true : super::is_a(inID); }
-};
-
-// ---- Fl_DeclBlock_Type declaration
-
-class Fl_DeclBlock_Type : public Fl_Type
-{
- typedef Fl_Type super;
- enum {
- CODE_IN_HEADER = 1,
- CODE_IN_SOURCE = 2,
- STATIC_IN_HEADER = 4,
- STATIC_IN_SOURCE = 8
- };
- const char* after; ///< code after all children of this block
- int write_map_; ///< see enum above
-
-public:
- Fl_DeclBlock_Type();
- ~Fl_DeclBlock_Type();
- Fl_Type *make(Strategy strategy) FL_OVERRIDE;
- void write_static(fld::io::Code_Writer& f) FL_OVERRIDE;
- void write_static_after(fld::io::Code_Writer& f) FL_OVERRIDE;
- void write_code1(fld::io::Code_Writer& f) FL_OVERRIDE;
- void write_code2(fld::io::Code_Writer& f) FL_OVERRIDE;
- void open() FL_OVERRIDE;
- const char *type_name() FL_OVERRIDE {return "declblock";}
- void write_properties(fld::io::Project_Writer &f) FL_OVERRIDE;
- void read_property(fld::io::Project_Reader &f, const char *) FL_OVERRIDE;
- int can_have_children() const FL_OVERRIDE {return 1;}
- int is_decl_block() const FL_OVERRIDE {return 1;}
- int is_public() const FL_OVERRIDE;
- ID id() const FL_OVERRIDE { return ID_DeclBlock; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_DeclBlock) ? true : super::is_a(inID); }
-};
-
-// ---- Fl_Comment_Type declaration
-
-class Fl_Comment_Type : public Fl_Type
-{
- typedef Fl_Type super;
- char in_c_, in_h_, style_;
-
-public:
- Fl_Comment_Type();
- Fl_Type *make(Strategy strategy) FL_OVERRIDE;
- void write_code1(fld::io::Code_Writer& f) FL_OVERRIDE;
- void write_code2(fld::io::Code_Writer& f) FL_OVERRIDE { }
- void open() FL_OVERRIDE;
- const char *type_name() FL_OVERRIDE {return "comment";}
- void write_properties(fld::io::Project_Writer &f) FL_OVERRIDE;
- void read_property(fld::io::Project_Reader &f, const char *) FL_OVERRIDE;
- int is_public() const FL_OVERRIDE { return 1; }
- ID id() const FL_OVERRIDE { return ID_Comment; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Comment) ? true : super::is_a(inID); }
-};
-
-// ---- Fl_Class_Type declaration
-
-class Fl_Class_Type : public Fl_Type
-{
- typedef Fl_Type super;
- const char* subclass_of;
- char public_;
- const char* class_prefix;
-
-public:
- Fl_Class_Type();
- ~Fl_Class_Type();
- // state variables for output:
- char write_public_state; // true when public: has been printed
- Fl_Class_Type* parent_class; // save class if nested
-//
- Fl_Type *make(Strategy strategy) FL_OVERRIDE;
- void write_code1(fld::io::Code_Writer& f) FL_OVERRIDE;
- void write_code2(fld::io::Code_Writer& f) FL_OVERRIDE;
- void open() FL_OVERRIDE;
- const char *type_name() FL_OVERRIDE {return "class";}
- int can_have_children() const FL_OVERRIDE {return 1;}
- int is_decl_block() const FL_OVERRIDE {return 1;}
- int is_class() const FL_OVERRIDE {return 1;}
- int is_public() const FL_OVERRIDE;
- ID id() const FL_OVERRIDE { return ID_Class; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Class) ? true : super::is_a(inID); }
- void write_properties(fld::io::Project_Writer &f) FL_OVERRIDE;
- void read_property(fld::io::Project_Reader &f, const char *) FL_OVERRIDE;
-
- // class prefix attribute access
- void prefix(const char* p);
- const char* prefix() const {return class_prefix;}
-};
-
-#endif // _FLUID_FL_FUNCTION_TYPE_H
diff --git a/fluid/nodes/Fl_Grid_Type.h b/fluid/nodes/Fl_Grid_Type.h
deleted file mode 100644
index 1ce5321c8..000000000
--- a/fluid/nodes/Fl_Grid_Type.h
+++ /dev/null
@@ -1,82 +0,0 @@
-//
-// Fl_Grid type header file for the Fast Light Tool Kit (FLTK).
-//
-// Copyright 2023 by Bill Spitzak and others.
-//
-// This library is free software. Distribution and use rights are outlined in
-// the file "COPYING" which should have been included with this file. If this
-// file is missing or damaged, see the license at:
-//
-// https://www.fltk.org/COPYING.php
-//
-// Please see the following page on how to report bugs and issues:
-//
-// https://www.fltk.org/bugs.php
-//
-
-#ifndef _FLUID_FL_GRID_TYPE_H
-#define _FLUID_FL_GRID_TYPE_H
-
-#include "nodes/Fl_Group_Type.h"
-#include <FL/Fl_Grid.H>
-
-// ---- Fl_Grid_Type --------------------------------------------------- MARK: -
-
-extern const char grid_type_name[];
-
-class Fl_Grid_Proxy : public Fl_Grid {
-protected:
- typedef struct { Fl_Widget *widget; Cell *cell; } Cell_Widget_Pair;
- Cell_Widget_Pair *transient_;
- int num_transient_;
- int cap_transient_;
- void transient_make_room_(int n);
- void transient_remove_(Fl_Widget *w);
-public:
- Fl_Grid_Proxy(int X,int Y,int W,int H);
- ~Fl_Grid_Proxy();
- void resize(int,int,int,int) FL_OVERRIDE;
- void draw() FL_OVERRIDE;
- void draw_overlay();
- void move_cell(Fl_Widget *child, int to_row, int to_col, int how = 0);
- Cell* any_cell(Fl_Widget *widget) const;
- Cell* transient_cell(Fl_Widget *widget) const;
- Cell* transient_widget(Fl_Widget *wi, int row, int col, int row_span, int col_span, Fl_Grid_Align align = FL_GRID_FILL);
- Cell* widget(Fl_Widget *wi, int row, int col, Fl_Grid_Align align = FL_GRID_FILL);
- Cell* widget(Fl_Widget *wi, int row, int col, int rowspan, int colspan, Fl_Grid_Align align = FL_GRID_FILL);
-};
-
-class Fl_Grid_Type : public Fl_Group_Type
-{
- typedef Fl_Group_Type super;
-public:
- Fl_Grid_Type();
- const char *type_name() FL_OVERRIDE {return grid_type_name;}
- const char *alt_type_name() FL_OVERRIDE {return "fltk::GridGroup";}
- Fl_Widget_Type *_make() FL_OVERRIDE { return new Fl_Grid_Type(); }
- Fl_Widget *widget(int X,int Y,int W,int H) FL_OVERRIDE;
- ID id() const FL_OVERRIDE { return ID_Grid; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Grid) ? true : super::is_a(inID); }
- void write_properties(fld::io::Project_Writer &f) FL_OVERRIDE;
- void read_property(fld::io::Project_Reader &f, const char *) FL_OVERRIDE;
- void write_parent_properties(fld::io::Project_Writer &f, Fl_Type *child, bool encapsulate) FL_OVERRIDE;
- void read_parent_property(fld::io::Project_Reader &f, Fl_Type *child, const char *property) FL_OVERRIDE;
- Fl_Widget *enter_live_mode(int top=0) FL_OVERRIDE;
- void leave_live_mode() FL_OVERRIDE;
- void copy_properties() FL_OVERRIDE;
- void copy_properties_for_children() FL_OVERRIDE;
- void write_code1(fld::io::Code_Writer& f) FL_OVERRIDE;
- void write_code2(fld::io::Code_Writer& f) FL_OVERRIDE;
- void add_child(Fl_Type*, Fl_Type*) FL_OVERRIDE;
- void move_child(Fl_Type*, Fl_Type*) FL_OVERRIDE;
- void remove_child(Fl_Type*) FL_OVERRIDE;
- void layout_widget() FL_OVERRIDE;
- void child_resized(Fl_Widget_Type *child);
- void insert_child_at(Fl_Widget *child, int x, int y);
- void insert_child_at_next_free_cell(Fl_Widget *child);
- void keyboard_move_child(Fl_Widget_Type*, int key);
-
- static class Fl_Grid *selected();
-};
-
-#endif // _FLUID_FL_GRID_TYPE_H
diff --git a/fluid/nodes/Fl_Group_Type.h b/fluid/nodes/Fl_Group_Type.h
deleted file mode 100644
index 30fab1d20..000000000
--- a/fluid/nodes/Fl_Group_Type.h
+++ /dev/null
@@ -1,242 +0,0 @@
-//
-// Group type header file for the Fast Light Tool Kit (FLTK).
-//
-// Copyright 1998-2023 by Bill Spitzak and others.
-//
-// This library is free software. Distribution and use rights are outlined in
-// the file "COPYING" which should have been included with this file. If this
-// file is missing or damaged, see the license at:
-//
-// https://www.fltk.org/COPYING.php
-//
-// Please see the following page on how to report bugs and issues:
-//
-// https://www.fltk.org/bugs.php
-//
-
-#ifndef _FLUID_FL_GROUP_TYPE_H
-#define _FLUID_FL_GROUP_TYPE_H
-
-#include "nodes/Fl_Widget_Type.h"
-
-#include <FL/Fl_Tabs.H>
-#include <FL/Fl_Pack.H>
-#include <FL/Fl_Flex.H>
-#include <FL/Fl_Wizard.H>
-
-void group_cb(Fl_Widget *, void *);
-void ungroup_cb(Fl_Widget *, void *);
-
-// ---- Fl_Group_Type -------------------------------------------------- MARK: -
-
-/**
- Proxy group to use in place of Fl_Group in the interactive window.
-
- In an interactive environment, groups should not automatically resize their
- children. This proxy disables the layout of children by default. Children
- layout propagation may be enable temporarily by incrementing `allow_layout`
- before resizing and decrementing it again afterwards.
- */
-class Fl_Group_Proxy : public Fl_Group {
-public:
- Fl_Group_Proxy(int X,int Y,int W,int H) : Fl_Group(X, Y, W, H) { Fl_Group::current(0); }
- void resize(int x, int y, int w, int h) FL_OVERRIDE;
- void draw() FL_OVERRIDE;
-};
-
-class Fl_Group_Type : public Fl_Widget_Type
-{
- typedef Fl_Widget_Type super;
-public:
- void ideal_size(int &w, int &h) FL_OVERRIDE;
- const char *type_name() FL_OVERRIDE {return "Fl_Group";}
- const char *alt_type_name() FL_OVERRIDE {return "fltk::Group";}
- Fl_Widget *widget(int X,int Y,int W,int H) FL_OVERRIDE {
- Fl_Group_Proxy *g = new Fl_Group_Proxy(X,Y,W,H); Fl_Group::current(0); return g;}
- Fl_Widget_Type *_make() FL_OVERRIDE {return new Fl_Group_Type();}
- void write_code1(fld::io::Code_Writer& f) FL_OVERRIDE;
- void write_code2(fld::io::Code_Writer& f) FL_OVERRIDE;
- void add_child(Fl_Type*, Fl_Type*) FL_OVERRIDE;
- void move_child(Fl_Type*, Fl_Type*) FL_OVERRIDE;
- void remove_child(Fl_Type*) FL_OVERRIDE;
- int can_have_children() 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;
- void leave_live_mode() FL_OVERRIDE;
- void copy_properties() FL_OVERRIDE;
-};
-
-// ---- Fl_Pack_Type --------------------------------------------------- MARK: -
-
-extern const char pack_type_name[];
-extern Fl_Menu_Item pack_type_menu[];
-
-class Fl_Pack_Type : public Fl_Group_Type
-{
- typedef Fl_Group_Type super;
- Fl_Menu_Item *subtypes() FL_OVERRIDE {return pack_type_menu;}
-public:
- const char *type_name() FL_OVERRIDE {return pack_type_name;}
- const char *alt_type_name() FL_OVERRIDE {return "fltk::PackedGroup";}
- Fl_Widget_Type *_make() FL_OVERRIDE {return new Fl_Pack_Type();}
- ID id() const FL_OVERRIDE { return ID_Pack; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Pack) ? true : super::is_a(inID); }
- Fl_Widget *enter_live_mode(int top=0) FL_OVERRIDE;
- void copy_properties() FL_OVERRIDE;
-};
-
-// ---- Fl_Flex_Type --------------------------------------------------- MARK: -
-
-extern const char flex_type_name[];
-extern Fl_Menu_Item flex_type_menu[];
-
-class Fl_Flex_Proxy : public Fl_Flex {
-public:
- Fl_Flex_Proxy(int X,int Y,int W,int H) : Fl_Flex(X, Y, W, H) { Fl_Group::current(0); }
- void resize(int x, int y, int w, int h) FL_OVERRIDE;
- void draw() FL_OVERRIDE;
-};
-
-class Fl_Flex_Type : public Fl_Group_Type
-{
- typedef Fl_Group_Type super;
- Fl_Menu_Item *subtypes() FL_OVERRIDE {return flex_type_menu;}
- int fixedSizeTupleSize; /* number of pairs in array */
- int *fixedSizeTuple; /* [ index, size, index2, size2, ... ] */
- int suspend_auto_layout;
-public:
- Fl_Flex_Type() : fixedSizeTupleSize(0), fixedSizeTuple(NULL), suspend_auto_layout(0) { }
- const char *type_name() FL_OVERRIDE {return flex_type_name;}
- const char *alt_type_name() FL_OVERRIDE {return "fltk::FlexGroup";}
- Fl_Widget_Type *_make() FL_OVERRIDE { return new Fl_Flex_Type(); }
- Fl_Widget *widget(int X,int Y,int W,int H) FL_OVERRIDE {
- Fl_Flex *g = new Fl_Flex_Proxy(X,Y,W,H); Fl_Group::current(0); return g;}
- ID id() const FL_OVERRIDE { return ID_Flex; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Flex) ? true : super::is_a(inID); }
- void write_properties(fld::io::Project_Writer &f) FL_OVERRIDE;
- void read_property(fld::io::Project_Reader &f, const char *) FL_OVERRIDE;
- Fl_Widget *enter_live_mode(int top=0) FL_OVERRIDE;
- void copy_properties() FL_OVERRIDE;
- void copy_properties_for_children() FL_OVERRIDE;
- void postprocess_read() FL_OVERRIDE;
- void write_code2(fld::io::Code_Writer& f) FL_OVERRIDE;
-// void add_child(Fl_Type*, Fl_Type*) FL_OVERRIDE;
-// void move_child(Fl_Type*, Fl_Type*) FL_OVERRIDE;
- void remove_child(Fl_Type*) FL_OVERRIDE;
- void layout_widget() FL_OVERRIDE;
- void change_subtype_to(int n);
- void insert_child_at(Fl_Widget *child, int x, int y);
- void keyboard_move_child(Fl_Widget_Type*, int key);
- static int parent_is_flex(Fl_Type*);
- static int size(Fl_Type*, char fixed_only=0);
- static int is_fixed(Fl_Type*);
-};
-
-// ---- Fl_Table_Type -------------------------------------------------- MARK: -
-
-class Fl_Table_Type : public Fl_Group_Type
-{
- typedef Fl_Group_Type super;
-public:
- void ideal_size(int &w, int &h) FL_OVERRIDE;
- const char *type_name() FL_OVERRIDE { return "Fl_Table"; }
- const char *alt_type_name() FL_OVERRIDE { return "fltk::TableGroup"; }
- Fl_Widget_Type *_make() FL_OVERRIDE { return new Fl_Table_Type(); }
- Fl_Widget *widget(int X, int Y, int W, int H) FL_OVERRIDE;
- ID id() const FL_OVERRIDE { return ID_Table; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Table) ? true : super::is_a(inID); }
- Fl_Widget *enter_live_mode(int top=0) FL_OVERRIDE;
- void add_child(Fl_Type*, Fl_Type*) FL_OVERRIDE;
- void move_child(Fl_Type*, Fl_Type*) FL_OVERRIDE;
- void remove_child(Fl_Type*) FL_OVERRIDE;
-};
-
-// ---- Fl_Tabs_Type --------------------------------------------------- MARK: -
-
-extern const char tabs_type_name[];
-
-class Fl_Tabs_Proxy : public Fl_Tabs {
-public:
- Fl_Tabs_Proxy(int X,int Y,int W,int H) : Fl_Tabs(X,Y,W,H) {}
- void resize(int,int,int,int) FL_OVERRIDE;
- void draw() FL_OVERRIDE;
-};
-
-class Fl_Tabs_Type : public Fl_Group_Type
-{
- typedef Fl_Group_Type super;
-public:
- const char *type_name() FL_OVERRIDE {return tabs_type_name;}
- const char *alt_type_name() FL_OVERRIDE {return "fltk::TabGroup";}
- Fl_Widget *widget(int X,int Y,int W,int H) FL_OVERRIDE {
- Fl_Tabs_Proxy *g = new Fl_Tabs_Proxy(X,Y,W,H); Fl_Group::current(0); return g;}
- Fl_Widget_Type *_make() FL_OVERRIDE {return new Fl_Tabs_Type();}
- Fl_Type* click_test(int,int) FL_OVERRIDE;
- void add_child(Fl_Type*, Fl_Type*) FL_OVERRIDE;
- void remove_child(Fl_Type*) FL_OVERRIDE;
- ID id() const FL_OVERRIDE { return ID_Tabs; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Tabs) ? true : super::is_a(inID); }
- Fl_Widget *enter_live_mode(int top=0) FL_OVERRIDE;
-};
-
-// ---- Fl_Scroll_Type ------------------------------------------------- MARK: -
-
-extern const char scroll_type_name[];
-extern Fl_Menu_Item scroll_type_menu[];
-
-class Fl_Scroll_Type : public Fl_Group_Type
-{
- typedef Fl_Group_Type super;
- Fl_Menu_Item *subtypes() FL_OVERRIDE {return scroll_type_menu;}
-public:
- const char *type_name() FL_OVERRIDE {return scroll_type_name;}
- const char *alt_type_name() FL_OVERRIDE {return "fltk::ScrollGroup";}
- Fl_Widget_Type *_make() FL_OVERRIDE {return new Fl_Scroll_Type();}
- ID id() const FL_OVERRIDE { return ID_Scroll; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Scroll) ? true : super::is_a(inID); }
- Fl_Widget *enter_live_mode(int top=0) FL_OVERRIDE;
- void copy_properties() FL_OVERRIDE;
-};
-
-// ---- Fl_Tile_Type --------------------------------------------------- MARK: -
-
-extern const char tile_type_name[];
-
-class Fl_Tile_Type : public Fl_Group_Type
-{
- typedef Fl_Group_Type super;
-public:
- const char *type_name() FL_OVERRIDE {return tile_type_name;}
- const char *alt_type_name() FL_OVERRIDE {return "fltk::TileGroup";}
- Fl_Widget_Type *_make() FL_OVERRIDE {return new Fl_Tile_Type();}
- ID id() const FL_OVERRIDE { return ID_Tile; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Tile) ? true : super::is_a(inID); }
- void copy_properties() FL_OVERRIDE;
-};
-
-// ---- Fl_Wizard_Type ------------------------------------------------- MARK: -
-
-class Fl_Wizard_Proxy : public Fl_Wizard {
-public:
- Fl_Wizard_Proxy(int X,int Y,int W,int H) : Fl_Wizard(X,Y,W,H) {}
- void resize(int,int,int,int) FL_OVERRIDE;
- void draw() FL_OVERRIDE;
-};
-
-extern const char wizard_type_name[];
-
-class Fl_Wizard_Type : public Fl_Group_Type
-{
- typedef Fl_Group_Type super;
-public:
- const char *type_name() FL_OVERRIDE {return wizard_type_name;}
- const char *alt_type_name() FL_OVERRIDE {return "fltk::WizardGroup";}
- Fl_Widget *widget(int X,int Y,int W,int H) FL_OVERRIDE {
- Fl_Wizard_Proxy *g = new Fl_Wizard_Proxy(X,Y,W,H); Fl_Group::current(0); return g;}
- Fl_Widget_Type *_make() FL_OVERRIDE {return new Fl_Wizard_Type();}
- ID id() const FL_OVERRIDE { return ID_Wizard; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Wizard) ? true : super::is_a(inID); }
-};
-
-#endif // _FLUID_FL_GROUP_TYPE_H
diff --git a/fluid/nodes/Fl_Menu_Type.h b/fluid/nodes/Fl_Menu_Type.h
deleted file mode 100644
index 136a1c289..000000000
--- a/fluid/nodes/Fl_Menu_Type.h
+++ /dev/null
@@ -1,287 +0,0 @@
-//
-// Menu type header file for the Fast Light Tool Kit (FLTK).
-//
-// Type for creating all subclasses of Fl_Widget
-// This should have the widget pointer in it, but it is still in the
-// Fl_Type base class.
-//
-// Copyright 1998-2023 by Bill Spitzak and others.
-//
-// This library is free software. Distribution and use rights are outlined in
-// the file "COPYING" which should have been included with this file. If this
-// file is missing or damaged, see the license at:
-//
-// https://www.fltk.org/COPYING.php
-//
-// Please see the following page on how to report bugs and issues:
-//
-// https://www.fltk.org/bugs.php
-//
-
-#ifndef _FLUID_FL_MENU_TYPE_H
-#define _FLUID_FL_MENU_TYPE_H
-
-#include "nodes/Fl_Button_Type.h"
-
-#include "app/Fd_Snap_Action.h"
-
-#include <FL/Fl_Choice.H>
-#include <FL/Fl_Menu_.H>
-#include <FL/Fl_Menu_Button.H>
-#include <FL/Fl_Input_Choice.H>
-#include <FL/Fl_Window.H>
-#include <FL/Fl_Menu_Bar.H>
-
-extern Fl_Menu_Item dummymenu[];
-extern Fl_Menu_Item button_type_menu[];
-extern Fl_Menu_Item menu_item_type_menu[];
-extern Fl_Menu_Item menu_bar_type_menu[];
-
-/**
- \brief Manage all types on menu items.
- Deriving Fl_Menu_Item_Type from Fl_Button_Type is intentional. For the purpose
- of editing, a Menu Item is implemented with `o` pointing to an Fl_Button for
- holding all properties.
- */
-class Fl_Menu_Item_Type : public Fl_Button_Type
-{
- typedef Fl_Button_Type super;
-public:
- Fl_Menu_Item* subtypes() FL_OVERRIDE {return menu_item_type_menu;}
- const char* type_name() FL_OVERRIDE {return "MenuItem";}
- const char* alt_type_name() FL_OVERRIDE {return "fltk::Item";}
- Fl_Type* make(Strategy strategy) FL_OVERRIDE;
- Fl_Type* make(int flags, Strategy strategy);
- int is_button() const FL_OVERRIDE {return 1;} // this gets shortcut to work
- Fl_Widget* widget(int,int,int,int) FL_OVERRIDE {return 0;}
- Fl_Widget_Type* _make() FL_OVERRIDE {return 0;}
- virtual const char* menu_name(fld::io::Code_Writer& f, int& i);
- int flags();
- void write_static(fld::io::Code_Writer& f) FL_OVERRIDE;
- void write_item(fld::io::Code_Writer& f);
- void write_code1(fld::io::Code_Writer& f) FL_OVERRIDE;
- void write_code2(fld::io::Code_Writer& f) FL_OVERRIDE;
- int is_true_widget() const FL_OVERRIDE { return 0; }
- ID id() const FL_OVERRIDE { return ID_Menu_Item; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Menu_Item) ? true : super::is_a(inID); }
-};
-
-/**
- \brief Manage Radio style Menu Items.
- */
-class Fl_Radio_Menu_Item_Type : public Fl_Menu_Item_Type
-{
- typedef Fl_Menu_Item_Type super;
-public:
- const char* type_name() FL_OVERRIDE {return "RadioMenuItem";}
- Fl_Type* make(Strategy strategy) FL_OVERRIDE;
- ID id() const FL_OVERRIDE { return ID_Radio_Menu_Item; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Radio_Menu_Item) ? true : super::is_a(inID); }
-};
-
-/**
- \brief Manage Checkbox style Menu Items.
- */
-class Fl_Checkbox_Menu_Item_Type : public Fl_Menu_Item_Type
-{
- typedef Fl_Menu_Item_Type super;
-public:
- const char* type_name() FL_OVERRIDE {return "CheckMenuItem";}
- Fl_Type* make(Strategy strategy) FL_OVERRIDE;
- ID id() const FL_OVERRIDE { return ID_Checkbox_Menu_Item; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Checkbox_Menu_Item) ? true : super::is_a(inID); }
-};
-
-/**
- \brief Manage Submenu style Menu Items.
- Submenu Items are simply buttons just like all other menu items, but they
- can also hold a pointer to a list of submenus, or have a flag set that
- allows submenus to follow in the current array. As buttons, they can
- be clicked by the user, and they will call their callback, if one is set.
- */
-class Fl_Submenu_Type : public Fl_Menu_Item_Type
-{
- typedef Fl_Menu_Item_Type super;
-public:
- Fl_Menu_Item* subtypes() FL_OVERRIDE {return 0;}
- const char* type_name() FL_OVERRIDE {return "Submenu";}
- const char* alt_type_name() FL_OVERRIDE {return "fltk::ItemGroup";}
- int can_have_children() const FL_OVERRIDE {return 1;}
- int is_button() const FL_OVERRIDE {return 0;} // disable shortcut
- Fl_Type* make(Strategy strategy) FL_OVERRIDE;
- // changes to submenu must propagate up so build_menu is called
- // on the parent Fl_Menu_Type:
- void add_child(Fl_Type*a, Fl_Type*b) FL_OVERRIDE {parent->add_child(a,b);}
- void move_child(Fl_Type*a, Fl_Type*b) FL_OVERRIDE {parent->move_child(a,b);}
- void remove_child(Fl_Type*a) FL_OVERRIDE {parent->remove_child(a);}
- ID id() const FL_OVERRIDE { return ID_Submenu; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Submenu) ? true : super::is_a(inID); }
-};
-
-// -----------------------------------------------------------------------------
-
-/**
- \brief Base class for all widgets that can have a pulldown menu attached.
- Widgets with this type can be derived from Fl_Menu_ or from
- Fl_Group (Fl_Input_Choice).
- */
-class Fl_Menu_Manager_Type : public Fl_Widget_Type
-{
- typedef Fl_Widget_Type super;
-public:
- void ideal_size(int &w, int &h) FL_OVERRIDE {
- h = layout->textsize_not_null() + 8;
- w = layout->textsize_not_null() * 6 + 8;
- Fd_Snap_Action::better_size(w, h);
- }
- int can_have_children() const FL_OVERRIDE {return 1;}
- int menusize;
- virtual void build_menu() = 0;
- Fl_Menu_Manager_Type() : Fl_Widget_Type() {menusize = 0;}
- void add_child(Fl_Type*, Fl_Type*) FL_OVERRIDE { build_menu(); }
- void move_child(Fl_Type*, Fl_Type*) FL_OVERRIDE { build_menu(); }
- void remove_child(Fl_Type*) FL_OVERRIDE { build_menu();}
- Fl_Type* click_test(int x, int y) FL_OVERRIDE = 0;
- void write_code2(fld::io::Code_Writer& f) FL_OVERRIDE;
- void copy_properties() FL_OVERRIDE = 0;
- ID id() const FL_OVERRIDE { return ID_Menu_Manager_; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Menu_Manager_) ? true : super::is_a(inID); }
-};
-
-/**
- \brief Manage the composite widget Input Choice.
- \note Input Choice is a composite window, so `o` will be pointing to a widget
- derived from Fl_Group. All menu related methods from Fl_Menu_Trait_Type must
- be virtual and must be reimplemented here (click_test, build_menu, textstuff).
- */
-class Fl_Input_Choice_Type : public Fl_Menu_Manager_Type
-{
- typedef Fl_Menu_Manager_Type super;
- int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) FL_OVERRIDE {
- Fl_Input_Choice *myo = (Fl_Input_Choice*)(w==4 ? ((Fl_Widget_Type*)this->factory)->o : this->o);
- switch (w) {
- case 4:
- case 0: f = (Fl_Font)myo->textfont(); s = myo->textsize(); c = myo->textcolor(); break;
- case 1: myo->textfont(f); break;
- case 2: myo->textsize(s); break;
- case 3: myo->textcolor(c); break;
- }
- return 1;
- }
-public:
- ~Fl_Input_Choice_Type() {
- if (menusize) delete[] (Fl_Menu_Item*)(((Fl_Input_Choice*)o)->menu());
- }
- const char *type_name() FL_OVERRIDE {return "Fl_Input_Choice";}
- const char *alt_type_name() FL_OVERRIDE {return "fltk::ComboBox";}
- Fl_Type* click_test(int,int) FL_OVERRIDE;
- Fl_Widget *widget(int X,int Y,int W,int H) FL_OVERRIDE {
- Fl_Input_Choice *myo = new Fl_Input_Choice(X,Y,W,H,"input choice:");
- myo->menu(dummymenu);
- myo->value("input");
- return myo;
- }
- Fl_Widget_Type *_make() FL_OVERRIDE {return new Fl_Input_Choice_Type();}
- void build_menu() FL_OVERRIDE;
- ID id() const FL_OVERRIDE { return ID_Input_Choice; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Input_Choice) ? true : super::is_a(inID); }
- void copy_properties() FL_OVERRIDE;
-};
-
-/**
- \brief Base class to handle widgets that are derived from Fl_Menu_.
- */
-class Fl_Menu_Base_Type : public Fl_Menu_Manager_Type
-{
- typedef Fl_Menu_Manager_Type super;
- int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) FL_OVERRIDE {
- Fl_Menu_ *myo = (Fl_Menu_*)(w==4 ? ((Fl_Widget_Type*)this->factory)->o : this->o);
- switch (w) {
- case 4:
- case 0: f = myo->textfont(); s = myo->textsize(); c = myo->textcolor(); break;
- case 1: myo->textfont(f); break;
- case 2: myo->textsize(s); break;
- case 3: myo->textcolor(c); break;
- }
- return 1;
- }
-public:
- int can_have_children() const FL_OVERRIDE {return 1;}
- void build_menu() FL_OVERRIDE;
- ~Fl_Menu_Base_Type() {
- if (menusize) delete[] (Fl_Menu_Item*)(((Fl_Menu_*)o)->menu());
- }
- Fl_Type* click_test(int x, int y) FL_OVERRIDE;
- void copy_properties() FL_OVERRIDE;
- ID id() const FL_OVERRIDE { return ID_Menu_; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Menu_) ? true : super::is_a(inID); }
-};
-
-extern Fl_Menu_Item button_type_menu[];
-
-/**
- \brief Make Menu Button widgets.
- */
-class Fl_Menu_Button_Type : public Fl_Menu_Base_Type
-{
- typedef Fl_Menu_Base_Type super;
- Fl_Menu_Item *subtypes() FL_OVERRIDE {return button_type_menu;}
-public:
- const char *type_name() FL_OVERRIDE {return "Fl_Menu_Button";}
- const char *alt_type_name() FL_OVERRIDE {return "fltk::MenuButton";}
- Fl_Widget *widget(int X,int Y,int W,int H) FL_OVERRIDE {
- return new Fl_Menu_Button(X,Y,W,H,"menu");}
- Fl_Widget_Type *_make() FL_OVERRIDE {return new Fl_Menu_Button_Type();}
- ID id() const FL_OVERRIDE { return ID_Menu_Button; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Menu_Button) ? true : super::is_a(inID); }
-};
-
-
-/**
- \brief Manage Choice type menu widgets.
- */
-class Fl_Choice_Type : public Fl_Menu_Base_Type
-{
- typedef Fl_Menu_Base_Type super;
-public:
- const char *type_name() FL_OVERRIDE {return "Fl_Choice";}
- const char *alt_type_name() FL_OVERRIDE {return "fltk::Choice";}
- Fl_Widget *widget(int X,int Y,int W,int H) FL_OVERRIDE {
- Fl_Choice *myo = new Fl_Choice(X,Y,W,H,"choice:");
- myo->menu(dummymenu);
- return myo;
- }
- Fl_Widget_Type *_make() FL_OVERRIDE {return new Fl_Choice_Type();}
- ID id() const FL_OVERRIDE { return ID_Choice; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Choice) ? true : super::is_a(inID); }
-};
-
-
-/**
- \brief Manage Menubar widgets.
- */
-class Fl_Menu_Bar_Type : public Fl_Menu_Base_Type
-{
- typedef Fl_Menu_Base_Type super;
- Fl_Menu_Item *subtypes() FL_OVERRIDE {return menu_bar_type_menu;}
-public:
- Fl_Menu_Bar_Type();
- ~Fl_Menu_Bar_Type() FL_OVERRIDE;
- const char *type_name() FL_OVERRIDE {return "Fl_Menu_Bar";}
- const char *alt_type_name() FL_OVERRIDE {return "fltk::MenuBar";}
- Fl_Widget *widget(int X,int Y,int W,int H) FL_OVERRIDE {return new Fl_Menu_Bar(X,Y,W,H);}
- Fl_Widget_Type *_make() FL_OVERRIDE {return new Fl_Menu_Bar_Type();}
- void write_static(fld::io::Code_Writer& f) FL_OVERRIDE;
- void write_code1(fld::io::Code_Writer& f) FL_OVERRIDE;
-// void write_code2(fld::io::Code_Writer& f) FL_OVERRIDE;
- ID id() const FL_OVERRIDE { return ID_Menu_Bar; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Menu_Bar) ? true : super::is_a(inID); }
- bool is_sys_menu_bar();
- const char *sys_menubar_name();
- const char *sys_menubar_proxy_name();
-protected:
- char *_proxy_name;
-};
-
-
-#endif // _FLUID_FL_MENU_TYPE_H
diff --git a/fluid/nodes/Fl_Widget_Type.cxx b/fluid/nodes/Fl_Widget_Type.cxx
deleted file mode 100644
index 2cde4d531..000000000
--- a/fluid/nodes/Fl_Widget_Type.cxx
+++ /dev/null
@@ -1,3939 +0,0 @@
-//
-// Widget type code for the Fast Light Tool Kit (FLTK).
-//
-// Copyright 1998-2025 by Bill Spitzak and others.
-//
-// This library is free software. Distribution and use rights are outlined in
-// the file "COPYING" which should have been included with this file. If this
-// file is missing or damaged, see the license at:
-//
-// https://www.fltk.org/COPYING.php
-//
-// Please see the following page on how to report bugs and issues:
-//
-// https://www.fltk.org/bugs.php
-//
-
-#include "nodes/Fl_Widget_Type.h"
-
-#include "app/fluid.h"
-#include "app/project.h"
-#include "app/Fluid_Image.h"
-#include "app/mergeback.h"
-#include "app/undo.h"
-#include "io/Project_Reader.h"
-#include "io/Project_Writer.h"
-#include "io/Code_Writer.h"
-#include "nodes/Fl_Window_Type.h"
-#include "nodes/Fl_Group_Type.h"
-#include "nodes/Fl_Menu_Type.h"
-#include "nodes/Fl_Function_Type.h"
-#include "panels/settings_panel.h"
-#include "panels/widget_panel.h"
-
-#include <FL/Fl.H>
-#include <FL/Fl_Group.H>
-#include <FL/Fl_Table.H>
-#include <FL/Fl_Input.H>
-#include <FL/fl_message.H>
-#include <FL/Fl_Slider.H>
-#include <FL/Fl_Spinner.H>
-#include <FL/Fl_Window.H>
-#include <FL/fl_show_colormap.H>
-#include "../src/flstring.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-
-// Make an Fl_Widget_Type subclass instance.
-// It figures out the automatic size and parent of the new widget,
-// creates the Fl_Widget (by calling the virtual function _make),
-// adds it to the Fl_Widget hierarchy, creates a new Fl_Type
-// instance, sets the widget pointers, and makes all the display
-// update correctly...
-
-int Fl_Widget_Type::is_widget() const {return 1;}
-int Fl_Widget_Type::is_public() const {return public_;}
-
-const char* subclassname(Fl_Type* l) {
- if (l->is_a(ID_Menu_Bar)) {
- Fl_Menu_Bar_Type *mb = static_cast<Fl_Menu_Bar_Type*>(l);
- if (mb->is_sys_menu_bar())
- return mb->sys_menubar_name();
- }
- if (l->is_widget()) {
- Fl_Widget_Type* p = (Fl_Widget_Type*)l;
- const char* c = p->subclass();
- if (c) return c;
- if (l->is_class()) return "Fl_Group";
- if (p->o->type() == FL_DOUBLE_WINDOW) return "Fl_Double_Window";
- if (p->id() == ID_Input) {
- if (p->o->type() == FL_FLOAT_INPUT) return "Fl_Float_Input";
- if (p->o->type() == FL_INT_INPUT) return "Fl_Int_Input";
- }
- }
- return l->type_name();
-}
-
-// Return the ideal widget size...
-void
-Fl_Widget_Type::ideal_size(int &w, int &h) {
- w = 120;
- h = 100;
- Fd_Snap_Action::better_size(w, h);
-}
-
-/**
- Make a new Widget node.
- \param[in] strategy is Strategy::AS_LAST_CHILD or Strategy::AFTER_CURRENT
- \return new node
- */
-Fl_Type *Fl_Widget_Type::make(Strategy strategy) {
- Fl_Type *anchor = Fl_Type::current, *pp = anchor;
- if (pp && (strategy.placement() == Strategy::AFTER_CURRENT))
- pp = pp->parent;
- while (pp && !pp->is_a(ID_Group)) {
- anchor = pp;
- strategy.placement(Strategy::AFTER_CURRENT);
- pp = pp->parent;
- }
- if (!pp || !pp->is_true_widget() || !anchor->is_true_widget()) {
- fl_message("Please select a group widget or window");
- return 0;
- }
-
- Fl_Widget_Type* p = (Fl_Widget_Type*)pp;
- Fl_Widget_Type* q = (Fl_Widget_Type*)anchor;
-
- // Figure out a border between widget and window:
- int B = p->o->w()/2; if (p->o->h()/2 < B) B = p->o->h()/2; if (B>25) B = 25;
-
- int ULX,ULY; // parent's origin in window
- if (!p->is_a(ID_Window)) { // if it is a group, add corner
- ULX = p->o->x(); ULY = p->o->y();
- } else {
- ULX = ULY = 0;
- }
-
- // Figure out a position and size for the widget
- int X,Y,W,H;
- if (is_a(ID_Group)) { // fill the parent with the widget
- X = ULX+B;
- W = p->o->w()-B;
- Y = ULY+B;
- H = p->o->h()-B;
- } else if (q != p) { // copy position and size of current widget
- W = q->o->w();
- H = q->o->h();
- X = q->o->x()+W;
- Y = q->o->y();
- if (X+W > ULX+p->o->w()) {
- X = q->o->x();
- Y = q->o->y()+H;
- if (Y+H > ULY+p->o->h()) Y = ULY+B;
- }
- } else { // just make it small and square...
- X = ULX+B;
- Y = ULY+B;
- W = H = B;
- }
-
- // Construct the Fl_Type:
- Fl_Widget_Type *t = _make();
- if (!o) o = widget(0,0,100,100); // create template widget
- t->factory = this;
- // Construct the Fl_Widget:
- t->o = widget(X,Y,W,H);
- if (strategy.source() == Strategy::FROM_FILE)
- t->o->label(0);
- else if (t->o->label()) t->label(t->o->label()); // allow editing
- t->o->user_data((void*)t);
- // Put it in the parent:
- // ((Fl_Group *)(p->o))->add(t->o); (done by Fl_Type::add())
- // add to browser:
- t->add(anchor, strategy);
- t->redraw();
- return t;
-}
-
-void Fl_Widget_Type::setimage(Fluid_Image *i) {
- if (i == image || is_a(ID_Window)) return;
- if (image) image->decrement();
- if (i) i->increment();
- image = i;
- if (i) {
- i->image(o);
- if (o->image() && (scale_image_w_ || scale_image_h_)) {
- int iw = scale_image_w_>0 ? scale_image_w_ : o->image()->data_w();
- int ih = scale_image_h_>0 ? scale_image_h_ : o->image()->data_h();
- o->image()->scale(iw, ih, 0, 1);
- }
- } else {
- o->image(0);
- //scale_image_w_ = scale_image_h_ = 0;
- }
- redraw();
-}
-
-void Fl_Widget_Type::setinactive(Fluid_Image *i) {
- if (i == inactive || is_a(ID_Window)) return;
- if (inactive) inactive->decrement();
- if (i) i->increment();
- inactive = i;
- if (i) {
- i->deimage(o);
- if (o->deimage()) {
- int iw = scale_deimage_w_>0 ? scale_deimage_w_ : o->deimage()->data_w();
- int ih = scale_deimage_h_>0 ? scale_deimage_h_ : o->deimage()->data_h();
- o->deimage()->scale(iw, ih, 0, 1);
- }
- } else {
- o->deimage(0);
- //scale_deimage_w_ = scale_deimage_h_ = 0;
- }
- redraw();
-}
-
-void Fl_Widget_Type::setlabel(const char *n) {
- o->label(n);
- redraw();
-}
-
-Fl_Widget_Type::Fl_Widget_Type()
-: override_visible_(0)
-{
- for (int n=0; n<NUM_EXTRA_CODE; n++) {extra_code_[n] = 0; }
- subclass_ = 0;
- hotspot_ = 0;
- tooltip_ = 0;
- image_name_ = 0;
- inactive_name_ = 0;
- image = 0;
- inactive = 0;
- o = 0;
- public_ = 1;
- bind_image_ = 0;
- compress_image_ = 1;
- bind_deimage_ = 0;
- compress_deimage_ = 1;
- scale_image_w_ = 0;
- scale_image_h_ = 0;
- scale_deimage_w_ = 0;
- scale_deimage_h_ = 0;
-}
-
-Fl_Widget_Type::~Fl_Widget_Type() {
- if (o) {
- Fl_Window *win = o->window();
- delete o;
- if (win)
- win->redraw();
- }
- if (subclass_) free((void*)subclass_);
- if (tooltip_) free((void*)tooltip_);
- if (image_name_) {
- free((void*)image_name_);
- if (image) image->decrement();
- }
- if (inactive_name_) {
- free((void*)inactive_name_);
- if (inactive) inactive->decrement();
- }
- for (int n=0; n<NUM_EXTRA_CODE; n++) {
- if (extra_code_[n]) free((void*) extra_code_[n]);
- }
-}
-
-void Fl_Widget_Type::extra_code(int m,const char *n) {
- storestring(n,extra_code_[m]);
-}
-
-extern void redraw_browser();
-void Fl_Widget_Type::subclass(const char *n) {
- if (storestring(n,subclass_) && visible)
- redraw_browser();
-}
-
-void Fl_Widget_Type::tooltip(const char *n) {
- storestring(n,tooltip_);
- o->tooltip(n);
-}
-
-void Fl_Widget_Type::image_name(const char *n) {
- setimage(Fluid_Image::find(n));
- storestring(n,image_name_);
-}
-
-void Fl_Widget_Type::inactive_name(const char *n) {
- setinactive(Fluid_Image::find(n));
- storestring(n,inactive_name_);
-}
-
-void Fl_Widget_Type::redraw() {
- Fl_Type *t = this;
- if (is_a(ID_Menu_Item)) {
- // find the menu button that parents this menu:
- do t = t->parent; while (t && t->is_a(ID_Menu_Item));
- // kludge to cause build_menu to be called again:
- if (t)
- t->add_child(0, 0);
- } else {
- while (t->parent && t->parent->is_widget()) t = t->parent;
- ((Fl_Widget_Type*)t)->o->redraw();
- }
-}
-
-// the recursive part sorts all children, returns pointer to next:
-Fl_Type *sort(Fl_Type *parent) {
- Fl_Type *f,*n=0;
- for (f = parent ? parent->next : Fl_Type::first; ; f = n) {
- if (!f || (parent && f->level <= parent->level)) break;
- n = sort(f);
- if (!f->selected || !f->is_true_widget()) continue;
- Fl_Widget* fw = ((Fl_Widget_Type*)f)->o;
- Fl_Type *g; // we will insert before this
- for (g = parent ? parent->next : Fl_Type::first; g != f; g = g->next) {
- if (!g->selected || g->level > f->level) continue;
- Fl_Widget* gw = ((Fl_Widget_Type*)g)->o;
- if (gw->y() > fw->y()) break;
- if (gw->y() == fw->y() && gw->x() > fw->x()) break;
- }
- if (g != f) f->move_before(g);
- }
- if (parent)
- parent->layout_widget();
- return f;
-}
-
-////////////////////////////////////////////////////////////////
-// The control panels!
-
-Fl_Window *the_panel;
-
-// All the callbacks use the argument to indicate whether to load or store.
-// This avoids the need for pointers to all the widgets, and keeps the
-// code localized in the callbacks.
-// A value of LOAD means to load. The hope is that this will not collide
-// with any actual useful values for the argument. I also use this to
-// initialized parts of the widget that are nyi by fluid.
-
-Fl_Widget_Type *current_widget; // one of the selected ones
-void* const LOAD = (void *)"LOAD"; // "magic" pointer to indicate that we need to load values into the dialog
-static int numselected; // number selected
-static int haderror;
-
-void name_cb(Fl_Input* o, void *v) {
- if (v == LOAD) {
- static char buf[1024];
- if (numselected != 1) {
- snprintf(buf, sizeof(buf), "Widget Properties (%d widgets)", numselected);
- o->hide();
- } else {
- o->value(current_widget->name());
- o->show();
- snprintf(buf, sizeof(buf), "%s Properties", current_widget->title());
- }
-
- the_panel->label(buf);
- } else {
- if (numselected == 1) {
- current_widget->name(o->value());
- // I don't update window title, as it probably is being closed
- // and wm2 (a window manager) barfs if you retitle and then
- // hide a window:
- // ((Fl_Window*)(o->parent()->parent()->parent()))->label(current_widget->title());
- }
- }
-}
-
-void name_public_member_cb(Fl_Choice* i, void* v) {
- if (v == LOAD) {
- i->value(current_widget->public_);
- if (current_widget->is_in_class()) i->show(); else i->hide();
- } else {
- int mod = 0;
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_widget()) {
- Fl_Widget_Type *w = ((Fl_Widget_Type*)o);
- if (w->is_in_class()) {
- w->public_ = i->value();
- } else {
- // if this is not in a class, it can be only private or public
- w->public_ = (i->value()>0);
- }
- mod = 1;
- }
- }
- if (mod) {
- set_modflag(1);
- redraw_browser();
- }
- }
-}
-
-void name_public_cb(Fl_Choice* i, void* v) {
- if (v == LOAD) {
- i->value(current_widget->public_>0);
- if (current_widget->is_in_class()) i->hide(); else i->show();
- } else {
- int mod = 0;
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_widget()) {
- ((Fl_Widget_Type*)o)->public_ = i->value();
- mod = 1;
- }
- }
- if (mod) {
- set_modflag(1);
- redraw_browser();
- }
- }
-}
-
-/* Treating UNDO for text widget.
-
- Goal: we want to continuously update the UI while the user is typing text
- (changing the label, in this case). Code View does deferred updates, and
- the widget browser and widget panel update on every keystroke. At the same
- time, we want to limit undo actions to few and logical units.
-
- Caveats:
-
- 1: the text widget has its own undo handling for the text field, but we may want to do a global undo
- 2: every o->label() call will create an undo entry, but we want only one single event for all selected widgets
- 3: we want a single undo for the entire editing phase, but still propagate changes as they happen
-
- The edit process has these main states:
-
- 1: starting to edit [first_change==1 && !unfocus]; we must create a single undo checkpoint before anything changes
- 2: continue editing [first_change==0 && !unfocus]; we must suspend any undo checkpoints
- 3: done editing, unfocus [first_change==0 && unfocus]; we must make sure that undo checkpoints are enabled again
- 4: losing focus without editing [first_change==1 && unfocus]; don't create and checkpoints
-
- We must also check:
- 1: changing focus without changing text (works)
- 2: copy and paste, drag and drop operations (works)
- 3: save operation without unfocus event (works)
- */
-void label_cb(Fl_Input* i, void *v) {
- static int first_change = 1;
- if (v == LOAD) {
- i->value(current_widget->label());
- first_change = 1;
- } else {
- if (i->changed()) {
- undo_suspend();
- int mod = 0;
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_widget()) {
- if (!mod) {
- if (first_change) {
- undo_resume();
- undo_checkpoint();
- undo_suspend();
- first_change = 0;
- }
- mod = 1;
- }
- o->label(i->value());
- }
- }
- undo_resume();
- if (mod) set_modflag(1);
- }
- int r = (int)Fl::callback_reason();
- if ( (r == FL_REASON_LOST_FOCUS) || (r == FL_REASON_ENTER_KEY) )
- first_change = 1;
- }
-}
-
-static Fl_Input *image_input;
-
-void image_cb(Fl_Input* i, void *v) {
- if (v == LOAD) {
- image_input = i;
- if (current_widget->is_widget() && !current_widget->is_a(ID_Window)) {
- i->activate();
- i->value(((Fl_Widget_Type*)current_widget)->image_name());
- } else i->deactivate();
- } else {
- int mod = 0;
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_widget()) {
- ((Fl_Widget_Type*)o)->image_name(i->value());
- mod = 1;
- }
- }
- if (mod) set_modflag(1);
- }
-}
-
-void image_browse_cb(Fl_Button* b, void *v) {
- if (v == LOAD) {
- if (current_widget->is_widget() && !current_widget->is_a(ID_Window))
- b->activate();
- else
- b->deactivate();
- } else {
- int mod = 0;
- if (ui_find_image(image_input->value())) {
- image_input->value(ui_find_image_name);
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_widget()) {
- ((Fl_Widget_Type*)o)->image_name(ui_find_image_name);
- mod = 1;
- }
- }
- if (mod) set_modflag(1);
- }
- }
-}
-
-void bind_image_cb(Fl_Check_Button* b, void *v) {
- if (v == LOAD) {
- if (current_widget->is_widget() && !current_widget->is_a(ID_Window)) {
- b->activate();
- b->value(current_widget->bind_image_);
- } else {
- b->deactivate();
- }
- } else {
- int mod = 0;
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_widget()) {
- ((Fl_Widget_Type*)o)->bind_image_ = b->value();
- mod = 1;
- }
- }
- if (mod) set_modflag(1);
- }
-}
-
-void compress_image_cb(Fl_Check_Button* b, void *v) {
- if (v == LOAD) {
- if (current_widget->is_widget() && !current_widget->is_a(ID_Window)) {
- b->activate();
- b->value(!current_widget->compress_image_);
- } else {
- b->deactivate();
- }
- } else {
- int mod = 0;
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_widget()) {
- ((Fl_Widget_Type*)o)->compress_image_ = !b->value();
- mod = 1;
- }
- }
- if (mod) set_modflag(1);
- }
-}
-
-static Fl_Input *inactive_input;
-
-void inactive_cb(Fl_Input* i, void *v) {
- if (v == LOAD) {
- inactive_input = i;
- if (current_widget->is_widget() && !current_widget->is_a(ID_Window)) {
- i->activate();
- i->value(((Fl_Widget_Type*)current_widget)->inactive_name());
- } else i->deactivate();
- } else {
- int mod = 0;
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_widget()) {
- ((Fl_Widget_Type*)o)->inactive_name(i->value());
- mod = 1;
- }
- }
- if (mod) set_modflag(1);
- }
-}
-
-void inactive_browse_cb(Fl_Button* b, void *v) {
- if (v == LOAD) {
- if (current_widget->is_widget() && !current_widget->is_a(ID_Window))
- b->activate();
- else
- b->deactivate();
- } else {
- int mod = 0;
- if (ui_find_image(inactive_input->value())) {
- inactive_input->value(ui_find_image_name);
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_widget()) {
- ((Fl_Widget_Type*)o)->inactive_name(ui_find_image_name);
- mod = 1;
- }
- }
- if (mod) set_modflag(1);
- }
- }
-}
-
-void bind_deimage_cb(Fl_Check_Button* b, void *v) {
- if (v == LOAD) {
- if (current_widget->is_widget() && !current_widget->is_a(ID_Window)) {
- b->activate();
- b->value(current_widget->bind_deimage_);
- } else {
- b->deactivate();
- }
- } else {
- int mod = 0;
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_widget()) {
- ((Fl_Widget_Type*)o)->bind_deimage_ = b->value();
- mod = 1;
- }
- }
- if (mod) set_modflag(1);
- }
-}
-
-void compress_deimage_cb(Fl_Check_Button* b, void *v) {
- if (v == LOAD) {
- if (current_widget->is_widget() && !current_widget->is_a(ID_Window)) {
- b->activate();
- b->value(!current_widget->compress_deimage_);
- } else {
- b->deactivate();
- }
- } else {
- int mod = 0;
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_widget()) {
- ((Fl_Widget_Type*)o)->compress_deimage_ = !b->value();
- mod = 1;
- }
- }
- if (mod) set_modflag(1);
- }
-}
-
-void tooltip_cb(Fl_Input* i, void *v) {
- if (v == LOAD) {
- if (current_widget->is_widget()) {
- i->activate();
- i->value(((Fl_Widget_Type*)current_widget)->tooltip());
- } else i->deactivate();
- } else {
- int mod = 0;
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_widget()) {
- ((Fl_Widget_Type*)o)->tooltip(i->value());
- mod = 1;
- }
- }
- if (mod) set_modflag(1);
- }
-}
-
-fld::widget::Formula_Input *x_input, *y_input, *w_input, *h_input;
-
-static int widget_i = 0;
-
-static int vars_i_cb(const fld::widget::Formula_Input*, void *v) {
- return widget_i;
-}
-
-static int vars_x_cb(const fld::widget::Formula_Input*, void *v) {
- Fl_Type *t = (Fl_Type*)v;
- if (t->is_widget())
- return ((Fl_Widget_Type*)t)->o->x();
- return 0;
-}
-
-static int vars_y_cb(const fld::widget::Formula_Input*, void *v) {
- Fl_Type *t = (Fl_Type*)v;
- if (t->is_widget())
- return ((Fl_Widget_Type*)t)->o->y();
- return 0;
-}
-
-static int vars_w_cb(const fld::widget::Formula_Input*, void *v) {
- Fl_Type *t = (Fl_Type*)v;
- if (t->is_widget())
- return ((Fl_Widget_Type*)t)->o->w();
- return 0;
-}
-
-static int vars_h_cb(const fld::widget::Formula_Input*, void *v) {
- Fl_Type *t = (Fl_Type*)v;
- if (t->is_widget())
- return ((Fl_Widget_Type*)t)->o->h();
- return 0;
-}
-
-static int vars_px_cb(const fld::widget::Formula_Input*, void *v) {
- Fl_Type *t = ((Fl_Type*)v)->parent;
- if (t && t->is_widget())
- return ((Fl_Widget_Type*)t)->o->x();
- return 0;
-}
-
-static int vars_py_cb(const fld::widget::Formula_Input*, void *v) {
- Fl_Type *t = ((Fl_Type*)v)->parent;
- if (t && t->is_widget())
- return ((Fl_Widget_Type*)t)->o->y();
- return 0;
-}
-
-static int vars_pw_cb(const fld::widget::Formula_Input*, void *v) {
- Fl_Type *t = ((Fl_Type*)v)->parent;
- if (t && t->is_widget())
- return ((Fl_Widget_Type*)t)->o->w();
- return 0;
-}
-
-static int vars_ph_cb(const fld::widget::Formula_Input*, void *v) {
- Fl_Type *t = ((Fl_Type*)v)->parent;
- if (t && t->is_widget())
- return ((Fl_Widget_Type*)t)->o->h();
- return 0;
-}
-
-static int vars_sx_cb(const fld::widget::Formula_Input*, void *v) {
- Fl_Type *t = ((Fl_Type*)v)->prev_sibling();
- if (t && t->is_widget())
- return ((Fl_Widget_Type*)t)->o->x();
- return 0;
-}
-
-static int vars_sy_cb(const fld::widget::Formula_Input*, void *v) {
- Fl_Type *t = ((Fl_Type*)v)->prev_sibling();
- if (t && t->is_widget())
- return ((Fl_Widget_Type*)t)->o->y();
- return 0;
-}
-
-static int vars_sw_cb(const fld::widget::Formula_Input*, void *v) {
- Fl_Type *t = ((Fl_Type*)v)->prev_sibling();
- if (t && t->is_widget())
- return ((Fl_Widget_Type*)t)->o->w();
- return 0;
-}
-
-static int vars_sh_cb(const fld::widget::Formula_Input*, void *v) {
- Fl_Type *t = ((Fl_Type*)v)->prev_sibling();
- if (t && t->is_widget())
- return ((Fl_Widget_Type*)t)->o->h();
- return 0;
-}
-
-static int bbox_x, bbox_y, bbox_r, bbox_b;
-static int bbox_min(int a, int b) { return (a<b) ? a : b; }
-static int bbox_max(int a, int b) { return (a>b) ? a : b; }
-
-static void calculate_bbox(Fl_Type *p) {
- char first = 1;
- bbox_x = bbox_y = bbox_r = bbox_b = 0;
- for (p=p->first_child(); p; p=p->next_sibling()) {
- if (p->is_widget()) {
- Fl_Widget *o = ((Fl_Widget_Type*)p)->o;
- if (first) {
- bbox_x = o->x(); bbox_y = o->y();
- bbox_r = o->x() + o->w(); bbox_b = o->y() + o->h();
- first = 0;
- } else {
- bbox_x = bbox_min(bbox_x, o->x());
- bbox_y = bbox_min(bbox_y, o->y());
- bbox_r = bbox_max(bbox_r, o->x() + o->w());
- bbox_b = bbox_max(bbox_b, o->y() + o->h());
- }
- }
- }
-}
-
-static int vars_cx_cb(const fld::widget::Formula_Input*, void *v) {
- calculate_bbox((Fl_Type*)v);
- return bbox_x;
-}
-
-static int vars_cy_cb(const fld::widget::Formula_Input*, void *v) {
- calculate_bbox((Fl_Type*)v);
- return bbox_y;
-}
-
-static int vars_cw_cb(const fld::widget::Formula_Input*, void *v) {
- calculate_bbox((Fl_Type*)v);
- return bbox_r - bbox_x;
-}
-
-static int vars_ch_cb(const fld::widget::Formula_Input*, void *v) {
- calculate_bbox((Fl_Type*)v);
- return bbox_b - bbox_y;
-}
-
-fld::widget::Formula_Input_Vars widget_vars[] = {
- { "i", vars_i_cb }, // zero based counter of selected widgets
- { "x", vars_x_cb }, // position and size of current widget
- { "y", vars_y_cb },
- { "w", vars_w_cb },
- { "h", vars_h_cb },
- { "px", vars_px_cb }, // position and size of parent widget
- { "py", vars_py_cb },
- { "pw", vars_pw_cb },
- { "ph", vars_ph_cb },
- { "sx", vars_sx_cb }, // position and size of previous sibling
- { "sy", vars_sy_cb },
- { "sw", vars_sw_cb },
- { "sh", vars_sh_cb },
- { "cx", vars_cx_cb }, // position and size of bounding box of all children
- { "cy", vars_cy_cb },
- { "cw", vars_cw_cb },
- { "ch", vars_ch_cb },
- { 0 }
-};
-
-void x_cb(fld::widget::Formula_Input *i, void *v) {
- if (v == LOAD) {
- x_input = i;
- if (current_widget->is_true_widget()) {
- i->value(((Fl_Widget_Type *)current_widget)->o->x());
- x_input->activate();
- } else x_input->deactivate();
- } else {
- undo_checkpoint();
- widget_i = 0;
- int mod = 0;
- int v = 0;
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_true_widget()) {
- Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
- i->variables(widget_vars, o);
- v = i->value();
- w->resize(v, w->y(), w->w(), w->h());
- if (w->window()) w->window()->redraw();
- widget_i++;
- mod = 1;
- }
- }
- if (mod) {
- set_modflag(1);
- i->value(v); // change the displayed value to the result of the last
- // calculation. Keep the formula if it was not used.
- }
- }
-}
-
-void y_cb(fld::widget::Formula_Input *i, void *v) {
- if (v == LOAD) {
- y_input = i;
- if (current_widget->is_true_widget()) {
- i->value(((Fl_Widget_Type *)current_widget)->o->y());
- y_input->activate();
- } else y_input->deactivate();
- } else {
- undo_checkpoint();
- widget_i = 0;
- int mod = 0;
- int v = 0;
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_true_widget()) {
- Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
- i->variables(widget_vars, o);
- v = i->value();
- w->resize(w->x(), v, w->w(), w->h());
- if (w->window()) w->window()->redraw();
- widget_i++;
- mod = 1;
- }
- }
- if (mod) {
- set_modflag(1);
- i->value(v);
- }
- }
-}
-
-void w_cb(fld::widget::Formula_Input *i, void *v) {
- if (v == LOAD) {
- w_input = i;
- if (current_widget->is_true_widget()) {
- i->value(((Fl_Widget_Type *)current_widget)->o->w());
- w_input->activate();
- } else w_input->deactivate();
- } else {
- undo_checkpoint();
- widget_i = 0;
- int mod = 0;
- int v = 0;
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_true_widget()) {
- Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
- i->variables(widget_vars, o);
- v = i->value();
- w->resize(w->x(), w->y(), v, w->h());
- if (w->window()) w->window()->redraw();
- widget_i++;
- mod = 1;
- }
- }
- if (mod) {
- set_modflag(1);
- i->value(v);
- }
- }
-}
-
-void h_cb(fld::widget::Formula_Input *i, void *v) {
- if (v == LOAD) {
- h_input = i;
- if (current_widget->is_true_widget()) {
- i->value(((Fl_Widget_Type *)current_widget)->o->h());
- h_input->activate();
- } else h_input->deactivate();
- } else {
- undo_checkpoint();
- widget_i = 0;
- int mod = 0;
- int v = 0;
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_true_widget()) {
- Fl_Widget *w = ((Fl_Widget_Type *)o)->o;
- i->variables(widget_vars, o);
- v = i->value();
- w->resize(w->x(), w->y(), w->w(), v);
- if (w->window()) w->window()->redraw();
- widget_i++;
- mod = 1;
- }
- }
- if (mod) {
- set_modflag(1);
- i->value(v);
- }
- }
-}
-
-void wc_relative_cb(Fl_Choice *i, void *v) {
- if (v == LOAD) {
- if (current_widget->is_a(ID_Widget_Class)) {
- i->show();
- i->value(((Fl_Widget_Class_Type *)current_widget)->wc_relative);
- } else {
- i->hide();
- }
- } else {
- int mod = 0;
- undo_checkpoint();
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && current_widget->is_a(ID_Widget_Class)) {
- Fl_Widget_Class_Type *t = (Fl_Widget_Class_Type *)o;
- t->wc_relative = i->value();
- mod = 1;
- }
- }
- if (mod) set_modflag(1);
- }
-}
-
-////////////////////////////////////////////////////////////////
-
-// turn number to string or string to number for saving to file:
-// does not work for hierarchical menus!
-
-const char *item_name(Fl_Menu_Item* m, int i) {
- if (m) {
- while (m->label()) {
- if (m->argument() == i) return m->label();
- m++;
- }
- }
- static char buffer[20];
- sprintf(buffer, "%d", i);
- return buffer;
-}
-int item_number(Fl_Menu_Item* m, const char* i) {
- if (!i)
- return 0;
- if (m && i) {
- if (i[0]=='F' && i[1]=='L' && i[2]=='_') i += 3;
- while (m->label()) {
- if (!strcmp(m->label(), i)) return int(m->argument());
- m++;
- }
- }
- return atoi(i);
-}
-
-#define ZERO_ENTRY 1000
-
-Fl_Menu_Item boxmenu[] = {
-{"NO_BOX",0,0,(void *)ZERO_ENTRY},
-{"boxes",0,0,0,FL_SUBMENU},
-{"UP_BOX",0,0,(void *)FL_UP_BOX},
-{"DOWN_BOX",0,0,(void *)FL_DOWN_BOX},
-{"FLAT_BOX",0,0,(void *)FL_FLAT_BOX},
-{"BORDER_BOX",0,0,(void *)FL_BORDER_BOX},
-{"THIN_UP_BOX",0,0,(void *)FL_THIN_UP_BOX},
-{"THIN_DOWN_BOX",0,0,(void *)FL_THIN_DOWN_BOX},
-{"ENGRAVED_BOX",0,0,(void *)FL_ENGRAVED_BOX},
-{"EMBOSSED_BOX",0,0,(void *)FL_EMBOSSED_BOX},
-{"ROUND_UP_BOX",0,0,(void *)FL_ROUND_UP_BOX},
-{"ROUND_DOWN_BOX",0,0,(void *)FL_ROUND_DOWN_BOX},
-{"DIAMOND_UP_BOX",0,0,(void *)FL_DIAMOND_UP_BOX},
-{"DIAMOND_DOWN_BOX",0,0,(void *)FL_DIAMOND_DOWN_BOX},
-{"SHADOW_BOX",0,0,(void *)FL_SHADOW_BOX},
-{"ROUNDED_BOX",0,0,(void *)FL_ROUNDED_BOX},
-{"RSHADOW_BOX",0,0,(void *)FL_RSHADOW_BOX},
-{"RFLAT_BOX",0,0,(void *)FL_RFLAT_BOX},
-{"OVAL_BOX",0,0,(void *)FL_OVAL_BOX},
-{"OSHADOW_BOX",0,0,(void *)FL_OSHADOW_BOX},
-{"OFLAT_BOX",0,0,(void *)FL_OFLAT_BOX},
-{"PLASTIC_UP_BOX",0,0,(void *)FL_PLASTIC_UP_BOX},
-{"PLASTIC_DOWN_BOX",0,0,(void *)FL_PLASTIC_DOWN_BOX},
-{"PLASTIC_THIN_UP_BOX",0,0,(void *)FL_PLASTIC_THIN_UP_BOX},
-{"PLASTIC_THIN_DOWN_BOX",0,0,(void *)FL_PLASTIC_THIN_DOWN_BOX},
-{"PLASTIC_ROUND_UP_BOX",0,0,(void *)FL_PLASTIC_ROUND_UP_BOX},
-{"PLASTIC_ROUND_DOWN_BOX",0,0,(void *)FL_PLASTIC_ROUND_DOWN_BOX},
-{"GTK_UP_BOX",0,0,(void *)FL_GTK_UP_BOX},
-{"GTK_DOWN_BOX",0,0,(void *)FL_GTK_DOWN_BOX},
-{"GTK_THIN_UP_BOX",0,0,(void *)FL_GTK_THIN_UP_BOX},
-{"GTK_THIN_DOWN_BOX",0,0,(void *)FL_GTK_THIN_DOWN_BOX},
-{"GTK_ROUND_UP_BOX",0,0,(void *)FL_GTK_ROUND_UP_BOX},
-{"GTK_ROUND_DOWN_BOX",0,0,(void *)FL_GTK_ROUND_DOWN_BOX},
-{"GLEAM_UP_BOX",0,0,(void *)FL_GLEAM_UP_BOX},
-{"GLEAM_DOWN_BOX",0,0,(void *)FL_GLEAM_DOWN_BOX},
-{"GLEAM_THIN_UP_BOX",0,0,(void *)FL_GLEAM_THIN_UP_BOX},
-{"GLEAM_THIN_DOWN_BOX",0,0,(void *)FL_GLEAM_THIN_DOWN_BOX},
-{"GLEAM_ROUND_UP_BOX",0,0,(void *)FL_GLEAM_ROUND_UP_BOX},
-{"GLEAM_ROUND_DOWN_BOX",0,0,(void *)FL_GLEAM_ROUND_DOWN_BOX},
-{"OXY_UP_BOX",0,0,(void *)FL_OXY_UP_BOX},
-{"OXY_DOWN_BOX",0,0,(void *)FL_OXY_DOWN_BOX},
-{"OXY_THIN_UP_BOX",0,0,(void *)FL_OXY_THIN_UP_BOX},
-{"OXY_THIN_DOWN_BOX",0,0,(void *)FL_OXY_THIN_DOWN_BOX},
-{"OXY_ROUND_UP_BOX",0,0,(void *)FL_OXY_ROUND_UP_BOX},
-{"OXY_ROUND_DOWN_BOX",0,0,(void *)FL_OXY_ROUND_DOWN_BOX},
-{"OXY_BUTTON_UP_BOX",0,0,(void *)FL_OXY_BUTTON_UP_BOX},
-{"OXY_BUTTON_DOWN_BOX",0,0,(void *)FL_OXY_BUTTON_DOWN_BOX},
-{0},
-{"frames",0,0,0,FL_SUBMENU},
-{"UP_FRAME",0,0,(void *)FL_UP_FRAME},
-{"DOWN_FRAME",0,0,(void *)FL_DOWN_FRAME},
-{"THIN_UP_FRAME",0,0,(void *)FL_THIN_UP_FRAME},
-{"THIN_DOWN_FRAME",0,0,(void *)FL_THIN_DOWN_FRAME},
-{"ENGRAVED_FRAME",0,0,(void *)FL_ENGRAVED_FRAME},
-{"EMBOSSED_FRAME",0,0,(void *)FL_EMBOSSED_FRAME},
-{"BORDER_FRAME",0,0,(void *)FL_BORDER_FRAME},
-{"SHADOW_FRAME",0,0,(void *)FL_SHADOW_FRAME},
-{"ROUNDED_FRAME",0,0,(void *)FL_ROUNDED_FRAME},
-{"OVAL_FRAME",0,0,(void *)FL_OVAL_FRAME},
-{"PLASTIC_UP_FRAME",0,0,(void *)FL_PLASTIC_UP_FRAME},
-{"PLASTIC_DOWN_FRAME",0,0,(void *)FL_PLASTIC_DOWN_FRAME},
-{"GTK_UP_FRAME",0,0,(void *)FL_GTK_UP_FRAME},
-{"GTK_DOWN_FRAME",0,0,(void *)FL_GTK_DOWN_FRAME},
-{"GTK_THIN_UP_FRAME",0,0,(void *)FL_GTK_THIN_UP_FRAME},
-{"GTK_THIN_DOWN_FRAME",0,0,(void *)FL_GTK_THIN_DOWN_FRAME},
-{"GLEAM_UP_FRAME",0,0,(void *)FL_GLEAM_UP_FRAME},
-{"GLEAM_DOWN_FRAME",0,0,(void *)FL_GLEAM_DOWN_FRAME},
-{"OXY_UP_FRAME",0,0,(void *)FL_OXY_UP_FRAME},
-{"OXY_DOWN_FRAME",0,0,(void *)FL_OXY_DOWN_FRAME},
-{"OXY_THIN_UP_FRAME",0,0,(void *)FL_OXY_THIN_UP_FRAME},
-{"OXY_THIN_DOWN_FRAME",0,0,(void *)FL_OXY_THIN_DOWN_FRAME},
-{0},
-{0}};
-
-const char *boxname(int i) {
- if (!i) i = ZERO_ENTRY;
- for (int j = 0; j < int(sizeof(boxmenu)/sizeof(*boxmenu)); j++)
- if (boxmenu[j].argument() == i) return boxmenu[j].label();
- return 0;
-}
-
-int boxnumber(const char *i) {
- if (i[0]=='F' && i[1]=='L' && i[2]=='_') i += 3;
- for (int j = 0; j < int(sizeof(boxmenu)/sizeof(*boxmenu)); j++)
- if (boxmenu[j].label() && !strcmp(boxmenu[j].label(), i)) {
- return int(boxmenu[j].argument());
- }
- return 0;
-}
-
-void box_cb(Fl_Choice* i, void *v) {
- if (v == LOAD) {
- if (current_widget->is_a(ID_Menu_Item)) {i->deactivate(); return;} else i->activate();
- int n = current_widget->o->box(); if (!n) n = ZERO_ENTRY;
- for (int j = 0; j < int(sizeof(boxmenu)/sizeof(*boxmenu)); j++)
- if (boxmenu[j].argument() == n) {i->value(j); break;}
- } else {
- int mod = 0;
- int m = i->value();
- int n = int(boxmenu[m].argument());
- if (!n) return; // should not happen
- if (n == ZERO_ENTRY) n = 0;
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_widget()) {
- Fl_Widget_Type* q = (Fl_Widget_Type*)o;
- q->o->box((Fl_Boxtype)n);
- q->redraw();
- mod = 1;
- }
- }
- if (mod) set_modflag(1);
- }
-}
-
-void down_box_cb(Fl_Choice* i, void *v) {
- if (v == LOAD) {
- int n;
- if (current_widget->is_a(ID_Button))
- n = ((Fl_Button*)(current_widget->o))->down_box();
- else if (current_widget->is_a(ID_Input_Choice))
- n = ((Fl_Input_Choice*)(current_widget->o))->down_box();
- else if (current_widget->is_a(ID_Menu_Manager_))
- n = ((Fl_Menu_*)(current_widget->o))->down_box();
- else {
- i->deactivate(); return;
- }
- i->activate();
- if (!n) n = ZERO_ENTRY;
- for (int j = 0; j < int(sizeof(boxmenu)/sizeof(*boxmenu)); j++)
- if (boxmenu[j].argument() == n) {i->value(j); break;}
- } else {
- int mod = 0;
- int m = i->value();
- int n = int(boxmenu[m].argument());
- if (!n) return; // should not happen
- if (n == ZERO_ENTRY) n = 0;
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected) {
- if (o->is_a(ID_Button)) {
- Fl_Widget_Type* q = (Fl_Widget_Type*)o;
- ((Fl_Button*)(q->o))->down_box((Fl_Boxtype)n);
- if (((Fl_Button*)(q->o))->value()) q->redraw();
- } else if (o->is_a(ID_Input_Choice)) {
- Fl_Widget_Type* q = (Fl_Widget_Type*)o;
- ((Fl_Input_Choice*)(q->o))->down_box((Fl_Boxtype)n);
- } else if (o->is_a(ID_Menu_Manager_)) {
- Fl_Widget_Type* q = (Fl_Widget_Type*)o;
- ((Fl_Menu_*)(q->o))->down_box((Fl_Boxtype)n);
- }
- mod = 1;
- }
- }
- if (mod) set_modflag(1);
- }
-}
-
-void compact_cb(Fl_Light_Button* i, void* v) {
- if (v == LOAD) {
- uchar n;
- if (current_widget->is_a(ID_Button) && !current_widget->is_a(ID_Menu_Item)) {
- n = ((Fl_Button*)(current_widget->o))->compact();
- i->value(n);
- i->show();
- } else {
- i->hide();
- }
- } else {
- int mod = 0;
- uchar n = (uchar)i->value();
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_a(ID_Button) && !o->is_a(ID_Menu_Item)) {
- Fl_Widget_Type* q = (Fl_Widget_Type*)o;
- uchar v = ((Fl_Button*)(q->o))->compact();
- if (n != v) {
- if (!mod) {
- mod = 1;
- undo_checkpoint();
- }
- ((Fl_Button*)(q->o))->compact(n);
- q->redraw();
- }
- }
- }
- if (mod) set_modflag(1);
- }
-}
-
-
-
-////////////////////////////////////////////////////////////////
-
-Fl_Menu_Item whenmenu[] = {
- // set individual bits
- {"FL_WHEN_CHANGED",0,0,(void*)FL_WHEN_CHANGED, FL_MENU_TOGGLE},
- {"FL_WHEN_NOT_CHANGED",0,0,(void*)FL_WHEN_NOT_CHANGED, FL_MENU_TOGGLE},
- {"FL_WHEN_RELEASE",0,0,(void*)FL_WHEN_RELEASE, FL_MENU_TOGGLE},
- {"FL_WHEN_ENTER_KEY",0,0,(void*)FL_WHEN_ENTER_KEY, FL_MENU_TOGGLE},
- {"FL_WHEN_CLOSED",0,0,(void*)FL_WHEN_CLOSED, FL_MENU_TOGGLE|FL_MENU_DIVIDER},
- // set bit combinations
- {"FL_WHEN_NEVER",0,0,(void*)FL_WHEN_NEVER},
- {"FL_WHEN_RELEASE_ALWAYS",0,0,(void*)FL_WHEN_RELEASE_ALWAYS},
- {"FL_WHEN_ENTER_KEY_ALWAYS",0,0,(void*)FL_WHEN_ENTER_KEY_ALWAYS},
- {"FL_WHEN_ENTER_KEY_CHANGED",0,0,(void*)FL_WHEN_ENTER_KEY_CHANGED},
- {0}};
-
-
-static Fl_Menu_Item whensymbolmenu[] = {
- /* 0 */ {"FL_WHEN_NEVER",0,0,(void*)FL_WHEN_NEVER},
- /* 1 */ {"FL_WHEN_CHANGED",0,0,(void*)FL_WHEN_CHANGED},
- /* 2 */ {"FL_WHEN_NOT_CHANGED",0,0,(void*)FL_WHEN_NOT_CHANGED},
- /* 3 */ {"FL_WHEN_CHANGED | FL_WHEN_NOT_CHANGED",0,0,(void*)(FL_WHEN_CHANGED|FL_WHEN_NOT_CHANGED)},
- /* 4 */ {"FL_WHEN_RELEASE",0,0,(void*)FL_WHEN_RELEASE},
- /* 5 */ {"FL_WHEN_CHANGED | FL_WHEN_RELEASE",0,0,(void*)(FL_WHEN_CHANGED|FL_WHEN_RELEASE)},
- /* 6 */ {"FL_WHEN_RELEASE_ALWAYS",0,0,(void*)FL_WHEN_RELEASE_ALWAYS},
- /* 7 */ {"FL_WHEN_CHANGED | FL_WHEN_RELEASE_ALWAYS",0,0,(void*)(FL_WHEN_CHANGED|FL_WHEN_RELEASE_ALWAYS)},
- /* 8 */ {"FL_WHEN_ENTER_KEY",0,0,(void*)FL_WHEN_ENTER_KEY},
- /* 9 */ {"FL_WHEN_CHANGED | FL_WHEN_ENTER_KEY",0,0,(void*)(FL_WHEN_CHANGED|FL_WHEN_ENTER_KEY)},
- /* 10 */ {"FL_WHEN_ENTER_KEY_ALWAYS",0,0,(void*)FL_WHEN_ENTER_KEY_ALWAYS},
- /* 11 */ {"FL_WHEN_ENTER_KEY_CHANGED",0,0,(void*)FL_WHEN_ENTER_KEY_CHANGED},
- /* 12 */ {"FL_WHEN_RELEASE | FL_WHEN_ENTER_KEY",0,0,(void*)(FL_WHEN_RELEASE|FL_WHEN_ENTER_KEY)},
- /* 13 */ {"FL_WHEN_RELEASE | FL_WHEN_CHANGED | FL_WHEN_ENTER_KEY",0,0,(void*)(FL_WHEN_RELEASE|FL_WHEN_CHANGED|FL_WHEN_ENTER_KEY)},
- /* 14 */ {"FL_WHEN_RELEASE | FL_WHEN_ENTER_KEY_ALWAYS",0,0,(void*)(FL_WHEN_RELEASE|FL_WHEN_ENTER_KEY_ALWAYS)},
- /* 15 */ {"FL_WHEN_RELEASE | FL_WHEN_ENTER_KEY_CHANGED",0,0,(void*)(FL_WHEN_RELEASE|FL_WHEN_ENTER_KEY_CHANGED)},
- {0}
-};
-
-// Return a text string representing the Fl_When value n
-const char* when_symbol_name(int n) {
- static char sym[128];
- if (n == FL_WHEN_CLOSED) {
- strcpy(sym, "FL_WHEN_CLOSED");
- } else {
- strcpy(sym, whensymbolmenu[n&15].label());
- if (n & FL_WHEN_CLOSED)
- strcat(sym, " | FL_WHEN_CLOSED");
- }
- return sym;
-}
-
-// Set the check marks in the "when()" menu according to the Fl_When value n
-void set_whenmenu(int n) {
- if (n&FL_WHEN_CHANGED) whenmenu[0].set(); else whenmenu[0].clear();
- if (n&FL_WHEN_NOT_CHANGED) whenmenu[1].set(); else whenmenu[1].clear();
- if (n&FL_WHEN_RELEASE) whenmenu[2].set(); else whenmenu[2].clear();
- if (n&FL_WHEN_ENTER_KEY) whenmenu[3].set(); else whenmenu[3].clear();
- if (n&FL_WHEN_CLOSED) whenmenu[4].set(); else whenmenu[4].clear();
-}
-
-void when_cb(Fl_Menu_Button* i, void *v) {
- if (v == LOAD) {
- if (current_widget->is_a(ID_Menu_Item)) {i->deactivate(); return;} else i->activate();
- int n = current_widget->o->when();
- set_whenmenu(n);
- w_when_box->copy_label(when_symbol_name(n));
- } else {
- int mod = 0;
- int n = 0;
- if (i->mvalue() && ((i->mvalue()->flags & FL_MENU_TOGGLE) == 0) ) {
- n = (int)i->mvalue()->argument();
- set_whenmenu(n);
- } else {
- if (whenmenu[0].value()) n |= FL_WHEN_CHANGED;
- if (whenmenu[1].value()) n |= FL_WHEN_NOT_CHANGED;
- if (whenmenu[2].value()) n |= FL_WHEN_RELEASE;
- if (whenmenu[3].value()) n |= FL_WHEN_ENTER_KEY;
- if (whenmenu[4].value()) n |= FL_WHEN_CLOSED;
- }
- w_when_box->copy_label(when_symbol_name(n));
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_widget()) {
- Fl_Widget_Type* q = (Fl_Widget_Type*)o;
- q->o->when(n);
- mod = 1;
- }
- }
- if (mod) set_modflag(1);
- }
-}
-
-uchar Fl_Widget_Type::resizable() const {
- if (is_a(ID_Window)) return ((Fl_Window*)o)->resizable() != 0;
- Fl_Group* p = (Fl_Group*)o->parent();
- if (p) return p->resizable() == o;
- else return 0;
-}
-
-void Fl_Widget_Type::resizable(uchar v) {
- if (v) {
- if (resizable()) return;
- if (is_a(ID_Window)) ((Fl_Window*)o)->resizable(o);
- else {
- Fl_Group* p = (Fl_Group*)o->parent();
- if (p) p->resizable(o);
- }
- } else {
- if (!resizable()) return;
- if (is_a(ID_Window)) {
- ((Fl_Window*)o)->resizable(0);
- } else {
- Fl_Group* p = (Fl_Group*)o->parent();
- if (p) p->resizable(0);
- }
- }
-}
-
-void resizable_cb(Fl_Light_Button* i,void* v) {
- if (v == LOAD) {
- if (current_widget->is_a(ID_Menu_Item)) {i->deactivate(); return;}
- if (numselected > 1) {i->deactivate(); return;}
- i->activate();
- i->value(current_widget->resizable());
- } else {
- undo_checkpoint();
- current_widget->resizable(i->value());
- set_modflag(1);
- }
-}
-
-void hotspot_cb(Fl_Light_Button* i,void* v) {
- if (v == LOAD) {
- if (numselected > 1) {i->deactivate(); return;}
- if (current_widget->is_a(ID_Menu_Item)) i->label("divider");
- else i->label("hotspot");
- i->activate();
- i->value(current_widget->hotspot());
- } else {
- undo_checkpoint();
- current_widget->hotspot(i->value());
- if (current_widget->is_a(ID_Menu_Item)) {
- current_widget->redraw();
- return;
- }
- if (i->value()) {
- Fl_Type *p = current_widget->parent;
- if (!p || !p->is_widget()) return;
- while (!p->is_a(ID_Window)) p = p->parent;
- for (Fl_Type *o = p->next; o && o->level > p->level; o = o->next) {
- if (o->is_widget() && o != current_widget)
- ((Fl_Widget_Type*)o)->hotspot(0);
- }
- }
- set_modflag(1);
- }
-}
-
-void visible_cb(Fl_Light_Button* i, void* v) {
- if (v == LOAD) {
- i->value(current_widget->o->visible());
- if (current_widget->is_a(ID_Window)) i->deactivate();
- else i->activate();
- } else {
- int mod = 0;
- int n = i->value();
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_widget()) {
- if (!mod) {
- mod = 1;
- undo_checkpoint();
- }
- Fl_Widget_Type* q = (Fl_Widget_Type*)o;
- n ? q->o->show() : q->o->hide();
- q->redraw();
- if (n && q->parent && q->parent->type_name()) {
- if (q->parent->is_a(ID_Tabs)) {
- ((Fl_Tabs *)q->o->parent())->value(q->o);
- } else if (q->parent->is_a(ID_Wizard)) {
- ((Fl_Wizard *)q->o->parent())->value(q->o);
- }
- }
- }
- }
- if (mod) {
- set_modflag(1);
- redraw_browser();
- }
- }
-}
-
-void active_cb(Fl_Light_Button* i, void* v) {
- if (v == LOAD) {
- i->value(current_widget->o->active());
- if (current_widget->is_a(ID_Window)) i->deactivate();
- else i->activate();
- } else {
- int mod = 0;
- int n = i->value();
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_widget()) {
- if (!mod) {
- mod = 1;
- undo_checkpoint();
- }
- Fl_Widget_Type* q = (Fl_Widget_Type*)o;
- n ? q->o->activate() : q->o->deactivate();
- q->redraw();
- }
- }
- if (mod) set_modflag(1);
- }
-}
-
-////////////////////////////////////////////////////////////////
-
-Fl_Menu_Item fontmenu[] = {
- {"Helvetica"},
- {"Helvetica bold"},
- {"Helvetica italic"},
- {"Helvetica bold italic"},
- {"Courier"},
- {"Courier bold"},
- {"Courier italic"},
- {"Courier bold italic"},
- {"Times"},
- {"Times bold"},
- {"Times italic"},
- {"Times bold italic"},
- {"Symbol"},
- {"Terminal"},
- {"Terminal Bold"},
- {"Zapf Dingbats"},
- {NULL}
-};
-
-Fl_Menu_Item fontmenu_w_default[] = {
- {"<default>", 0, NULL, NULL, FL_MENU_DIVIDER},
- {"Helvetica"},
- {"Helvetica bold"},
- {"Helvetica italic"},
- {"Helvetica bold italic"},
- {"Courier"},
- {"Courier bold"},
- {"Courier italic"},
- {"Courier bold italic"},
- {"Times"},
- {"Times bold"},
- {"Times italic"},
- {"Times bold italic"},
- {"Symbol"},
- {"Terminal"},
- {"Terminal Bold"},
- {"Zapf Dingbats"},
- {NULL}
-};
-
-void labelfont_cb(Fl_Choice* i, void *v) {
- if (v == LOAD) {
- int n = current_widget->o->labelfont();
- if (n > 15) n = 0;
- i->value(n);
- } else {
- int mod = 0;
- int n = i->value();
- if (n <= 0) n = layout->labelfont;
- if (n <= 0) n = FL_HELVETICA;
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_widget()) {
- Fl_Widget_Type* q = (Fl_Widget_Type*)o;
- q->o->labelfont(n);
- q->redraw();
- mod = 1;
- }
- }
- if (mod) set_modflag(1);
- }
-}
-
-void labelsize_cb(Fl_Value_Input* i, void *v) {
- int n;
- if (v == LOAD) {
- n = current_widget->o->labelsize();
- } else {
- int mod = 0;
- n = int(i->value());
- if (n <= 0) n = layout->labelsize;
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_widget()) {
- Fl_Widget_Type* q = (Fl_Widget_Type*)o;
- q->o->labelsize(n);
- q->redraw();
- mod = 1;
- }
- }
- if (mod) set_modflag(1);
- }
- i->value(n);
-}
-
-extern const char *ui_find_image_name;
-
-Fl_Menu_Item labeltypemenu[] = {
- {"NORMAL_LABEL",0,0,(void*)0},
- {"SHADOW_LABEL",0,0,(void*)FL_SHADOW_LABEL},
- {"ENGRAVED_LABEL",0,0,(void*)FL_ENGRAVED_LABEL},
- {"EMBOSSED_LABEL",0,0,(void*)FL_EMBOSSED_LABEL},
- {"NO_LABEL",0,0,(void*)(FL_NO_LABEL)},
-{0}};
-
-void labeltype_cb(Fl_Choice* i, void *v) {
- if (v == LOAD) {
- int n;
- n = current_widget->o->labeltype();
- i->when(FL_WHEN_RELEASE);
- for (int j = 0; j < int(sizeof(labeltypemenu)/sizeof(*labeltypemenu)); j++)
- if (labeltypemenu[j].argument() == n) {i->value(j); break;}
- } else {
- int mod = 0;
- int m = i->value();
- int n = int(labeltypemenu[m].argument());
- if (n<0) return; // should not happen
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_widget()) {
- Fl_Widget_Type* p = (Fl_Widget_Type*)o;
- p->o->labeltype((Fl_Labeltype)n);
- p->redraw();
- mod = 1;
- }
- }
- if (mod) set_modflag(1);
- }
-}
-
-////////////////////////////////////////////////////////////////
-
-Fl_Menu_Item colormenu[] = {
- { "Foreground Color", 0, 0, (void*)(fl_intptr_t)FL_FOREGROUND_COLOR, 0, 0, FL_HELVETICA, 11},
- { "Background Color", 0, 0, (void*)(fl_intptr_t)FL_BACKGROUND_COLOR, 0, 0, FL_HELVETICA, 11},
- { "Background Color 2", 0, 0, (void*)(fl_intptr_t)FL_BACKGROUND2_COLOR, 0, 0, FL_HELVETICA, 11},
- { "Selection Color", 0, 0, (void*)(fl_intptr_t)FL_SELECTION_COLOR, 0, 0, FL_HELVETICA, 11},
- { "Inactive Color", 0, 0, (void*)(fl_intptr_t)FL_INACTIVE_COLOR, FL_MENU_DIVIDER, 0, FL_HELVETICA, 11},
- { "Black", 0, 0, (void*)(fl_intptr_t)FL_BLACK, 0, 0, FL_HELVETICA, 11},
- { "White", 0, 0, (void*)(fl_intptr_t)FL_WHITE, FL_MENU_DIVIDER, 0, FL_HELVETICA, 11},
- { "Gray 0", 0, 0, (void*)(fl_intptr_t)FL_GRAY0, 0, 0, FL_HELVETICA, 11},
- { "Dark 3", 0, 0, (void*)(fl_intptr_t)FL_DARK3, 0, 0, FL_HELVETICA, 11},
- { "Dark 2", 0, 0, (void*)(fl_intptr_t)FL_DARK2, 0, 0, FL_HELVETICA, 11},
- { "Dark 1", 0, 0, (void*)(fl_intptr_t)FL_DARK1, 0, 0, FL_HELVETICA, 11},
- { "Light 1", 0, 0, (void*)(fl_intptr_t)FL_LIGHT1, 0, 0, FL_HELVETICA, 11},
- { "Light 2", 0, 0, (void*)(fl_intptr_t)FL_LIGHT2, 0, 0, FL_HELVETICA, 11},
- { "Light 3", 0, 0, (void*)(fl_intptr_t)FL_LIGHT3, 0, 0, FL_HELVETICA, 11},
- { 0 }
-};
-
-void color_common(Fl_Color c) {
- int mod = 0;
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_widget()) {
- Fl_Widget_Type* q = (Fl_Widget_Type*)o;
- q->o->color(c); q->o->redraw();
- if (q->parent && q->parent->is_a(ID_Tabs)) {
- if (q->o->parent()) q->o->parent()->redraw();
- }
- mod = 1;
- }
- }
- if (mod) set_modflag(1);
-}
-
-void color_cb(Fl_Button* i, void *v) {
- Fl_Color c = current_widget->o->color();
- if (v == LOAD) {
- if (current_widget->is_a(ID_Menu_Item)) {i->deactivate(); return;} else i->activate();
- } else {
- Fl_Color d = fl_show_colormap(c);
- if (d == c) return;
- c = d;
- color_common(c);
- }
- i->color(c); i->labelcolor(fl_contrast(FL_BLACK,c)); i->redraw();
-}
-
-void color_menu_cb(Fl_Menu_Button* i, void *v) {
- Fl_Color c = current_widget->o->color();
- if (v == LOAD) {
- if (current_widget->is_a(ID_Menu_Item)) {i->deactivate(); return;} else i->activate();
- } else {
- Fl_Color d = (Fl_Color)(i->mvalue()->argument());
- if (d == c) return;
- c = d;
- color_common(c);
- w_color->color(c); w_color->labelcolor(fl_contrast(FL_BLACK,c)); w_color->redraw();
- }
-}
-
-void color2_common(Fl_Color c) {
- int mod = 0;
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_widget()) {
- Fl_Widget_Type* q = (Fl_Widget_Type*)o;
- q->o->selection_color(c); q->o->redraw();
- mod = 1;
- }
- }
- if (mod) set_modflag(1);
-}
-
-void color2_cb(Fl_Button* i, void *v) {
- Fl_Color c = current_widget->o->selection_color();
- if (v == LOAD) {
- if (current_widget->is_a(ID_Menu_Item)) {i->deactivate(); return;} else i->activate();
- } else {
- Fl_Color d = fl_show_colormap(c);
- if (d == c) return;
- c = d;
- color2_common(c);
- }
- i->color(c); i->labelcolor(fl_contrast(FL_BLACK,c)); i->redraw();
-}
-
-void color2_menu_cb(Fl_Menu_Button* i, void *v) {
- Fl_Color c = current_widget->o->selection_color();
- if (v == LOAD) {
- if (current_widget->is_a(ID_Menu_Item)) {i->deactivate(); return;} else i->activate();
- } else {
- Fl_Color d = (Fl_Color)(i->mvalue()->argument());
- if (d == c) return;
- c = d;
- color2_common(c);
- w_selectcolor->color(c); w_selectcolor->labelcolor(fl_contrast(FL_BLACK,c)); w_selectcolor->redraw();
- }
-}
-
-void labelcolor_common(Fl_Color c) {
- int mod = 0;
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_widget()) {
- Fl_Widget_Type* q = (Fl_Widget_Type*)o;
- q->o->labelcolor(c); q->redraw();
- mod = 1;
- }
- }
- if (mod) set_modflag(1);
-}
-
-void labelcolor_cb(Fl_Button* i, void *v) {
- Fl_Color c = current_widget->o->labelcolor();
- if (v != LOAD) {
- Fl_Color d = fl_show_colormap(c);
- if (d == c) return;
- c = d;
- labelcolor_common(c);
- }
- i->color(c); i->labelcolor(fl_contrast(FL_BLACK,c)); i->redraw();
-}
-
-void labelcolor_menu_cb(Fl_Menu_Button* i, void *v) {
- Fl_Color c = current_widget->o->labelcolor();
- if (v != LOAD) {
- Fl_Color d = (Fl_Color)(i->mvalue()->argument());
- if (d == c) return;
- c = d;
- labelcolor_common(c);
- w_labelcolor->color(c); w_labelcolor->labelcolor(fl_contrast(FL_BLACK,c)); w_labelcolor->redraw();
- }
-}
-
-static Fl_Button* relative(Fl_Widget* o, int i) {
- Fl_Group* g = (Fl_Group*)(o->parent());
- return (Fl_Button*)(g->child(g->find(*o)+i));
-}
-
-static Fl_Menu_Item alignmenu[] = {
- {"FL_ALIGN_CENTER",0,0,(void*)(fl_intptr_t)(FL_ALIGN_CENTER)},
- {"FL_ALIGN_TOP",0,0,(void*)(fl_intptr_t)(FL_ALIGN_TOP)},
- {"FL_ALIGN_BOTTOM",0,0,(void*)(fl_intptr_t)(FL_ALIGN_BOTTOM)},
- {"FL_ALIGN_LEFT",0,0,(void*)(fl_intptr_t)(FL_ALIGN_LEFT)},
- {"FL_ALIGN_RIGHT",0,0,(void*)(fl_intptr_t)(FL_ALIGN_RIGHT)},
- {"FL_ALIGN_INSIDE",0,0,(void*)(fl_intptr_t)(FL_ALIGN_INSIDE)},
- {"FL_ALIGN_CLIP",0,0,(void*)(fl_intptr_t)(FL_ALIGN_CLIP)},
- {"FL_ALIGN_WRAP",0,0,(void*)(fl_intptr_t)(FL_ALIGN_WRAP)},
- {"FL_ALIGN_TEXT_OVER_IMAGE",0,0,(void*)(fl_intptr_t)(FL_ALIGN_TEXT_OVER_IMAGE)},
- {"FL_ALIGN_TOP_LEFT",0,0,(void*)(fl_intptr_t)(FL_ALIGN_TOP_LEFT)},
- {"FL_ALIGN_TOP_RIGHT",0,0,(void*)(fl_intptr_t)(FL_ALIGN_TOP_RIGHT)},
- {"FL_ALIGN_BOTTOM_LEFT",0,0,(void*)(fl_intptr_t)(FL_ALIGN_BOTTOM_LEFT)},
- {"FL_ALIGN_BOTTOM_RIGHT",0,0,(void*)(fl_intptr_t)(FL_ALIGN_BOTTOM_RIGHT)},
- {"FL_ALIGN_LEFT_TOP",0,0,(void*)(fl_intptr_t)(FL_ALIGN_LEFT_TOP)},
- {"FL_ALIGN_RIGHT_TOP",0,0,(void*)(fl_intptr_t)(FL_ALIGN_RIGHT_TOP)},
- {"FL_ALIGN_LEFT_BOTTOM",0,0,(void*)(fl_intptr_t)(FL_ALIGN_LEFT_BOTTOM)},
- {"FL_ALIGN_RIGHT_BOTTOM",0,0,(void*)(fl_intptr_t)(FL_ALIGN_RIGHT_BOTTOM)},
-{0}};
-
-void align_cb(Fl_Button* i, void *v) {
- Fl_Align b = Fl_Align(fl_uintptr_t(i->user_data()));
- if (v == LOAD) {
- if (current_widget->is_a(ID_Menu_Item)) {i->deactivate(); return;} else i->activate();
- i->value(current_widget->o->align() & b);
- } else {
- int mod = 0;
- undo_checkpoint();
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_widget()) {
- Fl_Widget_Type* q = (Fl_Widget_Type*)o;
- Fl_Align x = q->o->align();
- Fl_Align y;
- if (i->value()) {
- y = x | b;
- if (b == FL_ALIGN_LEFT || b == FL_ALIGN_TOP) {
- Fl_Button *b1 = relative(i,+1);
- b1->clear();
- y = y & ~(b1->argument());
- }
- if (b == FL_ALIGN_RIGHT || b == FL_ALIGN_BOTTOM) {
- Fl_Button *b1 = relative(i,-1);
- b1->clear();
- y = y & ~(b1->argument());
- }
- } else {
- y = x & ~b;
- }
- if (x != y) {
- q->o->align(y);
- q->redraw();
- mod = 1;
- }
- }
- }
- if (mod) set_modflag(1);
- }
-}
-
-void align_position_cb(Fl_Choice *i, void *v) {
- if (v == LOAD) {
- if (current_widget->is_a(ID_Menu_Item)) {i->deactivate(); return;} else i->activate();
- Fl_Menu_Item *mi = (Fl_Menu_Item*)i->menu();
- Fl_Align b = current_widget->o->align() & FL_ALIGN_POSITION_MASK;
- for (;mi->text;mi++) {
- if ((Fl_Align)(mi->argument())==b)
- i->value(mi);
- }
- } else {
- const Fl_Menu_Item *mi = i->menu() + i->value();
- Fl_Align b = Fl_Align(fl_uintptr_t(mi->user_data()));
- int mod = 0;
- undo_checkpoint();
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_widget()) {
- Fl_Widget_Type* q = (Fl_Widget_Type*)o;
- Fl_Align x = q->o->align();
- Fl_Align y = (x & ~FL_ALIGN_POSITION_MASK) | b;
- if (x != y) {
- q->o->align(y);
- q->redraw();
- mod = 1;
- }
- }
- }
- if (mod) set_modflag(1);
- }
-}
-
-void align_text_image_cb(Fl_Choice *i, void *v) {
- if (v == LOAD) {
- if (current_widget->is_a(ID_Menu_Item)) {i->deactivate(); return;} else i->activate();
- Fl_Menu_Item *mi = (Fl_Menu_Item*)i->menu();
- Fl_Align b = current_widget->o->align() & FL_ALIGN_IMAGE_MASK;
- for (;mi->text;mi++) {
- if ((Fl_Align)(mi->argument())==b)
- i->value(mi);
- }
- } else {
- const Fl_Menu_Item *mi = i->menu() + i->value();
- Fl_Align b = Fl_Align(fl_uintptr_t(mi->user_data()));
- int mod = 0;
- undo_checkpoint();
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_widget()) {
- Fl_Widget_Type* q = (Fl_Widget_Type*)o;
- Fl_Align x = q->o->align();
- Fl_Align y = (x & ~FL_ALIGN_IMAGE_MASK) | b;
- if (x != y) {
- q->o->align(y);
- q->redraw();
- mod = 1;
- }
- }
- }
- if (mod) set_modflag(1);
- }
-}
-
-////////////////////////////////////////////////////////////////
-
-void callback_cb(fld::widget::Code_Editor* i, void *v) {
- if (v == LOAD) {
- const char *cbtext = current_widget->callback();
- i->buffer()->text( cbtext ? cbtext : "" );
- } else {
- int mod = 0;
- char *c = i->buffer()->text();
- const char *d = c_check(c);
- if (d) {
- fl_message("Error in callback: %s",d);
- if (i->window()) i->window()->make_current();
- haderror = 1;
- }
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected) {
- o->callback(c);
- mod = 1;
- }
- }
- if (mod) set_modflag(1);
- free(c);
- }
-}
-
-void comment_cb(Fl_Text_Editor* i, void *v) {
- if (v == LOAD) {
- const char *cmttext = current_widget->comment();
- i->buffer()->text( cmttext ? cmttext : "" );
- } else {
- int mod = 0;
- char *c = i->buffer()->text();
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected) {
- o->comment(c);
- mod = 1;
- }
- }
- if (mod) set_modflag(1);
- free(c);
- }
-}
-
-void user_data_cb(Fl_Input *i, void *v) {
- if (v == LOAD) {
- i->value(current_widget->user_data());
- } else {
- int mod = 0;
- const char *c = i->value();
- const char *d = c_check(c);
- if (d) {fl_message("Error in user_data: %s",d); haderror = 1; return;}
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected) {
- o->user_data(c);
- mod = 1;
- }
- }
- if (mod) set_modflag(1);
- }
-}
-
-void user_data_type_cb(Fl_Input_Choice *i, void *v) {
- static const char *dflt = "void*";
- if (v == LOAD) {
- const char *c = current_widget->user_data_type();
- if (!c) c = dflt;
- i->value(c);
- } else {
- int mod = 0;
- const char *c = i->value();
- const char *d = c_check(c);
- if (!*c) i->value(dflt);
- else if (!strcmp(c,dflt)) c = 0;
- if (!d) {
- if (c && *c && c[strlen(c)-1] != '*' && strcmp(c,"long"))
- d = "must be pointer or long";
- }
- if (d) {fl_message("Error in type: %s",d); haderror = 1; return;}
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected) {
- o->user_data_type(c);
- mod = 1;
- }
- }
- if (mod) set_modflag(1);
- }
-}
-
-// "v_attributes" let user type in random code for attribute settings:
-
-void v_input_cb(Fl_Input* i, void* v) {
- int n = fl_int(i->user_data());
- if (v == LOAD) {
- i->value(current_widget->extra_code(n));
- } else {
- int mod = 0;
- const char *c = i->value();
- const char *d = c_check(c&&c[0]=='#' ? c+1 : c);
- if (d) {fl_message("Error in %s: %s",i->label(),d); haderror = 1; return;}
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_widget()) {
- Fl_Widget_Type *t = (Fl_Widget_Type*)o;
- t->extra_code(n,c);
- mod = 1;
- }
- }
- if (mod) set_modflag(1);
- }
-}
-
-void subclass_cb(Fl_Input* i, void* v) {
- if (v == LOAD) {
- if (current_widget->is_a(ID_Menu_Item)) {i->deactivate(); return;} else i->activate();
- i->value(current_widget->subclass());
- } else {
- int mod = 0;
- const char *c = i->value();
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_widget()) {
- Fl_Widget_Type *t = (Fl_Widget_Type*)o;
- t->subclass(c);
- mod = 1;
- }
- }
- if (mod) set_modflag(1);
- }
-}
-
-////////////////////////////////////////////////////////////////
-
-// textstuff: set textfont, textsize, textcolor attributes:
-
-// default widget returns 0 to indicate not-implemented:
-// The first parameter specifies the operation:
-// 0: get all values
-// 1: set the text font
-// 2: set the text size
-// 3: set the text color
-// 4: get all default values for this type
-int Fl_Widget_Type::textstuff(int, Fl_Font&, int&, Fl_Color&) {
- return 0;
-}
-
-void textfont_cb(Fl_Choice* i, void* v) {
- Fl_Font n; int s; Fl_Color c;
- if (v == LOAD) {
- if (!current_widget->textstuff(0,n,s,c)) {i->deactivate(); return;}
- i->activate();
- if (n > 15) n = FL_HELVETICA;
- i->value(n);
- } else {
- int mod = 0;
- n = (Fl_Font)i->value();
- if (n <= 0) n = layout->textfont;
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_widget()) {
- Fl_Widget_Type* q = (Fl_Widget_Type*)o;
- q->textstuff(1,n,s,c);
- q->o->redraw();
- mod = 1;
- }
- }
- if (mod) set_modflag(1);
- }
-}
-
-void textsize_cb(Fl_Value_Input* i, void* v) {
- Fl_Font n; int s; Fl_Color c;
- if (v == LOAD) {
- if (!current_widget->textstuff(0,n,s,c)) {i->deactivate(); return;}
- i->activate();
- } else {
- int mod = 0;
- s = int(i->value());
- if (s <= 0) s = layout->textsize;
- if (s <= 0) s = layout->labelsize;
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_widget()) {
- Fl_Widget_Type* q = (Fl_Widget_Type*)o;
- q->textstuff(2,n,s,c);
- q->o->redraw();
- mod = 1;
- }
- }
- if (mod) set_modflag(1);
- }
- i->value(s);
-}
-
-void textcolor_common(Fl_Color c) {
- Fl_Font n; int s;
- int mod = 0;
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_widget()) {
- Fl_Widget_Type* q = (Fl_Widget_Type*)o;
- q->textstuff(3,n,s,c); q->o->redraw();
- mod = 1;
- }
- }
- if (mod) set_modflag(1);
-}
-
-void textcolor_cb(Fl_Button* i, void* v) {
- Fl_Font n; int s; Fl_Color c;
- if (v == LOAD) {
- if (!current_widget->textstuff(0,n,s,c)) {i->deactivate(); return;}
- i->activate();
- } else {
- c = i->color();
- Fl_Color d = fl_show_colormap(c);
- if (d == c) return;
- c = d;
- textcolor_common(c);
- }
- i->color(c); i->labelcolor(fl_contrast(FL_BLACK,c)); i->redraw();
-}
-
-void textcolor_menu_cb(Fl_Menu_Button* i, void* v) {
- Fl_Font n; int s; Fl_Color c;
- if (v == LOAD) {
- if (!current_widget->textstuff(0,n,s,c)) {i->deactivate(); return;}
- i->activate();
- } else {
- c = i->color();
- Fl_Color d = (Fl_Color)(i->mvalue()->argument());
- if (d == c) return;
- c = d;
- textcolor_common(c);
- w_textcolor->color(c); w_textcolor->labelcolor(fl_contrast(FL_BLACK,c)); w_textcolor->redraw();
- }
-}
-
-void image_spacing_cb(Fl_Value_Input* i, void* v) {
- int s;
- if (v == LOAD) {
- if (!current_widget->is_true_widget()) {
- i->deactivate();
- i->value(0);
- } else {
- i->activate();
- i->value(((Fl_Widget_Type*)current_widget)->o->label_image_spacing());
- }
- } else {
- int mod = 0;
- s = int(i->value());
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_true_widget()) {
- Fl_Widget_Type* q = (Fl_Widget_Type*)o;
- if (q->o->label_image_spacing() != s) {
- q->o->label_image_spacing(s);
- if (!(q->o->align() & FL_ALIGN_INSIDE) && q->o->window())
- q->o->window()->damage(FL_DAMAGE_EXPOSE); // outside labels
- q->o->redraw();
- mod = 1;
- }
- }
- }
- if (mod) set_modflag(1);
- }
-}
-
-void h_label_margin_cb(Fl_Value_Input* i, void* v) {
- int s;
- if (v == LOAD) {
- if (!current_widget->is_true_widget()) {
- i->deactivate();
- i->value(0);
- } else {
- i->activate();
- i->value(((Fl_Widget_Type*)current_widget)->o->horizontal_label_margin());
- }
- } else {
- int mod = 0;
- s = int(i->value());
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_true_widget()) {
- Fl_Widget_Type* q = (Fl_Widget_Type*)o;
- if (q->o->horizontal_label_margin() != s) {
- q->o->horizontal_label_margin(s);
- if (!(q->o->align() & FL_ALIGN_INSIDE) && q->o->window())
- q->o->window()->damage(FL_DAMAGE_EXPOSE); // outside labels
- q->o->redraw();
- mod = 1;
- }
- }
- }
- if (mod) set_modflag(1);
- }
-}
-
-void v_label_margin_cb(Fl_Value_Input* i, void* v) {
- int s;
- if (v == LOAD) {
- if (!current_widget->is_true_widget()) {
- i->deactivate();
- i->value(0);
- } else {
- i->activate();
- i->value(((Fl_Widget_Type*)current_widget)->o->vertical_label_margin());
- }
- } else {
- int mod = 0;
- s = int(i->value());
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_true_widget()) {
- Fl_Widget_Type* q = (Fl_Widget_Type*)o;
- if (q->o->vertical_label_margin() != s) {
- q->o->vertical_label_margin(s);
- if (!(q->o->align() & FL_ALIGN_INSIDE) && q->o->window())
- q->o->window()->damage(FL_DAMAGE_EXPOSE); // outside labels
- q->o->redraw();
- mod = 1;
- }
- }
- }
- if (mod) set_modflag(1);
- }
-}
-
-////////////////////////////////////////////////////////////////
-// Kludges to the panel for subclasses:
-
-void min_w_cb(Fl_Value_Input* i, void* v) {
- if (v == LOAD) {
- if (!current_widget->is_a(ID_Window)) return;
- i->value(((Fl_Window_Type*)current_widget)->sr_min_w);
- } else {
- int mod = 0;
- undo_checkpoint();
- int n = (int)i->value();
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_a(ID_Window)) {
- ((Fl_Window_Type*)current_widget)->sr_min_w = n;
- mod = 1;
- }
- }
- if (mod) set_modflag(1);
- }
-}
-
-void min_h_cb(Fl_Value_Input* i, void* v) {
- if (v == LOAD) {
- if (!current_widget->is_a(ID_Window)) return;
- i->value(((Fl_Window_Type*)current_widget)->sr_min_h);
- } else {
- int mod = 0;
- undo_checkpoint();
- int n = (int)i->value();
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_a(ID_Window)) {
- ((Fl_Window_Type*)current_widget)->sr_min_h = n;
- mod = 1;
- }
- }
- if (mod) set_modflag(1);
- }
-}
-
-void max_w_cb(Fl_Value_Input* i, void* v) {
- if (v == LOAD) {
- if (!current_widget->is_a(ID_Window)) return;
- i->value(((Fl_Window_Type*)current_widget)->sr_max_w);
- } else {
- int mod = 0;
- undo_checkpoint();
- int n = (int)i->value();
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_a(ID_Window)) {
- ((Fl_Window_Type*)current_widget)->sr_max_w = n;
- mod = 1;
- }
- }
- if (mod) set_modflag(1);
- }
-}
-
-void max_h_cb(Fl_Value_Input* i, void* v) {
- if (v == LOAD) {
- if (!current_widget->is_a(ID_Window)) return;
- i->value(((Fl_Window_Type*)current_widget)->sr_max_h);
- } else {
- int mod = 0;
- undo_checkpoint();
- int n = (int)i->value();
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_a(ID_Window)) {
- ((Fl_Window_Type*)current_widget)->sr_max_h = n;
- mod = 1;
- }
- }
- if (mod) set_modflag(1);
- }
-}
-
-void set_min_size_cb(Fl_Button*, void* v) {
- if (v == LOAD) {
- } else {
- int mod = 0;
- undo_checkpoint();
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_a(ID_Window)) {
- Fl_Window_Type *win = (Fl_Window_Type*)current_widget;
- win->sr_min_w = win->o->w();
- win->sr_min_h = win->o->h();
- mod = 1;
- }
- }
- propagate_load(the_panel, LOAD);
- if (mod) set_modflag(1);
- }
-}
-
-void set_max_size_cb(Fl_Button*, void* v) {
- if (v == LOAD) {
- } else {
- int mod = 0;
- undo_checkpoint();
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_a(ID_Window)) {
- Fl_Window_Type *win = (Fl_Window_Type*)current_widget;
- win->sr_max_w = win->o->w();
- win->sr_max_h = win->o->h();
- mod = 1;
- }
- }
- propagate_load(the_panel, LOAD);
- if (mod) set_modflag(1);
- }
-}
-
-void slider_size_cb(Fl_Value_Input* i, void* v) {
- if (v == LOAD) {
- if (!current_widget->is_a(ID_Slider)) {i->deactivate(); return;}
- i->activate();
- i->value(((Fl_Slider*)(current_widget->o))->slider_size());
- } else {
- int mod = 0;
- undo_checkpoint();
- double n = i->value();
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_widget()) {
- Fl_Widget_Type* q = (Fl_Widget_Type*)o;
- if (q->is_a(ID_Slider)) {
- ((Fl_Slider*)(q->o))->slider_size(n);
- q->o->redraw();
- mod = 1;
- }
- }
- }
- if (mod) set_modflag(1);
- }
-}
-
-void min_cb(Fl_Value_Input* i, void* v) {
- if (v == LOAD) {
- if (current_widget->is_a(ID_Valuator_)) {
- i->activate();
- i->value(((Fl_Valuator*)(current_widget->o))->minimum());
- } else if (current_widget->is_a(ID_Spinner)) {
- i->activate();
- i->value(((Fl_Spinner*)(current_widget->o))->minimum());
- } else {
- i->deactivate();
- return;
- }
- } else {
- int mod = 0;
- undo_checkpoint();
- double n = i->value();
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_widget()) {
- Fl_Widget_Type* q = (Fl_Widget_Type*)o;
- if (q->is_a(ID_Valuator_)) {
- ((Fl_Valuator*)(q->o))->minimum(n);
- q->o->redraw();
- mod = 1;
- } else if (q->is_a(ID_Spinner)) {
- ((Fl_Spinner*)(q->o))->minimum(n);
- q->o->redraw();
- mod = 1;
- }
- }
- }
- if (mod) set_modflag(1);
- }
-}
-
-void max_cb(Fl_Value_Input* i, void* v) {
- if (v == LOAD) {
- if (current_widget->is_a(ID_Valuator_)) {
- i->activate();
- i->value(((Fl_Valuator*)(current_widget->o))->maximum());
- } else if (current_widget->is_a(ID_Spinner)) {
- i->activate();
- i->value(((Fl_Spinner*)(current_widget->o))->maximum());
- } else {
- i->deactivate();
- return;
- }
- } else {
- int mod = 0;
- undo_checkpoint();
- double n = i->value();
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_widget()) {
- Fl_Widget_Type* q = (Fl_Widget_Type*)o;
- if (q->is_a(ID_Valuator_)) {
- ((Fl_Valuator*)(q->o))->maximum(n);
- q->o->redraw();
- mod = 1;
- } else if (q->is_a(ID_Spinner)) {
- ((Fl_Spinner*)(q->o))->maximum(n);
- q->o->redraw();
- mod = 1;
- }
- }
- }
- if (mod) set_modflag(1);
- }
-}
-
-void step_cb(Fl_Value_Input* i, void* v) {
- if (v == LOAD) {
- if (current_widget->is_a(ID_Valuator_)) {
- i->activate();
- i->value(((Fl_Valuator*)(current_widget->o))->step());
- } else if (current_widget->is_a(ID_Spinner)) {
- i->activate();
- i->value(((Fl_Spinner*)(current_widget->o))->step());
- } else {
- i->deactivate();
- return;
- }
- } else {
- int mod = 0;
- undo_checkpoint();
- double n = i->value();
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_widget()) {
- Fl_Widget_Type* q = (Fl_Widget_Type*)o;
- if (q->is_a(ID_Valuator_)) {
- ((Fl_Valuator*)(q->o))->step(n);
- q->o->redraw();
- mod = 1;
- } else if (q->is_a(ID_Spinner)) {
- ((Fl_Spinner*)(q->o))->step(n);
- q->o->redraw();
- mod = 1;
- }
- }
- }
- if (mod) set_modflag(1);
- }
-}
-
-void value_cb(Fl_Value_Input* i, void* v) {
- if (v == LOAD) {
- if (current_widget->is_a(ID_Valuator_)) {
- i->activate();
- i->value(((Fl_Valuator*)(current_widget->o))->value());
- } else if (current_widget->is_button()) {
- i->activate();
- i->value(((Fl_Button*)(current_widget->o))->value());
- } else if (current_widget->is_a(ID_Spinner)) {
- i->activate();
- i->value(((Fl_Spinner*)(current_widget->o))->value());
- } else
- i->deactivate();
- } else {
- int mod = 0;
- undo_checkpoint();
- double n = i->value();
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_widget()) {
- Fl_Widget_Type* q = (Fl_Widget_Type*)o;
- if (q->is_a(ID_Valuator_)) {
- ((Fl_Valuator*)(q->o))->value(n);
- mod = 1;
- } else if (q->is_button()) {
- ((Fl_Button*)(q->o))->value(n != 0);
- if (q->is_a(ID_Menu_Item)) q->redraw();
- mod = 1;
- } else if (q->is_a(ID_Spinner)) {
- ((Fl_Spinner*)(q->o))->value(n);
- mod = 1;
- }
- }
- }
- if (mod) set_modflag(1);
- }
-}
-
-// The following three callbacks cooperate, showing only one of the groups of
-// widgets that use the same space in the dialog.
-
-void values_group_cb(Fl_Group* g, void* v) {
- if (v == LOAD) {
- if ( current_widget->is_a(ID_Flex)
- || current_widget->is_a(ID_Grid)
- || current_widget->is_a(ID_Window))
- {
- g->hide();
- } else {
- g->show();
- }
- propagate_load(g, v);
- }
-}
-
-void flex_margin_group_cb(Fl_Group* g, void* v) {
- if (v == LOAD) {
- if (current_widget->is_a(ID_Flex)) {
- g->show();
- } else {
- g->hide();
- }
- propagate_load(g, v);
- }
-}
-
-void size_range_group_cb(Fl_Group* g, void* v) {
- if (v == LOAD) {
- if (current_widget->is_a(ID_Window)) {
- g->show();
- } else {
- g->hide();
- }
- propagate_load(g, v);
- }
-}
-
-
-static void flex_margin_cb(Fl_Value_Input* i, void* v,
- void (*load_margin)(Fl_Flex*,Fl_Value_Input*),
- int (*update_margin)(Fl_Flex*,int)) {
- if (v == LOAD) {
- if (current_widget->is_a(ID_Flex)) {
- load_margin((Fl_Flex*)current_widget->o, i);
- }
- } else {
- int mod = 0;
- int new_value = (int)i->value();
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_a(ID_Flex)) {
- Fl_Flex_Type* q = (Fl_Flex_Type*)o;
- Fl_Flex* w = (Fl_Flex*)q->o;
- if (update_margin(w, new_value)) {
- w->layout();
- mod = 1;
- }
- }
- }
- if (mod) set_modflag(1);
- }
-}
-
-static void load_left_margin(Fl_Flex *w, Fl_Value_Input* i)
-{
- int v;
- w->margin(&v, NULL, NULL, NULL);
- i->value((double)v);
-}
-
-static int update_left_margin(Fl_Flex *w, int new_value)
-{
- int l, t, r, b;
- w->margin(&l, &t, &r, &b);
- if (new_value!=l) {
- w->margin(new_value, t, r, b);
- return 1;
- } else {
- return 0;
- }
-}
-
-void flex_margin_left_cb(Fl_Value_Input* i, void* v) {
- flex_margin_cb(i, v, load_left_margin, update_left_margin);
-}
-
-static void load_top_margin(Fl_Flex *w, Fl_Value_Input* i)
-{
- int v;
- w->margin(NULL, &v, NULL, NULL);
- i->value((double)v);
-}
-
-static int update_top_margin(Fl_Flex *w, int new_value)
-{
- int l, t, r, b;
- w->margin(&l, &t, &r, &b);
- if (new_value!=t) {
- w->margin(l, new_value, r, b);
- return 1;
- } else {
- return 0;
- }
-}
-
-void flex_margin_top_cb(Fl_Value_Input* i, void* v) {
- flex_margin_cb(i, v, load_top_margin, update_top_margin);
-}
-
-static void load_right_margin(Fl_Flex *w, Fl_Value_Input* i)
-{
- int v;
- w->margin(NULL, NULL, &v, NULL);
- i->value((double)v);
-}
-
-static int update_right_margin(Fl_Flex *w, int new_value)
-{
- int l, t, r, b;
- w->margin(&l, &t, &r, &b);
- if (new_value!=r) {
- w->margin(l, t, new_value, b);
- return 1;
- } else {
- return 0;
- }
-}
-
-void flex_margin_right_cb(Fl_Value_Input* i, void* v) {
- flex_margin_cb(i, v, load_right_margin, update_right_margin);
-}
-
-static void load_bottom_margin(Fl_Flex *w, Fl_Value_Input* i)
-{
- int v;
- w->margin(NULL, NULL, NULL, &v);
- i->value((double)v);
-}
-
-static int update_bottom_margin(Fl_Flex *w, int new_value)
-{
- int l, t, r, b;
- w->margin(&l, &t, &r, &b);
- if (new_value!=b) {
- w->margin(l, t, r, new_value);
- return 1;
- } else {
- return 0;
- }
-}
-
-void flex_margin_bottom_cb(Fl_Value_Input* i, void* v) {
- flex_margin_cb(i, v, load_bottom_margin, update_bottom_margin);
-}
-
-static void load_gap(Fl_Flex *w, Fl_Value_Input* i)
-{
- int v = w->gap();
- i->value((double)v);
-}
-
-static int update_gap(Fl_Flex *w, int new_value)
-{
- int g = w->gap();
- if (new_value!=g) {
- w->gap(new_value);
- return 1;
- } else {
- return 0;
- }
-}
-
-void flex_margin_gap_cb(Fl_Value_Input* i, void* v) {
- flex_margin_cb(i, v, load_gap, update_gap);
-}
-
-void position_group_cb(Fl_Group* g, void* v) {
- if (v == LOAD) {
- if (Fl_Flex_Type::parent_is_flex(current_widget)) {
- g->hide();
- } else {
- g->show();
- }
- }
- propagate_load(g, v);
-}
-
-void flex_size_group_cb(Fl_Group* g, void* v) {
- if (v == LOAD) {
- if (Fl_Flex_Type::parent_is_flex(current_widget)) {
- g->show();
- } else {
- g->hide();
- }
- }
- propagate_load(g, v);
-}
-
-void flex_size_cb(Fl_Value_Input* i, void* v) {
- if (v == LOAD) {
- if (Fl_Flex_Type::parent_is_flex(current_widget)) {
- i->value(Fl_Flex_Type::size(current_widget));
- }
- } else {
- int mod = 0;
- int new_size = (int)i->value();
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_widget() && Fl_Flex_Type::parent_is_flex(o)) {
- Fl_Widget* w = (Fl_Widget*)((Fl_Widget_Type*)o)->o;
- Fl_Flex* f = (Fl_Flex*)((Fl_Flex_Type*)o->parent)->o;
- int was_fixed = f->fixed(w);
- if (new_size==0) {
- if (was_fixed) {
- f->fixed(w, 0);
- f->layout();
- widget_flex_fixed->value(0);
- mod = 1;
- }
- } else {
- int old_size = Fl_Flex_Type::size(o);
- if (old_size!=new_size || !was_fixed) {
- f->fixed(w, new_size);
- f->layout();
- widget_flex_fixed->value(1);
- mod = 1;
- }
- }
- }
- }
- if (mod) set_modflag(1);
- }
-}
-
-void flex_fixed_cb(Fl_Check_Button* i, void* v) {
- if (v == LOAD) {
- if (Fl_Flex_Type::parent_is_flex(current_widget)) {
- i->value(Fl_Flex_Type::is_fixed(current_widget));
- }
- } else {
- int mod = 0;
- int new_fixed = (int)i->value();
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_widget() && Fl_Flex_Type::parent_is_flex(o)) {
- Fl_Widget* w = (Fl_Widget*)((Fl_Widget_Type*)o)->o;
- Fl_Flex* f = (Fl_Flex*)((Fl_Flex_Type*)o->parent)->o;
- int was_fixed = f->fixed(w);
- if (new_fixed==0) {
- if (was_fixed) {
- f->fixed(w, 0);
- f->layout();
- mod = 1;
- }
- } else {
- if (!was_fixed) {
- f->fixed(w, Fl_Flex_Type::size(o));
- f->layout();
- mod = 1;
- }
- }
- }
- }
- if (mod) set_modflag(1);
- }
-}
-
-////////////////////////////////////////////////////////////////
-
-// subtypes:
-
-Fl_Menu_Item *Fl_Widget_Type::subtypes() {return 0;}
-
-void subtype_cb(Fl_Choice* i, void* v) {
- static Fl_Menu_Item empty_type_menu[] = {
- {"Normal",0,0,(void*)0},
- {0}};
-
- if (v == LOAD) {
- Fl_Menu_Item* m = current_widget->subtypes();
- if (!m) {
- i->menu(empty_type_menu);
- i->value(0);
- i->deactivate();
- } else {
- i->menu(m);
- int j;
- for (j = 0;; j++) {
- if (!m[j].text) {j = 0; break;}
- if (current_widget->is_a(ID_Spinner)) {
- if (m[j].argument() == ((Fl_Spinner*)current_widget->o)->type()) break;
- } else {
- if (m[j].argument() == current_widget->o->type()) break;
- }
- }
- i->value(j);
- i->activate();
- }
- i->redraw();
- } else {
- int mod = 0;
- int n = int(i->mvalue()->argument());
- Fl_Menu_Item* m = current_widget->subtypes();
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_widget()) {
- Fl_Widget_Type* q = (Fl_Widget_Type*)o;
- if (q->subtypes()==m) {
- if (q->is_a(ID_Spinner))
- ((Fl_Spinner*)q->o)->type(n);
- else if (q->is_a(ID_Flex))
- ((Fl_Flex_Type*)q)->change_subtype_to(n);
- else
- q->o->type(n);
- q->redraw();
- mod = 1;
- }
- }
- }
- if (mod) set_modflag(1);
- }
-}
-
-////////////////////////////////////////////////////////////////
-
-void propagate_load(Fl_Group* g, void* v) {
- if (v == LOAD) {
- Fl_Widget*const* a = g->array();
- for (int i=g->children(); i--;) {
- Fl_Widget* o = *a++;
- o->do_callback(o, LOAD, FL_REASON_USER);
- }
- }
-}
-
-void set_cb(Fl_Button*, void*) {
- haderror = 0;
- Fl_Widget*const* a = the_panel->array();
- for (int i=the_panel->children(); i--;) {
- Fl_Widget* o = *a++;
- if (o->changed()) {
- o->do_callback();
- if (haderror) return;
- o->clear_changed();
- }
- }
-}
-
-void ok_cb(Fl_Return_Button* o, void* v) {
- set_cb(o,v);
- if (!haderror) the_panel->hide();
-}
-
-void toggle_overlays(Fl_Widget *,void *); // in Fl_Window_Type.cxx
-void overlay_cb(Fl_Button*o,void *v) {
- toggle_overlays(o,v);
-}
-
-void leave_live_mode_cb(Fl_Widget*, void*);
-
-void live_mode_cb(Fl_Button*o,void *) {
- /// \todo live mode should end gracefully when the application quits
- /// or when the user closes the live widget
- static Fl_Type *live_type = 0L;
- static Fl_Widget *live_widget = 0L;
- static Fl_Window *live_window = 0L;
- // if 'o' is 0, we must quit live mode
- if (!o) {
- o = wLiveMode;
- o->value(0);
- }
- if (o->value()) {
- if (numselected == 1) {
- Fl_Group::current(0L);
- live_widget = current_widget->enter_live_mode(1);
- if (live_widget) {
- live_type = current_widget;
- Fl_Group::current(0);
- int w = live_widget->w();
- int h = live_widget->h();
- live_window = new Fl_Double_Window(w+20, h+55, "Fluid Live Resize");
- live_window->box(FL_FLAT_BOX);
- live_window->color(FL_GREEN);
- Fl_Group *rsz = new Fl_Group(0, h+20, 130, 35);
- rsz->box(FL_NO_BOX);
- Fl_Box *rsz_dummy = new Fl_Box(110, h+20, 1, 25);
- rsz_dummy->box(FL_NO_BOX);
- rsz->resizable(rsz_dummy);
- Fl_Button *btn = new Fl_Button(10, h+20, 100, 25, "Exit Live Resize");
- btn->labelsize(12);
- btn->callback(leave_live_mode_cb);
- rsz->end();
- live_window->add(live_widget);
- live_widget->position(10, 10);
- live_window->resizable(live_widget);
- live_window->set_modal(); // block all other UI
- live_window->callback(leave_live_mode_cb);
- if (current_widget->is_a(ID_Window)) {
- Fl_Window_Type *w = (Fl_Window_Type*)current_widget;
- int mw = w->sr_min_w; if (mw>0) mw += 20;
- int mh = w->sr_min_h; if (mh>0) mh += 55;
- int MW = w->sr_max_w; if (MW>0) MW += 20;
- int MH = w->sr_max_h; if (MH>2) MH += 55;
- if (mw || mh || MW || MH)
- live_window->size_range(mw, mh, MW, MH);
- }
- live_window->show();
- live_widget->show();
- } else o->value(0);
- } else o->value(0);
- } else {
- if (live_type)
- live_type->leave_live_mode();
- if (live_window) {
- live_window->hide();
- Fl::delete_widget(live_window);
- }
- live_type = 0L;
- live_widget = 0L;
- live_window = 0L;
- }
-}
-
-// update the panel according to current widget set:
-void load_panel() {
- if (!the_panel) return;
-
- // find all the Fl_Widget subclasses currently selected:
- numselected = 0;
- current_widget = 0;
- if (Fl_Type::current) {
- if (Fl_Type::current->is_widget())
- current_widget=(Fl_Widget_Type*)Fl_Type::current;
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->is_widget() && o->selected) {
- numselected++;
- if (!current_widget) current_widget = (Fl_Widget_Type*)o;
- }
- }
- }
- if (current_widget && current_widget->is_a(ID_Grid)) {
- if (widget_tab_grid->parent()!=widget_tabs)
- widget_tabs->add(widget_tab_grid);
- } else {
- if (widget_tab_grid->parent()==widget_tabs) {
- widget_tabs_repo->add(widget_tab_grid);
- }
- }
- if (current_widget && current_widget->parent && current_widget->parent->is_a(ID_Grid)) {
- if (widget_tab_grid_child->parent()!=widget_tabs)
- widget_tabs->add(widget_tab_grid_child);
- } else {
- if (widget_tab_grid_child->parent()==widget_tabs) {
- widget_tabs_repo->add(widget_tab_grid_child);
- }
- }
- if (numselected)
- propagate_load(the_panel, LOAD);
- else
- the_panel->hide();
-}
-
-extern Fl_Window *widgetbin_panel;
-
-// This is called when user double-clicks an item, open or update the panel:
-void Fl_Widget_Type::open() {
- bool adjust_position = false;
- if (!the_panel) {
- the_panel = make_widget_panel();
- adjust_position = true;
- }
- load_panel();
- if (numselected) {
- the_panel->show();
- if (adjust_position) {
- if (widgetbin_panel && widgetbin_panel->visible()) {
- if ( (the_panel->x()+the_panel->w() > widgetbin_panel->x())
- && (the_panel->x() < widgetbin_panel->x()+widgetbin_panel->w())
- && (the_panel->y()+the_panel->h() > widgetbin_panel->y())
- && (the_panel->y() < widgetbin_panel->y()+widgetbin_panel->h()) )
- {
- if (widgetbin_panel->y()+widgetbin_panel->h()+the_panel->h() > Fl::h())
- the_panel->position(the_panel->x(), widgetbin_panel->y()-the_panel->h()-30);
- else
- the_panel->position(the_panel->x(), widgetbin_panel->y()+widgetbin_panel->h()+30);
- }
- }
- }
- }
-}
-
-extern void redraw_overlays();
-extern void check_redraw_corresponding_parent(Fl_Type*);
-extern void redraw_browser();
-extern void update_codeview_position();
-
-// Called when ui changes what objects are selected:
-// p is selected object, null for all deletions (we must throw away
-// old panel in that case, as the object may no longer exist)
-void selection_changed(Fl_Type *p) {
- // store all changes to the current selected objects:
- if (p && the_panel && the_panel->visible()) {
- set_cb(0,0);
- // if there was an error, we try to leave the selected set unchanged:
- if (haderror) {
- Fl_Type *q = 0;
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- o->new_selected = o->selected;
- if (!q && o->selected) q = o;
- }
- if (!p || !p->selected) p = q;
- Fl_Type::current = p;
- redraw_browser();
- return;
- }
- }
- // update the selected flags to new set:
- Fl_Type *q = 0;
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- o->selected = o->new_selected;
- if (!q && o->selected) q = o;
- }
- if (!p || !p->selected) p = q;
- Fl_Type::current = p;
- check_redraw_corresponding_parent(p);
- redraw_overlays();
- // load the panel with the new settings:
- load_panel();
- // update the code viewer to show the code for the selected object
- update_codeview_position();
-}
-
-////////////////////////////////////////////////////////////////
-// Writing the C code:
-
-// test to see if user named a function, or typed in code:
-int is_name(const char *c) {
- for (; *c; c++)
- if ((ispunct(*c)||*c=='\n') && *c!='_' && *c!=':') return 0;
- return 1;
-}
-
-// Test to see if name() is an array entry. If so, and this is the
-// highest number, return name[num+1]. Return null if not the highest
-// number or a field or function. Return name() if not an array entry.
-const char *array_name(Fl_Widget_Type *o) {
- const char *c = o->name();
- if (!c) return 0;
- const char *d;
- for (d = c; *d != '['; d++) {
- if (!*d) return c;
- if (ispunct(*d) && *d!='_') return 0;
- }
- int num = atoi(d+1);
- int sawthis = 0;
- Fl_Type *t = o->prev;
- Fl_Type *tp = o;
- const char *cn = o->class_name(1);
- for (; t && t->class_name(1) == cn; tp = t, t = t->prev) {/*empty*/}
- for (t = tp; t && t->class_name(1) == cn; t = t->next) {
- if (t == o) {sawthis=1; continue;}
- const char *e = t->name();
- if (!e) continue;
- if (strncmp(c,e,d-c)) continue;
- int n1 = atoi(e+(d-c)+1);
- if (n1 > num || (n1==num && sawthis)) return 0;
- }
- static char buffer[128];
- // MRS: we want strncpy() here...
- strncpy(buffer,c,d-c+1);
- snprintf(buffer+(d-c+1),sizeof(buffer) - (d-c+1), "%d]",num+1);
- return buffer;
-}
-
-// Test to see if extra code is a declaration:
-int isdeclare(const char *c) {
- while (isspace(*c)) c++;
- if (*c == '#') return 1;
- if (!strncmp(c,"extern",6)) return 1;
- if (!strncmp(c,"typedef",7)) return 1;
- if (!strncmp(c,"using",5)) return 1;
- return 0;
-}
-
-void Fl_Widget_Type::write_static(fld::io::Code_Writer& f) {
- const char* t = subclassname(this);
- if (!subclass() || (is_class() && !strncmp(t, "Fl_", 3))) {
- f.write_h_once("#include <FL/Fl.H>");
- f.write_h_once("#include <FL/%s.H>", t);
- }
- for (int n=0; n < NUM_EXTRA_CODE; n++) {
- if (extra_code(n) && isdeclare(extra_code(n)))
- f.write_h_once("%s", extra_code(n));
- }
- if (callback() && is_name(callback())) {
- int write_extern_declaration = 1;
- char buf[1024]; snprintf(buf, 1023, "%s(*)", callback());
- if (is_in_class()) {
- if (has_function("static void", buf))
- write_extern_declaration = 0;
- } else {
- if (has_toplevel_function(0L, buf))
- write_extern_declaration = 0;
- }
- if (write_extern_declaration)
- f.write_h_once("extern void %s(%s*, %s);", callback(), t,
- user_data_type() ? user_data_type() : "void*");
- }
- const char* k = class_name(1);
- const char* c = array_name(this);
- if (c && !k && !is_class()) {
- f.write_c("\n");
- if (!public_) f.write_c("static ");
- else f.write_h("extern %s *%s;\n", t, c);
- if (strchr(c, '[') == NULL) f.write_c("%s *%s=(%s *)0;\n", t, c, t);
- else f.write_c("%s *%s={(%s *)0};\n", t, c, t);
- }
- if (callback() && !is_name(callback())) {
- // see if 'o' or 'v' used, to prevent unused argument warnings:
- int use_o = 0;
- int use_v = 0;
- const char *d;
- for (d = callback(); *d;) {
- if (*d == 'o' && !is_id(d[1])) use_o = 1;
- if (*d == 'v' && !is_id(d[1])) use_v = 1;
- do d++; while (is_id(*d));
- while (*d && !is_id(*d)) d++;
- }
- const char* cn = callback_name(f);
- if (k) {
- f.write_c("\nvoid %s::%s_i(%s*", k, cn, t);
- } else {
- f.write_c("\nstatic void %s(%s*", cn, t);
- }
- if (use_o) f.write_c(" o");
- const char* ut = user_data_type() ? user_data_type() : "void*";
- f.write_c(", %s", ut);
- if (use_v) f.write_c(" v");
- f.write_c(") {\n");
- // Matt: disabled f.tag(FD_TAG_GENERIC, 0);
- f.write_c_indented(callback(), 1, 0);
- if (*(d-1) != ';' && *(d-1) != '}') {
- const char *p = strrchr(callback(), '\n');
- if (p) p ++;
- else p = callback();
- // Only add trailing semicolon if the last line is not a preprocessor
- // statement...
- if (*p != '#' && *p) f.write_c(";");
- }
- f.write_c("\n");
- // Matt: disabled f.tag(FD_TAG_WIDGET_CALLBACK, get_uid());
- f.write_c("}\n");
- if (k) {
- f.write_c("void %s::%s(%s* o, %s v) {\n", k, cn, t, ut);
- f.write_c("%s((%s*)(o", f.indent(1), k);
- Fl_Type *q = 0;
- for (Fl_Type* p = parent; p && p->is_widget(); q = p, p = p->parent)
- f.write_c("->parent()");
- if (!q || !q->is_a(ID_Widget_Class))
- f.write_c("->user_data()");
- f.write_c("))->%s_i(o,v);\n}\n", cn);
- }
- }
- if (image) {
- if (!f.c_contains(image))
- image->write_static(f, compress_image_);
- }
- if (inactive) {
- if (!f.c_contains(inactive))
- inactive->write_static(f, compress_deimage_);
- }
-}
-
-void Fl_Widget_Type::write_code1(fld::io::Code_Writer& f) {
- const char* t = subclassname(this);
- const char *c = array_name(this);
- if (c) {
- if (class_name(1)) {
- f.write_public(public_);
- f.write_h("%s%s *%s;\n", f.indent(1), t, c);
- }
- }
- if (class_name(1) && callback() && !is_name(callback())) {
- const char* cn = callback_name(f);
- const char* ut = user_data_type() ? user_data_type() : "void*";
- f.write_public(0);
- f.write_h("%sinline void %s_i(%s*, %s);\n", f.indent(1), cn, t, ut);
- f.write_h("%sstatic void %s(%s*, %s);\n", f.indent(1), cn, t, ut);
- }
- // figure out if local variable will be used (prevent compiler warnings):
- int wused = !name() && is_a(ID_Window);
- const char *ptr;
-
- f.varused = wused;
-
- if (!name() && !f.varused) {
- f.varused |= can_have_children();
-
- if (!f.varused) {
- f.varused_test = 1;
- write_widget_code(f);
- f.varused_test = 0;
- }
- }
-
- if (!f.varused) {
- for (int n=0; n < NUM_EXTRA_CODE; n++)
- if (extra_code(n) && !isdeclare(extra_code(n)))
- {
- int instring = 0;
- int inname = 0;
- int incomment = 0;
- int incppcomment = 0;
- for (ptr = extra_code(n); *ptr; ptr ++) {
- if (instring) {
- if (*ptr == '\\') ptr++;
- else if (*ptr == '\"') instring = 0;
- } else if (inname && !isalnum(*ptr & 255)) {
- inname = 0;
- } else if (*ptr == '/' && ptr[1]=='*') {
- incomment = 1; ptr++;
- } else if (incomment) {
- if (*ptr == '*' && ptr[1]=='/') {
- incomment = 0; ptr++;
- }
- } else if (*ptr == '/' && ptr[1]=='/') {
- incppcomment = 1; ptr++;
- } else if (incppcomment) {
- if (*ptr == '\n')
- incppcomment = 0;
- } else if (*ptr == '\"') {
- instring = 1;
- } else if (isalnum(*ptr & 255) || *ptr == '_') {
- size_t len = strspn(ptr, "0123456789_"
- "abcdefghijklmnopqrstuvwxyz"
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
- if (!strncmp(ptr, "o", len)) {
- f.varused = 1;
- break;
- } else {
- ptr += len - 1;
- }
- }
- }
- }
- }
-
- f.write_c("%s{ ", f.indent());
- write_comment_inline_c(f);
- if (f.varused) f.write_c("%s* o = ", t);
- if (name()) f.write_c("%s = ", name());
- if (is_a(ID_Window)) {
- // Handle special case where user is faking a Fl_Group type as a window,
- // there is no 2-argument constructor in that case:
- if (!strstr(t, "Window"))
- f.write_c("new %s(0, 0, %d, %d", t, o->w(), o->h());
- else
- f.write_c("new %s(%d, %d", t, o->w(), o->h());
- } else if (is_a(ID_Menu_Bar)
- && ((Fl_Menu_Bar_Type*)this)->is_sys_menu_bar()
- && is_in_class()) {
- f.write_c("(%s*)new %s(%d, %d, %d, %d",
- t, ((Fl_Menu_Bar_Type*)this)->sys_menubar_proxy_name(),
- o->x(), o->y(), o->w(), o->h());
- } else {
- f.write_c("new %s(%d, %d, %d, %d", t, o->x(), o->y(), o->w(), o->h());
- }
- if (label() && *label()) {
- f.write_c(", ");
- switch (g_project.i18n_type) {
- case FD_I18N_NONE : /* None */
- f.write_cstring(label());
- break;
- case FD_I18N_GNU : /* GNU gettext */
- f.write_c("%s(", g_project.i18n_gnu_function.c_str());
- f.write_cstring(label());
- f.write_c(")");
- break;
- case FD_I18N_POSIX : /* POSIX catgets */
- f.write_c("catgets(%s,%s,%d,",
- g_project.i18n_pos_file.empty() ? "_catalog" : g_project.i18n_pos_file.c_str(),
- g_project.i18n_pos_set.c_str(), msgnum());
- f.write_cstring(label());
- f.write_c(")");
- break;
- }
- }
- f.write_c(");\n");
-
- f.indentation++;
-
- // Avoid compiler warning for unused variable.
- // Also avoid quality control warnings about incorrect allocation error handling.
- if (wused) f.write_c("%sw = o; (void)w;\n", f.indent());
-
- write_widget_code(f);
-}
-
-void Fl_Widget_Type::write_color(fld::io::Code_Writer& f, const char* field, Fl_Color color) {
- const char* color_name = 0;
- switch (color) {
- case FL_FOREGROUND_COLOR: color_name = "FL_FOREGROUND_COLOR"; break;
- case FL_BACKGROUND2_COLOR: color_name = "FL_BACKGROUND2_COLOR"; break;
- case FL_INACTIVE_COLOR: color_name = "FL_INACTIVE_COLOR"; break;
- case FL_SELECTION_COLOR: color_name = "FL_SELECTION_COLOR"; break;
- case FL_GRAY0: color_name = "FL_GRAY0"; break;
- case FL_DARK3: color_name = "FL_DARK3"; break;
- case FL_DARK2: color_name = "FL_DARK2"; break;
- case FL_DARK1: color_name = "FL_DARK1"; break;
- case FL_BACKGROUND_COLOR: color_name = "FL_BACKGROUND_COLOR"; break;
- case FL_LIGHT1: color_name = "FL_LIGHT1"; break;
- case FL_LIGHT2: color_name = "FL_LIGHT2"; break;
- case FL_LIGHT3: color_name = "FL_LIGHT3"; break;
- case FL_BLACK: color_name = "FL_BLACK"; break;
- case FL_RED: color_name = "FL_RED"; break;
- case FL_GREEN: color_name = "FL_GREEN"; break;
- case FL_YELLOW: color_name = "FL_YELLOW"; break;
- case FL_BLUE: color_name = "FL_BLUE"; break;
- case FL_MAGENTA: color_name = "FL_MAGENTA"; break;
- case FL_CYAN: color_name = "FL_CYAN"; break;
- case FL_DARK_RED: color_name = "FL_DARK_RED"; break;
- case FL_DARK_GREEN: color_name = "FL_DARK_GREEN"; break;
- case FL_DARK_YELLOW: color_name = "FL_DARK_YELLOW"; break;
- case FL_DARK_BLUE: color_name = "FL_DARK_BLUE"; break;
- case FL_DARK_MAGENTA: color_name = "FL_DARK_MAGENTA"; break;
- case FL_DARK_CYAN: color_name = "FL_DARK_CYAN"; break;
- case FL_WHITE: color_name = "FL_WHITE"; break;
- }
- const char *var = is_class() ? "this" : name() ? name() : "o";
- if (color_name) {
- f.write_c("%s%s->%s(%s);\n", f.indent(), var, field, color_name);
- } else {
- f.write_c("%s%s->%s((Fl_Color)%d);\n", f.indent(), var, field, color);
- }
-}
-
-// this is split from write_code1(fld::io::Code_Writer& f) for Fl_Window_Type:
-void Fl_Widget_Type::write_widget_code(fld::io::Code_Writer& f) {
- Fl_Widget* tplate = ((Fl_Widget_Type*)factory)->o;
- const char *var = is_class() ? "this" : name() ? name() : "o";
-
- if (tooltip() && *tooltip()) {
- f.write_c("%s%s->tooltip(",f.indent(), var);
- switch (g_project.i18n_type) {
- case FD_I18N_NONE : /* None */
- f.write_cstring(tooltip());
- break;
- case FD_I18N_GNU : /* GNU gettext */
- f.write_c("%s(", g_project.i18n_gnu_function.c_str());
- f.write_cstring(tooltip());
- f.write_c(")");
- break;
- case FD_I18N_POSIX : /* POSIX catgets */
- f.write_c("catgets(%s,%s,%d,",
- g_project.i18n_pos_file.empty() ? "_catalog" : g_project.i18n_pos_file.c_str(),
- g_project.i18n_pos_set.c_str(),
- msgnum() + 1);
- f.write_cstring(tooltip());
- f.write_c(")");
- break;
- }
- f.write_c(");\n");
- }
-
- if (is_a(ID_Spinner) && ((Fl_Spinner*)o)->type() != ((Fl_Spinner*)tplate)->type())
- f.write_c("%s%s->type(%d);\n", f.indent(), var, ((Fl_Spinner*)o)->type());
- else if (o->type() != tplate->type() && !is_a(ID_Window))
- f.write_c("%s%s->type(%d);\n", f.indent(), var, o->type());
- if (o->box() != tplate->box() || subclass())
- f.write_c("%s%s->box(FL_%s);\n", f.indent(), var, boxname(o->box()));
-
- // write shortcut command if needed
- int shortcut = 0;
- if (is_button()) shortcut = ((Fl_Button*)o)->shortcut();
- else if (is_a(ID_Input)) shortcut = ((Fl_Input_*)o)->shortcut();
- else if (is_a(ID_Value_Input)) shortcut = ((Fl_Value_Input*)o)->shortcut();
- else if (is_a(ID_Text_Display)) shortcut = ((Fl_Text_Display*)o)->shortcut();
- if (shortcut) {
- int s = shortcut;
- f.write_c("%s%s->shortcut(", f.indent(), var);
- if (g_project.use_FL_COMMAND) {
- if (s & FL_CTRL) { f.write_c("FL_CONTROL|"); s &= ~FL_CTRL; }
- if (s & FL_META) { f.write_c("FL_COMMAND|"); s &= ~FL_META; }
- } else {
- if (s & FL_CTRL) { f.write_c("FL_CTRL|"); s &= ~FL_CTRL; }
- if (s & FL_META) { f.write_c("FL_META|"); s &= ~FL_META; }
- }
- if (s & FL_SHIFT) { f.write_c("FL_SHIFT|"); s &= ~FL_SHIFT; }
- if (s & FL_ALT) { f.write_c("FL_ALT|"); s &= ~FL_ALT; }
- if ((s < 127) && isprint(s))
- f.write_c("'%c');\n", s);
- else
- f.write_c("0x%x);\n", s);
- }
-
- if (is_a(ID_Button)) {
- Fl_Button* b = (Fl_Button*)o;
- if (b->down_box()) f.write_c("%s%s->down_box(FL_%s);\n", f.indent(), var,
- boxname(b->down_box()));
- if (b->value()) f.write_c("%s%s->value(1);\n", f.indent(), var);
- if (b->compact()) f.write_c("%s%s->compact(%d);\n", f.indent(), var, b->compact());
- } else if (is_a(ID_Input_Choice)) {
- Fl_Input_Choice* b = (Fl_Input_Choice*)o;
- if (b->down_box()) f.write_c("%s%s->down_box(FL_%s);\n", f.indent(), var,
- boxname(b->down_box()));
- } else if (is_a(ID_Menu_Manager_)) {
- Fl_Menu_* b = (Fl_Menu_*)o;
- if (b->down_box()) f.write_c("%s%s->down_box(FL_%s);\n", f.indent(), var,
- boxname(b->down_box()));
- }
- if (o->color() != tplate->color() || subclass())
- write_color(f, "color", o->color());
- if (o->selection_color() != tplate->selection_color() || subclass())
- write_color(f, "selection_color", o->selection_color());
- if (image) {
- image->write_code(f, bind_image_, var);
- if (scale_image_w_ || scale_image_h_) {
- f.write_c("%s%s->image()->scale(", f.indent(), var);
- if (scale_image_w_>0)
- f.write_c("%d, ", scale_image_w_);
- else
- f.write_c("%s->image()->data_w(), ", var);
- if (scale_image_h_>0)
- f.write_c("%d, 0, 1);\n", scale_image_h_);
- else
- f.write_c("%s->image()->data_h(), 0, 1);\n", var);
- }
- }
- if (inactive) {
- inactive->write_code(f, bind_deimage_, var, 1);
- if (scale_deimage_w_ || scale_deimage_h_) {
- f.write_c("%s%s->deimage()->scale(", f.indent(), var);
- if (scale_deimage_w_>0)
- f.write_c("%d, ", scale_deimage_w_);
- else
- f.write_c("%s->deimage()->data_w(), ", var);
- if (scale_deimage_h_>0)
- f.write_c("%d, 0, 1);\n", scale_deimage_h_);
- else
- f.write_c("%s->deimage()->data_h(), 0, 1);\n", var);
- }
- }
- if (o->labeltype() != tplate->labeltype() || subclass())
- f.write_c("%s%s->labeltype(FL_%s);\n", f.indent(), var,
- item_name(labeltypemenu, o->labeltype()));
- if (o->labelfont() != tplate->labelfont() || subclass())
- f.write_c("%s%s->labelfont(%d);\n", f.indent(), var, o->labelfont());
- if (o->labelsize() != tplate->labelsize() || subclass())
- f.write_c("%s%s->labelsize(%d);\n", f.indent(), var, o->labelsize());
- if (o->labelcolor() != tplate->labelcolor() || subclass())
- write_color(f, "labelcolor", o->labelcolor());
- if (o->horizontal_label_margin() != tplate->horizontal_label_margin())
- f.write_c("%s%s->horizontal_label_margin(%d);\n", f.indent(), var, o->horizontal_label_margin());
- if (o->vertical_label_margin() != tplate->vertical_label_margin())
- f.write_c("%s%s->vertical_label_margin(%d);\n", f.indent(), var, o->vertical_label_margin());
- if (o->label_image_spacing() != tplate->label_image_spacing())
- f.write_c("%s%s->label_image_spacing(%d);\n", f.indent(), var, o->label_image_spacing());
- if (is_a(ID_Valuator_)) {
- Fl_Valuator* v = (Fl_Valuator*)o;
- Fl_Valuator* t = (Fl_Valuator*)(tplate);
- if (v->minimum()!=t->minimum())
- f.write_c("%s%s->minimum(%g);\n", f.indent(), var, v->minimum());
- if (v->maximum()!=t->maximum())
- f.write_c("%s%s->maximum(%g);\n", f.indent(), var, v->maximum());
- if (v->step()!=t->step())
- f.write_c("%s%s->step(%g);\n", f.indent(), var, v->step());
- if (v->value()) {
- if (is_a(ID_Scrollbar)) { // Fl_Scrollbar::value(double) is not available
- f.write_c("%s%s->Fl_Slider::value(%g);\n", f.indent(), var, v->value());
- } else {
- f.write_c("%s%s->value(%g);\n", f.indent(), var, v->value());
- }
- }
- if (is_a(ID_Slider)) {
- double x = ((Fl_Slider*)v)->slider_size();
- double y = ((Fl_Slider*)t)->slider_size();
- if (x != y) f.write_c("%s%s->slider_size(%g);\n", f.indent(), var, x);
- }
- }
- if (is_a(ID_Spinner)) {
- Fl_Spinner* v = (Fl_Spinner*)o;
- Fl_Spinner* t = (Fl_Spinner*)(tplate);
- if (v->minimum()!=t->minimum())
- f.write_c("%s%s->minimum(%g);\n", f.indent(), var, v->minimum());
- if (v->maximum()!=t->maximum())
- f.write_c("%s%s->maximum(%g);\n", f.indent(), var, v->maximum());
- if (v->step()!=t->step())
- f.write_c("%s%s->step(%g);\n", f.indent(), var, v->step());
- if (v->value()!=1.0f)
- f.write_c("%s%s->value(%g);\n", f.indent(), var, v->value());
- }
-
- {Fl_Font ff; int fs; Fl_Color fc; if (textstuff(4,ff,fs,fc)) {
- Fl_Font g; int s; Fl_Color c; textstuff(0,g,s,c);
- if (g != ff) f.write_c("%s%s->textfont(%d);\n", f.indent(), var, g);
- if (s != fs) f.write_c("%s%s->textsize(%d);\n", f.indent(), var, s);
- if (c != fc) write_color(f, "textcolor", c);
- }}
- const char* ud = user_data();
- if (class_name(1) && !parent->is_widget()) ud = "this";
- if (callback()) {
- f.write_c("%s%s->callback((Fl_Callback*)%s", f.indent(), var, callback_name(f));
- if (ud)
- f.write_c(", (void*)(%s));\n", ud);
- else
- f.write_c(");\n");
- } else if (ud) {
- f.write_c("%s%s->user_data((void*)(%s));\n", f.indent(), var, ud);
- }
- if (o->align() != tplate->align() || subclass()) {
- int i = o->align();
- f.write_c("%s%s->align(Fl_Align(%s", f.indent(), var,
- item_name(alignmenu, i & ~FL_ALIGN_INSIDE));
- if (i & FL_ALIGN_INSIDE) f.write_c("|FL_ALIGN_INSIDE");
- f.write_c("));\n");
- }
- Fl_When ww = o->when();
- if (ww != tplate->when() || subclass())
- f.write_c("%s%s->when(%s);\n", f.indent(), var, when_symbol_name(ww));
- if (!o->visible() && o->parent())
- 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_a(ID_Group) && resizable())
- f.write_c("%sFl_Group::current()->resizable(%s);\n", f.indent(), var);
- if (hotspot()) {
- if (is_class())
- f.write_c("%shotspot(%s);\n", f.indent(), var);
- else if (is_a(ID_Window))
- f.write_c("%s%s->hotspot(%s);\n", f.indent(), var, var);
- else
- f.write_c("%s%s->window()->hotspot(%s);\n", f.indent(), var, var);
- }
-}
-
-void Fl_Widget_Type::write_extra_code(fld::io::Code_Writer& f) {
- for (int n=0; n < NUM_EXTRA_CODE; n++)
- if (extra_code(n) && !isdeclare(extra_code(n)))
- f.write_c("%s%s\n", f.indent(), extra_code(n));
-}
-
-void Fl_Widget_Type::write_block_close(fld::io::Code_Writer& f) {
- f.indentation--;
- f.write_c("%s} // %s* %s\n", f.indent(), subclassname(this),
- name() ? name() : "o");
-}
-
-void Fl_Widget_Type::write_code2(fld::io::Code_Writer& f) {
- write_extra_code(f);
- write_block_close(f);
-}
-
-////////////////////////////////////////////////////////////////
-
-void Fl_Widget_Type::write_properties(fld::io::Project_Writer &f) {
- Fl_Type::write_properties(f);
- f.write_indent(level+1);
- switch (public_) {
- case 0: f.write_string("private"); break;
- case 1: break;
- case 2: f.write_string("protected"); break;
- }
- if (tooltip() && *tooltip()) {
- f.write_string("tooltip");
- f.write_word(tooltip());
- }
- if (image_name() && *image_name()) {
- if (scale_image_w_ || scale_image_h_)
- f.write_string("scale_image {%d %d}", scale_image_w_, scale_image_h_);
- f.write_string("image");
- f.write_word(image_name());
- f.write_string("compress_image %d", compress_image_);
- }
- if (bind_image_) f.write_string("bind_image 1");
- if (inactive_name() && *inactive_name()) {
- if (scale_deimage_w_ || scale_deimage_h_)
- f.write_string("scale_deimage {%d %d}", scale_deimage_w_, scale_deimage_h_);
- f.write_string("deimage");
- f.write_word(inactive_name());
- f.write_string("compress_deimage %d", compress_deimage_);
- }
- if (bind_deimage_) f.write_string("bind_deimage 1");
- f.write_string("xywh {%d %d %d %d}", o->x(), o->y(), o->w(), o->h());
- Fl_Widget* tplate = ((Fl_Widget_Type*)factory)->o;
- if (is_a(ID_Spinner) && ((Fl_Spinner*)o)->type() != ((Fl_Spinner*)tplate)->type()) {
- f.write_string("type");
- f.write_word(item_name(subtypes(), ((Fl_Spinner*)o)->type()));
- } else if (subtypes() && (o->type() != tplate->type() || is_a(ID_Window))) {
- f.write_string("type");
- f.write_word(item_name(subtypes(), o->type()));
- }
- if (o->box() != tplate->box()) {
- f.write_string("box"); f.write_word(boxname(o->box()));}
- if (is_a(ID_Input)) {
- Fl_Input_* b = (Fl_Input_*)o;
- if (b->shortcut()) f.write_string("shortcut 0x%x", b->shortcut());
- }
- if (is_a(ID_Value_Input)) {
- Fl_Value_Input* b = (Fl_Value_Input*)o;
- if (b->shortcut()) f.write_string("shortcut 0x%x", b->shortcut());
- }
- if (is_a(ID_Text_Display)) {
- Fl_Text_Display* b = (Fl_Text_Display*)o;
- if (b->shortcut()) f.write_string("shortcut 0x%x", b->shortcut());
- }
- if (is_a(ID_Button)) {
- Fl_Button* b = (Fl_Button*)o;
- if (b->down_box()) {
- f.write_string("down_box"); f.write_word(boxname(b->down_box()));}
- if (b->shortcut()) f.write_string("shortcut 0x%x", b->shortcut());
- if (b->value()) f.write_string("value 1");
- } else if (is_a(ID_Input_Choice)) {
- Fl_Input_Choice* b = (Fl_Input_Choice*)o;
- if (b->down_box()) {
- f.write_string("down_box"); f.write_word(boxname(b->down_box()));}
- } else if (is_a(ID_Menu_)) {
- Fl_Menu_* b = (Fl_Menu_*)o;
- if (b->down_box()) {
- f.write_string("down_box"); f.write_word(boxname(b->down_box()));}
- }
- if (o->color()!=tplate->color())
- f.write_string("color %d", o->color());
- if (o->selection_color()!=tplate->selection_color())
- f.write_string("selection_color %d", o->selection_color());
- if (o->labeltype()!=tplate->labeltype()) {
- f.write_string("labeltype");
- f.write_word(item_name(labeltypemenu, o->labeltype()));
- }
- if (o->labelfont()!=tplate->labelfont())
- f.write_string("labelfont %d", o->labelfont());
- if (o->labelsize()!=tplate->labelsize())
- f.write_string("labelsize %d", o->labelsize());
- if (o->labelcolor()!=tplate->labelcolor())
- f.write_string("labelcolor %d", o->labelcolor());
- if (o->align()!=tplate->align())
- f.write_string("align %d", o->align());
- if (o->horizontal_label_margin()!=tplate->horizontal_label_margin())
- f.write_string("h_label_margin %d", o->horizontal_label_margin());
- if (o->vertical_label_margin()!=tplate->vertical_label_margin())
- f.write_string("v_label_margin %d", o->vertical_label_margin());
- if (o->label_image_spacing()!=tplate->label_image_spacing())
- f.write_string("image_spacing %d", o->label_image_spacing());
- if (o->when() != tplate->when())
- f.write_string("when %d", o->when());
- if (is_a(ID_Valuator_)) {
- Fl_Valuator* v = (Fl_Valuator*)o;
- Fl_Valuator* t = (Fl_Valuator*)(tplate);
- if (v->minimum()!=t->minimum()) f.write_string("minimum %g",v->minimum());
- if (v->maximum()!=t->maximum()) f.write_string("maximum %g",v->maximum());
- if (v->step()!=t->step()) f.write_string("step %g",v->step());
- if (v->value()!=0.0) f.write_string("value %g",v->value());
- if (is_a(ID_Slider)) {
- double x = ((Fl_Slider*)v)->slider_size();
- double y = ((Fl_Slider*)t)->slider_size();
- if (x != y) f.write_string("slider_size %g", x);
- }
- }
- if (is_a(ID_Spinner)) {
- Fl_Spinner* v = (Fl_Spinner*)o;
- Fl_Spinner* t = (Fl_Spinner*)(tplate);
- if (v->minimum()!=t->minimum()) f.write_string("minimum %g",v->minimum());
- if (v->maximum()!=t->maximum()) f.write_string("maximum %g",v->maximum());
- if (v->step()!=t->step()) f.write_string("step %g",v->step());
- if (v->value()!=1.0) f.write_string("value %g",v->value());
- }
- {Fl_Font ff; int fs; Fl_Color fc; if (textstuff(4,ff,fs,fc)) {
- Fl_Font ft; int s; Fl_Color c; textstuff(0,ft,s,c);
- if (ft != ff) f.write_string("textfont %d", ft);
- if (s != fs) f.write_string("textsize %d", s);
- if (c != fc) f.write_string("textcolor %d", c);
- }}
- if (!o->visible() && !override_visible_) f.write_string("hide");
- if (!o->active()) f.write_string("deactivate");
- if (resizable()) f.write_string("resizable");
- if (hotspot()) f.write_string(is_a(ID_Menu_Item) ? "divider" : "hotspot");
- for (int n=0; n < NUM_EXTRA_CODE; n++) if (extra_code(n)) {
- f.write_indent(level+1);
- f.write_string("code%d",n);
- f.write_word(extra_code(n));
- }
- if (subclass()) {
- f.write_indent(level+1);
- f.write_string("class");
- f.write_word(subclass());
- }
-}
-
-void Fl_Widget_Type::read_property(fld::io::Project_Reader &f, const char *c) {
- int x,y,w,h; Fl_Font ft; int s; Fl_Color cc;
- if (!strcmp(c,"private")) {
- public_ = 0;
- } else if (!strcmp(c,"protected")) {
- public_ = 2;
- } else if (!strcmp(c,"xywh")) {
- if (sscanf(f.read_word(),"%d %d %d %d",&x,&y,&w,&h) == 4) {
- x += pasteoffset;
- y += pasteoffset;
- // FIXME temporary change!
- if (f.read_version>=2.0 && o->parent() && o->parent()!=o->window()) {
- x += o->parent()->x();
- y += o->parent()->y();
- }
- o->resize(x,y,w,h);
- }
- } else if (!strcmp(c,"tooltip")) {
- tooltip(f.read_word());
- } else if (!strcmp(c,"scale_image")) {
- if (sscanf(f.read_word(),"%d %d",&w,&h) == 2) {
- scale_image_w_ = w;
- scale_image_h_ = h;
- }
- } else if (!strcmp(c,"image")) {
- image_name(f.read_word());
- // starting in 2023, `image` is always followed by `compress_image`
- // the code below is for compatibility with older .fl files
- const char *ext = fl_filename_ext(image_name_);
- if ( strcmp(ext, ".jpg")
- && strcmp(ext, ".png")
- && strcmp(ext, ".svg")
- && strcmp(ext, ".svgz"))
- compress_image_ = 0; // if it is neither of those, default to uncompressed
- } else if (!strcmp(c,"bind_image")) {
- bind_image_ = (int)atol(f.read_word());
- } else if (!strcmp(c,"compress_image")) {
- compress_image_ = (int)atol(f.read_word());
- } else if (!strcmp(c,"scale_deimage")) {
- if (sscanf(f.read_word(),"%d %d",&w,&h) == 2) {
- scale_deimage_w_ = w;
- scale_deimage_h_ = h;
- }
- } else if (!strcmp(c,"deimage")) {
- inactive_name(f.read_word());
- // starting in 2023, `deimage` is always followed by `compress_deimage`
- // the code below is for compatibility with older .fl files
- const char *ext = fl_filename_ext(inactive_name_);
- if ( strcmp(ext, ".jpg")
- && strcmp(ext, ".png")
- && strcmp(ext, ".svg")
- && strcmp(ext, ".svgz"))
- compress_deimage_ = 0; // if it is neither of those, default to uncompressed
- } else if (!strcmp(c,"bind_deimage")) {
- bind_deimage_ = (int)atol(f.read_word());
- } else if (!strcmp(c,"compress_deimage")) {
- compress_deimage_ = (int)atol(f.read_word());
- } else if (!strcmp(c,"type")) {
- if (is_a(ID_Spinner))
- ((Fl_Spinner*)o)->type(item_number(subtypes(), f.read_word()));
- else
- o->type(item_number(subtypes(), f.read_word()));
- } else if (!strcmp(c,"box")) {
- const char* value = f.read_word();
- if ((x = boxnumber(value))) {
- if (x == ZERO_ENTRY) x = 0;
- o->box((Fl_Boxtype)x);
- } else if (sscanf(value,"%d",&x) == 1) o->box((Fl_Boxtype)x);
- } else if (is_a(ID_Button) && !strcmp(c,"down_box")) {
- const char* value = f.read_word();
- if ((x = boxnumber(value))) {
- if (x == ZERO_ENTRY) x = 0;
- ((Fl_Button*)o)->down_box((Fl_Boxtype)x);
- }
- } else if (is_a(ID_Input_Choice) && !strcmp(c,"down_box")) {
- const char* value = f.read_word();
- if ((x = boxnumber(value))) {
- if (x == ZERO_ENTRY) x = 0;
- ((Fl_Input_Choice*)o)->down_box((Fl_Boxtype)x);
- }
- } else if (is_a(ID_Menu_) && !strcmp(c,"down_box")) {
- const char* value = f.read_word();
- if ((x = boxnumber(value))) {
- if (x == ZERO_ENTRY) x = 0;
- ((Fl_Menu_*)o)->down_box((Fl_Boxtype)x);
- }
- } else if (is_button() && !strcmp(c,"value")) {
- const char* value = f.read_word();
- ((Fl_Button*)o)->value(atoi(value));
- } else if (!strcmp(c,"color")) {
- const char *cw = f.read_word();
- if (cw[0]=='0' && cw[1]=='x') {
- sscanf(cw,"0x%x",&x);
- o->color(x);
- } else {
- int n = sscanf(cw,"%d %d",&x,&y);
- if (n == 2) { // back compatibility...
- if (x != 47) o->color(x);
- o->selection_color(y);
- } else {
- o->color(x);
- }
- }
- } else if (!strcmp(c,"selection_color")) {
- if (sscanf(f.read_word(),"%d",&x)) o->selection_color(x);
- } else if (!strcmp(c,"labeltype")) {
- c = f.read_word();
- if (!strcmp(c,"image")) {
- Fluid_Image *i = Fluid_Image::find(label());
- if (!i) f.read_error("Image file '%s' not found", label());
- else setimage(i);
- image_name(label());
- label("");
- } else {
- o->labeltype((Fl_Labeltype)item_number(labeltypemenu,c));
- }
- } else if (!strcmp(c,"labelfont")) {
- if (sscanf(f.read_word(),"%d",&x) == 1) o->labelfont(x);
- } else if (!strcmp(c,"labelsize")) {
- if (sscanf(f.read_word(),"%d",&x) == 1) o->labelsize(x);
- } else if (!strcmp(c,"labelcolor")) {
- if (sscanf(f.read_word(),"%d",&x) == 1) o->labelcolor(x);
- } else if (!strcmp(c,"align")) {
- if (sscanf(f.read_word(),"%d",&x) == 1) o->align(x);
- } else if (!strcmp(c,"h_label_margin")) {
- if (sscanf(f.read_word(),"%d",&x) == 1) o->horizontal_label_margin(x);
- } else if (!strcmp(c,"v_label_margin")) {
- if (sscanf(f.read_word(),"%d",&x) == 1) o->vertical_label_margin(x);
- } else if (!strcmp(c,"image_spacing")) {
- if (sscanf(f.read_word(),"%d",&x) == 1) o->label_image_spacing(x);
- } else if (!strcmp(c,"when")) {
- if (sscanf(f.read_word(),"%d",&x) == 1) o->when(x);
- } else if (!strcmp(c,"minimum")) {
- if (is_a(ID_Valuator_)) ((Fl_Valuator*)o)->minimum(strtod(f.read_word(),0));
- if (is_a(ID_Spinner)) ((Fl_Spinner*)o)->minimum(strtod(f.read_word(),0));
- } else if (!strcmp(c,"maximum")) {
- if (is_a(ID_Valuator_)) ((Fl_Valuator*)o)->maximum(strtod(f.read_word(),0));
- if (is_a(ID_Spinner)) ((Fl_Spinner*)o)->maximum(strtod(f.read_word(),0));
- } else if (!strcmp(c,"step")) {
- if (is_a(ID_Valuator_)) ((Fl_Valuator*)o)->step(strtod(f.read_word(),0));
- if (is_a(ID_Spinner)) ((Fl_Spinner*)o)->step(strtod(f.read_word(),0));
- } else if (!strcmp(c,"value")) {
- if (is_a(ID_Valuator_)) ((Fl_Valuator*)o)->value(strtod(f.read_word(),0));
- if (is_a(ID_Spinner)) ((Fl_Spinner*)o)->value(strtod(f.read_word(),0));
- } else if ( (!strcmp(c,"slider_size") || !strcmp(c,"size")) && is_a(ID_Slider)) {
- ((Fl_Slider*)o)->slider_size(strtod(f.read_word(),0));
- } else if (!strcmp(c,"textfont")) {
- if (sscanf(f.read_word(),"%d",&x) == 1) {ft=(Fl_Font)x; textstuff(1,ft,s,cc);}
- } else if (!strcmp(c,"textsize")) {
- if (sscanf(f.read_word(),"%d",&x) == 1) {s=x; textstuff(2,ft,s,cc);}
- } else if (!strcmp(c,"textcolor")) {
- if (sscanf(f.read_word(),"%d",&x) == 1) {cc=(Fl_Color)x;textstuff(3,ft,s,cc);}
- } else if (!strcmp(c,"hide")) {
- o->hide();
- } else if (!strcmp(c,"deactivate")) {
- o->deactivate();
- } else if (!strcmp(c,"resizable")) {
- resizable(1);
- } else if (!strcmp(c,"hotspot") || !strcmp(c, "divider")) {
- hotspot(1);
- } else if (!strcmp(c,"class")) {
- subclass(f.read_word());
- } else if (!strcmp(c,"shortcut")) {
- int shortcut = (int)strtol(f.read_word(),0,0);
- if (is_button()) ((Fl_Button*)o)->shortcut(shortcut);
- else if (is_a(ID_Input)) ((Fl_Input_*)o)->shortcut(shortcut);
- else if (is_a(ID_Value_Input)) ((Fl_Value_Input*)o)->shortcut(shortcut);
- else if (is_a(ID_Text_Display)) ((Fl_Text_Display*)o)->shortcut(shortcut);
- } else {
- if (!strncmp(c,"code",4)) {
- int n = atoi(c+4);
- if (n >= 0 && n <= NUM_EXTRA_CODE) {
- extra_code(n,f.read_word());
- return;
- }
- } else if (!strcmp(c,"extra_code")) {
- extra_code(0,f.read_word());
- return;
- }
- Fl_Type::read_property(f, c);
- }
-}
-
-Fl_Menu_Item boxmenu1[] = {
- // these extra ones are for looking up fdesign saved strings:
- {"NO_FRAME", 0,0,(void *)FL_NO_BOX},
- {"ROUNDED3D_UPBOX", 0,0,(void *)_FL_ROUND_UP_BOX},
- {"ROUNDED3D_DOWNBOX", 0,0,(void *)_FL_ROUND_DOWN_BOX},
- {"OVAL3D_UPBOX", 0,0,(void *)_FL_ROUND_UP_BOX},
- {"OVAL3D_DOWNBOX", 0,0,(void *)_FL_ROUND_DOWN_BOX},
- {"0", 0,0,(void *)ZERO_ENTRY},
- {"1", 0,0,(void *)FL_UP_BOX},
- {"2", 0,0,(void *)FL_DOWN_BOX},
- {"3", 0,0,(void *)FL_FLAT_BOX},
- {"4", 0,0,(void *)FL_BORDER_BOX},
- {"5", 0,0,(void *)FL_SHADOW_BOX},
- {"6", 0,0,(void *)FL_FRAME_BOX},
- {"7", 0,0,(void *)FL_ROUNDED_BOX},
- {"8", 0,0,(void *)FL_RFLAT_BOX},
- {"9", 0,0,(void *)FL_RSHADOW_BOX},
- {"10", 0,0,(void *)FL_UP_FRAME},
- {"11", 0,0,(void *)FL_DOWN_FRAME},
-{0}};
-
-int lookup_symbol(const char *, int &, int numberok = 0);
-
-int Fl_Widget_Type::read_fdesign(const char* propname, const char* value) {
- int v;
- if (!strcmp(propname,"box")) {
- float x,y,w,h;
- if (sscanf(value,"%f %f %f %f",&x,&y,&w,&h) == 4) {
- if (fld::io::fdesign_flip) {
- Fl_Type *p;
- for (p = parent; p && !p->is_a(ID_Window); p = p->parent) {/*empty*/}
- if (p && p->is_widget()) y = ((Fl_Widget_Type*)p)->o->h()-(y+h);
- }
- x += pasteoffset;
- y += pasteoffset;
- o->resize(int(x),int(y),int(w),int(h));
- }
- } else if (!strcmp(propname,"label")) {
- label(value);
- } else if (!strcmp(propname,"name")) {
- this->name(value);
- } else if (!strcmp(propname,"callback")) {
- callback(value); user_data_type("long");
- } else if (!strcmp(propname,"argument")) {
- user_data(value);
- } else if (!strcmp(propname,"shortcut")) {
- if (value[0]) {
- char buf[128]; sprintf(buf,"o->shortcut(\"%s\");",value);
- extra_code(0,buf);
- }
- } else if (!strcmp(propname,"style")) {
- if (!strncmp(value,"FL_NORMAL",9)) return 1;
- if (!lookup_symbol(value,v,1)) return 0;
- o->labelfont(v); o->labeltype((Fl_Labeltype)(v>>8));
- } else if (!strcmp(propname,"size")) {
- if (!lookup_symbol(value,v,1)) return 0;
- o->labelsize(v);
- } else if (!strcmp(propname,"type")) {
- if (!strncmp(value,"NORMAL",6)) return 1;
- if (lookup_symbol(value,v,1)) {o->type(v); return 1;}
- if (!strcmp(value+strlen(value)-5,"FRAME")) goto TRY_BOXTYPE;
- if (!strcmp(value+strlen(value)-3,"BOX")) goto TRY_BOXTYPE;
- return 0;
- } else if (!strcmp(propname,"lcol")) {
- if (!lookup_symbol(value,v,1)) return 0;
- o->labelcolor(v);
- } else if (!strcmp(propname,"return")) {
- if (!lookup_symbol(value,v,0)) return 0;
- o->when(v|FL_WHEN_RELEASE);
- } else if (!strcmp(propname,"alignment")) {
- if (!lookup_symbol(value,v)) {
- // convert old numeric values:
- int v1 = atoi(value); if (v1 <= 0 && strcmp(value,"0")) return 0;
- v = 0;
- if (v1 >= 5) {v = FL_ALIGN_INSIDE; v1 -= 5;}
- switch (v1) {
- case 0: v += FL_ALIGN_TOP; break;
- case 1: v += FL_ALIGN_BOTTOM; break;
- case 2: v += FL_ALIGN_LEFT; break;
- case 3: v += FL_ALIGN_RIGHT; break;
- case 4: v += FL_ALIGN_CENTER; break;
- default: return 0;
- }
- }
- o->align(v);
- } else if (!strcmp(propname,"resizebox")) {
- resizable(1);
- } else if (!strcmp(propname,"colors")) {
- char* p = (char*)value;
- while (*p != ' ') {if (!*p) return 0; p++;}
- *p = 0;
- int v1;
- if (!lookup_symbol(value,v,1) || !lookup_symbol(p+1,v1,1)) {
- *p=' '; return 0;}
- o->color(v,v1);
- } else if (!strcmp(propname,"resize")) {
- return !strcmp(value,"FL_RESIZE_ALL");
- } else if (!strcmp(propname,"gravity")) {
- return !strcmp(value,"FL_NoGravity FL_NoGravity");
- } else if (!strcmp(propname,"boxtype")) {
- TRY_BOXTYPE:
- int x = boxnumber(value);
- if (!x) {x = item_number(boxmenu1, value); if (x < 0) return 0;}
- if (x == ZERO_ENTRY) {
- x = 0;
- if (o->box() != ((Fl_Widget_Type*)factory)->o->box()) return 1; // kludge for frame
- }
- o->box((Fl_Boxtype)x);
- } else {
- return 0;
- }
- return 1;
-}
-
-void leave_live_mode_cb(Fl_Widget*, void*) {
- live_mode_cb(0, 0);
-}
-
-Fl_Widget *Fl_Widget_Type::enter_live_mode(int) {
- live_widget = widget(o->x(), o->y(), o->w(), o->h());
- if (live_widget)
- copy_properties();
- return live_widget;
-}
-
-Fl_Widget* Fl_Widget_Type::propagate_live_mode(Fl_Group* grp) {
- live_widget = grp;
- copy_properties();
- Fl_Type *n;
- for (n = next; n && n->level > level; n = n->next) {
- if (n->level == level+1) {
- Fl_Widget* proxy_child = n->enter_live_mode();
- if (proxy_child && n->is_widget() && ((Fl_Widget_Type*)n)->resizable()) {
- grp->resizable(proxy_child);
- }
- }
- }
- grp->end();
- live_widget = grp;
- copy_properties_for_children();
- return live_widget;
-}
-
-
-void Fl_Widget_Type::leave_live_mode() {
-}
-
-/**
- copy all properties from the edit widget to the live widget
- */
-void Fl_Widget_Type::copy_properties() {
- if (!live_widget)
- return;
-
- Fl_Font ff = 0;
- int fs = 0;
- Fl_Color fc = 0;
- textstuff(0, ff, fs, fc);
-
- // copy all attributes common to all widget types
- Fl_Widget *w = live_widget;
- w->label(o->label());
- w->tooltip(tooltip());
- w->type(o->type());
- w->box(o->box());
- w->color(o->color());
- w->selection_color(o->selection_color());
- w->labeltype(o->labeltype());
- w->labelfont(o->labelfont());
- w->labelsize(o->labelsize());
- w->labelcolor(o->labelcolor());
- w->align(o->align());
- w->when(o->when());
-
- // copy all attributes specific to widgets derived from Fl_Button
- if (is_button()) {
- Fl_Button* d = (Fl_Button*)live_widget, *s = (Fl_Button*)o;
- d->down_box(s->down_box());
- d->shortcut(s->shortcut());
- d->value(s->value());
- }
-
- // copy all attributes specific to widgets derived from Fl_Input_
- if (is_a(ID_Input)) {
- Fl_Input_* d = (Fl_Input_*)live_widget, *s = (Fl_Input_*)o;
- d->shortcut(s->shortcut());
- d->textfont(ff);
- d->textsize(fs);
- d->textcolor(fc);
- }
-
- // copy all attributes specific to widgets derived from Fl_Value_Input
- if (is_a(ID_Value_Input)) {
- Fl_Value_Input* d = (Fl_Value_Input*)live_widget, *s = (Fl_Value_Input*)o;
- d->shortcut(s->shortcut());
- d->textfont(ff);
- d->textsize(fs);
- d->textcolor(fc);
- }
-
- // copy all attributes specific to widgets derived from Fl_Text_Display
- if (is_a(ID_Text_Display)) {
- Fl_Text_Display* d = (Fl_Text_Display*)live_widget, *s = (Fl_Text_Display*)o;
- d->shortcut(s->shortcut());
- d->textfont(ff);
- d->textsize(fs);
- d->textcolor(fc);
- }
-
- // copy all attributes specific to Fl_Valuator and derived classes
- if (is_a(ID_Valuator_)) {
- Fl_Valuator* d = (Fl_Valuator*)live_widget, *s = (Fl_Valuator*)o;
- d->minimum(s->minimum());
- d->maximum(s->maximum());
- d->step(s->step());
- d->value(s->value());
- if (is_a(ID_Slider)) {
- Fl_Slider *d = (Fl_Slider*)live_widget, *s = (Fl_Slider*)o;
- d->slider_size(s->slider_size());
- }
- }
-
- // copy all attributes specific to Fl_Spinner and derived classes
- if (is_a(ID_Spinner)) {
- Fl_Spinner* d = (Fl_Spinner*)live_widget, *s = (Fl_Spinner*)o;
- d->minimum(s->minimum());
- d->maximum(s->maximum());
- d->step(s->step());
- d->value(s->value());
- }
-
- if (!o->visible())
- w->hide();
- if (!o->active())
- w->deactivate();
-}
-
diff --git a/fluid/nodes/Fl_Window_Type.h b/fluid/nodes/Fl_Window_Type.h
deleted file mode 100644
index 0dcb9e96e..000000000
--- a/fluid/nodes/Fl_Window_Type.h
+++ /dev/null
@@ -1,157 +0,0 @@
-//
-// Window type header file for the Fast Light Tool Kit (FLTK).
-//
-// Type for creating all subclasses of Fl_Widget
-// This should have the widget pointer in it, but it is still in the
-// Fl_Type base class.
-//
-// Copyright 1998-2023 by Bill Spitzak and others.
-//
-// This library is free software. Distribution and use rights are outlined in
-// the file "COPYING" which should have been included with this file. If this
-// file is missing or damaged, see the license at:
-//
-// https://www.fltk.org/COPYING.php
-//
-// Please see the following page on how to report bugs and issues:
-//
-// https://www.fltk.org/bugs.php
-//
-
-#ifndef _FLUID_FL_WINDOW_TYPE_H
-#define _FLUID_FL_WINDOW_TYPE_H
-
-#include "nodes/Fl_Group_Type.h"
-
-class Fl_Widget_Class_Type;
-
-extern Fl_Menu_Item window_type_menu[];
-extern Fl_Widget_Class_Type *current_widget_class;
-
-void toggle_overlays(Fl_Widget *,void *);
-void toggle_guides(Fl_Widget *,void *);
-void toggle_restricted(Fl_Widget *,void *);
-void show_project_cb(Fl_Widget *, void *);
-void show_grid_cb(Fl_Widget *, void *);
-void show_settings_cb(Fl_Widget *, void *);
-
-enum {
- FD_LEFT = 1, // user drags the left side of the selection box
- FD_RIGHT = 2,
- FD_BOTTOM = 4,
- FD_TOP = 8,
- FD_DRAG = 16, // user drags the entire selection
- FD_BOX = 32 // user creates a new selection box
-};
-
-class Fl_Window_Type : public Fl_Group_Type
-{
- typedef Fl_Group_Type super;
-protected:
-
- Fl_Menu_Item* subtypes() FL_OVERRIDE {return window_type_menu;}
-
- friend class Overlay_Window;
- int mx,my; // mouse position during dragging
- int x1,y1; // initial position of selection box
- int bx,by,br,bt; // bounding box of selection before snapping
- int sx,sy,sr,st; // bounding box of selection after snapping to guides
- int dx,dy;
- int drag; // which parts of bbox are being moved
- int numselected; // number of children selected
- void draw_out_of_bounds(Fl_Widget_Type *group, int x, int y, int w, int h);
- void draw_out_of_bounds();
- void draw_overlaps();
- void draw_overlay();
- void newdx();
- void newposition(Fl_Widget_Type *,int &x,int &y,int &w,int &h);
- int handle(int);
- void setlabel(const char *) FL_OVERRIDE;
- void write_code1(fld::io::Code_Writer& f) FL_OVERRIDE;
- void write_code2(fld::io::Code_Writer& f) FL_OVERRIDE;
- Fl_Widget_Type *_make() FL_OVERRIDE {return 0;} // we don't call this
- Fl_Widget *widget(int,int,int,int) FL_OVERRIDE {return 0;}
- int recalc; // set by fix_overlay()
- void moveallchildren(int key=0);
- ID id() const FL_OVERRIDE { return ID_Window; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Window) ? true : super::is_a(inID); }
- void open_();
-
-public:
-
- Fl_Window_Type() :
- mx(0), my(0),
- x1(0), y1(0),
- bx(0), by(0), br(0), bt(0),
- sx(0), sy(0), sr(0), st(0),
- dx(0), dy(0),
- drag(0),
- numselected(0),
- recalc(0),
- modal(0), non_modal(0),
- xclass(NULL),
- sr_min_w(0), sr_min_h(0), sr_max_w(0), sr_max_h(0)
- { }
- uchar modal, non_modal;
- const char *xclass; // junk string, used for shortcut
-
- Fl_Type *make(Strategy strategy) FL_OVERRIDE;
- const char *type_name() FL_OVERRIDE {return "Fl_Window";}
- const char *alt_type_name() FL_OVERRIDE {return "fltk::Window";}
-
- void open() FL_OVERRIDE;
- void ideal_size(int &w, int &h) FL_OVERRIDE;
-
- void fix_overlay(); // Update the bounding box, etc
- uchar *read_image(int &ww, int &hh); // Read an image of the window
-
- void write_properties(fld::io::Project_Writer &f) FL_OVERRIDE;
- void read_property(fld::io::Project_Reader &f, const char *) FL_OVERRIDE;
- int read_fdesign(const char*, const char*) FL_OVERRIDE;
-
- void add_child(Fl_Type*, Fl_Type*) FL_OVERRIDE;
- void move_child(Fl_Type*, Fl_Type*) FL_OVERRIDE;
- void remove_child(Fl_Type*) FL_OVERRIDE;
-
- int can_have_children() const FL_OVERRIDE {return 1;}
-
- Fl_Widget *enter_live_mode(int top=0) FL_OVERRIDE;
- void leave_live_mode() FL_OVERRIDE;
- void copy_properties() FL_OVERRIDE;
-
- int sr_min_w, sr_min_h, sr_max_w, sr_max_h;
-
- static int popupx, popupy;
-};
-
-class Fl_Widget_Class_Type : private Fl_Window_Type
-{
- typedef Fl_Window_Type super;
-protected:
- Fl_Menu_Item* subtypes() FL_OVERRIDE {return 0;}
-
-public:
- Fl_Widget_Class_Type() {
- write_public_state = 0;
- wc_relative = 0;
- }
- // state variables for output:
- char write_public_state; // true when public: has been printed
- char wc_relative; // if 1, reposition all children, if 2, reposition and resize
-
- void write_properties(fld::io::Project_Writer &f) FL_OVERRIDE;
- void read_property(fld::io::Project_Reader &f, const char *) FL_OVERRIDE;
-
- void write_code1(fld::io::Code_Writer& f) FL_OVERRIDE;
- void write_code2(fld::io::Code_Writer& f) FL_OVERRIDE;
- Fl_Type *make(Strategy strategy) FL_OVERRIDE;
- const char *type_name() FL_OVERRIDE {return "widget_class";}
- ID id() const FL_OVERRIDE { return ID_Widget_Class; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Widget_Class) ? true : super::is_a(inID); }
- int can_have_children() const FL_OVERRIDE {return 1;}
- int is_code_block() const FL_OVERRIDE {return 1;}
- int is_decl_block() const FL_OVERRIDE {return 1;}
- int is_class() const FL_OVERRIDE {return 1;}
-};
-
-#endif // _FLUID_FL_WINDOW_TYPE_H
diff --git a/fluid/nodes/Fl_Function_Type.cxx b/fluid/nodes/Function_Node.cxx
index 5778324bf..8ffdbef01 100644
--- a/fluid/nodes/Fl_Function_Type.cxx
+++ b/fluid/nodes/Function_Node.cxx
@@ -1,7 +1,7 @@
//
-// C function type code for the Fast Light Tool Kit (FLTK).
+// C function Node code for the Fast Light Tool Kit (FLTK).
//
-// Copyright 1998-2023 by Bill Spitzak and others.
+// Copyright 1998-2025 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
@@ -14,16 +14,16 @@
// https://www.fltk.org/bugs.php
//
-#include "nodes/Fl_Function_Type.h"
+#include "nodes/Function_Node.h"
-#include "app/fluid.h"
-#include "app/mergeback.h"
-#include "app/undo.h"
+#include "Fluid.h"
+#include "proj/mergeback.h"
+#include "proj/undo.h"
#include "io/Project_Reader.h"
#include "io/Project_Writer.h"
#include "io/Code_Writer.h"
-#include "nodes/Fl_Window_Type.h"
-#include "nodes/Fl_Group_Type.h"
+#include "nodes/Window_Node.h"
+#include "nodes/Group_Node.h"
#include "panels/function_panel.h"
#include "rsrcs/comments.h"
#include "widgets/Node_Browser.h"
@@ -37,22 +37,22 @@
/// Set a current class, so that the code of the children is generated correctly.
-Fl_Class_Type *current_class = NULL;
+Class_Node *current_class = nullptr;
/**
\brief Return 1 if the list contains a function with the given signature at the top level.
- Fl_Widget_Type uses this to check if a callback by a certain signature is
- already defined by the user within this file. If not, Fl_Widget_Type will
+ Widget_Node uses this to check if a callback by a certain signature is
+ already defined by the user within this file. If not, Widget_Node will
generate an `extern $sig$;` statement.
- \param[in] rtype return type, can be NULL to avoid checking (not used by Fl_Widget_Type)
+ \param[in] rtype return type, can be nullptr to avoid checking (not used by Widget_Node)
\param[in] sig function signature
\return 1 if found.
*/
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() && child->is_a(ID_Function)) {
- const Fl_Function_Type *fn = (const Fl_Function_Type*)child;
+ Node *child;
+ for (child = Fluid.proj.tree.first; child; child = child->next) {
+ if (!child->is_in_class() && child->is_a(Type::Function)) {
+ const Function_Node *fn = (const Function_Node*)child;
if (fn->has_signature(rtype, sig))
return 1;
}
@@ -71,7 +71,7 @@ static char buffer[128]; // for error messages
This is used to find a matching " or ' in a string.
\param[inout] c start searching here, return where we found \c type
\param[in] type find this character
- \return NULL if the character was found, else a pointer to a static string
+ \return nullptr if the character was found, else a pointer to a static string
with an error message
*/
const char *_q_check(const char * & c, int type) {
@@ -83,7 +83,7 @@ const char *_q_check(const char * & c, int type) {
if (*c) c++;
break;
default:
- if (*(c-1) == type) return 0;
+ if (*(c-1) == type) return nullptr;
}
}
@@ -93,14 +93,14 @@ const char *_q_check(const char * & c, int type) {
{, [, ", ', and ( are matched.
\param[inout] c start searching here, return the end of the search
\param[in] type find this character match
- \return NULL if the character was found, else a pointer to a static string
+ \return nullptr if the character was found, else a pointer to a static string
with an error message
*/
const char *_c_check(const char * & c, int type) {
const char *d;
for (;;) switch (*c++) {
case 0:
- if (!type) return 0;
+ if (!type) return nullptr;
sprintf(buffer, "missing '%c'", type);
return buffer;
case '/':
@@ -123,7 +123,8 @@ const char *_c_check(const char * & c, int type) {
// while (*c != '\n' && *c) c++;
// break;
case '{':
- if (type==')') goto UNEXPECTED;
+// // Matt: C++ does allow {} inside () now
+// if (type==')') goto UNEXPECTED;
d = _c_check(c,'}');
if (d) return d;
break;
@@ -146,8 +147,8 @@ const char *_c_check(const char * & c, int type) {
case '}':
case ')':
case ']':
- UNEXPECTED:
- if (type == *(c-1)) return 0;
+// UNEXPECTED:
+ if (type == *(c-1)) return nullptr;
sprintf(buffer, "unexpected '%c'", *(c-1));
return buffer;
}
@@ -158,7 +159,7 @@ const char *_c_check(const char * & c, int type) {
Make sure that {, ", ', and ( are matched.
\param[in] c start searching here
\param[in] type find this character match (default is 0)
- \return NULL if the character was found, else a pointer to a static string
+ \return nullptr if the character was found, else a pointer to a static string
with an error message
\note This function checks every conceivable line of code, which is not
always wanted. It can't differentiate characters in comments, and the
@@ -169,9 +170,9 @@ const char *c_check(const char *c, int type) {
return _c_check(c,type);
}
-// ---- Fl_Function_Type implementation
+// ---- Function_Node implementation
-/** \class Fl_Function_Type
+/** \class Function_Node
Manage a C++ function node in the Fluid design.
A function can have a signature (name followed by arguments), a return type
@@ -180,14 +181,14 @@ const char *c_check(const char *c, int type) {
*/
/// Prototype for a function to be used by the factory.
-Fl_Function_Type Fl_Function_type;
+Function_Node Function_Node::prototype;
/**
Create a new function.
*/
-Fl_Function_Type::Fl_Function_Type() :
- Fl_Type(),
- return_type(0L),
+Function_Node::Function_Node() :
+ Node(),
+ return_type(nullptr),
public_(0),
cdecl_(0),
constructor(0),
@@ -197,7 +198,7 @@ Fl_Function_Type::Fl_Function_Type() :
/**
Destructor.
*/
-Fl_Function_Type::~Fl_Function_Type() {
+Function_Node::~Function_Node() {
if (return_type) free((void*)return_type);
}
@@ -206,8 +207,8 @@ Fl_Function_Type::~Fl_Function_Type() {
\param[in] strategy add new function after current or as last child
\return the new node
*/
-Fl_Type *Fl_Function_Type::make(Strategy strategy) {
- Fl_Type *anchor = Fl_Type::current, *p = anchor;
+Node *Function_Node::make(Strategy strategy) {
+ Node *anchor = Fluid.proj.tree.current, *p = anchor;
if (p && (strategy.placement() == Strategy::AFTER_CURRENT))
p = p->parent;
while (p && !p->is_decl_block()) {
@@ -215,9 +216,9 @@ Fl_Type *Fl_Function_Type::make(Strategy strategy) {
strategy.placement(Strategy::AFTER_CURRENT);
p = p->parent;
}
- Fl_Function_Type *o = new Fl_Function_Type();
+ Function_Node *o = new Function_Node();
o->name("make_window()");
- o->return_type = 0;
+ o->return_type = nullptr;
o->add(anchor, strategy);
o->factory = this;
o->public_ = 1;
@@ -231,8 +232,8 @@ Fl_Type *Fl_Function_Type::make(Strategy strategy) {
- "C" is written if we want a C signature instead of C++
- "return_type" is followed by the return type of the function
*/
-void Fl_Function_Type::write_properties(fld::io::Project_Writer &f) {
- Fl_Type::write_properties(f);
+void Function_Node::write_properties(fld::io::Project_Writer &f) {
+ Node::write_properties(f);
switch (public_) {
case 0: f.write_string("private"); break;
case 2: f.write_string("protected"); break;
@@ -248,7 +249,7 @@ void Fl_Function_Type::write_properties(fld::io::Project_Writer &f) {
Read function specific properties fron an .fl file.
\param[in] c read from this string
*/
-void Fl_Function_Type::read_property(fld::io::Project_Reader &f, const char *c) {
+void Function_Node::read_property(fld::io::Project_Reader &f, const char *c) {
if (!strcmp(c,"private")) {
public_ = 0;
} else if (!strcmp(c,"protected")) {
@@ -258,14 +259,14 @@ void Fl_Function_Type::read_property(fld::io::Project_Reader &f, const char *c)
} else if (!strcmp(c,"return_type")) {
storestring(f.read_word(),return_type);
} else {
- Fl_Type::read_property(f, c);
+ Node::read_property(f, c);
}
}
/**
Open the function_panel dialog box to edit this function.
*/
-void Fl_Function_Type::open() {
+void Function_Node::open() {
// fill dialog box
if (!function_panel) make_function_panel();
f_return_type_input->value(return_type);
@@ -285,7 +286,7 @@ void Fl_Function_Type::open() {
const char *c = comment();
f_comment_input->buffer()->text(c?c:"");
function_panel->show();
- const char* message = 0;
+ const char* message = nullptr;
for (;;) { // repeat as long as there are errors
// - message loop until OK or cancel is pressed
for (;;) {
@@ -311,7 +312,7 @@ void Fl_Function_Type::open() {
// - alert user
if (message) {
int v = fl_choice("Potential syntax error detected: %s",
- "Continue Editing", "Ignore Error", NULL, message);
+ "Continue Editing", "Ignore Error", nullptr, message);
if (v==0) continue; // Continue Editing
//if (v==1) { } // Ignore Error and close dialog
}
@@ -338,14 +339,14 @@ void Fl_Function_Type::open() {
}
c = f_comment_input->buffer()->text();
if (c && *c) {
- if (!comment() || strcmp(c, comment())) { set_modflag(1); redraw_browser(); }
+ if (!comment() || strcmp(c, comment())) { Fluid.proj.set_modflag(1); redraw_browser(); }
comment(c);
} else {
- if (comment()) { set_modflag(1); redraw_browser(); }
- comment(0);
+ if (comment()) { Fluid.proj.set_modflag(1); redraw_browser(); }
+ comment(nullptr);
}
if (c) free((void*)c);
- if (mod) set_modflag(1);
+ if (mod) Fluid.proj.set_modflag(1);
break;
}
BREAK2:
@@ -356,7 +357,7 @@ BREAK2:
Return 1 if the function is global.
\return 1 if public, 0 if local.
*/
-int Fl_Function_Type::is_public() const {
+int Function_Node::is_public() const {
return public_;
}
@@ -410,10 +411,10 @@ static void clean_function_for_implementation(char *out, const char *function_na
This writes the code that goes \b before all children of this class.
\see write_code2(fld::io::Code_Writer& f)
*/
-void Fl_Function_Type::write_code1(fld::io::Code_Writer& f) {
+void Function_Node::write_code1(fld::io::Code_Writer& f) {
constructor=0;
havewidgets = 0;
- Fl_Type *child;
+ Node *child;
// if the function has no children (hence no body), Fluid will not generate
// the function either. This is great if you decide to implement that function
// inside another module
@@ -438,11 +439,11 @@ void Fl_Function_Type::write_code1(fld::io::Code_Writer& f) {
int is_static = 0;
int is_virtual = 0;
if (rtype) {
- if (!strcmp(rtype,"static")) {is_static = 1; rtype = 0;}
+ if (!strcmp(rtype,"static")) {is_static = 1; rtype = nullptr;}
else if (!strncmp(rtype, "static ",7)) {is_static = 1; rtype += 7;}
}
if (rtype) {
- if (!strcmp(rtype, "virtual")) {is_virtual = 1; rtype = 0;}
+ if (!strcmp(rtype, "virtual")) {is_virtual = 1; rtype = nullptr;}
else if (!strncmp(rtype, "virtual ",8)) {is_virtual = 1; rtype += 8;}
}
if (!rtype) {
@@ -529,13 +530,13 @@ void Fl_Function_Type::write_code1(fld::io::Code_Writer& f) {
This writes the code that goes \b after all children of this class.
\see write_code1(fld::io::Code_Writer& f)
*/
-void Fl_Function_Type::write_code2(fld::io::Code_Writer& f) {
- Fl_Type *child;
+void Function_Node::write_code2(fld::io::Code_Writer& f) {
+ Node *child;
const char *var = "w";
char havechildren = 0;
for (child = next; child && child->level > level; child = child->next) {
havechildren = 1;
- if (child->is_a(ID_Window) && child->name()) var = child->name();
+ if (child->is_a(Type::Window) && child->name()) var = child->name();
}
if (ismain()) {
@@ -552,24 +553,24 @@ void Fl_Function_Type::write_code2(fld::io::Code_Writer& f) {
}
/**
- Check if the return type and signature s match.
+ Check if the return type and signatures match.
\param[in] rtype function return type
\param[in] sig function name followed by arguments
\return 1 if they match, 0 if not
*/
-int Fl_Function_Type::has_signature(const char *rtype, const char *sig) const {
+int Function_Node::has_signature(const char *rtype, const char *sig) const {
if (rtype && !return_type) return 0;
if (!name()) return 0;
- if ( (rtype==0L || strcmp(return_type, rtype)==0)
+ if ( (rtype==nullptr || strcmp(return_type, rtype)==0)
&& fl_filename_match(name(), sig)) {
return 1;
}
return 0;
}
-// ---- Fl_Code_Type declaration
+// ---- Code_Node declaration
-/** \class Fl_Code_Type
+/** \class Code_Node
Manage a block of C++ code in the Fluid design.
This node manages an arbitrary block of code inside a function that will
@@ -578,12 +579,12 @@ int Fl_Function_Type::has_signature(const char *rtype, const char *sig) const {
*/
/// Prototype for code to be used by the factory.
-Fl_Code_Type Fl_Code_type;
+Code_Node Code_Node::prototype;
/**
Constructor.
*/
-Fl_Code_Type::Fl_Code_Type() :
+Code_Node::Code_Node() :
cursor_position_(0),
code_input_scroll_row(0),
code_input_scroll_col(0)
@@ -596,8 +597,8 @@ Fl_Code_Type::Fl_Code_Type() :
\param[in] strategy add code after current or as last child
\return new Code node
*/
-Fl_Type *Fl_Code_Type::make(Strategy strategy) {
- Fl_Type *anchor = Fl_Type::current, *p = anchor;
+Node *Code_Node::make(Strategy strategy) {
+ Node *anchor = Fluid.proj.tree.current, *p = anchor;
if (p && (strategy.placement() == Strategy::AFTER_CURRENT))
p = p->parent;
while (p && !p->is_code_block()) {
@@ -607,9 +608,9 @@ Fl_Type *Fl_Code_Type::make(Strategy strategy) {
}
if (!p) {
fl_message("Please select a function");
- return 0;
+ return nullptr;
}
- Fl_Code_Type *o = new Fl_Code_Type();
+ Code_Node *o = new Code_Node();
o->name("printf(\"Hello, World!\\n\");");
o->add(anchor, strategy);
o->factory = this;
@@ -619,10 +620,10 @@ Fl_Type *Fl_Code_Type::make(Strategy strategy) {
/**
Open the code_panel or an external editor to edit this code section.
*/
-void Fl_Code_Type::open() {
+void Code_Node::open() {
// Using an external code editor? Open it..
- if ( G_use_external_editor && G_external_editor_command[0] ) {
- const char *cmd = G_external_editor_command;
+ if ( Fluid.use_external_editor && Fluid.external_editor_command[0] ) {
+ const char *cmd = Fluid.external_editor_command;
const char *code = name();
if (!code) code = "";
if ( editor_.open_editor(cmd, code) == 0 )
@@ -635,7 +636,7 @@ void Fl_Code_Type::open() {
code_input->insert_position(cursor_position_);
code_input->scroll(code_input_scroll_row, code_input_scroll_col);
code_panel->show();
- const char* message = 0;
+ const char* message = nullptr;
for (;;) { // repeat as long as there are errors
for (;;) {
Fl_Widget* w = Fl::readqueue();
@@ -647,7 +648,7 @@ void Fl_Code_Type::open() {
message = c_check(c);
if (message) {
int v = fl_choice("Potential syntax error detected: %s",
- "Continue Editing", "Ignore Error", NULL, message);
+ "Continue Editing", "Ignore Error", nullptr, message);
if (v==0) continue; // Continue Editing
//if (v==1) { } // Ignore Error and close dialog
}
@@ -665,21 +666,21 @@ BREAK2:
/**
Grab changes from an external editor and write this node.
*/
-void Fl_Code_Type::write(fld::io::Project_Writer &f) {
+void Code_Node::write(fld::io::Project_Writer &f) {
// External editor changes? If so, load changes into ram, update mtime/size
if ( handle_editor_changes() == 1 ) {
- main_window->redraw(); // tell fluid to redraw; edits may affect tree's contents
+ Fluid.main_window->redraw(); // tell fluid to redraw; edits may affect tree's contents
}
- Fl_Type::write(f);
+ Node::write(f);
}
/**
Write the code block with the correct indentation.
*/
-void Fl_Code_Type::write_code1(fld::io::Code_Writer& f) {
+void Code_Node::write_code1(fld::io::Code_Writer& f) {
// External editor changes? If so, load changes into ram, update mtime/size
if ( handle_editor_changes() == 1 ) {
- main_window->redraw(); // tell fluid to redraw; edits may affect tree's contents
+ Fluid.main_window->redraw(); // tell fluid to redraw; edits may affect tree's contents
}
// Matt: disabled f.tag(FD_TAG_GENERIC, 0);
f.write_c_indented(name(), 0, '\n');
@@ -689,7 +690,7 @@ void Fl_Code_Type::write_code1(fld::io::Code_Writer& f) {
/**
See if external editor is open.
*/
-int Fl_Code_Type::is_editing() {
+int Code_Node::is_editing() {
return editor_.is_editing();
}
@@ -700,7 +701,7 @@ int Fl_Code_Type::is_editing() {
\return 0: process still running
\return \>0: process finished + reaped (returns pid)
*/
-int Fl_Code_Type::reap_editor() {
+int Code_Node::reap_editor() {
return editor_.reap_editor();
}
@@ -713,8 +714,8 @@ int Fl_Code_Type::reap_editor() {
\todo Figure out how saving a fluid file can be intercepted to grab
current contents of editor file..
*/
-int Fl_Code_Type::handle_editor_changes() {
- const char *newcode = 0;
+int Code_Node::handle_editor_changes() {
+ const char *newcode = nullptr;
switch ( editor_.handle_changes(&newcode) ) {
case 1: { // (1)=changed
name(newcode); // update value in ram
@@ -727,9 +728,9 @@ int Fl_Code_Type::handle_editor_changes() {
return 0;
}
-// ---- Fl_CodeBlock_Type implementation
+// ---- CodeBlock_Node implementation
-/** \class Fl_CodeBlock_Type
+/** \class CodeBlock_Node
Manage two blocks of C++ code enclosing its children.
This node manages two lines of code that enclose all children
@@ -739,20 +740,20 @@ int Fl_Code_Type::handle_editor_changes() {
*/
/// Prototype for a block of code to be used by the factory.
-Fl_CodeBlock_Type Fl_CodeBlock_type;
+CodeBlock_Node CodeBlock_Node::prototype;
/**
Constructor.
*/
-Fl_CodeBlock_Type::Fl_CodeBlock_Type() :
- Fl_Type(),
- after(NULL)
+CodeBlock_Node::CodeBlock_Node() :
+ Node(),
+ after(nullptr)
{ }
/**
Destructor.
*/
-Fl_CodeBlock_Type::~Fl_CodeBlock_Type() {
+CodeBlock_Node::~CodeBlock_Node() {
if (after)
free((void*)after);
}
@@ -764,8 +765,8 @@ Fl_CodeBlock_Type::~Fl_CodeBlock_Type() {
\param[in] strategy add after current or as last child
\return new CodeBlock
*/
-Fl_Type *Fl_CodeBlock_Type::make(Strategy strategy) {
- Fl_Type *anchor = Fl_Type::current, *p = anchor;
+Node *CodeBlock_Node::make(Strategy strategy) {
+ Node *anchor = Fluid.proj.tree.current, *p = anchor;
if (p && (strategy.placement() == Strategy::AFTER_CURRENT))
p = p->parent;
while (p && !p->is_code_block()) {
@@ -775,11 +776,11 @@ Fl_Type *Fl_CodeBlock_Type::make(Strategy strategy) {
}
if (!p) {
fl_message("Please select a function");
- return 0;
+ return nullptr;
}
- Fl_CodeBlock_Type *o = new Fl_CodeBlock_Type();
+ CodeBlock_Node *o = new CodeBlock_Node();
o->name("if (test())");
- o->after = 0;
+ o->after = nullptr;
o->add(anchor, strategy);
o->factory = this;
return o;
@@ -790,8 +791,8 @@ Fl_Type *Fl_CodeBlock_Type::make(Strategy strategy) {
- "after" is followed by the code that comes after the children
The "before" code is stored in the name() field.
*/
-void Fl_CodeBlock_Type::write_properties(fld::io::Project_Writer &f) {
- Fl_Type::write_properties(f);
+void CodeBlock_Node::write_properties(fld::io::Project_Writer &f) {
+ Node::write_properties(f);
if (after) {
f.write_string("after");
f.write_word(after);
@@ -801,23 +802,23 @@ void Fl_CodeBlock_Type::write_properties(fld::io::Project_Writer &f) {
/**
Read the node specific properties.
*/
-void Fl_CodeBlock_Type::read_property(fld::io::Project_Reader &f, const char *c) {
+void CodeBlock_Node::read_property(fld::io::Project_Reader &f, const char *c) {
if (!strcmp(c,"after")) {
storestring(f.read_word(),after);
} else {
- Fl_Type::read_property(f, c);
+ Node::read_property(f, c);
}
}
/**
Open the codeblock_panel.
*/
-void Fl_CodeBlock_Type::open() {
+void CodeBlock_Node::open() {
if (!codeblock_panel) make_codeblock_panel();
code_before_input->value(name());
code_after_input->value(after);
codeblock_panel->show();
- const char* message = 0;
+ const char* message = nullptr;
for (;;) { // repeat as long as there are errors
// event loop
for (;;) {
@@ -834,7 +835,7 @@ void Fl_CodeBlock_Type::open() {
// alert user
if (message) {
int v = fl_choice("Potential syntax error detected: %s",
- "Continue Editing", "Ignore Error", NULL, message);
+ "Continue Editing", "Ignore Error", nullptr, message);
if (v==0) continue; // Continue Editing
//if (v==1) { } // Ignore Error and close dialog
}
@@ -850,7 +851,7 @@ BREAK2:
/**
Write the "before" code.
*/
-void Fl_CodeBlock_Type::write_code1(fld::io::Code_Writer& f) {
+void CodeBlock_Node::write_code1(fld::io::Code_Writer& f) {
const char* c = name();
f.write_c("%s%s {\n", f.indent(), c ? c : "");
f.indentation++;
@@ -859,15 +860,15 @@ void Fl_CodeBlock_Type::write_code1(fld::io::Code_Writer& f) {
/**
Write the "after" code.
*/
-void Fl_CodeBlock_Type::write_code2(fld::io::Code_Writer& f) {
+void CodeBlock_Node::write_code2(fld::io::Code_Writer& f) {
f.indentation--;
if (after) f.write_c("%s} %s\n", f.indent(), after);
else f.write_c("%s}\n", f.indent());
}
-// ---- Fl_Decl_Type declaration
+// ---- Decl_Node declaration
-/** \class Fl_Decl_Type
+/** \class Decl_Node
Manage the C/C++ declaration of a variable.
This node manages a single line of code that can be in the header or the source
@@ -877,12 +878,12 @@ void Fl_CodeBlock_Type::write_code2(fld::io::Code_Writer& f) {
*/
/// Prototype for a declaration to be used by the factory.
-Fl_Decl_Type Fl_Decl_type;
+Decl_Node Decl_Node::prototype;
/**
Constructor.
*/
-Fl_Decl_Type::Fl_Decl_Type() :
+Decl_Node::Decl_Node() :
public_(0),
static_(1)
{ }
@@ -890,9 +891,9 @@ Fl_Decl_Type::Fl_Decl_Type() :
/**
Return 1 if this declaration and its parents are public.
*/
-int Fl_Decl_Type::is_public() const
+int Decl_Node::is_public() const
{
- Fl_Type *p = parent;
+ Node *p = parent;
while (p && !p->is_decl_block()) p = p->parent;
if(p && p->is_public() && public_)
return public_;
@@ -906,8 +907,8 @@ int Fl_Decl_Type::is_public() const
\param[in] strategy add after current or as last child
\return new Declaration node
*/
-Fl_Type *Fl_Decl_Type::make(Strategy strategy) {
- Fl_Type *anchor = Fl_Type::current, *p = anchor;
+Node *Decl_Node::make(Strategy strategy) {
+ Node *anchor = Fluid.proj.tree.current, *p = anchor;
if (p && (strategy.placement() == Strategy::AFTER_CURRENT))
p = p->parent;
while (p && !p->is_decl_block()) {
@@ -915,7 +916,7 @@ Fl_Type *Fl_Decl_Type::make(Strategy strategy) {
strategy.placement(Strategy::AFTER_CURRENT);
p = p->parent;
}
- Fl_Decl_Type *o = new Fl_Decl_Type();
+ Decl_Node *o = new Decl_Node();
o->public_ = 0;
o->static_ = 1;
o->name("int x;");
@@ -929,8 +930,8 @@ Fl_Type *Fl_Decl_Type::make(Strategy strategy) {
- "private"/"public"/"protected"
- "local"/"global" if this is static or not
*/
-void Fl_Decl_Type::write_properties(fld::io::Project_Writer &f) {
- Fl_Type::write_properties(f);
+void Decl_Node::write_properties(fld::io::Project_Writer &f) {
+ Node::write_properties(f);
switch (public_) {
case 0: f.write_string("private"); break;
case 1: f.write_string("public"); break;
@@ -945,7 +946,7 @@ void Fl_Decl_Type::write_properties(fld::io::Project_Writer &f) {
/**
Read the specific properties.
*/
-void Fl_Decl_Type::read_property(fld::io::Project_Reader &f, const char *c) {
+void Decl_Node::read_property(fld::io::Project_Reader &f, const char *c) {
if (!strcmp(c,"public")) {
public_ = 1;
} else if (!strcmp(c,"private")) {
@@ -957,14 +958,14 @@ void Fl_Decl_Type::read_property(fld::io::Project_Reader &f, const char *c) {
} else if (!strcmp(c,"global")) {
static_ = 0;
} else {
- Fl_Type::read_property(f, c);
+ Node::read_property(f, c);
}
}
/**
Open the decl_panel to edit this node.
*/
-void Fl_Decl_Type::open() {
+void Decl_Node::open() {
if (!decl_panel) make_decl_panel();
decl_input->buffer()->text(name());
if (is_in_class()) {
@@ -979,7 +980,7 @@ void Fl_Decl_Type::open() {
const char *c = comment();
decl_comment_input->buffer()->text(c?c:"");
decl_panel->show();
- const char* message = 0;
+ const char* message = nullptr;
for (;;) { // repeat as long as there are errors
// event loop
for (;;) {
@@ -995,7 +996,7 @@ void Fl_Decl_Type::open() {
// alert user
if (message) {
int v = fl_choice("Potential syntax error detected: %s",
- "Continue Editing", "Ignore Error", NULL, message);
+ "Continue Editing", "Ignore Error", nullptr, message);
if (v==0) continue; // Continue Editing
//if (v==1) { } // Ignore Error and close dialog
}
@@ -1003,26 +1004,26 @@ void Fl_Decl_Type::open() {
name(c);
if (is_in_class()) {
if (public_!=decl_class_choice->value()) {
- set_modflag(1);
+ Fluid.proj.set_modflag(1);
public_ = decl_class_choice->value();
}
} else {
if (public_!=(decl_choice->value()&1)) {
- set_modflag(1);
+ Fluid.proj.set_modflag(1);
public_ = (decl_choice->value()&1);
}
if (static_!=((decl_choice->value()>>1)&1)) {
- set_modflag(1);
+ Fluid.proj.set_modflag(1);
static_ = ((decl_choice->value()>>1)&1);
}
}
c = decl_comment_input->buffer()->text();
if (c && *c) {
- if (!comment() || strcmp(c, comment())) { set_modflag(1); redraw_browser(); }
+ if (!comment() || strcmp(c, comment())) { Fluid.proj.set_modflag(1); redraw_browser(); }
comment(c);
} else {
- if (comment()) { set_modflag(1); redraw_browser(); }
- comment(0);
+ if (comment()) { Fluid.proj.set_modflag(1); redraw_browser(); }
+ comment(nullptr);
}
if (c) free((void*)c);
break;
@@ -1036,7 +1037,7 @@ BREAK2:
\todo There are a lot of side effect in this node depending on the given text
and the parent node. They need to be understood and documented.
*/
-void Fl_Decl_Type::write_code1(fld::io::Code_Writer& f) {
+void Decl_Node::write_code1(fld::io::Code_Writer& f) {
const char* c = name();
if (!c) return;
// handle a few keywords differently if inside a class
@@ -1100,9 +1101,9 @@ void Fl_Decl_Type::write_code1(fld::io::Code_Writer& f) {
}
}
-// ---- Fl_Data_Type declaration
+// ---- Data_Node declaration
-/** \class Fl_Data_Type
+/** \class Data_Node
Manage data from an external arbitrary file.
The content of the file will be stored in binary inside the generated
@@ -1110,21 +1111,21 @@ void Fl_Decl_Type::write_code1(fld::io::Code_Writer& f) {
*/
/// Prototype for a data node to be used by the factory.
-Fl_Data_Type Fl_Data_type;
+Data_Node Data_Node::prototype;
/**
Constructor.
*/
-Fl_Data_Type::Fl_Data_Type() :
- Fl_Decl_Type(),
- filename_(NULL),
+Data_Node::Data_Node() :
+ Decl_Node(),
+ filename_(nullptr),
text_mode_(0)
{ }
/**
Destructor.
*/
-Fl_Data_Type::~Fl_Data_Type() {
+Data_Node::~Data_Node() {
if (filename_)
free((void*)filename_);
}
@@ -1134,8 +1135,8 @@ Fl_Data_Type::~Fl_Data_Type() {
\param[in] strategy add after current or as last child
\return new inline data node
*/
-Fl_Type *Fl_Data_Type::make(Strategy strategy) {
- Fl_Type *anchor = Fl_Type::current, *p = anchor;
+Node *Data_Node::make(Strategy strategy) {
+ Node *anchor = Fluid.proj.tree.current, *p = anchor;
if (p && (strategy.placement() == Strategy::AFTER_CURRENT))
p = p->parent;
while (p && !p->is_decl_block()) {
@@ -1143,10 +1144,10 @@ Fl_Type *Fl_Data_Type::make(Strategy strategy) {
strategy.placement(Strategy::AFTER_CURRENT);
p = p->parent;
}
- Fl_Data_Type *o = new Fl_Data_Type();
+ Data_Node *o = new Data_Node();
o->public_ = 1;
o->static_ = 1;
- o->filename_ = 0;
+ o->filename_ = nullptr;
o->text_mode_ = 0;
o->name("myInlineData");
o->add(anchor, strategy);
@@ -1159,8 +1160,8 @@ Fl_Type *Fl_Data_Type::make(Strategy strategy) {
- "filename" followed by the filename of the file to inline
- "textmode" if data is written in ASCII vs. binary
*/
-void Fl_Data_Type::write_properties(fld::io::Project_Writer &f) {
- Fl_Decl_Type::write_properties(f);
+void Data_Node::write_properties(fld::io::Project_Writer &f) {
+ Decl_Node::write_properties(f);
if (filename_) {
f.write_string("filename");
f.write_word(filename_);
@@ -1176,7 +1177,7 @@ void Fl_Data_Type::write_properties(fld::io::Project_Writer &f) {
/**
Read specific properties.
*/
-void Fl_Data_Type::read_property(fld::io::Project_Reader &f, const char *c) {
+void Data_Node::read_property(fld::io::Project_Reader &f, const char *c) {
if (!strcmp(c,"filename")) {
storestring(f.read_word(), filename_, 1);
} else if (!strcmp(c,"textmode")) {
@@ -1184,14 +1185,14 @@ void Fl_Data_Type::read_property(fld::io::Project_Reader &f, const char *c) {
} else if (!strcmp(c,"compressed")) {
text_mode_ = 2;
} else {
- Fl_Decl_Type::read_property(f, c);
+ Decl_Node::read_property(f, c);
}
}
/**
Open the data_panel to edit this node.
*/
-void Fl_Data_Type::open() {
+void Data_Node::open() {
if (!data_panel) make_data_panel();
data_input->value(name());
if (is_in_class()) {
@@ -1214,12 +1215,12 @@ void Fl_Data_Type::open() {
if (w == data_panel_cancel) goto BREAK2;
else if (w == data_panel_ok) break;
else if (w == data_filebrowser) {
- enter_project_dir();
- const char *fn = fl_file_chooser("Load Inline Data", 0L, data_filename->value(), 1);
- leave_project_dir();
+ Fluid.proj.enter_project_dir();
+ const char *fn = fl_file_chooser("Load Inline Data", nullptr, data_filename->value(), 1);
+ Fluid.proj.leave_project_dir();
if (fn) {
if (strcmp(fn, data_filename->value()))
- set_modflag(1);
+ Fluid.proj.set_modflag(1);
data_filename->value(fn);
}
}
@@ -1246,27 +1247,27 @@ void Fl_Data_Type::open() {
if (n==q) {
OOPS:
int v = fl_choice("%s",
- "Continue Editing", "Ignore Error", NULL,
+ "Continue Editing", "Ignore Error", nullptr,
"Variable name must be a C identifier");
if (v==0) { free(s); continue; } // Continue Editing
//if (v==1) { } // Ignore Error and close dialog
}
- undo_checkpoint();
+ Fluid.proj.undo.checkpoint();
name(n);
free(s);
// store flags
if (is_in_class()) {
if (public_!=data_class_choice->value()) {
- set_modflag(1);
+ Fluid.proj.set_modflag(1);
public_ = data_class_choice->value();
}
} else {
if (public_!=(data_choice->value()&1)) {
- set_modflag(1);
+ Fluid.proj.set_modflag(1);
public_ = (data_choice->value()&1);
}
if (static_!=((data_choice->value()>>1)&1)) {
- set_modflag(1);
+ Fluid.proj.set_modflag(1);
static_ = ((data_choice->value()>>1)&1);
}
}
@@ -1276,22 +1277,22 @@ void Fl_Data_Type::open() {
// store the filename
c = data_filename->value();
if (filename_ && strcmp(filename_, data_filename->value()))
- set_modflag(1);
+ Fluid.proj.set_modflag(1);
else if (!filename_ && *c)
- set_modflag(1);
- if (filename_) { free((void*)filename_); filename_ = 0L; }
+ Fluid.proj.set_modflag(1);
+ if (filename_) { free((void*)filename_); filename_ = nullptr; }
if (c && *c) filename_ = fl_strdup(c);
// store the comment
c = data_comment_input->buffer()->text();
if (c && *c) {
- if (!comment() || strcmp(c, comment())) { set_modflag(1); redraw_browser(); }
+ if (!comment() || strcmp(c, comment())) { Fluid.proj.set_modflag(1); redraw_browser(); }
comment(c);
} else {
- if (comment()) { set_modflag(1); redraw_browser(); }
- comment(0);
+ if (comment()) { Fluid.proj.set_modflag(1); redraw_browser(); }
+ comment(nullptr);
}
if (c) free((void*)c);
- set_modflag(1);
+ Fluid.proj.set_modflag(1);
break;
}
BREAK2:
@@ -1301,19 +1302,19 @@ BREAK2:
/**
Write the content of the external file inline into the source code.
*/
-void Fl_Data_Type::write_code1(fld::io::Code_Writer& f) {
- const char *message = 0;
+void Data_Node::write_code1(fld::io::Code_Writer& f) {
+ const char *message = nullptr;
const char *c = name();
if (!c) return;
const char *fn = filename_;
- char *data = 0;
+ char *data = nullptr;
int nData = -1;
int uncompressedDataSize = 0;
// path should be set correctly already
if (filename_ && !f.write_codeview) {
- enter_project_dir();
+ Fluid.proj.enter_project_dir();
FILE *f = fl_fopen(filename_, "rb");
- leave_project_dir();
+ Fluid.proj.leave_project_dir();
if (!f) {
message = "Can't include data from file. Can't open";
} else {
@@ -1426,9 +1427,9 @@ void Fl_Data_Type::write_code1(fld::io::Code_Writer& f) {
}
}
// if we are in interactive mode, we pop up a warning dialog
- // giving the error: (batch_mode && !write_codeview) ???
+ // giving the error: (Fluid.batch_mode && !write_codeview) ???
if (message && !f.write_codeview) {
- if (batch_mode)
+ if (Fluid.batch_mode)
fprintf(stderr, "FLUID ERROR: %s %s\n", message, fn);
else
fl_alert("%s\n%s\n", message, fn);
@@ -1436,9 +1437,9 @@ void Fl_Data_Type::write_code1(fld::io::Code_Writer& f) {
if (data) free(data);
}
-// ---- Fl_DeclBlock_Type declaration
+// ---- DeclBlock_Node declaration
-/** \class Fl_DeclBlock_Type
+/** \class DeclBlock_Node
Manage a declaration block.
Declaration blocks have two text field that are written before and after
@@ -1447,21 +1448,21 @@ void Fl_Data_Type::write_code1(fld::io::Code_Writer& f) {
*/
/// Prototype for a declaration block to be used by the factory.
-Fl_DeclBlock_Type Fl_DeclBlock_type;
+DeclBlock_Node DeclBlock_Node::prototype;
/**
Constructor.
*/
-Fl_DeclBlock_Type::Fl_DeclBlock_Type() :
- Fl_Type(),
- after(NULL),
+DeclBlock_Node::DeclBlock_Node() :
+ Node(),
+ after(nullptr),
write_map_(CODE_IN_SOURCE)
{ }
/**
Destructor.
*/
-Fl_DeclBlock_Type::~Fl_DeclBlock_Type() {
+DeclBlock_Node::~DeclBlock_Node() {
if (after)
::free((void*)after);
}
@@ -1469,7 +1470,7 @@ Fl_DeclBlock_Type::~Fl_DeclBlock_Type() {
/**
Return 1 if this block is public.
*/
-int Fl_DeclBlock_Type::is_public() const {
+int DeclBlock_Node::is_public() const {
return ((write_map_&CODE_IN_HEADER) != 0);
}
@@ -1478,15 +1479,15 @@ int Fl_DeclBlock_Type::is_public() const {
\param[in] strategy add after current or as last child
\return new Declaration Block node
*/
-Fl_Type *Fl_DeclBlock_Type::make(Strategy strategy) {
- Fl_Type *anchor = Fl_Type::current, *p = anchor;
+Node *DeclBlock_Node::make(Strategy strategy) {
+ Node *anchor = Fluid.proj.tree.current, *p = anchor;
if (p && (strategy.placement() == Strategy::AFTER_CURRENT)) p = p->parent;
while (p && !p->is_decl_block()) {
anchor = p;
strategy.placement(Strategy::AFTER_CURRENT);
p = p->parent;
}
- Fl_DeclBlock_Type *o = new Fl_DeclBlock_Type();
+ DeclBlock_Node *o = new DeclBlock_Node();
o->name("#if 1");
o->write_map_ = CODE_IN_SOURCE;
o->after = fl_strdup("#endif");
@@ -1500,8 +1501,8 @@ Fl_Type *Fl_DeclBlock_Type::make(Strategy strategy) {
- "public"/"protected"
- "after" followed by the second code block.
*/
-void Fl_DeclBlock_Type::write_properties(fld::io::Project_Writer &f) {
- Fl_Type::write_properties(f);
+void DeclBlock_Node::write_properties(fld::io::Project_Writer &f) {
+ Node::write_properties(f);
// deprecated
if (is_public()) f.write_string("public");
// new way to map declaration block to various parts of the generated code
@@ -1514,7 +1515,7 @@ void Fl_DeclBlock_Type::write_properties(fld::io::Project_Writer &f) {
/**
Read the specific properties.
*/
-void Fl_DeclBlock_Type::read_property(fld::io::Project_Reader &f, const char *c) {
+void DeclBlock_Node::read_property(fld::io::Project_Reader &f, const char *c) {
if(!strcmp(c,"public")) {
write_map_ |= CODE_IN_HEADER;
} else if(!strcmp(c,"protected")) {
@@ -1524,14 +1525,14 @@ void Fl_DeclBlock_Type::read_property(fld::io::Project_Reader &f, const char *c)
} else if (!strcmp(c,"after")) {
storestring(f.read_word(),after);
} else {
- Fl_Type::read_property(f, c);
+ Node::read_property(f, c);
}
}
/**
Open the declblock_panel to edit this node.
*/
-void Fl_DeclBlock_Type::open() {
+void DeclBlock_Node::open() {
// build dialog box
if (!declblock_panel) make_declblock_panel();
// preset all values
@@ -1545,7 +1546,7 @@ void Fl_DeclBlock_Type::open() {
declblock_comment_input->buffer()->text(c?c:"");
// show modal dialog and loop until satisfied
declblock_panel->show();
- const char* message = 0;
+ const char* message = nullptr;
for (;;) { // repeat as long as there are errors
for (;;) {
Fl_Widget* w = Fl::readqueue();
@@ -1563,7 +1564,7 @@ void Fl_DeclBlock_Type::open() {
message = c_check(b&&b[0]=='#' ? b+1 : b);
if (message) {
int v = fl_choice("Potential syntax error detected: %s",
- "Continue Editing", "Ignore Error", NULL, message);
+ "Continue Editing", "Ignore Error", nullptr, message);
if (v==0) continue; // Continue Editing
//if (v==1) { } // Ignore Error and close dialog
}
@@ -1573,54 +1574,54 @@ void Fl_DeclBlock_Type::open() {
if (write_map_ & STATIC_IN_HEADER) {
if (declblock_static_header->value()==0) {
write_map_ &= ~STATIC_IN_HEADER;
- set_modflag(1);
+ Fluid.proj.set_modflag(1);
}
} else {
if (declblock_static_header->value()) {
write_map_ |= STATIC_IN_HEADER;
- set_modflag(1);
+ Fluid.proj.set_modflag(1);
}
}
if (write_map_ & STATIC_IN_SOURCE) {
if (declblock_static_source->value()==0) {
write_map_ &= ~STATIC_IN_SOURCE;
- set_modflag(1);
+ Fluid.proj.set_modflag(1);
}
} else {
if (declblock_static_source->value()) {
write_map_ |= STATIC_IN_SOURCE;
- set_modflag(1);
+ Fluid.proj.set_modflag(1);
}
}
if (write_map_ & CODE_IN_HEADER) {
if (declblock_code_header->value()==0) {
write_map_ &= ~CODE_IN_HEADER;
- set_modflag(1);
+ Fluid.proj.set_modflag(1);
}
} else {
if (declblock_code_header->value()) {
write_map_ |= CODE_IN_HEADER;
- set_modflag(1);
+ Fluid.proj.set_modflag(1);
}
}
if (write_map_ & CODE_IN_SOURCE) {
if (declblock_code_source->value()==0) {
write_map_ &= ~CODE_IN_SOURCE;
- set_modflag(1);
+ Fluid.proj.set_modflag(1);
}
} else {
if (declblock_code_source->value()) {
write_map_ |= CODE_IN_SOURCE;
- set_modflag(1);
+ Fluid.proj.set_modflag(1);
}
}
c = declblock_comment_input->buffer()->text();
if (c && *c) {
- if (!comment() || strcmp(c, comment())) { set_modflag(1); redraw_browser(); }
+ if (!comment() || strcmp(c, comment())) { Fluid.proj.set_modflag(1); redraw_browser(); }
comment(c);
} else {
- if (comment()) { set_modflag(1); redraw_browser(); }
- comment(0);
+ if (comment()) { Fluid.proj.set_modflag(1); redraw_browser(); }
+ comment(nullptr);
}
if (c) free((void*)c);
break;
@@ -1633,7 +1634,7 @@ BREAK2:
Write the \b before static code to the source file, and to the header file if declared public.
The before code is stored in the name() field.
*/
-void Fl_DeclBlock_Type::write_static(fld::io::Code_Writer& f) {
+void DeclBlock_Node::write_static(fld::io::Code_Writer& f) {
const char* c = name();
if (c && *c) {
if (write_map_ & STATIC_IN_HEADER)
@@ -1646,7 +1647,7 @@ void Fl_DeclBlock_Type::write_static(fld::io::Code_Writer& f) {
/**
Write the \b after static code to the source file, and to the header file if declared public.
*/
-void Fl_DeclBlock_Type::write_static_after(fld::io::Code_Writer& f) {
+void DeclBlock_Node::write_static_after(fld::io::Code_Writer& f) {
const char* c = after;
if (c && *c) {
if (write_map_ & STATIC_IN_HEADER)
@@ -1660,7 +1661,7 @@ void Fl_DeclBlock_Type::write_static_after(fld::io::Code_Writer& f) {
Write the \b before code to the source file, and to the header file if declared public.
The before code is stored in the name() field.
*/
-void Fl_DeclBlock_Type::write_code1(fld::io::Code_Writer& f) {
+void DeclBlock_Node::write_code1(fld::io::Code_Writer& f) {
const char* c = name();
if (c && *c) {
if (write_map_ & CODE_IN_HEADER)
@@ -1673,7 +1674,7 @@ void Fl_DeclBlock_Type::write_code1(fld::io::Code_Writer& f) {
/**
Write the \b after code to the source file, and to the header file if declared public.
*/
-void Fl_DeclBlock_Type::write_code2(fld::io::Code_Writer& f) {
+void DeclBlock_Node::write_code2(fld::io::Code_Writer& f) {
const char* c = after;
if (c && *c) {
if (write_map_ & CODE_IN_HEADER)
@@ -1683,9 +1684,9 @@ void Fl_DeclBlock_Type::write_code2(fld::io::Code_Writer& f) {
}
}
-// ---- Fl_Comment_Type declaration
+// ---- Comment_Node declaration
-/** \class Fl_Comment_Type
+/** \class Comment_Node
Manage a comment node.
The comment field takes one or more lines of ASCII text. If the text starts
@@ -1694,12 +1695,12 @@ void Fl_DeclBlock_Type::write_code2(fld::io::Code_Writer& f) {
*/
/// Prototype for a comment node to be used by the factory.
-Fl_Comment_Type Fl_Comment_type;
+Comment_Node Comment_Node::prototype;
/**
Constructor.
*/
-Fl_Comment_Type::Fl_Comment_Type() :
+Comment_Node::Comment_Node() :
in_c_(1),
in_h_(1),
style_(0)
@@ -1710,8 +1711,8 @@ Fl_Comment_Type::Fl_Comment_Type() :
\param[in] strategy add after current or as last child
\return new Comment node
*/
-Fl_Type *Fl_Comment_Type::make(Strategy strategy) {
- Fl_Type *anchor = Fl_Type::current, *p = anchor;
+Node *Comment_Node::make(Strategy strategy) {
+ Node *anchor = Fluid.proj.tree.current, *p = anchor;
if (p && (strategy.placement() == Strategy::AFTER_CURRENT))
p = p->parent;
while (p && !p->is_code_block()) {
@@ -1719,7 +1720,7 @@ Fl_Type *Fl_Comment_Type::make(Strategy strategy) {
strategy.placement(Strategy::AFTER_CURRENT);
p = p->parent;
}
- Fl_Comment_Type *o = new Fl_Comment_Type();
+ Comment_Node *o = new Comment_Node();
o->in_c_ = 1;
o->in_h_ = 1;
o->style_ = 0;
@@ -1734,8 +1735,8 @@ Fl_Type *Fl_Comment_Type::make(Strategy strategy) {
- "in_source"/"not_in_source" if the comment will be written to the source code
- "in_header"/"not_in_header" if the comment will be written to the header file
*/
-void Fl_Comment_Type::write_properties(fld::io::Project_Writer &f) {
- Fl_Type::write_properties(f);
+void Comment_Node::write_properties(fld::io::Project_Writer &f) {
+ Node::write_properties(f);
if (in_c_) f.write_string("in_source"); else f.write_string("not_in_source");
if (in_h_) f.write_string("in_header"); else f.write_string("not_in_header");
}
@@ -1743,7 +1744,7 @@ void Fl_Comment_Type::write_properties(fld::io::Project_Writer &f) {
/**
Read extra properties.
*/
-void Fl_Comment_Type::read_property(fld::io::Project_Reader &f, const char *c) {
+void Comment_Node::read_property(fld::io::Project_Reader &f, const char *c) {
if (!strcmp(c,"in_source")) {
in_c_ = 1;
} else if (!strcmp(c,"not_in_source")) {
@@ -1753,7 +1754,7 @@ void Fl_Comment_Type::read_property(fld::io::Project_Reader &f, const char *c) {
} else if (!strcmp(c,"not_in_header")) {
in_h_ = 0;
} else {
- Fl_Type::read_property(f, c);
+ Node::read_property(f, c);
}
}
@@ -1782,7 +1783,7 @@ static void load_comments_preset(Fl_Preferences &menu) {
/**
Open the comment_panel to edit this node.
*/
-void Fl_Comment_Type::open() {
+void Comment_Node::open() {
if (!comment_panel) make_comment_panel();
const char *text = name();
{
@@ -1838,7 +1839,7 @@ void Fl_Comment_Type::open() {
fl_message("Please select an entry from this menu first.");
} else if (fl_choice("Are you sure that you want to delete the entry\n"
"\"%s\"\nfrom the database?", "Cancel", "Delete",
- NULL, itempath)) {
+ nullptr, itempath)) {
Fl_Preferences db(Fl_Preferences::USER_L, "fltk.org", "fluid_comments");
db.deleteEntry(itempath);
comment_predefined->remove(last_selected_item);
@@ -1869,8 +1870,8 @@ void Fl_Comment_Type::open() {
else if (w == comment_load) {
// load a comment from disk
fl_file_chooser_ok_label("Use File");
- const char *fname = fl_file_chooser("Pick a comment", 0L, 0L);
- fl_file_chooser_ok_label(NULL);
+ const char *fname = fl_file_chooser("Pick a comment", nullptr, nullptr);
+ fl_file_chooser_ok_label(nullptr);
if (fname) {
if (comment_input->buffer()->loadfile(fname)) {
fl_alert("Error loading file\n%s", fname);
@@ -1891,7 +1892,7 @@ void Fl_Comment_Type::open() {
in_h_ = comment_in_header->value();
mod = 1;
}
- if (mod) set_modflag(1);
+ if (mod) Fluid.proj.set_modflag(1);
break;
}
BREAK2:
@@ -1901,7 +1902,7 @@ BREAK2:
/**
Write the comment to the files.
*/
-void Fl_Comment_Type::write_code1(fld::io::Code_Writer& f) {
+void Comment_Node::write_code1(fld::io::Code_Writer& f) {
const char* c = name();
if (!c) return;
if (!in_c_ && !in_h_) return;
@@ -1941,29 +1942,29 @@ void Fl_Comment_Type::write_code1(fld::io::Code_Writer& f) {
free(txt);
}
-// ---- Fl_Class_Type declaration
+// ---- Class_Node declaration
-/** \class Fl_Class_Type
+/** \class Class_Node
Manage a class declaration and implementation.
*/
/// Prototype for a class node to be used by the factory.
-Fl_Class_Type Fl_Class_type;
+Class_Node Class_Node::prototype;
/**
Constructor.
*/
-Fl_Class_Type::Fl_Class_Type() :
- Fl_Type(),
- subclass_of(NULL),
+Class_Node::Class_Node() :
+ Node(),
+ subclass_of(nullptr),
public_(1),
- class_prefix(NULL)
+ class_prefix(nullptr)
{ }
/**
Destructor.
*/
-Fl_Class_Type::~Fl_Class_Type() {
+Class_Node::~Class_Node() {
if (subclass_of)
free((void*)subclass_of);
if (class_prefix)
@@ -1973,14 +1974,14 @@ Fl_Class_Type::~Fl_Class_Type() {
/**
Return 1 if this class is marked public.
*/
-int Fl_Class_Type::is_public() const {
+int Class_Node::is_public() const {
return public_;
}
/**
Set the prefixx string.
*/
-void Fl_Class_Type::prefix(const char*p) {
+void Class_Node::prefix(const char*p) {
free((void*) class_prefix);
class_prefix=fl_strdup(p ? p : "" );
}
@@ -1990,8 +1991,8 @@ void Fl_Class_Type::prefix(const char*p) {
\param[in] strategy add after current or as last child
\return new Class node
*/
-Fl_Type *Fl_Class_Type::make(Strategy strategy) {
- Fl_Type *anchor = Fl_Type::current, *p = anchor;
+Node *Class_Node::make(Strategy strategy) {
+ Node *anchor = Fluid.proj.tree.current, *p = anchor;
if (p && (strategy.placement() == Strategy::AFTER_CURRENT))
p = p->parent;
while (p && !p->is_decl_block()) {
@@ -1999,10 +2000,10 @@ Fl_Type *Fl_Class_Type::make(Strategy strategy) {
strategy.placement(Strategy::AFTER_CURRENT);
p = p->parent;
}
- Fl_Class_Type *o = new Fl_Class_Type();
+ Class_Node *o = new Class_Node();
o->name("UserInterface");
- o->class_prefix = NULL;
- o->subclass_of = NULL;
+ o->class_prefix = nullptr;
+ o->subclass_of = nullptr;
o->public_ = 1;
o->add(anchor, strategy);
o->factory = this;
@@ -2014,8 +2015,8 @@ Fl_Type *Fl_Class_Type::make(Strategy strategy) {
- ":" followed by the super class
- "private"/"protected"
*/
-void Fl_Class_Type::write_properties(fld::io::Project_Writer &f) {
- Fl_Type::write_properties(f);
+void Class_Node::write_properties(fld::io::Project_Writer &f) {
+ Node::write_properties(f);
if (subclass_of) {
f.write_string(":");
f.write_word(subclass_of);
@@ -2029,7 +2030,7 @@ void Fl_Class_Type::write_properties(fld::io::Project_Writer &f) {
/**
Read additional properties.
*/
-void Fl_Class_Type::read_property(fld::io::Project_Reader &f, const char *c) {
+void Class_Node::read_property(fld::io::Project_Reader &f, const char *c) {
if (!strcmp(c,"private")) {
public_ = 0;
} else if (!strcmp(c,"protected")) {
@@ -2037,14 +2038,14 @@ void Fl_Class_Type::read_property(fld::io::Project_Reader &f, const char *c) {
} else if (!strcmp(c,":")) {
storestring(f.read_word(), subclass_of);
} else {
- Fl_Type::read_property(f, c);
+ Node::read_property(f, c);
}
}
/**
Open the class_panel to edit the class name and superclass name.
*/
-void Fl_Class_Type::open() {
+void Class_Node::open() {
if (!class_panel) make_class_panel();
char fullname[FL_PATH_MAX]="";
if (prefix() && strlen(prefix()))
@@ -2057,9 +2058,9 @@ void Fl_Class_Type::open() {
const char *c = comment();
c_comment_input->buffer()->text(c?c:"");
class_panel->show();
- const char* message = 0;
+ const char* message = nullptr;
- char *na=0,*pr=0,*p=0; // name and prefix substrings
+ char *na=nullptr,*pr=nullptr,*p=nullptr; // name and prefix substrings
for (;;) { // repeat as long as there are errors
// we don;t give the option to ignore this error here because code depends
@@ -2099,15 +2100,15 @@ void Fl_Class_Type::open() {
storestring(c, subclass_of);
if (public_ != c_public_button->value()) {
public_ = c_public_button->value();
- set_modflag(1);
+ Fluid.proj.set_modflag(1);
}
c = c_comment_input->buffer()->text();
if (c && *c) {
- if (!comment() || strcmp(c, comment())) { set_modflag(1); redraw_browser(); }
+ if (!comment() || strcmp(c, comment())) { Fluid.proj.set_modflag(1); redraw_browser(); }
comment(c);
} else {
- if (comment()) { set_modflag(1); redraw_browser(); }
- comment(0);
+ if (comment()) { Fluid.proj.set_modflag(1); redraw_browser(); }
+ comment(nullptr);
}
if (c) free((void*)c);
break;
@@ -2119,7 +2120,7 @@ BREAK2:
/**
Write the header code that declares this class.
*/
-void Fl_Class_Type::write_code1(fld::io::Code_Writer& f) {
+void Class_Node::write_code1(fld::io::Code_Writer& f) {
parent_class = current_class;
current_class = this;
write_public_state = 0;
@@ -2136,7 +2137,7 @@ void Fl_Class_Type::write_code1(fld::io::Code_Writer& f) {
/**
Write the header code that ends the declaration of this class.
*/
-void Fl_Class_Type::write_code2(fld::io::Code_Writer& f) {
+void Class_Node::write_code2(fld::io::Code_Writer& f) {
f.write_h("};\n");
current_class = parent_class;
}
@@ -2144,11 +2145,11 @@ void Fl_Class_Type::write_code2(fld::io::Code_Writer& f) {
/**
Return 1 if this class contains a function with the given signature.
*/
-int Fl_Type::has_function(const char *rtype, const char *sig) const {
- Fl_Type *child;
+int Node::has_function(const char *rtype, const char *sig) const {
+ Node *child;
for (child = next; child && child->level > level; child = child->next) {
- if (child->level == level+1 && child->is_a(ID_Function)) {
- const Fl_Function_Type *fn = (const Fl_Function_Type*)child;
+ if (child->level == level+1 && child->is_a(Type::Function)) {
+ const Function_Node *fn = (const Function_Node*)child;
if (fn->has_signature(rtype, sig))
return 1;
}
diff --git a/fluid/nodes/Function_Node.h b/fluid/nodes/Function_Node.h
new file mode 100644
index 000000000..ac8bcdcc2
--- /dev/null
+++ b/fluid/nodes/Function_Node.h
@@ -0,0 +1,277 @@
+//
+// C function Node header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2025 by Bill Spitzak and others.
+//
+// This library is free software. Distribution and use rights are outlined in
+// the file "COPYING" which should have been included with this file. If this
+// file is missing or damaged, see the license at:
+//
+// https://www.fltk.org/COPYING.php
+//
+// Please see the following page on how to report bugs and issues:
+//
+// https://www.fltk.org/bugs.php
+//
+
+#ifndef FLUID_NODES_FUNCTION_NODE_H
+#define FLUID_NODES_FUNCTION_NODE_H
+
+#include "nodes/Node.h"
+
+#include "app/Image_Asset.h"
+#ifdef _WIN32
+#include "tools/ExternalCodeEditor_WIN32.h"
+#else
+#include "tools/ExternalCodeEditor_UNIX.h"
+#endif
+
+#include <FL/Fl_Widget.H>
+#include <FL/Fl_Menu.H>
+#include <FL/fl_draw.H>
+#include <FL/fl_attr.h>
+
+#include <stdarg.h>
+#include <stdlib.h>
+
+extern class Class_Node *current_class;
+
+int has_toplevel_function(const char *rtype, const char *sig);
+
+const char *c_check(const char *c, int type = 0);
+
+// ---- Function_Node declaration
+
+class Function_Node : public Node
+{
+public:
+ typedef Node super;
+ static Function_Node prototype;
+private:
+ const char* return_type;
+ char public_, cdecl_, constructor, havewidgets;
+public:
+ Function_Node();
+ ~Function_Node();
+ Node *make(Strategy strategy) override;
+ void write_code1(fld::io::Code_Writer& f) override;
+ void write_code2(fld::io::Code_Writer& f) override;
+ void open() override;
+ int ismain() {return name_ == nullptr;}
+ const char *type_name() override {return "Function";}
+ const char *title() override {
+ return name() ? name() : "main()";
+ }
+ int can_have_children() const override {return 1;}
+ int is_code_block() const override {return 1;}
+ int is_public() const override;
+ Type type() const override { return Type::Function; }
+ bool is_a(Type inType) const override { return (inType==Type::Function) ? true : super::is_a(inType); }
+ void write_properties(fld::io::Project_Writer &f) override;
+ void read_property(fld::io::Project_Reader &f, const char *) override;
+ int has_signature(const char *, const char*) const;
+};
+
+// ---- Code_Node declaration
+
+class Code_Node : public Node
+{
+public:
+ typedef Node super;
+ static Code_Node prototype;
+private:
+ ExternalCodeEditor editor_;
+ int cursor_position_;
+ int code_input_scroll_row;
+ int code_input_scroll_col;
+public:
+ Code_Node();
+ Node *make(Strategy strategy) override;
+ void write(fld::io::Project_Writer &f) override;
+ void write_code1(fld::io::Code_Writer& f) override;
+ void write_code2(fld::io::Code_Writer& f) override { }
+ void open() override;
+ const char *type_name() override {return "code";}
+ int is_code_block() const override {return 0;}
+ Type type() const override { return Type::Code; }
+ bool is_a(Type inType) const override { return (inType==Type::Code) ? true : super::is_a(inType); }
+ int is_public() const override { return -1; }
+ int is_editing();
+ int reap_editor();
+ int handle_editor_changes();
+};
+
+// ---- CodeBlock_Node declaration
+
+class CodeBlock_Node : public Node
+{
+public:
+ typedef Node super;
+ static CodeBlock_Node prototype;
+private:
+ const char* after;
+public:
+ CodeBlock_Node();
+ ~CodeBlock_Node();
+ Node *make(Strategy strategy) override;
+ void write_code1(fld::io::Code_Writer& f) override;
+ void write_code2(fld::io::Code_Writer& f) override;
+ void open() override;
+ const char *type_name() override {return "codeblock";}
+ int is_code_block() const override {return 1;}
+ int can_have_children() const override {return 1;}
+ int is_public() const override { return -1; }
+ Type type() const override { return Type::CodeBlock; }
+ bool is_a(Type inType) const override { return (inType==Type::CodeBlock) ? true : super::is_a(inType); }
+ void write_properties(fld::io::Project_Writer &f) override;
+ void read_property(fld::io::Project_Reader &f, const char *) override;
+};
+
+// ---- Decl_Node declaration
+
+class Decl_Node : public Node
+{
+public:
+ typedef Node super;
+ static Decl_Node prototype;
+protected:
+ char public_;
+ char static_;
+
+public:
+ Decl_Node();
+ Node *make(Strategy strategy) override;
+ void write_code1(fld::io::Code_Writer& f) override;
+ void write_code2(fld::io::Code_Writer& f) override { }
+ void open() override;
+ const char *type_name() override {return "decl";}
+ void write_properties(fld::io::Project_Writer &f) override;
+ void read_property(fld::io::Project_Reader &f, const char *) override;
+ int is_public() const override;
+ Type type() const override { return Type::Decl; }
+ bool is_a(Type inType) const override { return (inType==Type::Decl) ? true : super::is_a(inType); }
+};
+
+// ---- Data_Node declaration
+
+class Data_Node : public Decl_Node
+{
+public:
+ typedef Decl_Node super;
+ static Data_Node prototype;
+private:
+ const char *filename_;
+ int text_mode_;
+
+public:
+ Data_Node();
+ ~Data_Node();
+ Node *make(Strategy strategy) override;
+ void write_code1(fld::io::Code_Writer& f) override;
+ void write_code2(fld::io::Code_Writer& f) override {}
+ void open() override;
+ const char *type_name() override {return "data";}
+ void write_properties(fld::io::Project_Writer &f) override;
+ void read_property(fld::io::Project_Reader &f, const char *) override;
+ Type type() const override { return Type::Data; }
+ bool is_a(Type inType) const override { return (inType==Type::Data) ? true : super::is_a(inType); }
+};
+
+// ---- DeclBlock_Node declaration
+
+class DeclBlock_Node : public Node
+{
+public:
+ typedef Node super;
+ static DeclBlock_Node prototype;
+private:
+ enum {
+ CODE_IN_HEADER = 1,
+ CODE_IN_SOURCE = 2,
+ STATIC_IN_HEADER = 4,
+ STATIC_IN_SOURCE = 8
+ };
+ const char* after; ///< code after all children of this block
+ int write_map_; ///< see enum above
+
+public:
+ DeclBlock_Node();
+ ~DeclBlock_Node();
+ Node *make(Strategy strategy) override;
+ void write_static(fld::io::Code_Writer& f) override;
+ void write_static_after(fld::io::Code_Writer& f) override;
+ void write_code1(fld::io::Code_Writer& f) override;
+ void write_code2(fld::io::Code_Writer& f) override;
+ void open() override;
+ const char *type_name() override {return "declblock";}
+ void write_properties(fld::io::Project_Writer &f) override;
+ void read_property(fld::io::Project_Reader &f, const char *) override;
+ int can_have_children() const override {return 1;}
+ int is_decl_block() const override {return 1;}
+ int is_public() const override;
+ Type type() const override { return Type::DeclBlock; }
+ bool is_a(Type inType) const override { return (inType==Type::DeclBlock) ? true : super::is_a(inType); }
+};
+
+// ---- Comment_Node declaration
+
+class Comment_Node : public Node
+{
+public:
+ typedef Node super;
+ static Comment_Node prototype;
+private:
+ char in_c_, in_h_, style_;
+
+public:
+ Comment_Node();
+ Node *make(Strategy strategy) override;
+ void write_code1(fld::io::Code_Writer& f) override;
+ void write_code2(fld::io::Code_Writer& f) override { }
+ void open() override;
+ const char *type_name() override {return "comment";}
+ void write_properties(fld::io::Project_Writer &f) override;
+ void read_property(fld::io::Project_Reader &f, const char *) override;
+ int is_public() const override { return 1; }
+ Type type() const override { return Type::Comment; }
+ bool is_a(Type inType) const override { return (inType==Type::Comment) ? true : super::is_a(inType); }
+};
+
+// ---- Class_Node declaration
+
+class Class_Node : public Node
+{
+public:
+ typedef Node super;
+ static Class_Node prototype;
+private:
+ const char* subclass_of;
+ char public_;
+ const char* class_prefix;
+public:
+ Class_Node();
+ ~Class_Node();
+ // state variables for output:
+ char write_public_state; // true when public: has been printed
+ Class_Node* parent_class; // save class if nested
+//
+ Node *make(Strategy strategy) override;
+ void write_code1(fld::io::Code_Writer& f) override;
+ void write_code2(fld::io::Code_Writer& f) override;
+ void open() override;
+ const char *type_name() override {return "class";}
+ int can_have_children() const override {return 1;}
+ int is_decl_block() const override {return 1;}
+ int is_class() const override {return 1;}
+ int is_public() const override;
+ Type type() const override { return Type::Class; }
+ bool is_a(Type inType) const override { return (inType==Type::Class) ? true : super::is_a(inType); }
+ void write_properties(fld::io::Project_Writer &f) override;
+ void read_property(fld::io::Project_Reader &f, const char *) override;
+
+ // class prefix attribute access
+ void prefix(const char* p);
+ const char* prefix() const {return class_prefix;}
+};
+
+#endif // FLUID_NODES_FUNCTION_NODE_H
diff --git a/fluid/nodes/Fl_Grid_Type.cxx b/fluid/nodes/Grid_Node.cxx
index 03d6620ea..06f6d4166 100644
--- a/fluid/nodes/Fl_Grid_Type.cxx
+++ b/fluid/nodes/Grid_Node.cxx
@@ -1,7 +1,7 @@
//
-// Fl_Grid object code for the Fast Light Tool Kit (FLTK).
+// Grid Node code for the Fast Light Tool Kit (FLTK).
//
-// Copyright 2023 by Bill Spitzak and others.
+// Copyright 2023-2025 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
@@ -14,11 +14,11 @@
// https://www.fltk.org/bugs.php
//
-#include "nodes/Fl_Grid_Type.h"
+#include "nodes/Grid_Node.h"
-#include "app/fluid.h"
-#include "app/Fd_Snap_Action.h"
-#include "app/undo.h"
+#include "Fluid.h"
+#include "app/Snap_Action.h"
+#include "proj/undo.h"
#include "io/Project_Reader.h"
#include "io/Project_Writer.h"
#include "io/Code_Writer.h"
@@ -35,6 +35,12 @@
#include <stdlib.h>
#include <assert.h>
+// TODO: better grid overlay?
+// TODO: grid_child_cb should move all selected cells, not just the current_selected.
+// TODO: buttons to add and delete rows and columns in the widget dialog
+// TODO: ways to resize rows and columns, add and delete them in the project window, pulldown menu?
+// TODO: alignment can be FL_GRID_LEFT|FL_GRID_VERTICAL?
+
// ---- Fl_Grid_Proxy --------------------------------------------------- MARK: -
/**
@@ -45,7 +51,7 @@
*/
Fl_Grid_Proxy::Fl_Grid_Proxy(int X,int Y,int W,int H)
: Fl_Grid(X,Y,W,H),
- transient_(NULL),
+ transient_(nullptr),
num_transient_(0),
cap_transient_(0)
{
@@ -63,7 +69,7 @@ Fl_Grid_Proxy::~Fl_Grid_Proxy() {
// Override group's resize behavior to do nothing to children:
void Fl_Grid_Proxy::resize(int X, int Y, int W, int H) {
- if (Fl_Type::allow_layout > 0) {
+ if (Fluid.proj.tree.allow_layout > 0) {
Fl_Grid::resize(X, Y, W, H);
} else {
Fl_Widget::resize(X, Y, W, H);
@@ -75,7 +81,7 @@ void Fl_Grid_Proxy::resize(int X, int Y, int W, int H) {
Override draw() to make groups with no box or flat box background visible.
*/
void Fl_Grid_Proxy::draw() {
- if (show_ghosted_outline && (box() == FL_NO_BOX)) {
+ if (Fluid.show_ghosted_outline && (box() == FL_NO_BOX)) {
fl_rect(x(), y(), w(), h(), Fl::box_color(fl_color_average(FL_FOREGROUND_COLOR, color(), .1f)));
}
Fl_Grid::draw();
@@ -131,27 +137,27 @@ void Fl_Grid_Proxy::move_cell(Fl_Widget *in_child, int to_row, int to_col, int h
}
if ((to_row < 0) || (to_row+rowspan > rows())) return;
if ((to_col < 0) || (to_col+colspan > cols())) return;
- Fl_Grid::Cell *new_cell = NULL;
+ Fl_Grid::Cell *new_cell = nullptr;
if (how == 0) { // replace old occupant in cell, making that one homeless
new_cell = widget(in_child, to_row, to_col, rowspan, colspan, align);
} else if (how == 1) { // don't replace an old occupant, making ourselves homeless
// todo: colspan, rowspan?
- if (cell(to_row, to_col) == NULL) {
+ if (cell(to_row, to_col) == nullptr) {
new_cell = widget(in_child, to_row, to_col, rowspan, colspan, align);
} else {
if (old_cell) remove_cell(old_cell->row(), old_cell->col());
}
} else if (how == 2) {
Cell *current = cell(to_row, to_col);
- if (current == NULL) {
+ if (current == nullptr) {
new_cell = widget(in_child, to_row, to_col, rowspan, colspan, align);
} else {
if (old_cell) remove_cell(old_cell->row(), old_cell->col());
new_cell = transient_widget(in_child, to_row, to_col, rowspan, colspan, align);
Fl_Widget *w = current->widget();
- Fl_Type::allow_layout++;
+ Fluid.proj.tree.allow_layout++;
in_child->resize(w->x(), w->y(), w->w(), w->h());
- Fl_Type::allow_layout--;
+ Fluid.proj.tree.allow_layout--;
}
}
if (new_cell) new_cell->minimum_size(w, h);
@@ -234,7 +240,7 @@ void Fl_Grid_Proxy::transient_remove_(Fl_Widget *w) {
/**
Find a cell in the grid or in the transient cell list.
\param[in] widget must be a child of the grid.
- \return the cell, the transient cell, or NULL if neither was found.
+ \return the cell, the transient cell, or nullptr if neither was found.
*/
Fl_Grid_Proxy::Cell *Fl_Grid_Proxy::any_cell(Fl_Widget *widget) const {
Cell *c = cell(widget);
@@ -245,14 +251,14 @@ Fl_Grid_Proxy::Cell *Fl_Grid_Proxy::any_cell(Fl_Widget *widget) const {
/**
Find a cell in the transient cell list.
\param[in] widget must be a child of the grid.
- \return the transient cell, or NULL if it was not found.
+ \return the transient cell, or nullptr if it was not found.
*/
Fl_Grid_Proxy::Cell *Fl_Grid_Proxy::transient_cell(Fl_Widget *widget) const {
for (int i=0; i<num_transient_; i++) {
if (transient_[i].widget == widget)
return transient_[i].cell;
}
- return NULL;
+ return nullptr;
}
/**
@@ -276,31 +282,29 @@ Fl_Grid::Cell *Fl_Grid_Proxy::widget(Fl_Widget *wi, int row, int col, int rowspa
-// ---- Fl_Grid_Type --------------------------------------------------- MARK: -
-
-const char grid_type_name[] = "Fl_Grid";
+// ---- Grid_Node --------------------------------------------------- MARK: -
-Fl_Grid_Type Fl_Grid_type; // the "factory"
+Grid_Node Grid_Node::prototype; // the "factory"
-Fl_Grid_Type::Fl_Grid_Type() {
+Grid_Node::Grid_Node() {
}
-Fl_Widget *Fl_Grid_Type::widget(int X,int Y,int W,int H) {
+Fl_Widget *Grid_Node::widget(int X,int Y,int W,int H) {
Fl_Grid *g = new Fl_Grid_Proxy(X,Y,W,H);
g->layout(3, 3);
- Fl_Group::current(0);
+ Fl_Group::current(nullptr);
return g;
}
-Fl_Widget *Fl_Grid_Type::enter_live_mode(int top) {
+Fl_Widget *Grid_Node::enter_live_mode(int top) {
Fl_Grid *grid = new Fl_Grid(o->x(), o->y(), o->w(), o->h());
return propagate_live_mode(grid);
}
-void Fl_Grid_Type::leave_live_mode() {
+void Grid_Node::leave_live_mode() {
}
-void Fl_Grid_Type::copy_properties()
+void Grid_Node::copy_properties()
{
super::copy_properties();
Fl_Grid *d = (Fl_Grid*)live_widget, *s =(Fl_Grid*)o;
@@ -325,7 +329,7 @@ void Fl_Grid_Type::copy_properties()
}
}
-void Fl_Grid_Type::copy_properties_for_children() {
+void Grid_Node::copy_properties_for_children() {
Fl_Grid *d = (Fl_Grid*)live_widget, *s =(Fl_Grid*)o;
for (int i=0; i<s->children(); i++) {
Fl_Grid::Cell *cell = s->cell(s->child(i));
@@ -339,7 +343,7 @@ void Fl_Grid_Type::copy_properties_for_children() {
d->layout();
}
-void Fl_Grid_Type::write_properties(fld::io::Project_Writer &f)
+void Grid_Node::write_properties(fld::io::Project_Writer &f)
{
super::write_properties(f);
Fl_Grid* grid = (Fl_Grid*)o;
@@ -404,7 +408,7 @@ void Fl_Grid_Type::write_properties(fld::io::Project_Writer &f)
}
}
-void Fl_Grid_Type::read_property(fld::io::Project_Reader &f, const char *c)
+void Grid_Node::read_property(fld::io::Project_Reader &f, const char *c)
{
Fl_Grid* grid = (Fl_Grid*)o;
if (!strcmp(c,"dimensions")) {
@@ -454,13 +458,13 @@ void Fl_Grid_Type::read_property(fld::io::Project_Reader &f, const char *c)
}
}
-void Fl_Grid_Type::write_parent_properties(fld::io::Project_Writer &f, Fl_Type *child, bool encapsulate) {
+void Grid_Node::write_parent_properties(fld::io::Project_Writer &f, Node *child, bool encapsulate) {
Fl_Grid *grid;
Fl_Widget *child_widget;
Fl_Grid::Cell *cell;
if (!child->is_true_widget()) return super::write_parent_properties(f, child, true);
grid = (Fl_Grid*)o;
- child_widget = ((Fl_Widget_Type*)child)->o;
+ child_widget = ((Widget_Node*)child)->o;
cell = grid->cell(child_widget);
if (!cell) return super::write_parent_properties(f, child, true);
if (encapsulate) {
@@ -501,13 +505,13 @@ void Fl_Grid_Type::write_parent_properties(fld::io::Project_Writer &f, Fl_Type *
// NOTE: we have to do this in a loop just as ::read_property() in case a new
// property is added. In the current setup, all the remaining properties
// will be skipped
-void Fl_Grid_Type::read_parent_property(fld::io::Project_Reader &f, Fl_Type *child, const char *property) {
+void Grid_Node::read_parent_property(fld::io::Project_Reader &f, Node *child, const char *property) {
if (!child->is_true_widget()) {
super::read_parent_property(f, child, property);
return;
}
Fl_Grid *grid = (Fl_Grid*)o;
- Fl_Widget *child_widget = ((Fl_Widget_Type*)child)->o;
+ Fl_Widget *child_widget = ((Widget_Node*)child)->o;
if (!strcmp(property, "location")) {
int row = -1, col = -1;
const char *value = f.read_word();
@@ -540,10 +544,10 @@ void Fl_Grid_Type::read_parent_property(fld::io::Project_Reader &f, Fl_Type *chi
}
}
-void Fl_Grid_Type::write_code1(fld::io::Code_Writer& f) {
+void Grid_Node::write_code1(fld::io::Code_Writer& f) {
const char *var = name() ? name() : "o";
Fl_Grid* grid = (Fl_Grid*)o;
- Fl_Widget_Type::write_code1(f);
+ Widget_Node::write_code1(f);
int i, rows = grid->rows(), cols = grid->cols();
f.write_c("%s%s->layout(%d, %d);\n", f.indent(), var, rows, cols);
int lm, tm, rm, bm;
@@ -604,7 +608,7 @@ void Fl_Grid_Type::write_code1(fld::io::Code_Writer& f) {
}
}
-void Fl_Grid_Type::write_code2(fld::io::Code_Writer& f) {
+void Grid_Node::write_code2(fld::io::Code_Writer& f) {
const char *var = name() ? name() : "o";
Fl_Grid* grid = (Fl_Grid*)o;
bool first_cell = true;
@@ -613,7 +617,7 @@ void Fl_Grid_Type::write_code2(fld::io::Code_Writer& f) {
Fl_Grid::Cell *cell = grid->cell(c);
if (cell) {
if (first_cell) {
- f.write_c("%sFl_Grid::Cell *cell = NULL;\n", f.indent());
+ f.write_c("%sFl_Grid::Cell *cell = 0L;\n", f.indent());
first_cell = false;
}
f.write_c("%scell = %s->widget(%s->child(%d), %d, %d, %d, %d, %d);\n",
@@ -627,21 +631,21 @@ void Fl_Grid_Type::write_code2(fld::io::Code_Writer& f) {
super::write_code2(f);
}
-void Fl_Grid_Type::add_child(Fl_Type* a, Fl_Type* b) {
+void Grid_Node::add_child(Node* a, Node* b) {
super::add_child(a, b);
Fl_Grid* grid = (Fl_Grid*)o;
grid->need_layout(1);
grid->redraw();
}
-void Fl_Grid_Type::move_child(Fl_Type* a, Fl_Type* b) {
+void Grid_Node::move_child(Node* a, Node* b) {
super::move_child(a, b);
Fl_Grid* grid = (Fl_Grid*)o;
grid->need_layout(1);
grid->redraw();
}
-void Fl_Grid_Type::remove_child(Fl_Type* a) {
+void Grid_Node::remove_child(Node* a) {
super::remove_child(a);
Fl_Grid* grid = (Fl_Grid*)o;
grid->need_layout(1);
@@ -653,7 +657,7 @@ void Fl_Grid_Type::remove_child(Fl_Type* a) {
FLUID, users will want to resize children. So we need to trick Fl_Grid into
taking the new size as the initial size.
*/
-void Fl_Grid_Type::child_resized(Fl_Widget_Type *child_type) {
+void Grid_Node::child_resized(Widget_Node *child_type) {
Fl_Grid *grid = (Fl_Grid*)o;
Fl_Widget *child = child_type->o;
Fl_Grid::Cell *cell = grid->cell(child);
@@ -671,10 +675,10 @@ void Fl_Grid_Type::child_resized(Fl_Widget_Type *child_type) {
}
/** Return the currently selected Grid widget if is a Grid Type. */
-Fl_Grid *Fl_Grid_Type::selected() {
- if (current_widget && current_widget->is_a(ID_Grid))
- return ((Fl_Grid*)((Fl_Grid_Type*)current_widget)->o);
- return NULL;
+Fl_Grid *Grid_Node::selected() {
+ if (current_widget && current_widget->is_a(Type::Grid))
+ return ((Fl_Grid*)((Grid_Node*)current_widget)->o);
+ return nullptr;
}
/**
@@ -682,10 +686,10 @@ Fl_Grid *Fl_Grid_Type::selected() {
/param[in] child
/param[in] x, y pixels from the top left of the window
*/
-void Fl_Grid_Type::insert_child_at(Fl_Widget *child, int x, int y) {
+void Grid_Node::insert_child_at(Fl_Widget *child, int x, int y) {
Fl_Grid_Proxy *grid = (Fl_Grid_Proxy*)o;
int row = -1, col = -1, ml, mt, grg, gcg;
- grid->margin(&ml, &mt, NULL, NULL);
+ grid->margin(&ml, &mt, nullptr, nullptr);
grid->gap(&grg, &gcg);
int x0 = grid->x() + Fl::box_dx(grid->box()) + ml;
int y0 = grid->y() + Fl::box_dy(grid->box()) + mt;
@@ -716,7 +720,7 @@ void Fl_Grid_Type::insert_child_at(Fl_Widget *child, int x, int y) {
/param[in] child
*/
-void Fl_Grid_Type::insert_child_at_next_free_cell(Fl_Widget *child) {
+void Grid_Node::insert_child_at_next_free_cell(Fl_Widget *child) {
Fl_Grid_Proxy *grid = (Fl_Grid_Proxy*)o;
if (grid->cell(child)) return;
// The code below would insert the new widget after the last selected one, but
@@ -748,7 +752,7 @@ void Fl_Grid_Type::insert_child_at_next_free_cell(Fl_Widget *child) {
\param[in] child pointer to the child type
\param[in] key code of the last keypress when handling a FL_KEYBOARD event.
*/
-void Fl_Grid_Type::keyboard_move_child(Fl_Widget_Type *child, int key) {
+void Grid_Node::keyboard_move_child(Widget_Node *child, int key) {
Fl_Grid_Proxy *grid = ((Fl_Grid_Proxy*)o);
Fl_Grid::Cell *cell = grid->any_cell(child->o);
if (!cell) return;
@@ -763,232 +767,9 @@ void Fl_Grid_Type::keyboard_move_child(Fl_Widget_Type *child, int key) {
}
}
-void Fl_Grid_Type::layout_widget() {
- allow_layout++;
+void Grid_Node::layout_widget() {
+ Fluid.proj.tree.allow_layout++;
((Fl_Grid*)o)->layout();
- allow_layout--;
-}
-
-
-// ---- Widget Panel Callbacks ---------------------------------------- MARK: -
-
-// TODO: better grid overlay?
-// TODO: grid_child_cb should move all selected cells, not just the current_selected.
-// TODO: buttons to add and delete rows and columns in the widget dialog
-// TODO: ways to resize rows and columns, add and delete them in the project window, pulldown menu?
-// TODO: alignment can be FL_GRID_LEFT|FL_GRID_VERTICAL?
-
-extern fld::widget::Formula_Input *widget_grid_row_input, *widget_grid_col_input,
-*widget_grid_rowspan_input, *widget_grid_colspan_input;
-extern Fl_Group *widget_tab_grid_child;
-
-void grid_child_cb(fld::widget::Formula_Input* i, void* v, int what) {
- if ( !current_widget
- || !current_widget->parent
- || !current_widget->parent->is_a(ID_Grid))
- {
- return;
- }
- Fl_Widget *child = ((Fl_Widget_Type*)current_widget)->o;
- Fl_Grid_Proxy *g = ((Fl_Grid_Proxy*)((Fl_Widget_Type*)current_widget->parent)->o);
- Fl_Grid::Cell *cell = g->any_cell(child);
- if (v == LOAD) {
- int v = -1;
- if (cell) {
- switch (what & 0x00ff) {
- case 8: v = cell->row(); break;
- case 9: v = cell->col(); break;
- case 10: v = cell->rowspan(); break;
- case 11: v = cell->colspan(); break;
- case 12: cell->minimum_size(&v, NULL); break;
- case 13: cell->minimum_size(NULL, &v); break;
- }
- }
- i->value(v);
- } else {
- undo_checkpoint();
- int v2 = -2, old_v = -2, v = i->value();
- if (i==widget_grid_row_input) v2 = widget_grid_col_input->value();
- if (i==widget_grid_col_input) v2 = widget_grid_row_input->value();
- Fl_Grid::Cell *new_cell = NULL;
- if (cell) {
- switch (what & 0x00ff) {
- case 8: old_v = cell->row(); v2 = cell->col(); break;
- case 9: old_v = cell->col(); v2 = cell->row(); break;
- case 10: old_v = cell->rowspan(); break;
- case 11: old_v = cell->colspan(); break;
- case 12: cell->minimum_size(&old_v, &v2); break;
- case 13: cell->minimum_size(&v2, &old_v); break;
- }
- }
- switch (what & 0xff00) {
- case 0x0100: v--; break;
- case 0x0200: v++; break;
- }
- if (old_v != v) {
- switch (what & 0x00ff) {
- case 8:
- if (v2 == -1 && v >= 0) v2 = 0;
- g->move_cell(current_widget->o, v, v2, 2); i->value(v);
- break;
- case 9:
- if (v2 == -1 && v >= 0) v2 = 0;
- g->move_cell(current_widget->o, v2, v, 2); i->value(v);
- break;
- case 10: if (cell && cell->row()+v<=g->rows() && v>0) cell->rowspan(v);
- break;
- case 11: if (cell && cell->col()+v<=g->cols() && v>0) cell->colspan(v);
- break;
- case 12: if (cell && v>=0) cell->minimum_size(v, v2);
- break;
- case 13: if (cell && v>=0) cell->minimum_size(v2, v);
- break;
- }
- if (!cell && new_cell)
- new_cell->minimum_size(20, 20);
- g->need_layout(true);
- set_modflag(1);
- }
- }
-}
-void grid_set_row_cb(fld::widget::Formula_Input* i, void* v) {
- grid_child_cb(i, v, 8);
- if (v!=LOAD) widget_tab_grid_child->do_callback(widget_tab_grid_child, LOAD);
-}
-void grid_dec_row_cb(Fl_Button* i, void* v) {
- if (v!=LOAD) {
- grid_child_cb(widget_grid_row_input, v, 0x0100 + 8);
- widget_tab_grid_child->do_callback(widget_tab_grid_child, LOAD);
- }
-}
-void grid_inc_row_cb(Fl_Button* i, void* v) {
- if (v!=LOAD) {
- grid_child_cb(widget_grid_row_input, v, 0x0200 + 8);
- widget_tab_grid_child->do_callback(widget_tab_grid_child, LOAD);
- }
-}
-void grid_set_col_cb(fld::widget::Formula_Input* i, void* v) {
- grid_child_cb(i, v, 9);
- if (v!=LOAD) widget_tab_grid_child->do_callback(widget_tab_grid_child, LOAD);
-}
-void grid_dec_col_cb(Fl_Button* i, void* v) {
- if (v!=LOAD) {
- grid_child_cb(widget_grid_col_input, v, 0x0100 + 9);
- widget_tab_grid_child->do_callback(widget_tab_grid_child, LOAD);
- }
-}
-void grid_inc_col_cb(Fl_Button* i, void* v) {
- if (v!=LOAD) {
- grid_child_cb(widget_grid_col_input, v, 0x0200 + 9);
- widget_tab_grid_child->do_callback(widget_tab_grid_child, LOAD);
- }
-}
-void grid_set_rowspan_cb(fld::widget::Formula_Input* i, void* v) {
- grid_child_cb(i, v, 10);
- if (v!=LOAD) widget_tab_grid_child->do_callback(widget_tab_grid_child, LOAD);
-}
-void grid_dec_rowspan_cb(Fl_Button* i, void* v) {
- if (v!=LOAD) {
- grid_child_cb(widget_grid_rowspan_input, v, 0x0100 + 10);
- widget_tab_grid_child->do_callback(widget_tab_grid_child, LOAD);
- }
-}
-void grid_inc_rowspan_cb(Fl_Button* i, void* v) {
- if (v!=LOAD) {
- grid_child_cb(widget_grid_rowspan_input, v, 0x0200 + 10);
- widget_tab_grid_child->do_callback(widget_tab_grid_child, LOAD);
- }
-}
-void grid_set_colspan_cb(fld::widget::Formula_Input* i, void* v) {
- grid_child_cb(i, v, 11);
- if (v!=LOAD) widget_tab_grid_child->do_callback(widget_tab_grid_child, LOAD);
-}
-void grid_dec_colspan_cb(Fl_Button* i, void* v) {
- if (v!=LOAD) {
- grid_child_cb(widget_grid_colspan_input, v, 0x0100 + 11);
- widget_tab_grid_child->do_callback(widget_tab_grid_child, LOAD);
- }
-}
-void grid_inc_colspan_cb(Fl_Button* i, void* v) {
- if (v!=LOAD) {
- grid_child_cb(widget_grid_colspan_input, v, 0x0200 + 11);
- widget_tab_grid_child->do_callback(widget_tab_grid_child, LOAD);
- }
-}
-void grid_set_min_wdt_cb(fld::widget::Formula_Input* i, void* v) {
- grid_child_cb(i, v, 12);
-}
-void grid_set_min_hgt_cb(fld::widget::Formula_Input* i, void* v) {
- grid_child_cb(i, v, 13);
-}
-
-void grid_align_horizontal_cb(Fl_Choice* i, void* v) {
- if ( !current_widget
- || !current_widget->parent
- || !current_widget->parent->is_a(ID_Grid))
- {
- return;
- }
- int mask = (FL_GRID_LEFT | FL_GRID_RIGHT | FL_GRID_HORIZONTAL);
- Fl_Grid *g = ((Fl_Grid*)((Fl_Widget_Type*)current_widget->parent)->o);
- if (v == LOAD) {
- int a = FL_GRID_FILL & mask;
- Fl_Grid::Cell *cell = g->cell(current_widget->o);
- if (cell) {
- a = cell->align() & mask;
- }
- const Fl_Menu_Item *mi = i->find_item_with_argument(a);
- if (mi) i->value(mi);
- } else {
- undo_checkpoint();
- int v = FL_GRID_FILL & mask, old_v = FL_GRID_FILL & mask;
- const Fl_Menu_Item *mi = i->mvalue();
- if (mi) v = (int)mi->argument();
- Fl_Grid::Cell *cell = g->cell(current_widget->o);
- if (cell) {
- old_v = cell->align() & mask;
- if (old_v != v) {
- cell->align((Fl_Grid_Align)(v | (cell->align() & ~mask)));
- g->need_layout(true);
- g->redraw();
- set_modflag(1);
- }
- }
- }
-}
-
-void grid_align_vertical_cb(Fl_Choice* i, void* v) {
- if ( !current_widget
- || !current_widget->parent
- || !current_widget->parent->is_a(ID_Grid))
- {
- return;
- }
- int mask = (FL_GRID_TOP | FL_GRID_BOTTOM | FL_GRID_VERTICAL);
- Fl_Grid *g = ((Fl_Grid*)((Fl_Widget_Type*)current_widget->parent)->o);
- if (v == LOAD) {
- int a = FL_GRID_FILL & mask;
- Fl_Grid::Cell *cell = g->cell(current_widget->o);
- if (cell) {
- a = cell->align() & mask;
- }
- const Fl_Menu_Item *mi = i->find_item_with_argument(a);
- if (mi) i->value(mi);
- } else {
- undo_checkpoint();
- int v = FL_GRID_FILL & mask, old_v = FL_GRID_FILL & mask;
- const Fl_Menu_Item *mi = i->mvalue();
- if (mi) v = (int)mi->argument();
- Fl_Grid::Cell *cell = g->cell(current_widget->o);
- if (cell) {
- old_v = cell->align() & mask;
- if (old_v != v) {
- cell->align((Fl_Grid_Align)(v | (cell->align() & ~mask)));
- g->need_layout(true);
- g->redraw();
- set_modflag(1);
- }
- }
- }
+ Fluid.proj.tree.allow_layout--;
}
diff --git a/fluid/nodes/Grid_Node.h b/fluid/nodes/Grid_Node.h
new file mode 100644
index 000000000..4363164ee
--- /dev/null
+++ b/fluid/nodes/Grid_Node.h
@@ -0,0 +1,82 @@
+//
+// Grid Node header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 2023-2025 by Bill Spitzak and others.
+//
+// This library is free software. Distribution and use rights are outlined in
+// the file "COPYING" which should have been included with this file. If this
+// file is missing or damaged, see the license at:
+//
+// https://www.fltk.org/COPYING.php
+//
+// Please see the following page on how to report bugs and issues:
+//
+// https://www.fltk.org/bugs.php
+//
+
+#ifndef FLUID_NODES_GRID_NODE_H
+#define FLUID_NODES_GRID_NODE_H
+
+#include "nodes/Group_Node.h"
+#include <FL/Fl_Grid.H>
+
+// ---- Grid_Node --------------------------------------------------- MARK: -
+
+class Fl_Grid_Proxy : public Fl_Grid {
+protected:
+ typedef struct { Fl_Widget *widget; Cell *cell; } Cell_Widget_Pair;
+ Cell_Widget_Pair *transient_;
+ int num_transient_;
+ int cap_transient_;
+ void transient_make_room_(int n);
+ void transient_remove_(Fl_Widget *w);
+public:
+ Fl_Grid_Proxy(int X,int Y,int W,int H);
+ ~Fl_Grid_Proxy();
+ void resize(int,int,int,int) override;
+ void draw() override;
+ void draw_overlay();
+ void move_cell(Fl_Widget *child, int to_row, int to_col, int how = 0);
+ Cell* any_cell(Fl_Widget *widget) const;
+ Cell* transient_cell(Fl_Widget *widget) const;
+ Cell* transient_widget(Fl_Widget *wi, int row, int col, int row_span, int col_span, Fl_Grid_Align align = FL_GRID_FILL);
+ Cell* widget(Fl_Widget *wi, int row, int col, Fl_Grid_Align align = FL_GRID_FILL);
+ Cell* widget(Fl_Widget *wi, int row, int col, int rowspan, int colspan, Fl_Grid_Align align = FL_GRID_FILL);
+};
+
+class Grid_Node : public Group_Node
+{
+public:
+ typedef Group_Node super;
+ static Grid_Node prototype;
+public:
+ Grid_Node();
+ const char *type_name() override {return "Fl_Grid";}
+ const char *alt_type_name() override {return "fltk::GridGroup";}
+ Widget_Node *_make() override { return new Grid_Node(); }
+ Fl_Widget *widget(int X,int Y,int W,int H) override;
+ Type type() const override { return Type::Grid; }
+ bool is_a(Type inType) const override { return (inType==Type::Grid) ? true : super::is_a(inType); }
+ void write_properties(fld::io::Project_Writer &f) override;
+ void read_property(fld::io::Project_Reader &f, const char *) override;
+ void write_parent_properties(fld::io::Project_Writer &f, Node *child, bool encapsulate) override;
+ void read_parent_property(fld::io::Project_Reader &f, Node *child, const char *property) override;
+ Fl_Widget *enter_live_mode(int top=0) override;
+ void leave_live_mode() override;
+ void copy_properties() override;
+ void copy_properties_for_children() override;
+ void write_code1(fld::io::Code_Writer& f) override;
+ void write_code2(fld::io::Code_Writer& f) override;
+ void add_child(Node*, Node*) override;
+ void move_child(Node*, Node*) override;
+ void remove_child(Node*) override;
+ void layout_widget() override;
+ void child_resized(Widget_Node *child);
+ void insert_child_at(Fl_Widget *child, int x, int y);
+ void insert_child_at_next_free_cell(Fl_Widget *child);
+ void keyboard_move_child(Widget_Node*, int key);
+
+ static class Fl_Grid *selected();
+};
+
+#endif // FLUID_NODES_GRID_NODE_H
diff --git a/fluid/nodes/Fl_Group_Type.cxx b/fluid/nodes/Group_Node.cxx
index 5d3cba07c..d269b62ab 100644
--- a/fluid/nodes/Fl_Group_Type.cxx
+++ b/fluid/nodes/Group_Node.cxx
@@ -1,7 +1,7 @@
//
-// Fl_Group object code for the Fast Light Tool Kit (FLTK).
+// Group Node code for the Fast Light Tool Kit (FLTK).
//
-// Object describing an Fl_Group and links to Fl_Window_Type.C and
+// Object describing an Fl_Group and links to Window_Node.C and
// the Fl_Tabs widget, with special stuff to select tab items and
// insure that only one is visible.
//
@@ -18,11 +18,11 @@
// https://www.fltk.org/bugs.php
//
-#include "nodes/Fl_Group_Type.h"
+#include "nodes/Group_Node.h"
-#include "app/fluid.h"
-#include "app/undo.h"
-#include "app/Fd_Snap_Action.h"
+#include "Fluid.h"
+#include "proj/undo.h"
+#include "app/Snap_Action.h"
#include "io/Project_Reader.h"
#include "io/Project_Writer.h"
#include "io/Code_Writer.h"
@@ -40,16 +40,16 @@
#include <stdlib.h>
-// ---- Fl_Group_Type -------------------------------------------------- MARK: -
+// ---- Group_Node -------------------------------------------------- MARK: -
-Fl_Group_Type Fl_Group_type; // the "factory"
+Group_Node Group_Node::prototype;
/**
Override group's resize behavior to do nothing to children by default.
\param[in] X, Y, W, H new size
*/
void Fl_Group_Proxy::resize(int X, int Y, int W, int H) {
- if (Fl_Type::allow_layout > 0) {
+ if (Fluid.proj.tree.allow_layout > 0) {
Fl_Group::resize(X, Y, W, H);
} else {
Fl_Widget::resize(X, Y, W, H);
@@ -61,7 +61,7 @@ void Fl_Group_Proxy::resize(int X, int Y, int W, int H) {
Override draw() to make groups with no box or flat box background visible.
*/
void Fl_Group_Proxy::draw() {
- if (show_ghosted_outline && (box() == FL_NO_BOX)) {
+ if (Fluid.show_ghosted_outline && (box() == FL_NO_BOX)) {
fl_rect(x(), y(), w(), h(), Fl::box_color(fl_color_average(FL_FOREGROUND_COLOR, color(), .1f)));
}
Fl_Group::draw();
@@ -71,16 +71,16 @@ void Fl_Group_Proxy::draw() {
/**
\brief Enlarge the group size, so all children fit within.
*/
-void fix_group_size(Fl_Type *tt) {
- if (!tt || !tt->is_a(ID_Group)) return;
- Fl_Group_Type* t = (Fl_Group_Type*)tt;
+void fix_group_size(Node *tt) {
+ if (!tt || !tt->is_a(Type::Group)) return;
+ Group_Node* t = (Group_Node*)tt;
int X = t->o->x();
int Y = t->o->y();
int R = X+t->o->w();
int B = Y+t->o->h();
- for (Fl_Type *nn = t->next; nn && nn->level > t->level; nn = nn->next) {
+ for (Node *nn = t->next; nn && nn->level > t->level; nn = nn->next) {
if (nn->is_true_widget()) {
- Fl_Widget_Type* n = (Fl_Widget_Type*)nn;
+ Widget_Node* n = (Widget_Node*)nn;
int x = n->o->x(); if (x < X) X = x;
int y = n->o->y(); if (y < Y) Y = y;
int r = x+n->o->w();if (r > R) R = r;
@@ -93,84 +93,84 @@ void fix_group_size(Fl_Type *tt) {
extern void group_selected_menuitems();
void group_cb(Fl_Widget *, void *) {
- if (!Fl_Type::current) {
+ if (!Fluid.proj.tree.current) {
fl_message("No widgets selected.");
return;
}
- if (!Fl_Type::current->is_widget()) {
+ if (!Fluid.proj.tree.current->is_widget()) {
fl_message("Only widgets and menu items can be grouped.");
return;
}
- if (Fl_Type::current->is_a(ID_Menu_Item)) {
+ if (Fluid.proj.tree.current->is_a(Type::Menu_Item)) {
group_selected_menuitems();
return;
}
// The group will be created in the parent group of the current widget
- Fl_Type *qq = Fl_Type::current->parent;
- Fl_Widget_Type *q = static_cast<Fl_Widget_Type*>(Fl_Type::current);
- while (qq && !qq->is_a(ID_Group)) {
+ Node *qq = Fluid.proj.tree.current->parent;
+ Widget_Node *q = static_cast<Widget_Node*>(Fluid.proj.tree.current);
+ while (qq && !qq->is_a(Type::Group)) {
qq = qq->parent;
}
if (!qq) {
fl_message("Can't create a new group here.");
return;
}
- undo_checkpoint();
- undo_suspend();
- Fl_Type::current = qq;
- Fl_Group_Type *n = (Fl_Group_Type*)(Fl_Group_type.make(Strategy::AS_LAST_CHILD));
+ Fluid.proj.undo.checkpoint();
+ Fluid.proj.undo.suspend();
+ Fluid.proj.tree.current = qq;
+ Group_Node *n = (Group_Node*)(Group_Node::prototype.make(Strategy::AS_LAST_CHILD));
n->move_before(q);
n->o->resize(q->o->x(),q->o->y(),q->o->w(),q->o->h());
- for (Fl_Type *t = qq->next; t && (t->level > qq->level);) {
+ for (Node *t = qq->next; t && (t->level > qq->level);) {
if (t->level != n->level || t == n || !t->selected) {
t = t->next;
continue;
}
- Fl_Type *nxt = t->remove();
+ Node *nxt = t->remove();
t->add(n, Strategy::AS_LAST_CHILD);
t = nxt;
}
fix_group_size(n);
- Fl_Type::current = q;
+ Fluid.proj.tree.current = q;
n->layout_widget();
widget_browser->rebuild();
- undo_resume();
- set_modflag(1);
+ Fluid.proj.undo.resume();
+ Fluid.proj.set_modflag(1);
}
extern void ungroup_selected_menuitems();
void ungroup_cb(Fl_Widget *, void *) {
- if (!Fl_Type::current) {
+ if (!Fluid.proj.tree.current) {
fl_message("No widgets selected.");
return;
}
- if (!Fl_Type::current->is_widget()) {
+ if (!Fluid.proj.tree.current->is_widget()) {
fl_message("Only widgets and menu items can be ungrouped.");
return;
}
- if (Fl_Type::current->is_a(ID_Menu_Item)) {
+ if (Fluid.proj.tree.current->is_a(Type::Menu_Item)) {
ungroup_selected_menuitems();
return;
}
- Fl_Widget_Type *q = static_cast<Fl_Widget_Type*>(Fl_Type::current);
+ Widget_Node *q = static_cast<Widget_Node*>(Fluid.proj.tree.current);
int q_level = q->level;
- Fl_Type *qq = Fl_Type::current->parent;
+ Node *qq = Fluid.proj.tree.current->parent;
while (qq && !qq->is_true_widget()) qq = qq->parent;
- if (!qq || !qq->is_a(ID_Group)) {
+ if (!qq || !qq->is_a(Type::Group)) {
fl_message("Only menu widgets inside a group can be ungrouped.");
return;
}
- undo_checkpoint();
- undo_suspend();
- Fl_Type::current = qq;
- for (Fl_Type *t = qq->next; t && (t->level > qq->level);) {
+ Fluid.proj.undo.checkpoint();
+ Fluid.proj.undo.suspend();
+ Fluid.proj.tree.current = qq;
+ for (Node *t = qq->next; t && (t->level > qq->level);) {
if (t->level != q_level || !t->selected) {
t = t->next;
continue;
}
- Fl_Type *nxt = t->remove();
+ Node *nxt = t->remove();
t->insert(qq);
t = nxt;
}
@@ -178,29 +178,29 @@ void ungroup_cb(Fl_Widget *, void *) {
qq->remove();
delete qq; // qq has no children that need to be delete
}
- Fl_Type::current = q;
+ Fluid.proj.tree.current = q;
widget_browser->rebuild();
- undo_resume();
- set_modflag(1);
+ Fluid.proj.undo.resume();
+ Fluid.proj.set_modflag(1);
}
-void Fl_Group_Type::ideal_size(int &w, int &h) {
+void Group_Node::ideal_size(int &w, int &h) {
if (parent && parent->is_true_widget()) {
- Fl_Widget *p = ((Fl_Widget_Type*)parent)->o;
+ Fl_Widget *p = ((Widget_Node*)parent)->o;
w = p->w() / 2;
h = p->h() / 2;
} else {
w = 140;
h = 140;
}
- Fd_Snap_Action::better_size(w, h);
+ fld::app::Snap_Action::better_size(w, h);
}
-void Fl_Group_Type::write_code1(fld::io::Code_Writer& f) {
- Fl_Widget_Type::write_code1(f);
+void Group_Node::write_code1(fld::io::Code_Writer& f) {
+ Widget_Node::write_code1(f);
}
-void Fl_Group_Type::write_code2(fld::io::Code_Writer& f) {
+void Group_Node::write_code2(fld::io::Code_Writer& f) {
const char *var = name() ? name() : "o";
write_extra_code(f);
f.write_c("%s%s->end();\n", f.indent(), var);
@@ -212,79 +212,79 @@ void Fl_Group_Type::write_code2(fld::io::Code_Writer& f) {
// This is called when o is created. If it is in the tab group make
// sure it is visible:
-void Fl_Group_Type::add_child(Fl_Type* cc, Fl_Type* before) {
- Fl_Widget_Type* c = (Fl_Widget_Type*)cc;
- Fl_Widget* b = before ? ((Fl_Widget_Type*)before)->o : 0;
+void Group_Node::add_child(Node* cc, Node* before) {
+ Widget_Node* c = (Widget_Node*)cc;
+ Fl_Widget* b = before ? ((Widget_Node*)before)->o : nullptr;
((Fl_Group*)o)->insert(*(c->o), b);
o->redraw();
}
// This is called when o is deleted. If it is in the tab group make
// sure it is not visible:
-void Fl_Group_Type::remove_child(Fl_Type* cc) {
- Fl_Widget_Type* c = (Fl_Widget_Type*)cc;
+void Group_Node::remove_child(Node* cc) {
+ Widget_Node* c = (Widget_Node*)cc;
((Fl_Group*)o)->remove(c->o);
o->redraw();
}
// move, don't change selected value:
-void Fl_Group_Type::move_child(Fl_Type* cc, Fl_Type* before) {
- Fl_Widget_Type* c = (Fl_Widget_Type*)cc;
- Fl_Widget* b = before ? ((Fl_Widget_Type*)before)->o : 0;
+void Group_Node::move_child(Node* cc, Node* before) {
+ Widget_Node* c = (Widget_Node*)cc;
+ Fl_Widget* b = before ? ((Widget_Node*)before)->o : nullptr;
((Fl_Group*)o)->insert(*(c->o), b);
o->redraw();
}
// live mode support
-Fl_Widget* Fl_Group_Type::enter_live_mode(int) {
+Fl_Widget* Group_Node::enter_live_mode(int) {
Fl_Group *grp = new Fl_Group(o->x(), o->y(), o->w(), o->h());
return propagate_live_mode(grp);
}
-void Fl_Group_Type::leave_live_mode() {
+void Group_Node::leave_live_mode() {
}
/**
copy all properties from the edit widget to the live widget
*/
-void Fl_Group_Type::copy_properties() {
- Fl_Widget_Type::copy_properties();
+void Group_Node::copy_properties() {
+ Widget_Node::copy_properties();
}
-// ---- Fl_Pack_Type --------------------------------------------------- MARK: -
+// ---- Pack_Node --------------------------------------------------- MARK: -
-Fl_Pack_Type Fl_Pack_type; // the "factory"
+Pack_Node Pack_Node::prototype; // the "factory"
const char pack_type_name[] = "Fl_Pack";
Fl_Menu_Item pack_type_menu[] = {
- {"HORIZONTAL", 0, 0, (void*)Fl_Pack::HORIZONTAL},
- {"VERTICAL", 0, 0, (void*)Fl_Pack::VERTICAL},
- {0}
+ {"HORIZONTAL", 0, nullptr, (void*)Fl_Pack::HORIZONTAL},
+ {"VERTICAL", 0, nullptr, (void*)Fl_Pack::VERTICAL},
+ {nullptr}
};
-Fl_Widget *Fl_Pack_Type::enter_live_mode(int) {
+Fl_Widget *Pack_Node::enter_live_mode(int) {
Fl_Group *grp = new Fl_Pack(o->x(), o->y(), o->w(), o->h());
return propagate_live_mode(grp);
}
-void Fl_Pack_Type::copy_properties()
+void Pack_Node::copy_properties()
{
- Fl_Group_Type::copy_properties();
+ Group_Node::copy_properties();
Fl_Pack *d = (Fl_Pack*)live_widget, *s =(Fl_Pack*)o;
d->spacing(s->spacing());
}
-// ---- Fl_Flex_Type --------------------------------------------------- MARK: -
+// ---- Flex_Node --------------------------------------------------- MARK: -
const char flex_type_name[] = "Fl_Flex";
Fl_Menu_Item flex_type_menu[] = {
- {"HORIZONTAL", 0, 0, (void*)Fl_Flex::HORIZONTAL},
- {"VERTICAL", 0, 0, (void*)Fl_Flex::VERTICAL},
- {0}};
+ {"HORIZONTAL", 0, nullptr, (void*)Fl_Flex::HORIZONTAL},
+ {"VERTICAL", 0, nullptr, (void*)Fl_Flex::VERTICAL},
+ {nullptr}};
-Fl_Flex_Type Fl_Flex_type; // the "factory"
+Flex_Node Flex_Node::prototype; // the "factory"
/**
Override flex's resize behavior to do nothing to children by default.
@@ -292,7 +292,7 @@ Fl_Flex_Type Fl_Flex_type; // the "factory"
\param[in] X, Y, W, H new size
*/
void Fl_Flex_Proxy::resize(int X, int Y, int W, int H) {
- if (Fl_Type::allow_layout > 0) {
+ if (Fluid.proj.tree.allow_layout > 0) {
Fl_Flex::resize(X, Y, W, H);
} else {
Fl_Widget::resize(X, Y, W, H);
@@ -304,13 +304,13 @@ void Fl_Flex_Proxy::resize(int X, int Y, int W, int H) {
Override draw() to make groups with no box or flat box background visible.
*/
void Fl_Flex_Proxy::draw() {
- if (show_ghosted_outline && (box() == FL_NO_BOX)) {
+ if (Fluid.show_ghosted_outline && (box() == FL_NO_BOX)) {
fl_rect(x(), y(), w(), h(), Fl::box_color(fl_color_average(FL_FOREGROUND_COLOR, color(), .1f)));
}
Fl_Flex::draw();
}
-Fl_Widget *Fl_Flex_Type::enter_live_mode(int) {
+Fl_Widget *Flex_Node::enter_live_mode(int) {
Fl_Flex *grp = new Fl_Flex(o->x(), o->y(), o->w(), o->h());
propagate_live_mode(grp);
Fl_Flex *d = grp, *s =(Fl_Flex*)o;
@@ -325,9 +325,9 @@ Fl_Widget *Fl_Flex_Type::enter_live_mode(int) {
return grp;
}
-void Fl_Flex_Type::copy_properties()
+void Flex_Node::copy_properties()
{
- Fl_Group_Type::copy_properties();
+ Group_Node::copy_properties();
Fl_Flex *d = (Fl_Flex*)live_widget, *s =(Fl_Flex*)o;
int lm, tm, rm, bm;
s->margin(&lm, &tm, &rm, &bm);
@@ -335,7 +335,7 @@ void Fl_Flex_Type::copy_properties()
d->gap( s->gap() );
}
-void Fl_Flex_Type::copy_properties_for_children() {
+void Flex_Node::copy_properties_for_children() {
Fl_Flex *d = (Fl_Flex*)live_widget, *s =(Fl_Flex*)o;
for (int i=0; i<s->children(); i++) {
if (s->fixed(s->child(i)) && i<d->children()) {
@@ -349,9 +349,9 @@ void Fl_Flex_Type::copy_properties_for_children() {
d->layout();
}
-void Fl_Flex_Type::write_properties(fld::io::Project_Writer &f)
+void Flex_Node::write_properties(fld::io::Project_Writer &f)
{
- Fl_Group_Type::write_properties(f);
+ Group_Node::write_properties(f);
Fl_Flex* flex = (Fl_Flex*)o;
int lm, tm, rm, bm;
flex->margin(&lm, &tm, &rm, &bm);
@@ -374,7 +374,7 @@ void Fl_Flex_Type::write_properties(fld::io::Project_Writer &f)
}
}
-void Fl_Flex_Type::read_property(fld::io::Project_Reader &f, const char *c)
+void Flex_Node::read_property(fld::io::Project_Reader &f, const char *c)
{
Fl_Flex* flex = (Fl_Flex*)o;
suspend_auto_layout = 1;
@@ -399,11 +399,11 @@ void Fl_Flex_Type::read_property(fld::io::Project_Reader &f, const char *c)
}
f.read_word(1); // must be '}'
} else {
- Fl_Group_Type::read_property(f, c);
+ Group_Node::read_property(f, c);
}
}
-void Fl_Flex_Type::postprocess_read()
+void Flex_Node::postprocess_read()
{
Fl_Flex* flex = (Fl_Flex*)o;
if (fixedSizeTupleSize>0) {
@@ -417,12 +417,12 @@ void Fl_Flex_Type::postprocess_read()
}
fixedSizeTupleSize = 0;
delete[] fixedSizeTuple;
- fixedSizeTuple = NULL;
+ fixedSizeTuple = nullptr;
}
suspend_auto_layout = 0;
}
-void Fl_Flex_Type::write_code2(fld::io::Code_Writer& f) {
+void Flex_Node::write_code2(fld::io::Code_Writer& f) {
const char *var = name() ? name() : "o";
Fl_Flex* flex = (Fl_Flex*)o;
int lm, tm, rm, bm;
@@ -437,40 +437,40 @@ void Fl_Flex_Type::write_code2(fld::io::Code_Writer& f) {
f.write_c("%s%s->fixed(%s->child(%d), %d);\n", f.indent(), var, var, i,
flex->horizontal() ? ci->w() : ci->h());
}
- Fl_Group_Type::write_code2(f);
+ Group_Node::write_code2(f);
}
-//void Fl_Flex_Type::add_child(Fl_Type* a, Fl_Type* b) {
-// Fl_Group_Type::add_child(a, b);
+//void Flex_Node::add_child(Node* a, Node* b) {
+// Group_Node::add_child(a, b);
// if (!suspend_auto_layout)
// ((Fl_Flex*)o)->layout();
//}
//
-//void Fl_Flex_Type::move_child(Fl_Type* a, Fl_Type* b) {
-// Fl_Group_Type::move_child(a, b);
+//void Flex_Node::move_child(Node* a, Node* b) {
+// Group_Node::move_child(a, b);
// if (!suspend_auto_layout)
// ((Fl_Flex*)o)->layout();
//}
-void Fl_Flex_Type::remove_child(Fl_Type* a) {
+void Flex_Node::remove_child(Node* a) {
if (a->is_widget())
- ((Fl_Flex*)o)->fixed(((Fl_Widget_Type*)a)->o, 0);
- Fl_Group_Type::remove_child(a);
+ ((Fl_Flex*)o)->fixed(((Widget_Node*)a)->o, 0);
+ Group_Node::remove_child(a);
// ((Fl_Flex*)o)->layout();
layout_widget();
}
-void Fl_Flex_Type::layout_widget() {
- allow_layout++;
+void Flex_Node::layout_widget() {
+ Fluid.proj.tree.allow_layout++;
((Fl_Flex*)o)->layout();
- allow_layout--;
+ Fluid.proj.tree.allow_layout--;
}
// Change from HORIZONTAL to VERTICAL or back.
// Children in a horizontal Flex have already the full vertical height. If we
// just change to vertical, the accumulated hight of all children is too big.
// We need to relayout existing children.
-void Fl_Flex_Type::change_subtype_to(int n) {
+void Flex_Node::change_subtype_to(int n) {
Fl_Flex* f = (Fl_Flex*)o;
if (f->type()==n) return;
@@ -504,10 +504,10 @@ void Fl_Flex_Type::change_subtype_to(int n) {
f->layout();
}
-int Fl_Flex_Type::parent_is_flex(Fl_Type *t) {
+int Flex_Node::parent_is_flex(Node *t) {
return (t->is_widget()
&& t->parent
- && t->parent->is_a(ID_Flex));
+ && t->parent->is_a(Type::Flex));
}
/**
@@ -517,7 +517,7 @@ int Fl_Flex_Type::parent_is_flex(Fl_Type *t) {
this and will be relocated if so
\param[in] x, y pixel coordinates relative to the top left of the window
*/
-void Fl_Flex_Type::insert_child_at(Fl_Widget *child, int x, int y) {
+void Flex_Node::insert_child_at(Fl_Widget *child, int x, int y) {
Fl_Flex *flex = (Fl_Flex*)o;
// find the insertion point closest to x, y
int d = flex->w() + flex->h(), di = -1;
@@ -551,7 +551,7 @@ void Fl_Flex_Type::insert_child_at(Fl_Widget *child, int x, int y) {
\param[in] child pointer to the child type
\param[in] key code of the last keypress when handling a FL_KEYBOARD event.
*/
-void Fl_Flex_Type::keyboard_move_child(Fl_Widget_Type *child, int key) {
+void Flex_Node::keyboard_move_child(Widget_Node *child, int key) {
Fl_Flex *flex = ((Fl_Flex*)o);
int ix = flex->find(child->o);
if (ix == flex->children()) return;
@@ -570,36 +570,36 @@ void Fl_Flex_Type::keyboard_move_child(Fl_Widget_Type *child, int key) {
}
}
-int Fl_Flex_Type::size(Fl_Type *t, char fixed_only) {
+int Flex_Node::size(Node *t, char fixed_only) {
if (!t->is_widget()) return 0;
if (!t->parent) return 0;
- if (!t->parent->is_a(ID_Flex)) return 0;
- Fl_Flex_Type* ft = (Fl_Flex_Type*)t->parent;
+ if (!t->parent->is_a(Type::Flex)) return 0;
+ Flex_Node* ft = (Flex_Node*)t->parent;
Fl_Flex* f = (Fl_Flex*)ft->o;
- Fl_Widget *w = ((Fl_Widget_Type*)t)->o;
+ Fl_Widget *w = ((Widget_Node*)t)->o;
if (fixed_only && !f->fixed(w)) return 0;
return f->horizontal() ? w->w() : w->h();
}
-int Fl_Flex_Type::is_fixed(Fl_Type *t) {
+int Flex_Node::is_fixed(Node *t) {
if (!t->is_widget()) return 0;
if (!t->parent) return 0;
- if (!t->parent->is_a(ID_Flex)) return 0;
- Fl_Flex_Type* ft = (Fl_Flex_Type*)t->parent;
+ if (!t->parent->is_a(Type::Flex)) return 0;
+ Flex_Node* ft = (Flex_Node*)t->parent;
Fl_Flex* f = (Fl_Flex*)ft->o;
- Fl_Widget *w = ((Fl_Widget_Type*)t)->o;
+ Fl_Widget *w = ((Widget_Node*)t)->o;
return f->fixed(w);
}
-// ---- Fl_Table_Type -------------------------------------------------- MARK: -
+// ---- Table_Node -------------------------------------------------- MARK: -
-Fl_Table_Type Fl_Table_type; // the "factory"
+Table_Node Table_Node::prototype; // the "factory"
static const int MAX_ROWS = 14;
static const int MAX_COLS = 7;
// this is a minimal table widget used as an example when adding tables in Fluid
-class Fluid_Table : public Fl_Table {
+class Fl_Table_Proxy : public Fl_Table {
int data[MAX_ROWS][MAX_COLS]; // data array for cells
// Draw the row/col headings
@@ -629,7 +629,7 @@ class Fluid_Table : public Fl_Table {
// Fl_Table calls this function to draw each visible cell in the table.
// It's up to us to use FLTK's drawing functions to draw the cells the way we want.
//
- void draw_cell(TableContext context, int ROW=0, int COL=0, int X=0, int Y=0, int W=0, int H=0) FL_OVERRIDE {
+ void draw_cell(TableContext context, int ROW=0, int COL=0, int X=0, int Y=0, int W=0, int H=0) override {
static char s[40];
switch ( context ) {
case CONTEXT_STARTPAGE: // before page is drawn..
@@ -652,7 +652,7 @@ class Fluid_Table : public Fl_Table {
}
}
public:
- Fluid_Table(int x, int y, int w, int h, const char *l=0L)
+ Fl_Table_Proxy(int x, int y, int w, int h, const char *l=nullptr)
: Fl_Table(x, y, w, h, l) {
end();
for ( int r=0; r<MAX_ROWS; r++ )
@@ -671,14 +671,14 @@ public:
}
};
-Fl_Widget *Fl_Table_Type::widget(int X,int Y,int W,int H) {
- Fluid_Table *table = new Fluid_Table(X, Y, W, H);
+Fl_Widget *Table_Node::widget(int X,int Y,int W,int H) {
+ Fl_Table_Proxy *table = new Fl_Table_Proxy(X, Y, W, H);
return table;
}
-void Fl_Table_Type::add_child(Fl_Type* cc, Fl_Type* before) {
- Fl_Widget_Type* c = (Fl_Widget_Type*)cc;
- Fl_Widget* b = before ? ((Fl_Widget_Type*)before)->o : 0;
+void Table_Node::add_child(Node* cc, Node* before) {
+ Widget_Node* c = (Widget_Node*)cc;
+ Fl_Widget* b = before ? ((Widget_Node*)before)->o : nullptr;
if (((Fl_Table*)o)->children()==1) { // the FLuid_Table has one extra child
fl_message("Inserting child widgets into an Fl_Table is not recommended.\n"
"Please refer to the documentation on Fl_Table.");
@@ -687,42 +687,42 @@ void Fl_Table_Type::add_child(Fl_Type* cc, Fl_Type* before) {
o->redraw();
}
-void Fl_Table_Type::remove_child(Fl_Type* cc) {
- Fl_Widget_Type* c = (Fl_Widget_Type*)cc;
+void Table_Node::remove_child(Node* cc) {
+ Widget_Node* c = (Widget_Node*)cc;
((Fl_Table*)o)->remove(*(c->o));
o->redraw();
}
-void Fl_Table_Type::move_child(Fl_Type* cc, Fl_Type* before) {
- Fl_Widget_Type* c = (Fl_Widget_Type*)cc;
- Fl_Widget* b = before ? ((Fl_Widget_Type*)before)->o : 0;
+void Table_Node::move_child(Node* cc, Node* before) {
+ Widget_Node* c = (Widget_Node*)cc;
+ Fl_Widget* b = before ? ((Widget_Node*)before)->o : nullptr;
((Fl_Table*)o)->insert(*(c->o), b);
o->redraw();
}
-Fl_Widget *Fl_Table_Type::enter_live_mode(int) {
- Fl_Group *grp = new Fluid_Table(o->x(), o->y(), o->w(), o->h());
+Fl_Widget *Table_Node::enter_live_mode(int) {
+ Fl_Group *grp = new Fl_Table_Proxy(o->x(), o->y(), o->w(), o->h());
live_widget = grp;
copy_properties();
grp->end();
return live_widget;
}
-void Fl_Table_Type::ideal_size(int &w, int &h) {
+void Table_Node::ideal_size(int &w, int &h) {
w = 160;
h = 120;
- Fd_Snap_Action::better_size(w, h);
+ fld::app::Snap_Action::better_size(w, h);
}
-// ---- Fl_Tabs_Type --------------------------------------------------- MARK: -
+// ---- Tabs_Node --------------------------------------------------- MARK: -
-Fl_Tabs_Type Fl_Tabs_type; // the "factory"
+Tabs_Node Tabs_Node::prototype;
const char tabs_type_name[] = "Fl_Tabs";
// Override group's resize behavior to do nothing to children:
void Fl_Tabs_Proxy::resize(int X, int Y, int W, int H) {
- if (Fl_Type::allow_layout > 0) {
+ if (Fluid.proj.tree.allow_layout > 0) {
Fl_Tabs::resize(X, Y, W, H);
} else {
Fl_Widget::resize(X, Y, W, H);
@@ -734,7 +734,7 @@ void Fl_Tabs_Proxy::resize(int X, int Y, int W, int H) {
Override draw() to make groups with no box or flat box background visible.
*/
void Fl_Tabs_Proxy::draw() {
- if (show_ghosted_outline && (box() == FL_NO_BOX)) {
+ if (Fluid.show_ghosted_outline && (box() == FL_NO_BOX)) {
fl_rect(x(), y(), w(), h(), Fl::box_color(fl_color_average(FL_FOREGROUND_COLOR, color(), .1f)));
}
Fl_Tabs::draw();
@@ -744,10 +744,10 @@ void Fl_Tabs_Proxy::draw() {
// if it is a tab title, and adjust visibility and return new selection:
// If none, return o unchanged:
-Fl_Type* Fl_Tabs_Type::click_test(int x, int y) {
+Node* Tabs_Node::click_test(int x, int y) {
Fl_Tabs *t = (Fl_Tabs*)o;
Fl_Widget *a = t->which(x,y);
- if (!a) return 0; // didn't click on tab
+ if (!a) return nullptr; // didn't click on tab
// changing the visible tab has an impact on the generated
// source code, so mark this project as changed.
int changed = (a!=t->value());
@@ -755,22 +755,22 @@ Fl_Type* Fl_Tabs_Type::click_test(int x, int y) {
t->handle(FL_PUSH);
Fl::pushed(t);
while (Fl::pushed()==t) Fl::wait();
- if (changed) set_modflag(1);
- return (Fl_Type*)(t->value()->user_data());
+ if (changed) Fluid.proj.set_modflag(1);
+ return (Node*)(t->value()->user_data());
}
-void Fl_Tabs_Type::add_child(Fl_Type* c, Fl_Type* before) {
- Fl_Group_Type::add_child(c, before);
+void Tabs_Node::add_child(Node* c, Node* before) {
+ Group_Node::add_child(c, before);
}
-void Fl_Tabs_Type::remove_child(Fl_Type* cc) {
- Fl_Widget_Type* c = (Fl_Widget_Type*)cc;
+void Tabs_Node::remove_child(Node* cc) {
+ Widget_Node* c = (Widget_Node*)cc;
Fl_Tabs *t = (Fl_Tabs*)o;
- if (t->value() == c->o) t->value(0);
- Fl_Group_Type::remove_child(c);
+ if (t->value() == c->o) t->value(nullptr);
+ Group_Node::remove_child(c);
}
-Fl_Widget *Fl_Tabs_Type::enter_live_mode(int) {
+Fl_Widget *Tabs_Node::enter_live_mode(int) {
Fl_Tabs *original = static_cast<Fl_Tabs*>(o);
Fl_Tabs *clone = new Fl_Tabs(o->x(), o->y(), o->w(), o->h());
propagate_live_mode(clone);
@@ -780,29 +780,29 @@ Fl_Widget *Fl_Tabs_Type::enter_live_mode(int) {
return clone;
}
-// ---- Fl_Scroll_Type ------------------------------------------------- MARK: -
+// ---- Scroll_Node ------------------------------------------------- MARK: -
-Fl_Scroll_Type Fl_Scroll_type; // the "factory"
+Scroll_Node Scroll_Node::prototype; // the "factory"
const char scroll_type_name[] = "Fl_Scroll";
Fl_Menu_Item scroll_type_menu[] = {
- {"BOTH", 0, 0, 0/*(void*)Fl_Scroll::BOTH*/},
- {"HORIZONTAL", 0, 0, (void*)Fl_Scroll::HORIZONTAL},
- {"VERTICAL", 0, 0, (void*)Fl_Scroll::VERTICAL},
- {"HORIZONTAL_ALWAYS", 0, 0, (void*)Fl_Scroll::HORIZONTAL_ALWAYS},
- {"VERTICAL_ALWAYS", 0, 0, (void*)Fl_Scroll::VERTICAL_ALWAYS},
- {"BOTH_ALWAYS", 0, 0, (void*)Fl_Scroll::BOTH_ALWAYS},
- {0}};
-
-Fl_Widget *Fl_Scroll_Type::enter_live_mode(int) {
+ {"BOTH", 0, nullptr, nullptr/*(void*)Fl_Scroll::BOTH*/},
+ {"HORIZONTAL", 0, nullptr, (void*)Fl_Scroll::HORIZONTAL},
+ {"VERTICAL", 0, nullptr, (void*)Fl_Scroll::VERTICAL},
+ {"HORIZONTAL_ALWAYS", 0, nullptr, (void*)Fl_Scroll::HORIZONTAL_ALWAYS},
+ {"VERTICAL_ALWAYS", 0, nullptr, (void*)Fl_Scroll::VERTICAL_ALWAYS},
+ {"BOTH_ALWAYS", 0, nullptr, (void*)Fl_Scroll::BOTH_ALWAYS},
+ {nullptr}};
+
+Fl_Widget *Scroll_Node::enter_live_mode(int) {
Fl_Group *grp = new Fl_Scroll(o->x(), o->y(), o->w(), o->h());
grp->show();
return propagate_live_mode(grp);
}
-void Fl_Scroll_Type::copy_properties() {
- Fl_Group_Type::copy_properties();
+void Scroll_Node::copy_properties() {
+ Group_Node::copy_properties();
Fl_Scroll *s = (Fl_Scroll*)o, *d = (Fl_Scroll*)live_widget;
d->scroll_to(s->xposition(), s->yposition());
d->type(s->type());
@@ -810,26 +810,26 @@ void Fl_Scroll_Type::copy_properties() {
d->hscrollbar.align(s->hscrollbar.align());
}
-// ---- Fl_Tile_Type --------------------------------------------------- MARK: -
+// ---- Tile_Node --------------------------------------------------- MARK: -
-Fl_Tile_Type Fl_Tile_type; // the "factory"
+Tile_Node Tile_Node::prototype; // the "factory"
const char tile_type_name[] = "Fl_Tile";
-void Fl_Tile_Type::copy_properties() {
- Fl_Group_Type::copy_properties();
+void Tile_Node::copy_properties() {
+ Group_Node::copy_properties();
// no additional properties
}
-// ---- Fl_Wizard_Type ------------------------------------------------ MARK: -
+// ---- Wizard_Node ------------------------------------------------ MARK: -
-Fl_Wizard_Type Fl_Wizard_type; // the "factory"
+Wizard_Node Wizard_Node::prototype; // the "factory"
const char wizard_type_name[] = "Fl_Wizard";
// Override group's resize behavior to do nothing to children:
void Fl_Wizard_Proxy::resize(int X, int Y, int W, int H) {
- if (Fl_Type::allow_layout > 0) {
+ if (Fluid.proj.tree.allow_layout > 0) {
Fl_Wizard::resize(X, Y, W, H);
} else {
Fl_Widget::resize(X, Y, W, H);
@@ -841,7 +841,7 @@ void Fl_Wizard_Proxy::resize(int X, int Y, int W, int H) {
Override draw() to make groups with no box or flat box background visible.
*/
void Fl_Wizard_Proxy::draw() {
- if (show_ghosted_outline && (box() == FL_NO_BOX)) {
+ if (Fluid.show_ghosted_outline && (box() == FL_NO_BOX)) {
fl_rect(x(), y(), w(), h(), Fl::box_color(fl_color_average(FL_FOREGROUND_COLOR, color(), .1f)));
}
Fl_Wizard::draw();
diff --git a/fluid/nodes/Group_Node.h b/fluid/nodes/Group_Node.h
new file mode 100644
index 000000000..6b6fe9fcd
--- /dev/null
+++ b/fluid/nodes/Group_Node.h
@@ -0,0 +1,261 @@
+//
+// Group Node header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2023 by Bill Spitzak and others.
+//
+// This library is free software. Distribution and use rights are outlined in
+// the file "COPYING" which should have been included with this file. If this
+// file is missing or damaged, see the license at:
+//
+// https://www.fltk.org/COPYING.php
+//
+// Please see the following page on how to report bugs and issues:
+//
+// https://www.fltk.org/bugs.php
+//
+
+#ifndef FLUID_NODES_GROUP_NODE_H
+#define FLUID_NODES_GROUP_NODE_H
+
+#include "nodes/Widget_Node.h"
+
+#include <FL/Fl_Tabs.H>
+#include <FL/Fl_Pack.H>
+#include <FL/Fl_Flex.H>
+#include <FL/Fl_Wizard.H>
+
+void group_cb(Fl_Widget *, void *);
+void ungroup_cb(Fl_Widget *, void *);
+
+// ---- Group_Node -------------------------------------------------- MARK: -
+
+/**
+ Proxy group to use in place of Fl_Group in the interactive window.
+
+ In an interactive environment, groups should not automatically resize their
+ children. This proxy disables the layout of children by default. Children
+ layout propagation may be enable temporarily by incrementing `allow_layout`
+ before resizing and decrementing it again afterwards.
+ */
+class Fl_Group_Proxy : public Fl_Group {
+public:
+ Fl_Group_Proxy(int X,int Y,int W,int H) : Fl_Group(X, Y, W, H) { Fl_Group::current(nullptr); }
+ void resize(int x, int y, int w, int h) override;
+ void draw() override;
+};
+
+class Group_Node : public Widget_Node
+{
+public:
+ typedef Widget_Node super;
+ static Group_Node prototype;
+public:
+ void ideal_size(int &w, int &h) override;
+ const char *type_name() override {return "Fl_Group";}
+ const char *alt_type_name() override {return "fltk::Group";}
+ Fl_Widget *widget(int X,int Y,int W,int H) override {
+ Fl_Group_Proxy *g = new Fl_Group_Proxy(X,Y,W,H); Fl_Group::current(nullptr); return g;}
+ Widget_Node *_make() override {return new Group_Node();}
+ void write_code1(fld::io::Code_Writer& f) override;
+ void write_code2(fld::io::Code_Writer& f) override;
+ void add_child(Node*, Node*) override;
+ void move_child(Node*, Node*) override;
+ void remove_child(Node*) override;
+ int can_have_children() const override {return 1;}
+ Type type() const override { return Type::Group; }
+ bool is_a(Type inType) const override { return (inType==Type::Group) ? true : super::is_a(inType); }
+ Fl_Widget *enter_live_mode(int top=0) override;
+ void leave_live_mode() override;
+ void copy_properties() override;
+};
+
+// ---- Pack_Node --------------------------------------------------- MARK: -
+
+extern const char pack_type_name[];
+extern Fl_Menu_Item pack_type_menu[];
+
+class Pack_Node : public Group_Node
+{
+public:
+ typedef Group_Node super;
+ static Pack_Node prototype;
+private:
+ Fl_Menu_Item *subtypes() override {return pack_type_menu;}
+public:
+ const char *type_name() override {return pack_type_name;}
+ const char *alt_type_name() override {return "fltk::PackedGroup";}
+ Widget_Node *_make() override {return new Pack_Node();}
+ Type type() const override { return Type::Pack; }
+ bool is_a(Type inType) const override { return (inType==Type::Pack) ? true : super::is_a(inType); }
+ Fl_Widget *enter_live_mode(int top=0) override;
+ void copy_properties() override;
+};
+
+// ---- Flex_Node --------------------------------------------------- MARK: -
+
+extern const char flex_type_name[];
+extern Fl_Menu_Item flex_type_menu[];
+
+class Fl_Flex_Proxy : public Fl_Flex {
+public:
+ Fl_Flex_Proxy(int X,int Y,int W,int H) : Fl_Flex(X, Y, W, H) { Fl_Group::current(nullptr); }
+ void resize(int x, int y, int w, int h) override;
+ void draw() override;
+};
+
+class Flex_Node : public Group_Node
+{
+public:
+ typedef Group_Node super;
+ static Flex_Node prototype;
+private:
+ Fl_Menu_Item *subtypes() override {return flex_type_menu;}
+ int fixedSizeTupleSize; /* number of pairs in array */
+ int *fixedSizeTuple; /* [ index, size, index2, size2, ... ] */
+ int suspend_auto_layout;
+public:
+ Flex_Node() : fixedSizeTupleSize(0), fixedSizeTuple(nullptr), suspend_auto_layout(0) { }
+ const char *type_name() override {return flex_type_name;}
+ const char *alt_type_name() override {return "fltk::FlexGroup";}
+ Widget_Node *_make() override { return new Flex_Node(); }
+ Fl_Widget *widget(int X,int Y,int W,int H) override {
+ Fl_Flex *g = new Fl_Flex_Proxy(X,Y,W,H); Fl_Group::current(nullptr); return g;}
+ Type type() const override { return Type::Flex; }
+ bool is_a(Type inType) const override { return (inType==Type::Flex) ? true : super::is_a(inType); }
+ void write_properties(fld::io::Project_Writer &f) override;
+ void read_property(fld::io::Project_Reader &f, const char *) override;
+ Fl_Widget *enter_live_mode(int top=0) override;
+ void copy_properties() override;
+ void copy_properties_for_children() override;
+ void postprocess_read() override;
+ void write_code2(fld::io::Code_Writer& f) override;
+// void add_child(Node*, Node*) override;
+// void move_child(Node*, Node*) override;
+ void remove_child(Node*) override;
+ void layout_widget() override;
+ void change_subtype_to(int n);
+ void insert_child_at(Fl_Widget *child, int x, int y);
+ void keyboard_move_child(Widget_Node*, int key);
+ static int parent_is_flex(Node*);
+ static int size(Node*, char fixed_only=0);
+ static int is_fixed(Node*);
+};
+
+// ---- Table_Node -------------------------------------------------- MARK: -
+
+class Table_Node : public Group_Node
+{
+public:
+ typedef Group_Node super;
+ static Table_Node prototype;
+public:
+ void ideal_size(int &w, int &h) override;
+ const char *type_name() override { return "Fl_Table"; }
+ const char *alt_type_name() override { return "fltk::TableGroup"; }
+ Widget_Node *_make() override { return new Table_Node(); }
+ Fl_Widget *widget(int X, int Y, int W, int H) override;
+ Type type() const override { return Type::Table; }
+ bool is_a(Type inType) const override { return (inType==Type::Table) ? true : super::is_a(inType); }
+ Fl_Widget *enter_live_mode(int top=0) override;
+ void add_child(Node*, Node*) override;
+ void move_child(Node*, Node*) override;
+ void remove_child(Node*) override;
+};
+
+// ---- Tabs_Node --------------------------------------------------- MARK: -
+
+extern const char tabs_type_name[];
+
+class Fl_Tabs_Proxy : public Fl_Tabs {
+public:
+ Fl_Tabs_Proxy(int X,int Y,int W,int H) : Fl_Tabs(X,Y,W,H) {}
+ void resize(int,int,int,int) override;
+ void draw() override;
+};
+
+class Tabs_Node : public Group_Node
+{
+public:
+ typedef Group_Node super;
+ static Tabs_Node prototype;
+public:
+ const char *type_name() override {return tabs_type_name;}
+ const char *alt_type_name() override {return "fltk::TabGroup";}
+ Fl_Widget *widget(int X,int Y,int W,int H) override {
+ Fl_Tabs_Proxy *g = new Fl_Tabs_Proxy(X,Y,W,H); Fl_Group::current(nullptr); return g;}
+ Widget_Node *_make() override {return new Tabs_Node();}
+ Node* click_test(int,int) override;
+ void add_child(Node*, Node*) override;
+ void remove_child(Node*) override;
+ Type type() const override { return Type::Tabs; }
+ bool is_a(Type inType) const override { return (inType==Type::Tabs) ? true : super::is_a(inType); }
+ Fl_Widget *enter_live_mode(int top=0) override;
+};
+
+// ---- Scroll_Node ------------------------------------------------- MARK: -
+
+extern const char scroll_type_name[];
+extern Fl_Menu_Item scroll_type_menu[];
+
+class Scroll_Node : public Group_Node
+{
+public:
+ typedef Group_Node super;
+ static Scroll_Node prototype;
+private:
+ Fl_Menu_Item *subtypes() override {return scroll_type_menu;}
+public:
+ const char *type_name() override {return scroll_type_name;}
+ const char *alt_type_name() override {return "fltk::ScrollGroup";}
+ Widget_Node *_make() override {return new Scroll_Node();}
+ Type type() const override { return Type::Scroll; }
+ bool is_a(Type inType) const override { return (inType==Type::Scroll) ? true : super::is_a(inType); }
+ Fl_Widget *enter_live_mode(int top=0) override;
+ void copy_properties() override;
+};
+
+// ---- Tile_Node --------------------------------------------------- MARK: -
+
+extern const char tile_type_name[];
+
+class Tile_Node : public Group_Node
+{
+public:
+ typedef Group_Node super;
+ static Tile_Node prototype;
+public:
+ const char *type_name() override {return tile_type_name;}
+ const char *alt_type_name() override {return "fltk::TileGroup";}
+ Widget_Node *_make() override {return new Tile_Node();}
+ Type type() const override { return Type::Tile; }
+ bool is_a(Type inType) const override { return (inType==Type::Tile) ? true : super::is_a(inType); }
+ void copy_properties() override;
+};
+
+// ---- Wizard_Node ------------------------------------------------- MARK: -
+
+class Fl_Wizard_Proxy : public Fl_Wizard {
+public:
+ Fl_Wizard_Proxy(int X,int Y,int W,int H) : Fl_Wizard(X,Y,W,H) {}
+ void resize(int,int,int,int) override;
+ void draw() override;
+};
+
+extern const char wizard_type_name[];
+
+class Wizard_Node : public Group_Node
+{
+public:
+ typedef Group_Node super;
+ static Wizard_Node prototype;
+public:
+ const char *type_name() override {return wizard_type_name;}
+ const char *alt_type_name() override {return "fltk::WizardGroup";}
+ Fl_Widget *widget(int X,int Y,int W,int H) override {
+ Fl_Wizard_Proxy *g = new Fl_Wizard_Proxy(X,Y,W,H); Fl_Group::current(nullptr); return g;}
+ Widget_Node *_make() override {return new Wizard_Node();}
+ Type type() const override { return Type::Wizard; }
+ bool is_a(Type inType) const override { return (inType==Type::Wizard) ? true : super::is_a(inType); }
+};
+
+#endif // FLUID_NODES_GROUP_NODE_H
diff --git a/fluid/nodes/Fl_Menu_Type.cxx b/fluid/nodes/Menu_Node.cxx
index 83435df50..2a76b833a 100644
--- a/fluid/nodes/Fl_Menu_Type.cxx
+++ b/fluid/nodes/Menu_Node.cxx
@@ -1,13 +1,7 @@
//
-// Menu item code for the Fast Light Tool Kit (FLTK).
+// Menu Node code for the Fast Light Tool Kit (FLTK).
//
-// Menu items are kludged by making a phony Fl_Box widget so the normal
-// widget panel can be used to control them.
-//
-// This file also contains code to make Fl_Menu_Button, Fl_Menu_Bar,
-// etc widgets.
-//
-// Copyright 1998-2023 by Bill Spitzak and others.
+// Copyright 1998-2025 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
@@ -20,17 +14,17 @@
// https://www.fltk.org/bugs.php
//
-#include "nodes/Fl_Menu_Type.h"
+#include "nodes/Menu_Node.h"
-#include "app/fluid.h"
-#include "app/project.h"
-#include "app/Fluid_Image.h"
-#include "app/mergeback.h"
-#include "app/undo.h"
+#include "Fluid.h"
+#include "Project.h"
+#include "app/Image_Asset.h"
+#include "proj/mergeback.h"
+#include "proj/undo.h"
#include "io/Project_Reader.h"
#include "io/Project_Writer.h"
#include "io/Code_Writer.h"
-#include "nodes/Fl_Window_Type.h"
+#include "nodes/Window_Node.h"
#include "widgets/Formula_Input.h"
#include "widgets/Node_Browser.h"
@@ -51,17 +45,17 @@
#include <stdlib.h>
Fl_Menu_Item menu_item_type_menu[] = {
- {"Normal",0,0,(void*)0},
- {"Toggle",0,0,(void*)FL_MENU_BOX},
- {"Radio",0,0,(void*)FL_MENU_RADIO},
- {0}};
+ {"Normal",0,nullptr,(void*)nullptr},
+ {"Toggle",0,nullptr,(void*)FL_MENU_BOX},
+ {"Radio",0,nullptr,(void*)FL_MENU_RADIO},
+ {nullptr}};
static void delete_dependents(Fl_Menu_Item *m) {
if (!m)
return;
int level = 0;
for (;;m++) {
- if (m->label()==NULL) {
+ if (m->label()==nullptr) {
if (level==0) {
break;
} else {
@@ -82,18 +76,18 @@ static void delete_menu(Fl_Menu_Item *m) {
delete[] m;
}
-void Fl_Input_Choice_Type::build_menu() {
+void Input_Choice_Node::build_menu() {
Fl_Input_Choice* w = (Fl_Input_Choice*)o;
// count how many Fl_Menu_Item structures needed:
int n = 0;
- Fl_Type* q;
+ Node* q;
for (q = next; q && q->level > level; q = q->next) {
if (q->can_have_children()) n++; // space for null at end of submenu
n++;
}
if (!n) {
if (menusize) delete_menu((Fl_Menu_Item*)(w->menu()));
- w->menu(0);
+ w->menu(nullptr);
menusize = 0;
} else {
n++; // space for null at end of menu
@@ -105,7 +99,7 @@ void Fl_Input_Choice_Type::build_menu() {
if (menusize) delete_dependents((Fl_Menu_Item*)(w->menu()));
}
// Menus are already built during the .fl file reading process, so if the
- // end of a menu list is not read yet, the end markers (label==NULL) will
+ // end of a menu list is not read yet, the end markers (label==nullptr) will
// not be set, and deleting dependents will randomly free memory.
// Clearing the array should avoid that.
memset( (void*)w->menu(), 0, menusize * sizeof(Fl_Menu_Item) );
@@ -113,7 +107,7 @@ void Fl_Input_Choice_Type::build_menu() {
Fl_Menu_Item* m = (Fl_Menu_Item*)(w->menu());
int lvl = level+1;
for (q = next; q && q->level > level; q = q->next) {
- Fl_Menu_Item_Type* i = (Fl_Menu_Item_Type*)q;
+ Menu_Item_Node* i = (Menu_Item_Node*)q;
if (i->o->image()) {
if (i->o->label() && i->o->label()[0]) {
Fl_Multi_Label *ml = new Fl_Multi_Label;
@@ -130,7 +124,7 @@ void Fl_Input_Choice_Type::build_menu() {
m->labeltype(i->o->labeltype());
}
m->shortcut(((Fl_Button*)(i->o))->shortcut());
- m->callback(0,(void*)i);
+ m->callback(nullptr,(void*)i);
m->flags = i->flags();
m->labelfont(i->o->labelfont());
m->labelsize(i->o->labelsize());
@@ -138,8 +132,8 @@ void Fl_Input_Choice_Type::build_menu() {
if (q->can_have_children()) {lvl++; m->flags |= FL_SUBMENU;}
m++;
int l1 =
- (q->next && q->next->is_a(ID_Menu_Item)) ? q->next->level : level;
- while (lvl > l1) {m->label(0); m++; lvl--;}
+ (q->next && q->next->is_a(Type::Menu_Item)) ? q->next->level : level;
+ while (lvl > l1) {m->label(nullptr); m++; lvl--;}
lvl = l1;
}
}
@@ -151,8 +145,8 @@ void Fl_Input_Choice_Type::build_menu() {
\param[in] strategy add after current or as last child
\return new Menu Item node
*/
-Fl_Type *Fl_Menu_Item_Type::make(Strategy strategy) {
- return Fl_Menu_Item_Type::make(0, strategy);
+Node *Menu_Item_Node::make(Strategy strategy) {
+ return Menu_Item_Node::make(0, strategy);
}
/**
@@ -161,29 +155,29 @@ Fl_Type *Fl_Menu_Item_Type::make(Strategy strategy) {
\param[in] strategy add after current or as last child
\return new Menu Item node
*/
-Fl_Type* Fl_Menu_Item_Type::make(int flags, Strategy strategy) {
+Node* Menu_Item_Node::make(int flags, Strategy strategy) {
// Find a good insert position based on the current marked node
- Fl_Type *anchor = Fl_Type::current, *p = anchor;
+ Node *anchor = Fluid.proj.tree.current, *p = anchor;
if (p && (strategy.placement() == Strategy::AFTER_CURRENT))
p = p->parent;
- while (p && !(p->is_a(ID_Menu_Manager_) || p->is_a(ID_Submenu))) {
+ while (p && !(p->is_a(Type::Menu_Manager_) || p->is_a(Type::Submenu))) {
anchor = p;
strategy.placement(Strategy::AFTER_CURRENT);
p = p->parent;
}
if (!p) {
fl_message("Please select a menu widget or a menu item");
- return 0;
+ return nullptr;
}
if (!o) {
o = new Fl_Button(0,0,100,20); // create template widget
}
- Fl_Menu_Item_Type* t = NULL;
+ Menu_Item_Node* t = nullptr;
if (flags==FL_SUBMENU) {
- t = new Fl_Submenu_Type();
+ t = new Submenu_Node();
} else {
- t = new Fl_Menu_Item_Type();
+ t = new Menu_Item_Node();
}
t->o = new Fl_Button(0,0,100,20);
t->o->type(flags);
@@ -201,50 +195,50 @@ Fl_Type* Fl_Menu_Item_Type::make(int flags, Strategy strategy) {
void group_selected_menuitems() {
// The group will be created in the parent group of the current menuitem
- if (!Fl_Type::current->is_a(ID_Menu_Item)) {
+ if (!Fluid.proj.tree.current->is_a(Type::Menu_Item)) {
return;
}
- Fl_Menu_Item_Type *q = static_cast<Fl_Menu_Item_Type*>(Fl_Type::current);
- Fl_Type *qq = Fl_Type::current->parent;
- if (!qq || !(qq->is_a(ID_Menu_Manager_) || qq->is_a(ID_Submenu))) {
+ Menu_Item_Node *q = static_cast<Menu_Item_Node*>(Fluid.proj.tree.current);
+ Node *qq = Fluid.proj.tree.current->parent;
+ if (!qq || !(qq->is_a(Type::Menu_Manager_) || qq->is_a(Type::Submenu))) {
fl_message("Can't create a new submenu here.");
return;
}
- undo_checkpoint();
- undo_suspend();
- Fl_Widget_Type *n = (Fl_Widget_Type*)(q->make(FL_SUBMENU, Strategy::AFTER_CURRENT));
- for (Fl_Type *t = qq->next; t && (t->level > qq->level);) {
+ Fluid.proj.undo.checkpoint();
+ Fluid.proj.undo.suspend();
+ Widget_Node *n = (Widget_Node*)(q->make(FL_SUBMENU, Strategy::AFTER_CURRENT));
+ for (Node *t = qq->next; t && (t->level > qq->level);) {
if (t->level != n->level || t == n || !t->selected) {
t = t->next;
continue;
}
- Fl_Type *nxt = t->remove();
+ Node *nxt = t->remove();
t->add(n, Strategy::AS_LAST_CHILD);
t = nxt;
}
widget_browser->rebuild();
- undo_resume();
- set_modflag(1);
+ Fluid.proj.undo.resume();
+ Fluid.proj.set_modflag(1);
}
void ungroup_selected_menuitems() {
// Find the submenu
- Fl_Type *qq = Fl_Type::current->parent;
- Fl_Widget_Type *q = static_cast<Fl_Widget_Type*>(Fl_Type::current);
+ Node *qq = Fluid.proj.tree.current->parent;
+ Widget_Node *q = static_cast<Widget_Node*>(Fluid.proj.tree.current);
int q_level = q->level;
- if (!qq || !qq->is_a(ID_Submenu)) {
+ if (!qq || !qq->is_a(Type::Submenu)) {
fl_message("Only menu items inside a submenu can be ungrouped.");
return;
}
- undo_checkpoint();
- undo_suspend();
- Fl_Type::current = qq;
- for (Fl_Type *t = qq->next; t && (t->level > qq->level);) {
+ Fluid.proj.undo.checkpoint();
+ Fluid.proj.undo.suspend();
+ Fluid.proj.tree.current = qq;
+ for (Node *t = qq->next; t && (t->level > qq->level);) {
if (t->level != q_level || !t->selected) {
t = t->next;
continue;
}
- Fl_Type *nxt = t->remove();
+ Node *nxt = t->remove();
t->insert(qq);
t = nxt;
}
@@ -252,10 +246,10 @@ void ungroup_selected_menuitems() {
qq->remove();
delete qq; // qq has no children that need to be delete
}
- Fl_Type::current = q;
+ Fluid.proj.tree.current = q;
widget_browser->rebuild();
- undo_resume();
- set_modflag(1);
+ Fluid.proj.undo.resume();
+ Fluid.proj.set_modflag(1);
}
@@ -264,8 +258,8 @@ void ungroup_selected_menuitems() {
\param[in] strategy add after current or as last child
\return new node
*/
-Fl_Type *Fl_Checkbox_Menu_Item_Type::make(Strategy strategy) {
- return Fl_Menu_Item_Type::make(FL_MENU_TOGGLE, strategy);
+Node *Checkbox_Menu_Item_Node::make(Strategy strategy) {
+ return Menu_Item_Node::make(FL_MENU_TOGGLE, strategy);
}
/**
@@ -273,8 +267,8 @@ Fl_Type *Fl_Checkbox_Menu_Item_Type::make(Strategy strategy) {
\param[in] strategy add after current or as last child
\return new node
*/
-Fl_Type *Fl_Radio_Menu_Item_Type::make(Strategy strategy) {
- return Fl_Menu_Item_Type::make(FL_MENU_RADIO, strategy);
+Node *Radio_Menu_Item_Node::make(Strategy strategy) {
+ return Menu_Item_Node::make(FL_MENU_RADIO, strategy);
}
/**
@@ -282,30 +276,33 @@ Fl_Type *Fl_Radio_Menu_Item_Type::make(Strategy strategy) {
\param[in] strategy add after current or as last child
\return new node
*/
-Fl_Type *Fl_Submenu_Type::make(Strategy strategy) {
- return Fl_Menu_Item_Type::make(FL_SUBMENU, strategy);
+Node *Submenu_Node::make(Strategy strategy) {
+ return Menu_Item_Node::make(FL_SUBMENU, strategy);
}
-Fl_Menu_Item_Type Fl_Menu_Item_type;
-Fl_Checkbox_Menu_Item_Type Fl_Checkbox_Menu_Item_type;
-Fl_Radio_Menu_Item_Type Fl_Radio_Menu_Item_type;
-Fl_Submenu_Type Fl_Submenu_type;
+Menu_Item_Node Menu_Item_Node::prototype;
+
+Checkbox_Menu_Item_Node Checkbox_Menu_Item_Node::prototype;
+
+Radio_Menu_Item_Node Radio_Menu_Item_Node::prototype;
+
+Submenu_Node Submenu_Node::prototype;
////////////////////////////////////////////////////////////////
// Writing the C code:
-// test functions in Fl_Widget_Type.C:
+// test functions in Widget_Node.C:
int is_name(const char *c);
-const char *array_name(Fl_Widget_Type *o);
+const char *array_name(Widget_Node *o);
int isdeclare(const char *c);
// Search backwards to find the parent menu button and return it's name.
// Also put in i the index into the button's menu item array belonging
// to this menu item.
-const char* Fl_Menu_Item_Type::menu_name(fld::io::Code_Writer& f, int& i) {
+const char* Menu_Item_Node::menu_name(fld::io::Code_Writer& f, int& i) {
i = 0;
- Fl_Type* t = prev;
- while (t && t->is_a(ID_Menu_Item)) {
+ Node* t = prev;
+ while (t && t->is_a(Type::Menu_Item)) {
// be sure to count the {0} that ends a submenu:
if (t->level > t->next->level) i += (t->level - t->next->level);
// detect empty submenu:
@@ -313,11 +310,11 @@ const char* Fl_Menu_Item_Type::menu_name(fld::io::Code_Writer& f, int& i) {
t = t->prev;
i++;
}
- if (!t) return "\n#error Fl_Menu_Item_Type::menu_name, invalid f\n";
+ if (!t) return "\n#error Menu_Item_Node::menu_name, invalid f\n";
return f.unique_id(t, "menu", t->name(), t->label());
}
-void Fl_Menu_Item_Type::write_static(fld::io::Code_Writer& f) {
+void Menu_Item_Node::write_static(fld::io::Code_Writer& f) {
if (image && label() && label()[0]) {
f.write_h_once("#include <FL/Fl.H>");
f.write_h_once("#include <FL/Fl_Multi_Label.H>");
@@ -374,16 +371,16 @@ void Fl_Menu_Item_Type::write_static(fld::io::Code_Writer& f) {
// Implement the callback as a static member function
f.write_c("void %s::%s(Fl_Menu_* o, %s v) {\n", k, cn, ut);
// Find the Fl_Menu_ container for this menu item
- Fl_Type* t = parent; while (t->is_a(ID_Menu_Item)) t = t->parent;
+ Node* t = parent; while (t->is_a(Type::Menu_Item)) t = t->parent;
if (t) {
- Fl_Widget_Type *tw = (t->is_widget()) ? static_cast<Fl_Widget_Type*>(t) : NULL;
- Fl_Type *q = NULL;
+ Widget_Node *tw = (t->is_widget()) ? static_cast<Widget_Node*>(t) : nullptr;
+ Node *q = nullptr;
// Generate code to call the callback
- if (tw->is_a(ID_Menu_Bar) && ((Fl_Menu_Bar_Type*)tw)->is_sys_menu_bar()) {
+ if (tw->is_a(Type::Menu_Bar) && ((Menu_Bar_Node*)tw)->is_sys_menu_bar()) {
// Fl_Sys_Menu_Bar removes itself from any parent on macOS, so we
// wrapped it in a class and remeber the parent class in a new
// class memeber variable.
- Fl_Menu_Bar_Type *tmb = (Fl_Menu_Bar_Type*)tw;
+ Menu_Bar_Node *tmb = (Menu_Bar_Node*)tw;
f.write_c("%s%s* sys_menu_bar = ((%s*)o);\n", f.indent(1),
tmb->sys_menubar_proxy_name(), tmb->sys_menubar_proxy_name());
f.write_c("%s%s* parent_class = ((%s*)sys_menu_bar->_parent_class);\n",
@@ -393,7 +390,7 @@ void Fl_Menu_Item_Type::write_static(fld::io::Code_Writer& f) {
} else {
f.write_c("%s((%s*)(o", f.indent(1), k);
// The class pointer is in the user_data field of the top widget
- if (t && t->is_a(ID_Input_Choice)) {
+ if (t && t->is_a(Type::Input_Choice)) {
// Go up one more level for Fl_Input_Choice, as these are groups themselves
f.write_c("->parent()");
}
@@ -401,7 +398,7 @@ void Fl_Menu_Item_Type::write_static(fld::io::Code_Writer& f) {
for (t = t->parent; t && t->is_widget() && !is_class(); q = t, t = t->parent)
f.write_c("->parent()");
// user_data is cast into a pointer to the
- if (!q || !q->is_a(ID_Widget_Class))
+ if (!q || !q->is_a(Type::Widget_Class))
f.write_c("->user_data()");
f.write_c("))->%s_i(o,v);\n}\n", cn);
}
@@ -414,7 +411,7 @@ void Fl_Menu_Item_Type::write_static(fld::io::Code_Writer& f) {
if (!f.c_contains(image))
image->write_static(f, compress_image_);
}
- if (next && next->is_a(ID_Menu_Item)) return;
+ if (next && next->is_a(Type::Menu_Item)) return;
// okay, when we hit last item in the menu we have to write the
// entire array out:
const char* k = class_name(1);
@@ -425,27 +422,27 @@ void Fl_Menu_Item_Type::write_static(fld::io::Code_Writer& f) {
int i;
f.write_c("\nFl_Menu_Item %s[] = {\n", menu_name(f, i));
}
- Fl_Type* t = prev; while (t && t->is_a(ID_Menu_Item)) t = t->prev;
- for (Fl_Type* q = t->next; q && q->is_a(ID_Menu_Item); q = q->next) {
- ((Fl_Menu_Item_Type*)q)->write_item(f);
+ Node* t = prev; while (t && t->is_a(Type::Menu_Item)) t = t->prev;
+ for (Node* q = t->next; q && q->is_a(Type::Menu_Item); q = q->next) {
+ ((Menu_Item_Node*)q)->write_item(f);
int thislevel = q->level; if (q->can_have_children()) thislevel++;
int nextlevel =
- (q->next && q->next->is_a(ID_Menu_Item)) ? q->next->level : t->level+1;
+ (q->next && q->next->is_a(Type::Menu_Item)) ? q->next->level : t->level+1;
while (thislevel > nextlevel) {f.write_c(" {0,0,0,0,0,0,0,0,0},\n"); thislevel--;}
}
f.write_c(" {0,0,0,0,0,0,0,0,0}\n};\n");
if (k) {
// Write menu item variables...
- t = prev; while (t && t->is_a(ID_Menu_Item)) t = t->prev;
- for (Fl_Type* q = t->next; q && q->is_a(ID_Menu_Item); q = q->next) {
- Fl_Menu_Item_Type *m = (Fl_Menu_Item_Type*)q;
+ t = prev; while (t && t->is_a(Type::Menu_Item)) t = t->prev;
+ for (Node* q = t->next; q && q->is_a(Type::Menu_Item); q = q->next) {
+ Menu_Item_Node *m = (Menu_Item_Node*)q;
const char *c = array_name(m);
if (c) {
if (c==m->name()) {
// assign a menu item address directly to a variable
int i;
- const char* n = ((Fl_Menu_Item_Type *)q)->menu_name(f, i);
+ const char* n = ((Menu_Item_Node *)q)->menu_name(f, i);
f.write_c("Fl_Menu_Item* %s::%s = %s::%s + %d;\n", k, c, k, n, i);
} else {
// if the name is an array, only define the array.
@@ -457,20 +454,20 @@ void Fl_Menu_Item_Type::write_static(fld::io::Code_Writer& f) {
}
}
-int Fl_Menu_Item_Type::flags() {
+int Menu_Item_Node::flags() {
int i = o->type();
if (((Fl_Button*)o)->value()) i |= FL_MENU_VALUE;
if (!o->active()) i |= FL_MENU_INACTIVE;
if (!o->visible()) i |= FL_MENU_INVISIBLE;
if (can_have_children()) {
- if (user_data() == NULL) i |= FL_SUBMENU;
+ if (user_data() == nullptr) i |= FL_SUBMENU;
else i |= FL_SUBMENU_POINTER;
}
if (hotspot()) i |= FL_MENU_DIVIDER;
return i;
}
-void Fl_Menu_Item_Type::write_item(fld::io::Code_Writer& f) {
+void Menu_Item_Node::write_item(fld::io::Code_Writer& f) {
static const char * const labeltypes[] = {
"FL_NORMAL_LABEL",
"FL_NO_LABEL",
@@ -485,14 +482,14 @@ void Fl_Menu_Item_Type::write_item(fld::io::Code_Writer& f) {
write_comment_inline_c(f, " ");
f.write_c(" {");
if (label() && label()[0])
- switch (g_project.i18n_type) {
- case FD_I18N_GNU:
+ switch (Fluid.proj.i18n_type) {
+ case fld::I18n_Type::GNU:
// we will call i18n when the menu is instantiated for the first time
- f.write_c("%s(", g_project.i18n_gnu_static_function.c_str());
+ f.write_c("%s(", Fluid.proj.i18n_gnu_static_function.c_str());
f.write_cstring(label());
f.write_c(")");
break;
- case FD_I18N_POSIX:
+ case fld::I18n_Type::POSIX:
// fall through: strings can't be translated before a catalog is chosen
default:
f.write_cstring(label());
@@ -502,7 +499,7 @@ void Fl_Menu_Item_Type::write_item(fld::io::Code_Writer& f) {
if (((Fl_Button*)o)->shortcut()) {
int s = ((Fl_Button*)o)->shortcut();
f.write_c(", ");
- if (g_project.use_FL_COMMAND) {
+ if (Fluid.proj.use_FL_COMMAND) {
if (s & FL_CTRL) { f.write_c("FL_CONTROL|"); s &= ~FL_CTRL; }
if (s & FL_META) { f.write_c("FL_COMMAND|"); s &= ~FL_META; }
} else {
@@ -519,7 +516,7 @@ void Fl_Menu_Item_Type::write_item(fld::io::Code_Writer& f) {
f.write_c(", 0, ");
}
if (callback()) {
- const char* k = is_name(callback()) ? 0 : class_name(1);
+ const char* k = is_name(callback()) ? nullptr : class_name(1);
if (k) {
f.write_c(" (Fl_Callback*)%s::%s,", k, callback_name(f));
} else {
@@ -544,10 +541,10 @@ void start_menu_initialiser(fld::io::Code_Writer& f, int &initialized, const cha
}
}
-void Fl_Menu_Item_Type::write_code1(fld::io::Code_Writer& f) {
+void Menu_Item_Node::write_code1(fld::io::Code_Writer& f) {
int i; const char* mname = menu_name(f, i);
- if (!prev->is_a(ID_Menu_Item)) {
+ if (!prev->is_a(Type::Menu_Item)) {
// for first menu item, declare the array
if (class_name(1)) {
f.write_h("%sstatic Fl_Menu_Item %s[];\n", f.indent(1), mname);
@@ -591,16 +588,16 @@ void Fl_Menu_Item_Type::write_code1(fld::io::Code_Writer& f) {
f.write_c("%sml->labela = (char*)", f.indent());
image->write_inline(f);
f.write_c(";\n");
- if (g_project.i18n_type==FD_I18N_NONE) {
+ if (Fluid.proj.i18n_type==fld::I18n_Type::NONE) {
f.write_c("%sml->labelb = o->label();\n", f.indent());
- } else if (g_project.i18n_type==FD_I18N_GNU) {
+ } else if (Fluid.proj.i18n_type==fld::I18n_Type::GNU) {
f.write_c("%sml->labelb = %s(o->label());\n",
- f.indent(), g_project.i18n_gnu_function.c_str());
- } else if (g_project.i18n_type==FD_I18N_POSIX) {
+ f.indent(), Fluid.proj.i18n_gnu_function.c_str());
+ } else if (Fluid.proj.i18n_type==fld::I18n_Type::POSIX) {
f.write_c("%sml->labelb = catgets(%s,%s,i+%d,o->label());\n",
f.indent(),
- g_project.i18n_pos_file.empty() ? "_catalog" : g_project.i18n_pos_file.c_str(),
- g_project.i18n_pos_set.c_str(), msgnum());
+ Fluid.proj.i18n_pos_file.empty() ? "_catalog" : Fluid.proj.i18n_pos_file.c_str(),
+ Fluid.proj.i18n_pos_set.c_str(), msgnum());
}
f.write_c("%sml->typea = FL_IMAGE_LABEL;\n", f.indent());
f.write_c("%sml->typeb = FL_NORMAL_LABEL;\n", f.indent());
@@ -609,21 +606,21 @@ void Fl_Menu_Item_Type::write_code1(fld::io::Code_Writer& f) {
image->write_code(f, 0, "o");
}
}
- if (g_project.i18n_type && label() && label()[0]) {
+ if ((Fluid.proj.i18n_type != fld::I18n_Type::NONE) && label() && label()[0]) {
Fl_Labeltype t = o->labeltype();
if (image) {
// label was already copied a few lines up
} else if ( t==FL_NORMAL_LABEL || t==FL_SHADOW_LABEL
|| t==FL_ENGRAVED_LABEL || t==FL_EMBOSSED_LABEL) {
start_menu_initialiser(f, menuItemInitialized, mname, i);
- if (g_project.i18n_type==FD_I18N_GNU) {
+ if (Fluid.proj.i18n_type==fld::I18n_Type::GNU) {
f.write_c("%so->label(%s(o->label()));\n",
- f.indent(), g_project.i18n_gnu_function.c_str());
- } else if (g_project.i18n_type==FD_I18N_POSIX) {
+ f.indent(), Fluid.proj.i18n_gnu_function.c_str());
+ } else if (Fluid.proj.i18n_type==fld::I18n_Type::POSIX) {
f.write_c("%so->label(catgets(%s,%s,i+%d,o->label()));\n",
f.indent(),
- g_project.i18n_pos_file.empty() ? "_catalog" : g_project.i18n_pos_file.c_str(),
- g_project.i18n_pos_set.c_str(), msgnum());
+ Fluid.proj.i18n_pos_file.empty() ? "_catalog" : Fluid.proj.i18n_pos_file.c_str(),
+ Fluid.proj.i18n_pos_set.c_str(), msgnum());
}
}
}
@@ -639,7 +636,7 @@ void Fl_Menu_Item_Type::write_code1(fld::io::Code_Writer& f) {
}
}
-void Fl_Menu_Item_Type::write_code2(fld::io::Code_Writer&) {}
+void Menu_Item_Node::write_code2(fld::io::Code_Writer&) {}
////////////////////////////////////////////////////////////////
// This is the base class for widgets that contain a menu (ie
@@ -648,18 +645,18 @@ void Fl_Menu_Item_Type::write_code2(fld::io::Code_Writer&) {}
// children. An actual array of Fl_Menu_Items is kept parallel
// with the child objects and updated as they change.
-void Fl_Menu_Base_Type::build_menu() {
+void Menu_Base_Node::build_menu() {
Fl_Menu_* w = (Fl_Menu_*)o;
// count how many Fl_Menu_Item structures needed:
int n = 0;
- Fl_Type* q;
+ Node* q;
for (q = next; q && q->level > level; q = q->next) {
if (q->can_have_children()) n++; // space for null at end of submenu
n++;
}
if (!n) {
if (menusize) delete_menu((Fl_Menu_Item*)(w->menu()));
- w->menu(0);
+ w->menu(nullptr);
menusize = 0;
} else {
n++; // space for null at end of menu
@@ -671,7 +668,7 @@ void Fl_Menu_Base_Type::build_menu() {
if (menusize) delete_dependents((Fl_Menu_Item*)(w->menu()));
}
// Menus are already built during the .fl file reading process, so if the
- // end of a menu list is not read yet, the end markers (label==NULL) will
+ // end of a menu list is not read yet, the end markers (label==nullptr) will
// not be set, and deleting dependents will randomly free memory.
// Clearing the array should avoid that.
memset( (void*)w->menu(), 0, menusize * sizeof(Fl_Menu_Item) );
@@ -679,7 +676,7 @@ void Fl_Menu_Base_Type::build_menu() {
Fl_Menu_Item* m = (Fl_Menu_Item*)(w->menu());
int lvl = level+1;
for (q = next; q && q->level > level; q = q->next) {
- Fl_Menu_Item_Type* i = (Fl_Menu_Item_Type*)q;
+ Menu_Item_Node* i = (Menu_Item_Node*)q;
if (i->o->image()) {
if (i->o->label() && i->o->label()[0]) {
Fl_Multi_Label *ml = new Fl_Multi_Label;
@@ -696,7 +693,7 @@ void Fl_Menu_Base_Type::build_menu() {
m->labeltype(i->o->labeltype());
}
m->shortcut(((Fl_Button*)(i->o))->shortcut());
- m->callback(0,(void*)i);
+ m->callback(nullptr,(void*)i);
m->flags = i->flags() | i->o->type();
m->labelfont(i->o->labelfont());
m->labelsize(i->o->labelsize());
@@ -704,43 +701,43 @@ void Fl_Menu_Base_Type::build_menu() {
if (q->can_have_children()) {lvl++; m->flags |= FL_SUBMENU;}
m++;
int l1 =
- (q->next && q->next->is_a(ID_Menu_Item)) ? q->next->level : level;
- while (lvl > l1) {m->label(0); m++; lvl--;}
+ (q->next && q->next->is_a(Type::Menu_Item)) ? q->next->level : level;
+ while (lvl > l1) {m->label(nullptr); m++; lvl--;}
lvl = l1;
}
}
o->redraw();
}
-Fl_Type* Fl_Menu_Base_Type::click_test(int, int) {
- if (selected) return 0; // let user move the widget
+Node* Menu_Base_Node::click_test(int, int) {
+ if (selected) return nullptr; // let user move the widget
Fl_Menu_* w = (Fl_Menu_*)o;
- if (!menusize) return 0;
+ if (!menusize) return nullptr;
const Fl_Menu_Item* save = w->mvalue();
- w->value((Fl_Menu_Item*)0);
+ w->value((Fl_Menu_Item*)nullptr);
Fl::pushed(w);
w->handle(FL_PUSH);
- Fl::focus(NULL);
+ Fl::focus(nullptr);
const Fl_Menu_Item* m = w->mvalue();
if (m) {
// restore the settings of toggles & radio items:
if (m->flags & (FL_MENU_RADIO | FL_MENU_TOGGLE)) build_menu();
- return (Fl_Type*)(m->user_data());
+ return (Node*)(m->user_data());
}
w->value(save);
return this;
}
-void Fl_Menu_Manager_Type::write_code2(fld::io::Code_Writer& f) {
- if (next && next->is_a(ID_Menu_Item)) {
+void Menu_Manager_Node::write_code2(fld::io::Code_Writer& f) {
+ if (next && next->is_a(Type::Menu_Item)) {
f.write_c("%s%s->menu(%s);\n", f.indent(), name() ? name() : "o",
f.unique_id(this, "menu", name(), label()));
}
- Fl_Widget_Type::write_code2(f);
+ Widget_Node::write_code2(f);
}
-void Fl_Menu_Base_Type::copy_properties() {
- Fl_Widget_Type::copy_properties();
+void Menu_Base_Node::copy_properties() {
+ Widget_Node::copy_properties();
Fl_Menu_ *s = (Fl_Menu_*)o, *d = (Fl_Menu_*)live_widget;
d->menu(s->menu());
d->down_box(s->down_box());
@@ -752,28 +749,28 @@ void Fl_Menu_Base_Type::copy_properties() {
////////////////////////////////////////////////////////////////
Fl_Menu_Item button_type_menu[] = {
- {"normal",0,0,(void*)0},
- {"popup1",0,0,(void*)Fl_Menu_Button::POPUP1},
- {"popup2",0,0,(void*)Fl_Menu_Button::POPUP2},
- {"popup3",0,0,(void*)Fl_Menu_Button::POPUP3},
- {"popup12",0,0,(void*)Fl_Menu_Button::POPUP12},
- {"popup23",0,0,(void*)Fl_Menu_Button::POPUP23},
- {"popup13",0,0,(void*)Fl_Menu_Button::POPUP13},
- {"popup123",0,0,(void*)Fl_Menu_Button::POPUP123},
- {0}};
-
-Fl_Menu_Button_Type Fl_Menu_Button_type;
+ {"normal",0,nullptr,(void*)nullptr},
+ {"popup1",0,nullptr,(void*)Fl_Menu_Button::POPUP1},
+ {"popup2",0,nullptr,(void*)Fl_Menu_Button::POPUP2},
+ {"popup3",0,nullptr,(void*)Fl_Menu_Button::POPUP3},
+ {"popup12",0,nullptr,(void*)Fl_Menu_Button::POPUP12},
+ {"popup23",0,nullptr,(void*)Fl_Menu_Button::POPUP23},
+ {"popup13",0,nullptr,(void*)Fl_Menu_Button::POPUP13},
+ {"popup123",0,nullptr,(void*)Fl_Menu_Button::POPUP123},
+ {nullptr}};
+
+Menu_Button_Node Menu_Button_Node::prototype;
////////////////////////////////////////////////////////////////
-Fl_Menu_Item dummymenu[] = {{"CHOICE"},{0}};
+Fl_Menu_Item dummymenu[] = {{"CHOICE"},{nullptr}};
-Fl_Choice_Type Fl_Choice_type;
+Choice_Node Choice_Node::prototype;
-Fl_Input_Choice_Type Fl_Input_Choice_type;
+Input_Choice_Node Input_Choice_Node::prototype;
-void Fl_Input_Choice_Type::copy_properties() {
- Fl_Widget_Type::copy_properties();
+void Input_Choice_Node::copy_properties() {
+ Widget_Node::copy_properties();
Fl_Input_Choice *s = (Fl_Input_Choice*)o, *d = (Fl_Input_Choice*)live_widget;
d->menu(s->menu());
d->down_box(s->down_box());
@@ -782,20 +779,20 @@ void Fl_Input_Choice_Type::copy_properties() {
d->textsize(s->textsize());
}
-Fl_Type* Fl_Input_Choice_Type::click_test(int, int) {
- if (selected) return 0; // let user move the widget
+Node* Input_Choice_Node::click_test(int, int) {
+ if (selected) return nullptr; // let user move the widget
Fl_Menu_* w = ((Fl_Input_Choice*)o)->menubutton();
- if (!menusize) return 0;
+ if (!menusize) return nullptr;
const Fl_Menu_Item* save = w->mvalue();
- w->value((Fl_Menu_Item*)0);
+ w->value((Fl_Menu_Item*)nullptr);
Fl::pushed(w);
w->handle(FL_PUSH);
- Fl::focus(NULL);
+ Fl::focus(nullptr);
const Fl_Menu_Item* m = w->mvalue();
if (m) {
// restore the settings of toggles & radio items:
if (m->flags & (FL_MENU_RADIO | FL_MENU_TOGGLE)) build_menu();
- return (Fl_Type*)(m->user_data());
+ return (Node*)(m->user_data());
}
w->value(save);
return this;
@@ -803,19 +800,19 @@ Fl_Type* Fl_Input_Choice_Type::click_test(int, int) {
////////////////////////////////////////////////////////////////
-Fl_Menu_Bar_Type Fl_Menu_Bar_type;
+Menu_Bar_Node Menu_Bar_Node::prototype;
Fl_Menu_Item menu_bar_type_menu[] = {
- {"Fl_Menu_Bar",0,0,(void*)0},
- {"Fl_Sys_Menu_Bar",0,0,(void*)1},
- {0}};
+ {"Fl_Menu_Bar",0,nullptr,(void*)nullptr},
+ {"Fl_Sys_Menu_Bar",0,nullptr,(void*)1},
+ {nullptr}};
-Fl_Menu_Bar_Type::Fl_Menu_Bar_Type()
-: _proxy_name(NULL)
+Menu_Bar_Node::Menu_Bar_Node()
+: _proxy_name(nullptr)
{
}
-Fl_Menu_Bar_Type::~Fl_Menu_Bar_Type() {
+Menu_Bar_Node::~Menu_Bar_Node() {
if (_proxy_name)
::free(_proxy_name);
}
@@ -825,19 +822,19 @@ Fl_Menu_Bar_Type::~Fl_Menu_Bar_Type() {
This test fails if subclass() is the name of a class that the user may have
derived from Fl_Sys_Menu_Bar.
*/
-bool Fl_Menu_Bar_Type::is_sys_menu_bar() {
+bool Menu_Bar_Node::is_sys_menu_bar() {
if (o->type()==1) return true;
return ( subclass() && (strcmp(subclass(), "Fl_Sys_Menu_Bar")==0) );
}
-const char *Fl_Menu_Bar_Type::sys_menubar_name() {
+const char *Menu_Bar_Node::sys_menubar_name() {
if (subclass())
return subclass();
else
return "Fl_Sys_Menu_Bar";
}
-const char *Fl_Menu_Bar_Type::sys_menubar_proxy_name() {
+const char *Menu_Bar_Node::sys_menubar_proxy_name() {
if (!_proxy_name)
_proxy_name = (char*)::malloc(128);
::snprintf(_proxy_name, 63, "%s_Proxy", sys_menubar_name());
@@ -845,7 +842,7 @@ const char *Fl_Menu_Bar_Type::sys_menubar_proxy_name() {
}
-void Fl_Menu_Bar_Type::write_static(fld::io::Code_Writer& f) {
+void Menu_Bar_Node::write_static(fld::io::Code_Writer& f) {
super::write_static(f);
if (is_sys_menu_bar()) {
f.write_h_once("#include <FL/Fl_Sys_Menu_Bar.H>");
@@ -854,7 +851,7 @@ void Fl_Menu_Bar_Type::write_static(fld::io::Code_Writer& f) {
f.write_c_once( // must be less than 1024 bytes!
"\nclass %s: public %s {\n"
"public:\n"
- " %s(int x, int y, int w, int h, const char *l=NULL)\n"
+ " %s(int x, int y, int w, int h, const char *l=0L)\n"
" : %s(x, y, w, h, l) { }\n"
" void *_parent_class;\n"
"};\n",
@@ -865,7 +862,7 @@ void Fl_Menu_Bar_Type::write_static(fld::io::Code_Writer& f) {
}
}
-void Fl_Menu_Bar_Type::write_code1(fld::io::Code_Writer& f) {
+void Menu_Bar_Node::write_code1(fld::io::Code_Writer& f) {
super::write_code1(f);
if (is_sys_menu_bar() && is_in_class()) {
f.write_c("%s((%s*)%s)->_parent_class = (void*)this;\n",
@@ -873,52 +870,7 @@ void Fl_Menu_Bar_Type::write_code1(fld::io::Code_Writer& f) {
}
}
-//void Fl_Menu_Bar_Type::write_code2(fld::io::Code_Writer& f) {
+//void Menu_Bar_Node::write_code2(fld::io::Code_Writer& f) {
// super::write_code2(f);
//}
-////////////////////////////////////////////////////////////////
-// Shortcut entry item in panel:
-void shortcut_in_cb(Fl_Shortcut_Button* i, void* v) {
- if (v == LOAD) {
- if (current_widget->is_button())
- i->value( ((Fl_Button*)(current_widget->o))->shortcut() );
- else if (current_widget->is_a(ID_Input))
- i->value( ((Fl_Input_*)(current_widget->o))->shortcut() );
- else if (current_widget->is_a(ID_Value_Input))
- i->value( ((Fl_Value_Input*)(current_widget->o))->shortcut() );
- else if (current_widget->is_a(ID_Text_Display))
- i->value( ((Fl_Text_Display*)(current_widget->o))->shortcut() );
- else {
- i->hide();
- i->parent()->hide();
- return;
- }
- //i->default_value( i->value() ); // enable the "undo" capability of the shortcut button
- i->show();
- i->parent()->show();
- i->redraw();
- } else {
- int mod = 0;
- for (Fl_Type *o = Fl_Type::first; o; o = o->next)
- if (o->selected && o->is_button()) {
- Fl_Button* b = (Fl_Button*)(((Fl_Widget_Type*)o)->o);
- if (b->shortcut() != (int)i->value()) mod = 1;
- b->shortcut(i->value());
- if (o->is_a(ID_Menu_Item)) ((Fl_Widget_Type*)o)->redraw();
- } else if (o->selected && o->is_a(ID_Input)) {
- Fl_Input_* b = (Fl_Input_*)(((Fl_Widget_Type*)o)->o);
- if (b->shortcut() != (int)i->value()) mod = 1;
- b->shortcut(i->value());
- } else if (o->selected && o->is_a(ID_Value_Input)) {
- Fl_Value_Input* b = (Fl_Value_Input*)(((Fl_Widget_Type*)o)->o);
- if (b->shortcut() != (int)i->value()) mod = 1;
- b->shortcut(i->value());
- } else if (o->selected && o->is_a(ID_Text_Display)) {
- Fl_Text_Display* b = (Fl_Text_Display*)(((Fl_Widget_Type*)o)->o);
- if (b->shortcut() != (int)i->value()) mod = 1;
- b->shortcut(i->value());
- }
- if (mod) set_modflag(1);
- }
-}
diff --git a/fluid/nodes/Menu_Node.h b/fluid/nodes/Menu_Node.h
new file mode 100644
index 000000000..59d3b06bb
--- /dev/null
+++ b/fluid/nodes/Menu_Node.h
@@ -0,0 +1,310 @@
+//
+// Menu Node header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2025 by Bill Spitzak and others.
+//
+// This library is free software. Distribution and use rights are outlined in
+// the file "COPYING" which should have been included with this file. If this
+// file is missing or damaged, see the license at:
+//
+// https://www.fltk.org/COPYING.php
+//
+// Please see the following page on how to report bugs and issues:
+//
+// https://www.fltk.org/bugs.php
+//
+
+// Type for creating all subclasses of Fl_Widget
+// This should have the widget pointer in it, but it is still in the
+// Node base class.
+//
+
+
+#ifndef FLUID_NODES_MENU_NODE_H
+#define FLUID_NODES_MENU_NODE_H
+
+#include "nodes/Button_Node.h"
+
+#include "Fluid.h"
+#include "app/Snap_Action.h"
+
+#include <FL/Fl_Choice.H>
+#include <FL/Fl_Menu_.H>
+#include <FL/Fl_Menu_Button.H>
+#include <FL/Fl_Input_Choice.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Menu_Bar.H>
+
+extern Fl_Menu_Item dummymenu[];
+extern Fl_Menu_Item button_type_menu[];
+extern Fl_Menu_Item menu_item_type_menu[];
+extern Fl_Menu_Item menu_bar_type_menu[];
+
+/**
+ \brief Manage all types on menu items.
+ Deriving Menu_Item_Node from Button_Node is intentional. For the purpose
+ of editing, a Menu Item is implemented with `o` pointing to an Fl_Button for
+ holding all properties.
+ */
+class Menu_Item_Node : public Button_Node
+{
+public:
+ typedef Button_Node super;
+ static Menu_Item_Node prototype;
+public:
+ Fl_Menu_Item* subtypes() override {return menu_item_type_menu;}
+ const char* type_name() override {return "MenuItem";}
+ const char* alt_type_name() override {return "fltk::Item";}
+ Node* make(Strategy strategy) override;
+ Node* make(int flags, Strategy strategy);
+ int is_button() const override {return 1;} // this gets shortcut to work
+ Fl_Widget* widget(int,int,int,int) override {return nullptr;}
+ Widget_Node* _make() override {return nullptr;}
+ virtual const char* menu_name(fld::io::Code_Writer& f, int& i);
+ int flags();
+ void write_static(fld::io::Code_Writer& f) override;
+ void write_item(fld::io::Code_Writer& f);
+ void write_code1(fld::io::Code_Writer& f) override;
+ void write_code2(fld::io::Code_Writer& f) override;
+ int is_true_widget() const override { return 0; }
+ Type type() const override { return Type::Menu_Item; }
+ bool is_a(Type inType) const override { return (inType==Type::Menu_Item) ? true : super::is_a(inType); }
+};
+
+/**
+ \brief Manage Radio style Menu Items.
+ */
+class Radio_Menu_Item_Node : public Menu_Item_Node
+{
+public:
+ typedef Menu_Item_Node super;
+ static Radio_Menu_Item_Node prototype;
+public:
+ const char* type_name() override {return "RadioMenuItem";}
+ Node* make(Strategy strategy) override;
+ Type type() const override { return Type::Radio_Menu_Item; }
+ bool is_a(Type inType) const override { return (inType==Type::Radio_Menu_Item) ? true : super::is_a(inType); }
+};
+
+/**
+ \brief Manage Checkbox style Menu Items.
+ */
+class Checkbox_Menu_Item_Node : public Menu_Item_Node
+{
+public:
+ typedef Menu_Item_Node super;
+ static Checkbox_Menu_Item_Node prototype;
+public:
+ const char* type_name() override {return "CheckMenuItem";}
+ Node* make(Strategy strategy) override;
+ Type type() const override { return Type::Checkbox_Menu_Item; }
+ bool is_a(Type inType) const override { return (inType==Type::Checkbox_Menu_Item) ? true : super::is_a(inType); }
+};
+
+/**
+ \brief Manage Submenu style Menu Items.
+ Submenu Items are simply buttons just like all other menu items, but they
+ can also hold a pointer to a list of submenus, or have a flag set that
+ allows submenus to follow in the current array. As buttons, they can
+ be clicked by the user, and they will call their callback, if one is set.
+ */
+class Submenu_Node : public Menu_Item_Node
+{
+public:
+ typedef Menu_Item_Node super;
+ static Submenu_Node prototype;
+public:
+ Fl_Menu_Item* subtypes() override {return nullptr;}
+ const char* type_name() override {return "Submenu";}
+ const char* alt_type_name() override {return "fltk::ItemGroup";}
+ int can_have_children() const override {return 1;}
+ int is_button() const override {return 0;} // disable shortcut
+ Node* make(Strategy strategy) override;
+ // changes to submenu must propagate up so build_menu is called
+ // on the parent Menu_Node:
+ void add_child(Node*a, Node*b) override {parent->add_child(a,b);}
+ void move_child(Node*a, Node*b) override {parent->move_child(a,b);}
+ void remove_child(Node*a) override {parent->remove_child(a);}
+ Type type() const override { return Type::Submenu; }
+ bool is_a(Type inType) const override { return (inType==Type::Submenu) ? true : super::is_a(inType); }
+};
+
+// -----------------------------------------------------------------------------
+
+/**
+ \brief Base class for all widgets that can have a pulldown menu attached.
+ Widgets with this type can be derived from Fl_Menu_ or from
+ Fl_Group (Fl_Input_Choice).
+ */
+class Menu_Manager_Node : public Widget_Node
+{
+ typedef Widget_Node super;
+public:
+ void ideal_size(int &w, int &h) override {
+ auto layout = Fluid.proj.layout;
+ h = layout->textsize_not_null() + 8;
+ w = layout->textsize_not_null() * 6 + 8;
+ fld::app::Snap_Action::better_size(w, h);
+ }
+ int can_have_children() const override {return 1;}
+ int menusize;
+ virtual void build_menu() = 0;
+ Menu_Manager_Node() : Widget_Node() {menusize = 0;}
+ void add_child(Node*, Node*) override { build_menu(); }
+ void move_child(Node*, Node*) override { build_menu(); }
+ void remove_child(Node*) override { build_menu();}
+ Node* click_test(int x, int y) override = 0;
+ void write_code2(fld::io::Code_Writer& f) override;
+ void copy_properties() override = 0;
+ Type type() const override { return Type::Menu_Manager_; }
+ bool is_a(Type inType) const override { return (inType==Type::Menu_Manager_) ? true : super::is_a(inType); }
+};
+
+/**
+ \brief Manage the composite widget Input Choice.
+ \note Input Choice is a composite window, so `o` will be pointing to a widget
+ derived from Fl_Group. All menu related methods from Fl_Menu_Trait_Type must
+ be virtual and must be reimplemented here (click_test, build_menu, textstuff).
+ */
+class Input_Choice_Node : public Menu_Manager_Node
+{
+public:
+ typedef Menu_Manager_Node super;
+ static Input_Choice_Node prototype;
+private:
+ int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) override {
+ Fl_Input_Choice *myo = (Fl_Input_Choice*)(w==4 ? ((Widget_Node*)this->factory)->o : this->o);
+ switch (w) {
+ case 4:
+ case 0: f = (Fl_Font)myo->textfont(); s = myo->textsize(); c = myo->textcolor(); break;
+ case 1: myo->textfont(f); break;
+ case 2: myo->textsize(s); break;
+ case 3: myo->textcolor(c); break;
+ }
+ return 1;
+ }
+public:
+ ~Input_Choice_Node() {
+ if (menusize) delete[] (Fl_Menu_Item*)(((Fl_Input_Choice*)o)->menu());
+ }
+ const char *type_name() override {return "Fl_Input_Choice";}
+ const char *alt_type_name() override {return "fltk::ComboBox";}
+ Node* click_test(int,int) override;
+ Fl_Widget *widget(int X,int Y,int W,int H) override {
+ Fl_Input_Choice *myo = new Fl_Input_Choice(X,Y,W,H,"input choice:");
+ myo->menu(dummymenu);
+ myo->value("input");
+ return myo;
+ }
+ Widget_Node *_make() override {return new Input_Choice_Node();}
+ void build_menu() override;
+ Type type() const override { return Type::Input_Choice; }
+ bool is_a(Type inType) const override { return (inType==Type::Input_Choice) ? true : super::is_a(inType); }
+ void copy_properties() override;
+};
+
+/**
+ \brief Base class to handle widgets that are derived from Fl_Menu_.
+ */
+class Menu_Base_Node : public Menu_Manager_Node
+{
+ typedef Menu_Manager_Node super;
+ int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) override {
+ Fl_Menu_ *myo = (Fl_Menu_*)(w==4 ? ((Widget_Node*)this->factory)->o : this->o);
+ switch (w) {
+ case 4:
+ case 0: f = myo->textfont(); s = myo->textsize(); c = myo->textcolor(); break;
+ case 1: myo->textfont(f); break;
+ case 2: myo->textsize(s); break;
+ case 3: myo->textcolor(c); break;
+ }
+ return 1;
+ }
+public:
+ int can_have_children() const override {return 1;}
+ void build_menu() override;
+ ~Menu_Base_Node() {
+ if (menusize) delete[] (Fl_Menu_Item*)(((Fl_Menu_*)o)->menu());
+ }
+ Node* click_test(int x, int y) override;
+ void copy_properties() override;
+ Type type() const override { return Type::Menu_; }
+ bool is_a(Type inType) const override { return (inType==Type::Menu_) ? true : super::is_a(inType); }
+};
+
+extern Fl_Menu_Item button_type_menu[];
+
+/**
+ \brief Make Menu Button widgets.
+ */
+class Menu_Button_Node : public Menu_Base_Node
+{
+public:
+ typedef Menu_Base_Node super;
+ static Menu_Button_Node prototype;
+private:
+ Fl_Menu_Item *subtypes() override {return button_type_menu;}
+public:
+ const char *type_name() override {return "Fl_Menu_Button";}
+ const char *alt_type_name() override {return "fltk::MenuButton";}
+ Fl_Widget *widget(int X,int Y,int W,int H) override {
+ return new Fl_Menu_Button(X,Y,W,H,"menu");}
+ Widget_Node *_make() override {return new Menu_Button_Node();}
+ Type type() const override { return Type::Menu_Button; }
+ bool is_a(Type inType) const override { return (inType==Type::Menu_Button) ? true : super::is_a(inType); }
+};
+
+
+/**
+ \brief Manage Choice type menu widgets.
+ */
+class Choice_Node : public Menu_Base_Node
+{
+public:
+ typedef Menu_Base_Node super;
+ static Choice_Node prototype;
+public:
+ const char *type_name() override {return "Fl_Choice";}
+ const char *alt_type_name() override {return "fltk::Choice";}
+ Fl_Widget *widget(int X,int Y,int W,int H) override {
+ Fl_Choice *myo = new Fl_Choice(X,Y,W,H,"choice:");
+ myo->menu(dummymenu);
+ return myo;
+ }
+ Widget_Node *_make() override {return new Choice_Node();}
+ Type type() const override { return Type::Choice; }
+ bool is_a(Type inType) const override { return (inType==Type::Choice) ? true : super::is_a(inType); }
+};
+
+
+/**
+ \brief Manage Menubar widgets.
+ */
+class Menu_Bar_Node : public Menu_Base_Node
+{
+public:
+ typedef Menu_Base_Node super;
+ static Menu_Bar_Node prototype;
+private:
+ Fl_Menu_Item *subtypes() override {return menu_bar_type_menu;}
+public:
+ Menu_Bar_Node();
+ ~Menu_Bar_Node() override;
+ const char *type_name() override {return "Fl_Menu_Bar";}
+ const char *alt_type_name() override {return "fltk::MenuBar";}
+ Fl_Widget *widget(int X,int Y,int W,int H) override {return new Fl_Menu_Bar(X,Y,W,H);}
+ Widget_Node *_make() override {return new Menu_Bar_Node();}
+ void write_static(fld::io::Code_Writer& f) override;
+ void write_code1(fld::io::Code_Writer& f) override;
+// void write_code2(fld::io::Code_Writer& f) override;
+ Type type() const override { return Type::Menu_Bar; }
+ bool is_a(Type inType) const override { return (inType==Type::Menu_Bar) ? true : super::is_a(inType); }
+ bool is_sys_menu_bar();
+ const char *sys_menubar_name();
+ const char *sys_menubar_proxy_name();
+protected:
+ char *_proxy_name;
+};
+
+
+#endif // FLUID_NODES_MENU_NODE_H
diff --git a/fluid/nodes/Fl_Type.cxx b/fluid/nodes/Node.cxx
index 8f078e06e..194484a93 100644
--- a/fluid/nodes/Fl_Type.cxx
+++ b/fluid/nodes/Node.cxx
@@ -1,7 +1,7 @@
//
-// Widget type code for the Fast Light Tool Kit (FLTK).
+// Node base class code for the Fast Light Tool Kit (FLTK).
//
-// Copyright 1998-2023 by Bill Spitzak and others.
+// Copyright 1998-2025 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
@@ -17,7 +17,7 @@
/// \defgroup fl_type Basic Node for all Widgets and Functions
/// \{
-/** \class Fl_Type
+/** \class Node
Each object described by Fluid is one of these objects. They
are all stored in a double-linked list.
@@ -30,84 +30,84 @@
not in the linked list and are not written to files or
copied or otherwise examined.
- The Fl_Type inheritance is currently:
- --+-- Fl_Type
- +-- Fl_Function_Type
- +-- Fl_Code_Type
- +-- Fl_CodeBlock_Type
- +-+ Fl_Decl_Type
+ The Node inheritance is currently:
+ --+-- Node
+ +-- Function_Node
+ +-- Code_Node
+ +-- CodeBlock_Node
+ +-+ Decl_Node
| +-- Fl_Data
- +-- Fl_DeclBlock_Type
- +-- Fl_Comment_Type
- +-- Fl_Class_Type
- +-+ Fl_Widget_Type, 'o' points to a class derived from Fl_Widget
- +-+ Fl_Browser_Base_Type, 'o' is Fl_Browser
+ +-- DeclBlock_Node
+ +-- Comment_Node
+ +-- Class_Node
+ +-+ Widget_Node, 'o' points to a class derived from Fl_Widget
+ +-+ Browser_Base_Node, 'o' is Fl_Browser
| +-+ Fl_Browser
| | +-- Fl_File_Browser
| +-- Fl_Check_Browser
- +-- Fl_Tree_Type
- +-- Fl_Help_View_Type
- +-+ Fl_Valuator_Type, 'o' is Fl_Valuator_
- | +-- Fl_Counter_Type
- | +-- Fl_Adjuster_Type
- | +-- Fl_Dial_Type
- | +-- Fl_Roller_Type
- | +-- Fl_Slider_Type
- | +-- Fl_Value_Input_Type
- | +-- Fl_Value_Output_Type
- +-+ Fl_Input_Type
- | +-- Fl_Output_Type
- +-+ Fl_Text_Display_Type
- | +-- Fl_Text_Editor_Type
- +-- Fl_Terminal_Type
- +-- Fl_Box_Type
- +-- Fl_Clock_Type
- +-- Fl_Progress_Type
- +-- Fl_Spinner_Type
- +-+ Fl_Group_Type
- | +-- Fl_Pack_Type
- | +-- Fl_Flex_Type
- | +-- Fl_Grid_Type
- | +-- Fl_Table_Type
- | +-- Fl_Tabs_Type
- | +-- Fl_Scroll_Type
- | +-- Fl_Tile_Type
- | +-- Fl_Wizard_Type
- | +-+ Fl_Window_Type
- | +-- Fl_Widget_Class_Type
- +-+ Fl_Menu_Manager_Type, 'o' is based on Fl_Widget
- | +-+ Fl_Menu_Base_Type, 'o' is based on Fl_Menu_
- | | +-- Fl_Menu_Button_Type
- | | +-- Fl_Choice_Type
- | | +-- Fl_Menu_Bar_Type
- | +-- Fl_Input_Choice_Type, 'o' is based on Fl_Input_Choice which is Fl_Group
- +-+ Fl_Button_Type
- +-- Fl_Return_Button_Type
- +-- Fl_Repeat_Button_Type
- +-- Fl_Light_Button_Type
- +-- Fl_Check_Button_Type
- +-- Fl_Round_Button_Type
- +-+ Fl_Menu_Item_Type, 'o' is derived from Fl_Button in FLUID
- +-- Fl_Radio_Menu_Item_Type
- +-- Fl_Checkbox_Menu_Item_Type
+ +-- Tree_Node
+ +-- Help_View_Node
+ +-+ Valuator_Node, 'o' is Fl_Valuator_
+ | +-- Counter_Node
+ | +-- Adjuster_Node
+ | +-- Dial_Node
+ | +-- Roller_Node
+ | +-- Slider_Node
+ | +-- Value_Input_Node
+ | +-- Value_Output_Node
+ +-+ Input_Node
+ | +-- Output_Node
+ +-+ Text_Display_Node
+ | +-- Text_Editor_Node
+ +-- Terminal_Node
+ +-- Box_Node
+ +-- Clock_Node
+ +-- Progress_Node
+ +-- Spinner_Node
+ +-+ Group_Node
+ | +-- Pack_Node
+ | +-- Flex_Node
+ | +-- Grid_Node
+ | +-- Table_Node
+ | +-- Tabs_Node
+ | +-- Scroll_Node
+ | +-- Tile_Node
+ | +-- Wizard_Node
+ | +-+ Window_Node
+ | +-- Widget_Class_Node
+ +-+ Menu_Manager_Node, 'o' is based on Fl_Widget
+ | +-+ Menu_Base_Node, 'o' is based on Fl_Menu_
+ | | +-- Menu_Button_Node
+ | | +-- Choice_Node
+ | | +-- Menu_Bar_Node
+ | +-- Input_Choice_Node, 'o' is based on Fl_Input_Choice which is Fl_Group
+ +-+ Button_Node
+ +-- Return_Button_Node
+ +-- Repeat_Button_Node
+ +-- Light_Button_Node
+ +-- Check_Button_Node
+ +-- Round_Button_Node
+ +-+ Menu_Item_Node, 'o' is derived from Fl_Button in FLUID
+ +-- Radio_Menu_Item_Node
+ +-- Checkbox_Menu_Item_Node
+-- Fl_Submenu_Item_Type
*/
-#include "nodes/Fl_Type.h"
+#include "nodes/Node.h"
-#include "app/fluid.h"
-#include "app/project.h"
-#include "app/Fd_Snap_Action.h"
+#include "Fluid.h"
+#include "Project.h"
+#include "app/Snap_Action.h"
#include "app/shell_command.h"
-#include "app/undo.h"
+#include "proj/undo.h"
#include "io/Project_Reader.h"
#include "io/Project_Writer.h"
#include "io/Code_Writer.h"
-#include "nodes/Fl_Function_Type.h"
-#include "nodes/Fl_Widget_Type.h"
-#include "nodes/Fl_Window_Type.h"
-#include "nodes/Fl_Group_Type.h"
+#include "nodes/Function_Node.h"
+#include "nodes/Widget_Node.h"
+#include "nodes/Window_Node.h"
+#include "nodes/Group_Node.h"
#include "rsrcs/pixmaps.h"
#include "widgets/Node_Browser.h"
@@ -121,13 +121,7 @@
// ---- global variables
-Fl_Type *Fl_Type::first = NULL;
-Fl_Type *Fl_Type::last = NULL;
-Fl_Type *Fl_Type::current = NULL;
-Fl_Type *Fl_Type::current_dnd = NULL;
-int Fl_Type::allow_layout = 0;
-
-Fl_Type *in_this_only; // set if menu popped-up in window
+Node *in_this_only; // set if menu popped-up in window
// ---- various functions
@@ -138,8 +132,8 @@ Fl_Type *in_this_only; // set if menu popped-up in window
Print the current project tree to stderr.
*/
void print_project_tree() {
- fprintf(stderr, "---- %s --->\n", g_project.projectfile_name().c_str());
- for (Fl_Type *t = Fl_Type::first; t; t = t->next) {
+ fprintf(stderr, "---- %s --->\n", Fluid.proj.projectfile_name().c_str());
+ for (Node *t = Fluid.proj.tree.first; t; t = t->next) {
for (int i = t->level; i > 0; i--)
fprintf(stderr, ". ");
fprintf(stderr, "%s\n", subclassname(t));
@@ -157,20 +151,20 @@ void print_project_tree() {
*/
bool validate_project_tree() {
// Validate `first` and `last`
- if (Fl_Type::first == NULL) {
- if (Fl_Type::last == NULL) {
+ if (Fluid.proj.tree.first == nullptr) {
+ if (Fluid.proj.tree.last == nullptr) {
return true;
} else {
- fprintf(stderr, "ERROR: `first` is NULL, but `last` is not!\n");
+ fprintf(stderr, "ERROR: `first` is nullptr, but `last` is not!\n");
return false;
}
}
- if (Fl_Type::last == NULL) {
- fprintf(stderr, "ERROR: `last` is NULL, but `first` is not!\n");
+ if (Fluid.proj.tree.last == nullptr) {
+ fprintf(stderr, "ERROR: `last` is nullptr, but `first` is not!\n");
return false;
}
// Validate the branch linkage, parent links, etc.
- return validate_branch(Fl_Type::first);
+ return validate_branch(Fluid.proj.tree.first);
}
#endif
@@ -183,19 +177,19 @@ bool validate_project_tree() {
\param[in] root the first node in a branch
\return true if the branch is correctly separated and valid
*/
-bool validate_independent_branch(class Fl_Type *root) {
+bool validate_independent_branch(class Node *root) {
// Make sure that `first` and `last` do not point at any node in this branch
- if (Fl_Type::first) {
- for (Fl_Type *t = root; t; t = t->next) {
- if (Fl_Type::first == t) {
+ if (Fluid.proj.tree.first) {
+ for (Node *t = root; t; t = t->next) {
+ if (Fluid.proj.tree.first == t) {
fprintf(stderr, "ERROR: Branch is not independent, `first` is pointing to branch member!\n");
return false;
}
}
}
- if (Fl_Type::last) {
- for (Fl_Type *t = root; t; t = t->next) {
- if (Fl_Type::last == t) {
+ if (Fluid.proj.tree.last) {
+ for (Node *t = root; t; t = t->next) {
+ if (Fluid.proj.tree.last == t) {
fprintf(stderr, "ERROR: Branch is not independent, `last` is pointing to branch member!\n");
return false;
}
@@ -215,14 +209,14 @@ bool validate_independent_branch(class Fl_Type *root) {
\param[in] root the first node in a branch
\return true if the branch is valid
*/
-bool validate_branch(class Fl_Type *root) {
+bool validate_branch(class Node *root) {
// Only check real branches
if (!root) {
fprintf(stderr, "WARNING: Branch is empty!\n");
return false;
}
// Check relation between this and next node
- for (Fl_Type *t = root; t; t = t->next) {
+ for (Node *t = root; t; t = t->next) {
if (t->level < root->level) {
fprintf(stderr, "ERROR: Node in tree is above root level!\n");
return false;
@@ -247,10 +241,10 @@ bool validate_branch(class Fl_Type *root) {
}
}
// Validate the `parent` entry
- for (Fl_Type *p = t->prev; ; p = p->prev) {
- if (p == NULL) {
- if (t->parent != NULL) {
- fprintf(stderr, "ERROR: `parent` pointer should be NULL!\n");
+ for (Node *p = t->prev; ; p = p->prev) {
+ if (p == nullptr) {
+ if (t->parent != nullptr) {
+ fprintf(stderr, "ERROR: `parent` pointer should be nullptr!\n");
return false;
}
break;
@@ -270,22 +264,22 @@ bool validate_branch(class Fl_Type *root) {
#endif
void select_all_cb(Fl_Widget *,void *) {
- Fl_Type *p = Fl_Type::current ? Fl_Type::current->parent : 0;
+ Node *p = Fluid.proj.tree.current ? Fluid.proj.tree.current->parent : nullptr;
if (in_this_only) {
- Fl_Type *t = p;
+ 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;
- for (Fl_Type *t = p->next; t && t->level>p->level; t = t->next) {
+ for (Node *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)
+ for (Node *t = Fluid.proj.tree.first; t; t = t->next)
widget_browser->select(t,1,0);
break;
}
@@ -294,22 +288,22 @@ void select_all_cb(Fl_Widget *,void *) {
}
void select_none_cb(Fl_Widget *,void *) {
- Fl_Type *p = Fl_Type::current ? Fl_Type::current->parent : 0;
+ Node *p = Fluid.proj.tree.current ? Fluid.proj.tree.current->parent : nullptr;
if (in_this_only) {
- Fl_Type *t = p;
+ 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;
- for (Fl_Type *t = p->next; t && t->level>p->level; t = t->next) {
+ for (Node *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)
+ for (Node *t = Fluid.proj.tree.first; t; t = t->next)
widget_browser->select(t,0,0);
break;
}
@@ -321,15 +315,15 @@ void select_none_cb(Fl_Widget *,void *) {
Callback to move all selected items before their previous unselected sibling.
*/
void earlier_cb(Fl_Widget*,void*) {
- Fl_Type *f;
+ Node *f;
int mod = 0;
- for (f = Fl_Type::first; f; ) {
- Fl_Type* nxt = f->next;
+ for (f = Fluid.proj.tree.first; f; ) {
+ Node* nxt = f->next;
if (f->selected) {
- Fl_Type* g;
+ Node* g;
for (g = f->prev; g && g->level > f->level; g = g->prev) {/*empty*/}
if (g && g->level == f->level && !g->selected) {
- if (!mod) undo_checkpoint();
+ if (!mod) Fluid.proj.undo.checkpoint();
f->move_before(g);
if (f->parent) f->parent->layout_widget();
mod = 1;
@@ -337,8 +331,8 @@ void earlier_cb(Fl_Widget*,void*) {
}
f = nxt;
}
- if (mod) set_modflag(1);
- widget_browser->display(Fl_Type::current);
+ if (mod) Fluid.proj.set_modflag(1);
+ widget_browser->display(Fluid.proj.tree.current);
widget_browser->rebuild();
}
@@ -346,15 +340,15 @@ void earlier_cb(Fl_Widget*,void*) {
Callback to move all selected items after their next unselected sibling.
*/
void later_cb(Fl_Widget*,void*) {
- Fl_Type *f;
+ Node *f;
int mod = 0;
- for (f = Fl_Type::last; f; ) {
- Fl_Type* prv = f->prev;
+ for (f = Fluid.proj.tree.last; f; ) {
+ Node* prv = f->prev;
if (f->selected) {
- Fl_Type* g;
+ Node* g;
for (g = f->next; g && g->level > f->level; g = g->next) {/*empty*/}
if (g && g->level == f->level && !g->selected) {
- if (!mod) undo_checkpoint();
+ if (!mod) Fluid.proj.undo.checkpoint();
g->move_before(f);
if (f->parent) f->parent->layout_widget();
mod = 1;
@@ -362,21 +356,21 @@ void later_cb(Fl_Widget*,void*) {
}
f = prv;
}
- if (mod) set_modflag(1);
- widget_browser->display(Fl_Type::current);
+ if (mod) Fluid.proj.set_modflag(1);
+ widget_browser->display(Fluid.proj.tree.current);
widget_browser->rebuild();
}
/** \brief Delete all children of a Type.
*/
-static void delete_children(Fl_Type *p) {
- Fl_Type *f;
+static void delete_children(Node *p) {
+ Node *f;
// find all types following p that are higher in level, effectively finding
// the last child of the last child
for (f = p; f && f->next && f->next->level > p->level; f = f->next) {/*empty*/}
// now loop back up to p, deleting all children on the way
for (; f != p; ) {
- Fl_Type *g = f->prev;
+ Node *g = f->prev;
delete f;
f = g;
}
@@ -384,7 +378,7 @@ static void delete_children(Fl_Type *p) {
/** Delete all nodes in the Types tree and reset project settings, or delete selected nodes.
Also calls the browser to refresh.
- \note Please refactor this into two separate methods of Fluid_Project.
+ \note Please refactor this into two separate methods of Project.
\param[in] selected_only if set, delete only the selected widgets and
don't reset the project.
*/
@@ -394,10 +388,10 @@ void delete_all(int selected_only) {
widget_browser->save_scroll_position();
widget_browser->new_list();
}
- for (Fl_Type *f = Fl_Type::first; f;) {
+ for (Node *f = Fluid.proj.tree.first; f;) {
if (f->selected || !selected_only) {
delete_children(f);
- Fl_Type *g = f->next;
+ Node *g = f->next;
delete f;
f = g;
} else {
@@ -407,7 +401,7 @@ void delete_all(int selected_only) {
if(!selected_only) {
// reset the setting for the external shell command
if (g_shell_config) {
- g_shell_config->clear(FD_STORE_PROJECT);
+ g_shell_config->clear(fld::Tool_Store::PROJECT);
g_shell_config->rebuild_shell_menu();
g_shell_config->update_settings_dialog();
}
@@ -415,12 +409,12 @@ void delete_all(int selected_only) {
widget_browser->hposition(0);
widget_browser->vposition(0);
}
- g_layout_list.remove_all(FD_STORE_PROJECT);
- g_layout_list.current_suite(0);
- g_layout_list.current_preset(0);
- g_layout_list.update_dialogs();
+ Fluid.layout_list.remove_all(fld::Tool_Store::PROJECT);
+ Fluid.layout_list.current_suite(0);
+ Fluid.layout_list.current_preset(0);
+ Fluid.layout_list.update_dialogs();
}
- selection_changed(0);
+ selection_changed(nullptr);
if (widget_browser) {
if (selected_only)
widget_browser->restore_scroll_position();
@@ -431,41 +425,41 @@ void delete_all(int selected_only) {
/** Update a string.
Replace a string pointer with new value, strips leading/trailing blanks.
As a side effect, this call also sets the mod flags.
- \param[in] n new string, can be NULL
+ \param[in] n new string, can be nullptr
\param[out] p update this pointer, possibly reallocate memory
\param[in] nostrip if set, do not strip leading and trailing spaces and tabs
\return 1 if the string in p changed
*/
int storestring(const char *n, const char * & p, int nostrip) {
if (n == p) return 0;
- undo_checkpoint();
+ Fluid.proj.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 (!length) n = nullptr;
}
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;
+ p = nullptr;
} else {
char *q = (char *)malloc(length+1);
strlcpy(q,n,length+1);
p = q;
}
- set_modflag(1);
+ Fluid.proj.set_modflag(1);
return 1;
}
/** Update the `visible` flag for `p` and all its descendants.
\param[in] p start here and update all descendants
*/
-void update_visibility_flag(Fl_Type *p) {
- Fl_Type *t = p;
+void update_visibility_flag(Node *p) {
+ Node *t = p;
for (;;) {
if (t->parent) t->visible = t->parent->visible && !t->parent->folded_;
else t->visible = 1;
@@ -474,49 +468,49 @@ void update_visibility_flag(Fl_Type *p) {
}
}
-// ---- implementation of Fl_Type
+// ---- implementation of Node
-/** \var Fl_Type *Fl_Type::parent
+/** \var Node *Node::parent
Link to the parent node in the tree structure.
Used for simulating a tree structure via a doubly linked list.
*/
-/** \var Fl_Type *Fl_Type::level
+/** \var Node *Node::level
Zero based depth of the node within the tree structure.
Level is used to emulate a tree structure: the first node with a lower
level in the prev list would be the parent of this node. If the next member
has a higher level value, it is this nodes first child. At the same level,
it would be the first sibling.
*/
-/** \var Fl_Type *Fl_Type::next
+/** \var Node *Node::next
Points to the next node in the doubly linked list.
- If this is NULL, we are at the end of the list.
+ If this is nullptr, we are at the end of the list.
Used for simulating a tree structure via a doubly linked list.
*/
-/** \var Fl_Type *Fl_Type::prev
+/** \var Node *Node::prev
Link to the next node in the tree structure.
- If this is NULL, we are at the beginning of the list.
+ If this is nullptr, we are at the beginning of the list.
Used for simulating a tree structure via a doubly linked list.
*/
/**
Constructor and base for any node in the widget tree.
*/
-Fl_Type::Fl_Type() :
- name_(NULL),
- label_(NULL),
- callback_(NULL),
- user_data_(NULL),
- user_data_type_(NULL),
- comment_(NULL),
+Node::Node() :
+ name_(nullptr),
+ label_(nullptr),
+ callback_(nullptr),
+ user_data_(nullptr),
+ user_data_type_(nullptr),
+ comment_(nullptr),
uid_(0),
- parent(NULL),
+ parent(nullptr),
new_selected(0),
selected(0),
folded_(0),
visible(0),
level(0),
- next(NULL), prev(NULL),
- factory(NULL),
+ next(nullptr), prev(nullptr),
+ factory(nullptr),
code_static_start(-1), code_static_end(-1),
code1_start(-1), code1_end(-1),
code2_start(-1), code2_end(-1),
@@ -536,13 +530,13 @@ Fl_Type::Fl_Type() :
because the node does not know if it is part of the widget tree, or if it is
in a separate tree. We try to take care of that as well as possible.
*/
-Fl_Type::~Fl_Type() {
+Node::~Node() {
// warning: destructor only works for widgets that have been add()ed.
if (prev) prev->next = next; // else first = next; // don't do that! The Type may not be part of the main list
if (next) next->prev = prev; // else last = prev;
- if (Fl_Type::last == this) Fl_Type::last = prev;
- if (Fl_Type::first == this) Fl_Type::first = next;
- if (current == this) current = NULL;
+ if (Fluid.proj.tree.last == this) Fluid.proj.tree.last = prev;
+ if (Fluid.proj.tree.first == this) Fluid.proj.tree.first = next;
+ if (Fluid.proj.tree.current == this) Fluid.proj.tree.current = nullptr;
if (parent) parent->remove_child(this);
if (name_) free((void*)name_);
if (label_) free((void*)label_);
@@ -552,34 +546,34 @@ Fl_Type::~Fl_Type() {
if (comment_) free((void*)comment_);
}
-// Return the previous sibling in the tree structure or NULL.
-Fl_Type *Fl_Type::prev_sibling() {
- Fl_Type *n;
+// Return the previous sibling in the tree structure or nullptr.
+Node *Node::prev_sibling() {
+ Node *n;
for (n = prev; n && n->level > level; n = n->prev) ;
if (n && (n->level == level))
return n;
- return 0;
+ return nullptr;
}
-// Return the next sibling in the tree structure or NULL.
-Fl_Type *Fl_Type::next_sibling() {
- Fl_Type *n;
+// Return the next sibling in the tree structure or nullptr.
+Node *Node::next_sibling() {
+ Node *n;
for (n = next; n && n->level > level; n = n->next) ;
if (n && (n->level == level))
return n;
- return 0;
+ return nullptr;
}
-// Return the first child or NULL
-Fl_Type *Fl_Type::first_child() {
- Fl_Type *n = next;
+// Return the first child or nullptr
+Node *Node::first_child() {
+ Node *n = next;
if (n->level > level)
return n;
- return NULL;
+ return nullptr;
}
// Generate a descriptive text for this item, to put in browser & window titles
-const char* Fl_Type::title() {
+const char* Node::title() {
const char* c = name();
if (c)
return c;
@@ -588,42 +582,42 @@ const char* Fl_Type::title() {
/**
Return the window that contains this widget.
- \return NULL if this is not a widget.
+ \return nullptr if this is not a widget.
*/
-Fl_Window_Type *Fl_Type::window() {
+Window_Node *Node::window() {
if (!is_widget())
- return NULL;
- for (Fl_Type *t = this; t; t=t->parent)
- if (t->is_a(ID_Window))
- return (Fl_Window_Type*)t;
- return NULL;
+ return nullptr;
+ for (Node *t = this; t; t=t->parent)
+ if (t->is_a(Type::Window))
+ return (Window_Node*)t;
+ return nullptr;
}
/**
Return the group that contains this widget.
- \return NULL if this is not a widget.
+ \return nullptr if this is not a widget.
*/
-Fl_Group_Type *Fl_Type::group() {
+Group_Node *Node::group() {
if (!is_widget())
- return NULL;
- for (Fl_Type *t = this; t; t=t->parent)
- if (t->is_a(ID_Group))
- return (Fl_Group_Type*)t;
- return NULL;
+ return nullptr;
+ for (Node *t = this; t; t=t->parent)
+ if (t->is_a(Type::Group))
+ return (Group_Node*)t;
+ return nullptr;
}
/**
Add this list/tree of widgets as a new last child of p.
\c this must not be part of the widget browser. \c p however must be in the
- widget_browser, so \c Fl_Type::first and \c Fl_Type::last are valid for \c p.
+ widget_browser, so \c Fluid.proj.tree.first and \c Fluid.proj.tree.last are valid for \c p.
This methods updates the widget_browser.
\param[in] p insert \c this tree as a child of \c p
\param[in] strategy is Strategy::AS_LAST_CHILD or Strategy::AFTER_CURRENT
*/
-void Fl_Type::add(Fl_Type *anchor, Strategy strategy) {
+void Node::add(Node *anchor, Strategy strategy) {
#if 0
#ifndef NDEBUG
// print_project_tree();
@@ -634,16 +628,16 @@ void Fl_Type::add(Fl_Type *anchor, Strategy strategy) {
#endif
#endif
- Fl_Type *target = NULL; // insert self before target node, if NULL, insert last
- Fl_Type *target_parent = NULL; // this will be the new parent for branch
+ Node *target = nullptr; // insert self before target node, if nullptr, insert last
+ Node *target_parent = nullptr; // this will be the new parent for branch
int target_level = 0; // adjust self to this new level
// Find the node after our insertion position
switch (strategy.placement()) {
case Strategy::AS_FIRST_CHILD:
default:
- if (anchor == NULL) {
- target = Fl_Type::first;
+ if (anchor == nullptr) {
+ target = Fluid.proj.tree.first;
} else {
target = anchor->next;
target_level = anchor->level + 1;
@@ -651,7 +645,7 @@ void Fl_Type::add(Fl_Type *anchor, Strategy strategy) {
}
break;
case Strategy::AS_LAST_CHILD:
- if (anchor == NULL) {
+ if (anchor == nullptr) {
/* empty */
} else {
for (target = anchor->next; target && target->level > anchor->level; target = target->next) {/*empty*/}
@@ -660,8 +654,8 @@ void Fl_Type::add(Fl_Type *anchor, Strategy strategy) {
}
break;
case Strategy::AFTER_CURRENT:
- if (anchor == NULL) {
- target = Fl_Type::first;
+ if (anchor == nullptr) {
+ target = Fluid.proj.tree.first;
} else {
for (target = anchor->next; target && target->level > anchor->level; target = target->next) {/*empty*/}
target_level = anchor->level;
@@ -672,54 +666,54 @@ void Fl_Type::add(Fl_Type *anchor, Strategy strategy) {
// Find the last node of our tree
- Fl_Type *end = this;
+ Node *end = this;
while (end->next) end = end->next;
// Everything is prepared, now insert ourself in front of the target node
- undo_checkpoint();
+ Fluid.proj.undo.checkpoint();
// Walk the tree to update parent pointers and levels
int source_level = level;
- for (Fl_Type *t = this; t; t = t->next) {
+ for (Node *t = this; t; t = t->next) {
t->level += (target_level-source_level);
if (t->level == target_level)
t->parent = target_parent;
}
- // Now link ourselves and our children before 'target', or last, if 'target' is NULL
+ // Now link ourselves and our children before 'target', or last, if 'target' is nullptr
if (target) {
prev = target->prev;
target->prev = end;
end->next = target;
} else {
- prev = Fl_Type::last;
- end->next = NULL;
- Fl_Type::last = end;
+ prev = Fluid.proj.tree.last;
+ end->next = nullptr;
+ Fluid.proj.tree.last = end;
}
if (prev) {
prev->next = this;
} else {
- Fl_Type::first = this;
+ Fluid.proj.tree.first = this;
}
#if 0
{ // make sure that we have no duplicate uid's
- Fl_Type *tp = this;
+ Node *tp = this;
do {
tp->set_uid(tp->uid_);
tp = tp->next;
- } while (tp!=end && tp!=NULL);
+ } while (tp!=end && tp!=nullptr);
}
#endif
// Give the widgets in our tree a chance to update themselves
- for (Fl_Type *t = this; t && t!=end->next; t = t->next) {
+ for (Node *t = this; t && t!=end->next; t = t->next) {
if (target_parent && (t->level == target_level))
- target_parent->add_child(t, 0);
+ target_parent->add_child(t, nullptr);
update_visibility_flag(t);
}
- set_modflag(1);
+ Fluid.proj.set_modflag(1);
widget_browser->redraw();
#if 0
@@ -734,35 +728,35 @@ void Fl_Type::add(Fl_Type *anchor, Strategy strategy) {
Add `this` list/tree of widgets as a new sibling before `g`.
`This` is not part of the widget browser. `g` must be in the
- widget_browser, so `Fl_Type::first` and `Fl_Type::last` are valid for `g .
+ widget_browser, so `Fluid.proj.tree.first` and `Fluid.proj.tree.last` are valid for `g .
This methods updates the widget_browser.
\param[in] g pointer to a node within the tree
*/
-void Fl_Type::insert(Fl_Type *g) {
+void Node::insert(Node *g) {
// 'this' is not in the Node_Browser, so we must run the linked list to find the last entry
- Fl_Type *end = this;
+ Node *end = this;
while (end->next) end = end->next;
// 'this' will get the same parent as 'g'
parent = g->parent;
// run the list again to set the future node levels
int newlevel = g->level;
visible = g->visible;
- for (Fl_Type *t = this->next; t; t = t->next) t->level += newlevel-level;
+ for (Node *t = this->next; t; t = t->next) t->level += newlevel-level;
level = newlevel;
// insert this in the list before g
prev = g->prev;
- if (prev) prev->next = this; else first = this;
+ if (prev) prev->next = this; else Fluid.proj.tree.first = this;
end->next = g;
g->prev = end;
update_visibility_flag(this);
{ // make sure that we have no duplicate uid's
- Fl_Type *tp = this;
+ Node *tp = this;
do {
tp->set_uid(tp->uid_);
tp = tp->next;
- } while (tp!=end && tp!=NULL);
+ } while (tp!=end && tp!=nullptr);
}
// tell parent that it has a new child, so it can update itself
if (parent) parent->add_child(this, g);
@@ -770,13 +764,13 @@ void Fl_Type::insert(Fl_Type *g) {
}
// Return message number for I18N...
-int Fl_Type::msgnum() {
+int Node::msgnum() {
int count;
- Fl_Type *p;
+ Node *p;
for (count = 0, p = this; p;) {
if (p->label()) count ++;
- if (p != this && p->is_widget() && ((Fl_Widget_Type *)p)->tooltip()) count ++;
+ if (p != this && p->is_widget() && ((Widget_Node *)p)->tooltip()) count ++;
if (p->prev) p = p->prev;
else p = p->parent;
@@ -789,14 +783,14 @@ int Fl_Type::msgnum() {
Remove this node and all its children from the parent node.
This does not delete anything. The resulting list//tree will no longer be in
- the widget_browser, so \c Fl_Type::first and \c Fl_Type::last do not apply
+ the widget_browser, so \c Fluid.proj.tree.first and \c Fluid.proj.tree.last do not apply
to it.
- \return the node that follows this node after the operation; can be NULL
+ \return the node that follows this node after the operation; can be nullptr
*/
-Fl_Type *Fl_Type::remove() {
+Node *Node::remove() {
// find the last child of this node
- Fl_Type *end = this;
+ Node *end = this;
for (;;) {
if (!end->next || end->next->level <= level)
break;
@@ -806,56 +800,56 @@ Fl_Type *Fl_Type::remove() {
if (prev)
prev->next = end->next;
else
- first = end->next;
+ Fluid.proj.tree.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;
+ Fluid.proj.tree.last = prev;
+ Node *r = end->next;
+ prev = end->next = nullptr;
// allow the parent to update changes in the UI
if (parent) parent->remove_child(this);
- parent = 0;
+ parent = nullptr;
// tell the widget_browser that we removed some nodes
widget_browser->redraw();
- selection_changed(0);
+ selection_changed(nullptr);
return r;
}
-void Fl_Type::name(const char *n) {
- int nostrip = is_a(ID_Comment);
+void Node::name(const char *n) {
+ int nostrip = is_a(Type::Comment);
if (storestring(n,name_,nostrip)) {
if (visible) widget_browser->redraw();
}
}
-void Fl_Type::label(const char *n) {
+void Node::label(const char *n) {
if (storestring(n,label_,1)) {
setlabel(label_);
if (visible && !name_) widget_browser->redraw();
}
}
-void Fl_Type::callback(const char *n) {
+void Node::callback(const char *n) {
storestring(n,callback_);
}
-void Fl_Type::user_data(const char *n) {
+void Node::user_data(const char *n) {
storestring(n,user_data_);
}
-void Fl_Type::user_data_type(const char *n) {
+void Node::user_data_type(const char *n) {
storestring(n,user_data_type_);
}
-void Fl_Type::comment(const char *n) {
+void Node::comment(const char *n) {
if (storestring(n,comment_,1)) {
if (visible) widget_browser->redraw();
}
}
-void Fl_Type::open() {
+void Node::open() {
printf("Open of '%s' is not yet implemented\n",type_name());
}
@@ -867,20 +861,20 @@ void Fl_Type::open() {
The caller must make sure that the widget browser is rebuilt correctly.
\param[in] g move \c this tree before \c g
*/
-void Fl_Type::move_before(Fl_Type* g) {
+void Node::move_before(Node* g) {
if (level != g->level) printf("move_before levels don't match! %d %d\n",
level, g->level);
// Find the last child in the list
- Fl_Type *n;
+ Node *n;
for (n = next; n && n->level > level; n = n->next) ;
if (n == g) return;
// now link this tree before g
- Fl_Type *l = n ? n->prev : Fl_Type::last;
+ Node *l = n ? n->prev : Fluid.proj.tree.last;
prev->next = n;
- if (n) n->prev = prev; else Fl_Type::last = prev;
+ if (n) n->prev = prev; else Fluid.proj.tree.last = prev;
prev = g->prev;
l->next = g;
- if (prev) prev->next = this; else Fl_Type::first = this;
+ if (prev) prev->next = this; else Fluid.proj.tree.first = this;
g->prev = l;
// tell parent that it has a new child, so it can update itself
if (parent && is_widget()) parent->move_child(this,g);
@@ -888,14 +882,14 @@ void Fl_Type::move_before(Fl_Type* g) {
// write a widget and all its children:
-void Fl_Type::write(fld::io::Project_Writer &f) {
+void Node::write(fld::io::Project_Writer &f) {
if (f.write_codeview()) proj1_start = (int)ftell(f.file()) + 1;
if (f.write_codeview()) proj2_start = (int)ftell(f.file()) + 1;
f.write_indent(level);
f.write_word(type_name());
if (is_class()) {
- const char * p = ((Fl_Class_Type*)this)->prefix();
+ const char * p = ((Class_Node*)this)->prefix();
if (p && strlen(p))
f.write_word(p);
}
@@ -912,7 +906,7 @@ void Fl_Type::write(fld::io::Project_Writer &f) {
}
// now do children:
f.write_open();
- Fl_Type *child;
+ Node *child;
for (child = next; child && child->level > level; child = child->next)
if (child->level == level+1) child->write(f);
if (f.write_codeview()) proj2_start = (int)ftell(f.file()) + 1;
@@ -920,9 +914,9 @@ void Fl_Type::write(fld::io::Project_Writer &f) {
if (f.write_codeview()) proj2_end = (int)ftell(f.file());
}
-void Fl_Type::write_properties(fld::io::Project_Writer &f) {
+void Node::write_properties(fld::io::Project_Writer &f) {
// repeat this for each attribute:
- if (g_project.write_mergeback_data && uid_) {
+ if (Fluid.proj.write_mergeback_data && uid_) {
f.write_word("uid");
f.write_string("%04x", uid_);
}
@@ -954,7 +948,7 @@ void Fl_Type::write_properties(fld::io::Project_Writer &f) {
if (selected) f.write_word("selected");
}
-void Fl_Type::read_property(fld::io::Project_Reader &f, const char *c) {
+void Node::read_property(fld::io::Project_Reader &f, const char *c) {
if (!strcmp(c,"uid")) {
const char *hex = f.read_word();
int x = 0;
@@ -1019,13 +1013,13 @@ void Fl_Type::read_property(fld::io::Project_Reader &f, const char *c) {
Lastly, this method should call the super class to give it a chance to append
its own properties.
- \see Fl_Grid_Type::write_parent_properties(fld::io::Project_Writer &f, Fl_Type *child, bool encapsulate)
+ \see Grid_Node::write_parent_properties(fld::io::Project_Writer &f, Node *child, bool encapsulate)
\param[in] f the project file writer
\param[in] child write properties for this child, make sure it has the correct type
\param[in] encapsulate write the `parent_properties {}` block if true before writing any properties
*/
-void Fl_Type::write_parent_properties(fld::io::Project_Writer &f, Fl_Type *child, bool encapsulate) {
+void Node::write_parent_properties(fld::io::Project_Writer &f, Node *child, bool encapsulate) {
(void)f; (void)child; (void)encapsulate;
// nothing to do here
// put the following code into your implementation of write_parent_properties
@@ -1052,26 +1046,26 @@ void Fl_Type::write_parent_properties(fld::io::Project_Writer &f, Fl_Type *child
method reads back those properties. This function is virtual, so if a Type
does not support a property, it will propagate to its super class.
- \see Fl_Type::write_parent_properties(fld::io::Project_Writer &f, Fl_Type *child, bool encapsulate)
- \see Fl_Grid_Type::read_parent_property(fld::io::Project_Reader &f, Fl_Type *child, const char *property)
+ \see Node::write_parent_properties(fld::io::Project_Writer &f, Node *child, bool encapsulate)
+ \see Grid_Node::read_parent_property(fld::io::Project_Reader &f, Node *child, const char *property)
\param[in] f the project file writer
\param[in] child read properties for this child
\param[in] property the name of a property, or "}" when we reach the end of the list
*/
-void Fl_Type::read_parent_property(fld::io::Project_Reader &f, Fl_Type *child, const char *property) {
+void Node::read_parent_property(fld::io::Project_Reader &f, Node *child, const char *property) {
(void)child;
f.read_error("Unknown parent property \"%s\"", property);
}
-int Fl_Type::read_fdesign(const char*, const char*) {return 0;}
+int Node::read_fdesign(const char*, const char*) {return 0;}
/**
Write a comment into the header file.
\param[in] pre indent the comment by this string
*/
-void Fl_Type::write_comment_h(fld::io::Code_Writer& f, const char *pre)
+void Node::write_comment_h(fld::io::Code_Writer& f, const char *pre)
{
if (comment() && *comment()) {
f.write_h("%s/**\n", pre);
@@ -1094,7 +1088,7 @@ void Fl_Type::write_comment_h(fld::io::Code_Writer& f, const char *pre)
/**
Write a comment into the source file.
*/
-void Fl_Type::write_comment_c(fld::io::Code_Writer& f, const char *pre)
+void Node::write_comment_c(fld::io::Code_Writer& f, const char *pre)
{
if (comment() && *comment()) {
f.write_c("%s/**\n", pre);
@@ -1119,11 +1113,11 @@ void Fl_Type::write_comment_c(fld::io::Code_Writer& f, const char *pre)
/**
Write a comment into the source file.
*/
-void Fl_Type::write_comment_inline_c(fld::io::Code_Writer& f, const char *pre)
+void Node::write_comment_inline_c(fld::io::Code_Writer& f, const char *pre)
{
if (comment() && *comment()) {
const char *s = comment();
- if (strchr(s, '\n')==0L) {
+ if (strchr(s, '\n')==nullptr) {
// single line comment
if (pre) f.write_c("%s", pre);
f.write_c("// %s\n", s);
@@ -1165,21 +1159,21 @@ void Fl_Type::write_comment_inline_c(fld::io::Code_Writer& f, const char *pre)
\return a widget pointer that the live mode initiator can 'show()'
\see leave_live_mode()
*/
-Fl_Widget *Fl_Type::enter_live_mode(int) {
- return 0L;
+Fl_Widget *Node::enter_live_mode(int) {
+ return nullptr;
}
/**
Release all resources created when entering live mode.
\see enter_live_mode()
*/
-void Fl_Type::leave_live_mode() {
+void Node::leave_live_mode() {
}
/**
Copy all needed properties for this type into the live object.
*/
-void Fl_Type::copy_properties() {
+void Node::copy_properties() {
}
/**
@@ -1190,16 +1184,16 @@ void Fl_Type::copy_properties() {
plain function or a member function within the same class and that
the parameter types match.
*/
-int Fl_Type::user_defined(const char* cbname) const {
- for (Fl_Type* p = Fl_Type::first; p ; p = p->next)
- if (p->is_a(ID_Function) && p->name() != 0)
+int Node::user_defined(const char* cbname) const {
+ for (Node* p = Fluid.proj.tree.first; p ; p = p->next)
+ if (p->is_a(Type::Function) && p->name() != nullptr)
if (strncmp(p->name(), cbname, strlen(cbname)) == 0)
if (p->name()[strlen(cbname)] == '(')
return 1;
return 0;
}
-const char *Fl_Type::callback_name(fld::io::Code_Writer& f) {
+const char *Node::callback_name(fld::io::Code_Writer& f) {
if (is_name(callback())) return callback();
return f.unique_id(this, "cb", name(), label());
}
@@ -1215,15 +1209,15 @@ const char *Fl_Type::callback_name(fld::io::Code_Writer& f) {
\param need_nest if clear, search up one level to the first enclosing class.
If set, recurse all the way up to the top node.
\return the name of the enclosing class, or names of the enclosing classes
- in a static buffe (don't call free), or NULL if this Type is not inside a class
+ in a static buffe (don't call free), or nullptr if this Type is not inside a class
*/
-const char* Fl_Type::class_name(const int need_nest) const {
- Fl_Type* p = parent;
+const char* Node::class_name(const int need_nest) const {
+ Node* 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;
+ const char* q = nullptr;
if(need_nest) q=p->class_name(need_nest);
if (q) {
static char s[256];
@@ -1236,15 +1230,15 @@ const char* Fl_Type::class_name(const int need_nest) const {
}
p = p->parent;
}
- return 0;
+ return nullptr;
}
/**
- 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
+ Check if this is inside a Class_Node or Widget_Class_Node.
+ \return true if any of the parents is Class_Node or Widget_Class_Node
*/
-bool Fl_Type::is_in_class() const {
- Fl_Type* p = parent;
+bool Node::is_in_class() const {
+ Node* p = parent;
while (p) {
if (p->is_class()) return true;
p = p->parent;
@@ -1252,18 +1246,18 @@ bool Fl_Type::is_in_class() const {
return false;
}
-void Fl_Type::write_static(fld::io::Code_Writer&) {
+void Node::write_static(fld::io::Code_Writer&) {
}
-void Fl_Type::write_static_after(fld::io::Code_Writer&) {
+void Node::write_static_after(fld::io::Code_Writer&) {
}
-void Fl_Type::write_code1(fld::io::Code_Writer& f) {
+void Node::write_code1(fld::io::Code_Writer& f) {
f.write_h("// Header for %s\n", title());
f.write_c("// Code for %s\n", title());
}
-void Fl_Type::write_code2(fld::io::Code_Writer&) {
+void Node::write_code2(fld::io::Code_Writer&) {
}
/** Set a uid that is unique within the project.
@@ -1275,15 +1269,15 @@ void Fl_Type::write_code2(fld::io::Code_Writer&) {
\param[in] suggested_uid the preferred uid for this node
\return the actualt uid that was given to the node
*/
-unsigned short Fl_Type::set_uid(unsigned short suggested_uid) {
+unsigned short Node::set_uid(unsigned short suggested_uid) {
if (suggested_uid==0)
suggested_uid = (unsigned short)rand();
for (;;) {
- Fl_Type *tp = Fl_Type::first;
+ Node *tp = Fluid.proj.tree.first;
for ( ; tp; tp = tp->next)
if (tp!=this && tp->uid_==suggested_uid)
break;
- if (tp==NULL)
+ if (tp==nullptr)
break;
suggested_uid = (unsigned short)rand();
}
@@ -1291,48 +1285,6 @@ unsigned short Fl_Type::set_uid(unsigned short suggested_uid) {
return suggested_uid;
}
-/** Find a node by its unique id.
-
- Every node in a type tree has an id that is unique for the current project.
- Walk the tree and return the node with this uid.
-
- \param[in] uid any number between 0 and 65535
- \return the node with this uid, or NULL if not found
- */
-Fl_Type *Fl_Type::find_by_uid(unsigned short uid) {
- for (Fl_Type *tp = Fl_Type::first; tp; tp = tp->next) {
- if (tp->uid_ == uid) return tp;
- }
- return NULL;
-}
-
-/** Find a type node by using the codeview text positions.
-
- \param[in] text_type 0=source file, 1=header, 2=.fl project file
- \param[in] crsr cursor position in text
- \return the node we found or NULL
- */
-Fl_Type *Fl_Type::find_in_text(int text_type, int crsr) {
- for (Fl_Type *node = first; node; node = node->next) {
- 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;
- 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;
- break;
- case 2:
- if (crsr >= node->proj1_start && crsr < node->proj1_end) return node;
- if (crsr >= node->proj2_start && crsr < node->proj2_end) return node;
- break;
- }
- }
- return 0;
-}
/// \}
diff --git a/fluid/nodes/Fl_Type.h b/fluid/nodes/Node.h
index e7dde3b39..5c473a936 100644
--- a/fluid/nodes/Fl_Type.h
+++ b/fluid/nodes/Node.h
@@ -1,5 +1,5 @@
//
-// Widget type header file for the Fast Light Tool Kit (FLTK).
+// Node base class header file for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-2025 by Bill Spitzak and others.
//
@@ -14,17 +14,17 @@
// https://www.fltk.org/bugs.php
//
-#ifndef _FLUID_FL_TYPE_H
-#define _FLUID_FL_TYPE_H
+#ifndef FLUID_NODES_NODE_H
+#define FLUID_NODES_NODE_H
#include "io/Code_Writer.h"
#include <FL/Fl_Widget.H>
#include <FL/fl_draw.H>
-class Fl_Type;
-class Fl_Group_Type;
-class Fl_Window_Type;
+class Node;
+class Group_Node;
+class Window_Node;
namespace fld {
namespace io {
@@ -45,15 +45,15 @@ class Project_Writer;
labels. Type created FROM_FILE will start with no label, so the label is set
correctly later.
- \see Fl_Type *Fl_..._Type::make(Strategy strategy) calls `add()`
+ \see Node *Fl_..._Type::make(Strategy strategy) calls `add()`
Add single Type:
- Fl_Type *add_new_widget_from_user(Fl_Type *inPrototype, Strategy strategy, bool and_open)
- Fl_Type *add_new_widget_from_user(const char *inName, Strategy strategy, bool and_open)
- Fl_Type *add_new_widget_from_file(const char *inName, Strategy strategy)
+ Node *add_new_widget_from_user(Node *inPrototype, Strategy strategy, bool and_open)
+ Node *add_new_widget_from_user(const char *inName, Strategy strategy, bool and_open)
+ Node *add_new_widget_from_file(const char *inName, Strategy strategy)
Add a hierarchy of Types
- void Fl_Type::add(Fl_Type *p, Strategy strategy)
+ void Node::add(Node *p, Strategy strategy)
int read_file(const char *filename, int merge, Strategy strategy)
- Fl_Type *fld::io::Project_Reader::read_children(Fl_Type *p, int merge, Strategy strategy, char skip_options)
+ Node *fld::io::Project_Reader::read_children(Node *p, int merge, Strategy strategy, char skip_options)
int fld::io::Project_Reader::read_project(const char *filename, int merge, Strategy strategy)
*/
typedef struct Strategy {
@@ -77,40 +77,40 @@ typedef struct Strategy {
Flags source() { return (Flags)(flags & SOURCE_MASK); }
} Strategy;
-enum ID {
+enum class Type {
// administrative
- ID_Base_, ID_Widget_, ID_Menu_Manager_, ID_Menu_, ID_Browser_, ID_Valuator_,
+ Base_, Widget_, Menu_Manager_, Menu_, Browser_, Valuator_,
// non-widget
- ID_Function, ID_Code, ID_CodeBlock,
- ID_Decl, ID_DeclBlock, ID_Class,
- ID_Widget_Class, ID_Comment, ID_Data,
+ Function, Code, CodeBlock,
+ Decl, DeclBlock, Class,
+ Widget_Class, Comment, Data,
// groups
- ID_Window, ID_Group, ID_Pack,
- ID_Flex, ID_Tabs, ID_Scroll,
- ID_Tile, ID_Wizard, ID_Grid,
+ Window, Group, Pack,
+ Flex, Tabs, Scroll,
+ Tile, Wizard, Grid,
// buttons
- ID_Button, ID_Return_Button, ID_Light_Button,
- ID_Check_Button, ID_Repeat_Button, ID_Round_Button,
+ Button, Return_Button, Light_Button,
+ Check_Button, Repeat_Button, Round_Button,
// valuators
- ID_Slider, ID_Scrollbar, ID_Value_Slider,
- ID_Adjuster, ID_Counter, ID_Spinner,
- ID_Dial, ID_Roller, ID_Value_Input, ID_Value_Output,
+ Slider, Scrollbar, Value_Slider,
+ Adjuster, Counter, Spinner,
+ Dial, Roller, Value_Input, Value_Output,
// text
- ID_Input, ID_Output, ID_Text_Editor,
- ID_Text_Display, ID_File_Input, ID_Terminal,
+ Input, Output, Text_Editor,
+ Text_Display, File_Input, Terminal,
// menus
- ID_Menu_Bar, ID_Menu_Button, ID_Choice,
- ID_Input_Choice, ID_Submenu, ID_Menu_Item,
- ID_Checkbox_Menu_Item, ID_Radio_Menu_Item,
+ Menu_Bar, Menu_Button, Choice,
+ Input_Choice, Submenu, Menu_Item,
+ Checkbox_Menu_Item, Radio_Menu_Item,
// browsers
- ID_Browser, ID_Check_Browser, ID_File_Browser,
- ID_Tree, ID_Help_View, ID_Table,
+ Browser, Check_Browser, File_Browser,
+ Tree, Help_View, Table,
// misc
- ID_Box, ID_Clock, ID_Progress,
- ID_Max_
+ Box, Clock, Progress,
+ Max_
};
-void update_visibility_flag(Fl_Type *p);
+void update_visibility_flag(Node *p);
void delete_all(int selected_only=0);
int storestring(const char *n, const char * & p, int nostrip=0);
@@ -122,8 +122,8 @@ void later_cb(Fl_Widget*,void*);
#ifndef NDEBUG
void print_project_tree();
bool validate_project_tree();
-bool validate_independent_branch(class Fl_Type *root);
-bool validate_branch(class Fl_Type *root);
+bool validate_independent_branch(class Node *root);
+bool validate_branch(class Node *root);
#endif
/**
@@ -134,8 +134,8 @@ bool validate_branch(class Fl_Type *root);
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
+ Types can be identified using the builtin Type system that works like RTTI. The
+ method `type()` returns the exact type, and the method `is_a(Type)` returns true
if this is the exact type or derived from the type, and a dynamic cast will
work reliably.
@@ -149,20 +149,20 @@ bool validate_branch(class Fl_Type *root);
\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 {
+class Node {
/** 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();
+ Node();
/** 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. */
+ it is the full callback C++ code. Can be nullptr. */
const char *callback_;
/** Widget user data field as C++ text. */
const char *user_data_;
@@ -175,9 +175,9 @@ protected:
unsigned short uid_;
public: // things that should not be public:
-
+ // TODO: reference back to the tree
/** Quick link to the parent Type instead of walking up the linked list. */
- Fl_Type *parent;
+ Node *parent;
/** This type is rendered "selected" in the tree browser. */
char new_selected; // browser highlight
/** Backup storage for selection if an error occurred during some operation
@@ -187,13 +187,12 @@ public: // things that should not be public:
char folded_; // if set, children are not shown in browser
char visible; // true if all parents are open
int level; // number of parents over this
- static Fl_Type *first, *last;
- Fl_Type *next, *prev;
- Fl_Type *prev_sibling();
- Fl_Type *next_sibling();
- Fl_Type *first_child();
+ Node *next, *prev;
+ Node *prev_sibling();
+ Node *next_sibling();
+ Node *first_child();
- Fl_Type *factory;
+ Node *factory;
const char *callback_name(fld::io::Code_Writer& f);
// text positions of this type in code, header, and project file (see codeview)
@@ -211,16 +210,16 @@ protected:
public:
- virtual ~Fl_Type();
- virtual Fl_Type *make(Strategy strategy) = 0;
+ virtual ~Node();
+ virtual Node *make(Strategy strategy) = 0;
- Fl_Window_Type *window();
- Fl_Group_Type *group();
+ Window_Node *window();
+ Group_Node *group();
- void add(Fl_Type *parent, Strategy strategy);
- void insert(Fl_Type *n); // insert into list before n
- Fl_Type* remove(); // remove from list
- void move_before(Fl_Type*); // move before a sibling
+ void add(Node *parent, Strategy strategy);
+ void insert(Node *n); // insert into list before n
+ Node* remove(); // remove from list
+ void move_before(Node*); // move before a sibling
virtual const char *title(); // string for browser
virtual const char *type_name() = 0; // type for code output
@@ -239,11 +238,11 @@ public:
const char *comment() { return comment_; }
void comment(const char *);
- virtual Fl_Type* click_test(int,int) { return NULL; }
+ virtual Node* click_test(int,int) { return nullptr; }
- virtual void add_child(Fl_Type*, Fl_Type* beforethis) { }
- virtual void move_child(Fl_Type*, Fl_Type* beforethis) { }
- virtual void remove_child(Fl_Type*) { }
+ virtual void add_child(Node*, Node* beforethis) { }
+ virtual void move_child(Node*, Node* beforethis) { }
+ virtual void remove_child(Node*) { }
/** Give widgets a chance to arrange their children after all children were added.
If adding individual children, this is called immediately, but if children
@@ -252,17 +251,14 @@ public:
*/
virtual void layout_widget() { }
- static Fl_Type *current; // most recently picked object
- static Fl_Type *current_dnd;
-
virtual void open(); // what happens when you double-click
// read and write data to a saved file:
virtual void write(fld::io::Project_Writer &f);
virtual void write_properties(fld::io::Project_Writer &f);
virtual void read_property(fld::io::Project_Reader &f, const char *);
- virtual void write_parent_properties(fld::io::Project_Writer &f, Fl_Type *child, bool encapsulate);
- virtual void read_parent_property(fld::io::Project_Reader &f, Fl_Type *child, const char *property);
+ virtual void write_parent_properties(fld::io::Project_Writer &f, Node *child, bool encapsulate);
+ virtual void read_parent_property(fld::io::Project_Reader &f, Node *child, const char *property);
virtual int read_fdesign(const char*, const char*);
virtual void postprocess_read() { }
@@ -273,7 +269,7 @@ public:
virtual void write_code2(fld::io::Code_Writer& f); // code and .h after children
void write_comment_h(fld::io::Code_Writer& f, const char *ind=""); // write the commentary text into the header file
void write_comment_c(fld::io::Code_Writer& f, const char *ind=""); // write the commentary text into the source file
- void write_comment_inline_c(fld::io::Code_Writer& f, const char *ind=0L); // write the commentary text
+ void write_comment_inline_c(fld::io::Code_Writer& f, const char *ind=nullptr); // write the commentary text
// live mode
virtual Fl_Widget *enter_live_mode(int top=0); // build widgets needed for live mode
@@ -290,20 +286,20 @@ public:
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, but not Fl_Submenu_Type. */
+ /** Return 1 if a type behaves like a button (Fl_Button and Fl_Menu_Item and derived, but not Submenu_Node. */
virtual int is_button() const {return 0;}
- /** Return 1 if this is a Fl_Widget_Class_Type, Fl_CodeBlock_Type, or Fl_Function_Type */
+ /** Return 1 if this is a Widget_Class_Node, CodeBlock_Node, or Function_Node */
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 */
+ /** Return 1 if this is a Widget_Class_Node, Class_Node, or DeclBlock_Node */
virtual int is_decl_block() const {return 0;}
- /** Return 1 if this is a Fl_Class_Type or Fl_Widget_Class_Type. */
+ /** Return 1 if this is a Class_Node or Widget_Class_Node. */
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_); }
+ /** Return the type Type for this Type. */
+ virtual Type type() const { return Type::Base_; }
+ /** Check if this Type is of the give type Type or derived from that type Type. */
+ virtual bool is_a(Type inType) const { return (inType==Type::Base_); }
const char* class_name(const int need_nest) const;
bool is_in_class() const;
@@ -312,12 +308,6 @@ public:
unsigned short set_uid(unsigned short suggested_uid=0);
unsigned short get_uid() { return uid_; }
- static Fl_Type *find_by_uid(unsigned short uid);
-
- static Fl_Type *find_in_text(int text_type, int crsr);
-
- /// If this is greater zero, widgets will be allowed to lay out their children.
- static int allow_layout;
};
-#endif // _FLUID_FL_TYPE_H
+#endif // FLUID_NODES_NODE_H
diff --git a/fluid/nodes/Tree.cxx b/fluid/nodes/Tree.cxx
new file mode 100644
index 000000000..ca9b3d761
--- /dev/null
+++ b/fluid/nodes/Tree.cxx
@@ -0,0 +1,128 @@
+//
+// Node Tree code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2025 by Bill Spitzak and others.
+//
+// This library is free software. Distribution and use rights are outlined in
+// the file "COPYING" which should have been included with this file. If this
+// file is missing or damaged, see the license at:
+//
+// https://www.fltk.org/COPYING.php
+//
+// Please see the following page on how to report bugs and issues:
+//
+// https://www.fltk.org/bugs.php
+//
+
+
+#include "nodes/Tree.h"
+
+#include "Project.h"
+
+using namespace fld;
+using namespace fld::node;
+
+
+Tree::Iterator::Iterator(Node *t, bool only_selected)
+: type_(t)
+, only_selected_(only_selected)
+{
+ if (t) {
+ if (only_selected_) {
+ if (!type_->selected) {
+ operator++();
+ }
+ }
+ }
+}
+
+Tree::Iterator &Tree::Iterator::operator++() {
+ if (only_selected_) {
+ do {
+ type_ = type_->next;
+ } while (type_ && !type_->selected);
+ } else {
+ type_ = type_->next;
+ }
+ return *this;
+}
+
+Tree::WIterator::WIterator(Node *t, bool only_selected)
+: type_(t)
+, only_selected_(only_selected)
+{
+ if (t) {
+ if (only_selected_) {
+ if (!type_->selected || !type_->is_widget()) {
+ operator++();
+ }
+ } else {
+ if (!type_->is_widget()) {
+ operator++();
+ }
+ }
+ }
+}
+
+Tree::WIterator& Tree::WIterator::operator++() {
+ if (only_selected_) {
+ do {
+ type_ = type_->next;
+ } while (type_ && (!type_->selected || !type_->is_widget()));
+ } else {
+ do {
+ type_ = type_->next;
+ } while (type_ && !type_->is_widget());
+ }
+ return *this;
+}
+
+
+Tree::Tree(Project &proj)
+: proj_(proj)
+{ (void)proj_; }
+
+
+/** Find a node by its unique id.
+
+ Every node in a type tree has an id that is unique for the current project.
+ Walk the tree and return the node with this uid.
+
+ \param[in] uid any number between 0 and 65535
+ \return the node with this uid, or nullptr if not found
+ */
+Node *Tree::find_by_uid(unsigned short uid) {
+ for (auto tp: all_nodes()) {
+ if (tp->get_uid() == uid) return tp;
+ }
+ return nullptr;
+}
+
+
+/** Find a type node by using the codeview text positions.
+
+ \param[in] text_type 0=source file, 1=header, 2=.fl project file
+ \param[in] crsr cursor position in text
+ \return the node we found or nullptr
+ */
+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;
+ 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;
+ break;
+ case 2:
+ if (crsr >= node->proj1_start && crsr < node->proj1_end) return node;
+ if (crsr >= node->proj2_start && crsr < node->proj2_end) return node;
+ break;
+ }
+ }
+ return nullptr;
+}
diff --git a/fluid/nodes/Tree.h b/fluid/nodes/Tree.h
new file mode 100644
index 000000000..f494af651
--- /dev/null
+++ b/fluid/nodes/Tree.h
@@ -0,0 +1,106 @@
+//
+// Node Tree header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2025 by Bill Spitzak and others.
+//
+// This library is free software. Distribution and use rights are outlined in
+// the file "COPYING" which should have been included with this file. If this
+// file is missing or damaged, see the license at:
+//
+// https://www.fltk.org/COPYING.php
+//
+// Please see the following page on how to report bugs and issues:
+//
+// https://www.fltk.org/bugs.php
+//
+
+#ifndef FLUID_NODES_TREE_H
+#define FLUID_NODES_TREE_H
+
+#include "nodes/Widget_Node.h"
+
+class Node;
+
+namespace fld {
+
+class Project;
+
+namespace node {
+
+class Tree {
+
+ // A class that can iterate over the entire scene graph.
+ class Iterator {
+ Node *type_ = nullptr;
+ bool only_selected_ = false;
+ public:
+ explicit Iterator(Node *t, bool only_selected);
+ Node* operator*() { return type_; }
+ Iterator& operator++();
+ bool operator!=(const Iterator& other) const { return type_ != other.type_; }
+ };
+
+ // A container for a node iterator
+ class Container {
+ Tree &tree_;
+ bool only_selected_ = false;
+ public:
+ Container(Tree &tree, bool only_selected) : tree_(tree), only_selected_(only_selected) { }
+ Iterator begin() { return Iterator(tree_.first, only_selected_); }
+ Iterator end() { return Iterator(nullptr, only_selected_); }
+ };
+
+ // A class that iterate over the scene graph, but returns only nodes of type widget.
+ class WIterator {
+ Node *type_ = nullptr;
+ bool only_selected_ = false;
+ public:
+ explicit WIterator(Node *t, bool only_selected);
+ Widget_Node* operator*() { return static_cast<Widget_Node*>(type_); }
+ WIterator& operator++();
+ bool operator!=(const WIterator& other) const { return type_ != other.type_; }
+ };
+
+ // A container for a widget node iterator
+ class WContainer {
+ Tree &tree_;
+ bool only_selected_ = false;
+ public:
+ WContainer(Tree &tree, bool only_selected) : tree_(tree), only_selected_(only_selected) { }
+ WIterator begin() { return WIterator(tree_.first, only_selected_); }
+ WIterator end() { return WIterator(nullptr, only_selected_); }
+ };
+
+ /// Link Tree class to the project.
+ Project &proj_;
+
+public:
+
+ Node *first = nullptr;
+ Node *last = nullptr;
+ Node *current = nullptr; // most recently picked object
+ Node *current_dnd = nullptr;
+ /// If this is greater zero, widgets will be allowed to lay out their children.
+ int allow_layout = 0;
+
+public:
+
+ Tree(Project &proj);
+
+ bool empty() { return first == nullptr; }
+
+ // Iterators: `for (auto &n: tree.all_nodes()) { n.print(); }
+ Container all_nodes() { return Container(*this, false); }
+ WContainer all_widgets() { return WContainer(*this, false); }
+ Container all_selected_nodes() { return Container(*this, true); }
+ WContainer all_selected_widgets() { return WContainer(*this, true); }
+
+ Node *find_by_uid(unsigned short uid);
+ Node *find_in_text(int text_type, int crsr);
+};
+
+} // namespace node
+} // namespace fld
+
+
+#endif // FLUID_NODES_TREE_H
diff --git a/fluid/nodes/Widget_Node.cxx b/fluid/nodes/Widget_Node.cxx
new file mode 100644
index 000000000..cba8607f2
--- /dev/null
+++ b/fluid/nodes/Widget_Node.cxx
@@ -0,0 +1,2438 @@
+//
+// Widget Node code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2025 by Bill Spitzak and others.
+//
+// This library is free software. Distribution and use rights are outlined in
+// the file "COPYING" which should have been included with this file. If this
+// file is missing or damaged, see the license at:
+//
+// https://www.fltk.org/COPYING.php
+//
+// Please see the following page on how to report bugs and issues:
+//
+// https://www.fltk.org/bugs.php
+//
+
+#include "nodes/Widget_Node.h"
+
+#include "Fluid.h"
+#include "Project.h"
+#include "app/Image_Asset.h"
+#include "proj/mergeback.h"
+#include "proj/undo.h"
+#include "io/Project_Reader.h"
+#include "io/Project_Writer.h"
+#include "io/Code_Writer.h"
+#include "nodes/Menu_Node.h"
+#include "nodes/Function_Node.h"
+#include "nodes/Window_Node.h"
+#include "panels/widget_panel.h"
+
+#include <FL/Fl.H>
+#include <FL/Fl_Group.H>
+#include <FL/Fl_Table.H>
+#include <FL/Fl_Input.H>
+#include <FL/fl_message.H>
+#include <FL/Fl_Slider.H>
+#include <FL/Fl_Spinner.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Flex.H>
+#include "../src/flstring.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#undef min
+#undef max
+#include <algorithm>
+
+// Make an Widget_Node subclass instance.
+// It figures out the automatic size and parent of the new widget,
+// creates the Fl_Widget (by calling the virtual function _make),
+// adds it to the Fl_Widget hierarchy, creates a new Node
+// instance, sets the widget pointers, and makes all the display
+// update correctly...
+
+int Widget_Node::is_widget() const {return 1;}
+int Widget_Node::is_public() const {return public_;}
+
+const char* subclassname(Node* l) {
+ if (l->is_a(Type::Menu_Bar)) {
+ Menu_Bar_Node *mb = static_cast<Menu_Bar_Node*>(l);
+ if (mb->is_sys_menu_bar())
+ return mb->sys_menubar_name();
+ }
+ if (l->is_widget()) {
+ Widget_Node* p = (Widget_Node*)l;
+ const char* c = p->subclass();
+ if (c) return c;
+ if (l->is_class()) return "Fl_Group";
+ if (p->o->type() == FL_DOUBLE_WINDOW) return "Fl_Double_Window";
+ if (p->type() == Type::Input) {
+ if (p->o->type() == FL_FLOAT_INPUT) return "Fl_Float_Input";
+ if (p->o->type() == FL_INT_INPUT) return "Fl_Int_Input";
+ }
+ }
+ return l->type_name();
+}
+
+// Return the ideal widget size...
+void
+Widget_Node::ideal_size(int &w, int &h) {
+ w = 120;
+ h = 100;
+ fld::app::Snap_Action::better_size(w, h);
+}
+
+/**
+ Make a new Widget node.
+ \param[in] strategy is Strategy::AS_LAST_CHILD or Strategy::AFTER_CURRENT
+ \return new node
+ */
+Node *Widget_Node::make(Strategy strategy) {
+ Node *anchor = Fluid.proj.tree.current, *pp = anchor;
+ if (pp && (strategy.placement() == Strategy::AFTER_CURRENT))
+ pp = pp->parent;
+ while (pp && !pp->is_a(Type::Group)) {
+ anchor = pp;
+ strategy.placement(Strategy::AFTER_CURRENT);
+ pp = pp->parent;
+ }
+ if (!pp || !pp->is_true_widget() || !anchor->is_true_widget()) {
+ fl_message("Please select a group widget or window");
+ return nullptr;
+ }
+
+ Widget_Node* p = (Widget_Node*)pp;
+ Widget_Node* q = (Widget_Node*)anchor;
+
+ // Figure out a border between widget and window:
+ int B = p->o->w()/2; if (p->o->h()/2 < B) B = p->o->h()/2; if (B>25) B = 25;
+
+ int ULX,ULY; // parent's origin in window
+ if (!p->is_a(Type::Window)) { // if it is a group, add corner
+ ULX = p->o->x(); ULY = p->o->y();
+ } else {
+ ULX = ULY = 0;
+ }
+
+ // Figure out a position and size for the widget
+ int X,Y,W,H;
+ if (is_a(Type::Group)) { // fill the parent with the widget
+ X = ULX+B;
+ W = p->o->w()-B;
+ Y = ULY+B;
+ H = p->o->h()-B;
+ } else if (q != p) { // copy position and size of current widget
+ W = q->o->w();
+ H = q->o->h();
+ X = q->o->x()+W;
+ Y = q->o->y();
+ if (X+W > ULX+p->o->w()) {
+ X = q->o->x();
+ Y = q->o->y()+H;
+ if (Y+H > ULY+p->o->h()) Y = ULY+B;
+ }
+ } else { // just make it small and square...
+ X = ULX+B;
+ Y = ULY+B;
+ W = H = B;
+ }
+
+ // Construct the Node:
+ Widget_Node *t = _make();
+ if (!o) o = widget(0,0,100,100); // create template widget
+ t->factory = this;
+ // Construct the Fl_Widget:
+ t->o = widget(X,Y,W,H);
+ if (strategy.source() == Strategy::FROM_FILE)
+ t->o->label(nullptr);
+ else if (t->o->label()) t->label(t->o->label()); // allow editing
+ t->o->user_data((void*)t);
+ // Put it in the parent:
+ // ((Fl_Group *)(p->o))->add(t->o); (done by Node::add())
+ // add to browser:
+ t->add(anchor, strategy);
+ t->redraw();
+ return t;
+}
+
+void Widget_Node::setimage(Image_Asset *i) {
+ if (i == image || is_a(Type::Window)) return;
+ if (image) image->dec_ref();
+ if (i) i->inc_ref();
+ image = i;
+ if (i) {
+ o->image(i->image());
+ if (o->image() && (scale_image_w_ || scale_image_h_)) {
+ int iw = scale_image_w_>0 ? scale_image_w_ : o->image()->data_w();
+ int ih = scale_image_h_>0 ? scale_image_h_ : o->image()->data_h();
+ o->image()->scale(iw, ih, 0, 1);
+ }
+ } else {
+ o->image(nullptr);
+ //scale_image_w_ = scale_image_h_ = 0;
+ }
+ redraw();
+}
+
+void Widget_Node::setinactive(Image_Asset *i) {
+ if (i == inactive || is_a(Type::Window)) return;
+ if (inactive) inactive->dec_ref();
+ if (i) i->inc_ref();
+ inactive = i;
+ if (i) {
+ o->deimage(i->image());
+ if (o->deimage()) {
+ int iw = scale_deimage_w_>0 ? scale_deimage_w_ : o->deimage()->data_w();
+ int ih = scale_deimage_h_>0 ? scale_deimage_h_ : o->deimage()->data_h();
+ o->deimage()->scale(iw, ih, 0, 1);
+ }
+ } else {
+ o->deimage(nullptr);
+ //scale_deimage_w_ = scale_deimage_h_ = 0;
+ }
+ redraw();
+}
+
+void Widget_Node::setlabel(const char *n) {
+ o->label(n);
+ redraw();
+}
+
+Widget_Node::Widget_Node()
+: override_visible_(0)
+{
+ for (int n=0; n<NUM_EXTRA_CODE; n++) {extra_code_[n] = nullptr; }
+ subclass_ = nullptr;
+ hotspot_ = 0;
+ tooltip_ = nullptr;
+ image_name_ = nullptr;
+ inactive_name_ = nullptr;
+ image = nullptr;
+ inactive = nullptr;
+ o = nullptr;
+ public_ = 1;
+ bind_image_ = 0;
+ compress_image_ = 1;
+ bind_deimage_ = 0;
+ compress_deimage_ = 1;
+ scale_image_w_ = 0;
+ scale_image_h_ = 0;
+ scale_deimage_w_ = 0;
+ scale_deimage_h_ = 0;
+}
+
+Widget_Node::~Widget_Node() {
+ if (o) {
+ Fl_Window *win = o->window();
+ delete o;
+ if (win)
+ win->redraw();
+ }
+ if (subclass_) free((void*)subclass_);
+ if (tooltip_) free((void*)tooltip_);
+ if (image_name_) {
+ free((void*)image_name_);
+ if (image) image->dec_ref();
+ }
+ if (inactive_name_) {
+ free((void*)inactive_name_);
+ if (inactive) inactive->dec_ref();
+ }
+ for (int n=0; n<NUM_EXTRA_CODE; n++) {
+ if (extra_code_[n]) free((void*) extra_code_[n]);
+ }
+}
+
+void Widget_Node::extra_code(int m,const char *n) {
+ storestring(n,extra_code_[m]);
+}
+
+extern void redraw_browser();
+void Widget_Node::subclass(const char *n) {
+ if (storestring(n,subclass_) && visible)
+ redraw_browser();
+}
+
+void Widget_Node::tooltip(const char *n) {
+ storestring(n,tooltip_);
+ o->tooltip(n);
+}
+
+void Widget_Node::image_name(const char *n) {
+ setimage(Image_Asset::find(n));
+ storestring(n,image_name_);
+}
+
+void Widget_Node::inactive_name(const char *n) {
+ setinactive(Image_Asset::find(n));
+ storestring(n,inactive_name_);
+}
+
+void Widget_Node::redraw() {
+ Node *t = this;
+ if (is_a(Type::Menu_Item)) {
+ // find the menu button that parents this menu:
+ do t = t->parent; while (t && t->is_a(Type::Menu_Item));
+ // kludge to cause build_menu to be called again:
+ if (t)
+ t->add_child(nullptr, nullptr);
+ } else {
+ while (t->parent && t->parent->is_widget()) t = t->parent;
+ ((Widget_Node*)t)->o->redraw();
+ }
+}
+
+// the recursive part sorts all children, returns pointer to next:
+Node *sort(Node *parent) {
+ Node *f,*n=nullptr;
+ for (f = parent ? parent->next : Fluid.proj.tree.first; ; f = n) {
+ if (!f || (parent && f->level <= parent->level)) break;
+ n = sort(f);
+ if (!f->selected || !f->is_true_widget()) continue;
+ Fl_Widget* fw = ((Widget_Node*)f)->o;
+ Node *g; // we will insert before this
+ for (g = parent ? parent->next : Fluid.proj.tree.first; g != f; g = g->next) {
+ if (!g->selected || g->level > f->level) continue;
+ Fl_Widget* gw = ((Widget_Node*)g)->o;
+ if (gw->y() > fw->y()) break;
+ if (gw->y() == fw->y() && gw->x() > fw->x()) break;
+ }
+ if (g != f) f->move_before(g);
+ }
+ if (parent)
+ parent->layout_widget();
+ return f;
+}
+
+////////////////////////////////////////////////////////////////
+// The control panels!
+
+Fl_Window *the_panel;
+
+// All the callbacks use the argument to indicate whether to load or store.
+// This avoids the need for pointers to all the widgets, and keeps the
+// code localized in the callbacks.
+// A value of LOAD means to load. The hope is that this will not collide
+// with any actual useful values for the argument. I also use this to
+// initialized parts of the widget that are nyi by fluid.
+
+Widget_Node *current_widget; // one of the selected ones
+void* const LOAD = (void *)"LOAD"; // "magic" pointer to indicate that we need to load values into the dialog
+int numselected; // number selected
+int haderror;
+
+void name_public_cb(Fl_Choice* i, void* v) {
+ if (v == LOAD) {
+ i->value(current_widget->public_>0);
+ if (current_widget->is_in_class()) i->hide(); else i->show();
+ } else {
+ int mod = 0;
+ for (Node *o = Fluid.proj.tree.first; o; o = o->next) {
+ if (o->selected && o->is_widget()) {
+ ((Widget_Node*)o)->public_ = i->value();
+ mod = 1;
+ }
+ }
+ if (mod) {
+ Fluid.proj.set_modflag(1);
+ redraw_browser();
+ }
+ }
+}
+
+/* Treating UNDO for text widget.
+
+ Goal: we want to continuously update the UI while the user is typing text
+ (changing the label, in this case). Code View does deferred updates, and
+ the widget browser and widget panel update on every keystroke. At the same
+ time, we want to limit undo actions to few and logical units.
+
+ Caveats:
+
+ 1: the text widget has its own undo handling for the text field, but we may want to do a global undo
+ 2: every o->label() call will create an undo entry, but we want only one single event for all selected widgets
+ 3: we want a single undo for the entire editing phase, but still propagate changes as they happen
+
+ The edit process has these main states:
+
+ 1: starting to edit [first_change==1 && !unfocus]; we must create a single undo checkpoint before anything changes
+ 2: continue editing [first_change==0 && !unfocus]; we must suspend any undo checkpoints
+ 3: done editing, unfocus [first_change==0 && unfocus]; we must make sure that undo checkpoints are enabled again
+ 4: losing focus without editing [first_change==1 && unfocus]; don't create and checkpoints
+
+ We must also check:
+ 1: changing focus without changing text (works)
+ 2: copy and paste, drag and drop operations (works)
+ 3: save operation without unfocus event (works)
+ */
+void label_cb(Fl_Input* i, void *v) {
+ static int first_change = 1;
+ if (v == LOAD) {
+ i->value(current_widget->label());
+ first_change = 1;
+ } else {
+ if (i->changed()) {
+ Fluid.proj.undo.suspend();
+ int mod = 0;
+ for (Node *o = Fluid.proj.tree.first; o; o = o->next) {
+ if (o->selected && o->is_widget()) {
+ if (!mod) {
+ if (first_change) {
+ Fluid.proj.undo.resume();
+ Fluid.proj.undo.checkpoint();
+ Fluid.proj.undo.suspend();
+ first_change = 0;
+ }
+ mod = 1;
+ }
+ o->label(i->value());
+ }
+ }
+ Fluid.proj.undo.resume();
+ if (mod) Fluid.proj.set_modflag(1);
+ }
+ int r = (int)Fl::callback_reason();
+ if ( (r == FL_REASON_LOST_FOCUS) || (r == FL_REASON_ENTER_KEY) )
+ first_change = 1;
+ }
+}
+
+
+
+
+
+
+int widget_i = 0;
+
+static int vars_i_cb(const fld::widget::Formula_Input*, void *v) {
+ return widget_i;
+}
+
+static int vars_x_cb(const fld::widget::Formula_Input*, void *v) {
+ Node *t = (Node*)v;
+ if (t->is_widget())
+ return ((Widget_Node*)t)->o->x();
+ return 0;
+}
+
+static int vars_y_cb(const fld::widget::Formula_Input*, void *v) {
+ Node *t = (Node*)v;
+ if (t->is_widget())
+ return ((Widget_Node*)t)->o->y();
+ return 0;
+}
+
+static int vars_w_cb(const fld::widget::Formula_Input*, void *v) {
+ Node *t = (Node*)v;
+ if (t->is_widget())
+ return ((Widget_Node*)t)->o->w();
+ return 0;
+}
+
+static int vars_h_cb(const fld::widget::Formula_Input*, void *v) {
+ Node *t = (Node*)v;
+ if (t->is_widget())
+ return ((Widget_Node*)t)->o->h();
+ return 0;
+}
+
+static int vars_px_cb(const fld::widget::Formula_Input*, void *v) {
+ Node *t = ((Node*)v)->parent;
+ if (t && t->is_widget())
+ return ((Widget_Node*)t)->o->x();
+ return 0;
+}
+
+static int vars_py_cb(const fld::widget::Formula_Input*, void *v) {
+ Node *t = ((Node*)v)->parent;
+ if (t && t->is_widget())
+ return ((Widget_Node*)t)->o->y();
+ return 0;
+}
+
+static int vars_pw_cb(const fld::widget::Formula_Input*, void *v) {
+ Node *t = ((Node*)v)->parent;
+ if (t && t->is_widget())
+ return ((Widget_Node*)t)->o->w();
+ return 0;
+}
+
+static int vars_ph_cb(const fld::widget::Formula_Input*, void *v) {
+ Node *t = ((Node*)v)->parent;
+ if (t && t->is_widget())
+ return ((Widget_Node*)t)->o->h();
+ return 0;
+}
+
+static int vars_sx_cb(const fld::widget::Formula_Input*, void *v) {
+ Node *t = ((Node*)v)->prev_sibling();
+ if (t && t->is_widget())
+ return ((Widget_Node*)t)->o->x();
+ return 0;
+}
+
+static int vars_sy_cb(const fld::widget::Formula_Input*, void *v) {
+ Node *t = ((Node*)v)->prev_sibling();
+ if (t && t->is_widget())
+ return ((Widget_Node*)t)->o->y();
+ return 0;
+}
+
+static int vars_sw_cb(const fld::widget::Formula_Input*, void *v) {
+ Node *t = ((Node*)v)->prev_sibling();
+ if (t && t->is_widget())
+ return ((Widget_Node*)t)->o->w();
+ return 0;
+}
+
+static int vars_sh_cb(const fld::widget::Formula_Input*, void *v) {
+ Node *t = ((Node*)v)->prev_sibling();
+ if (t && t->is_widget())
+ return ((Widget_Node*)t)->o->h();
+ return 0;
+}
+
+static int bbox_x, bbox_y, bbox_r, bbox_b;
+
+static void calculate_bbox(Node *p) {
+ char first = 1;
+ bbox_x = bbox_y = bbox_r = bbox_b = 0;
+ for (p=p->first_child(); p; p=p->next_sibling()) {
+ if (p->is_widget()) {
+ Fl_Widget *o = ((Widget_Node*)p)->o;
+ if (first) {
+ bbox_x = o->x(); bbox_y = o->y();
+ bbox_r = o->x() + o->w(); bbox_b = o->y() + o->h();
+ first = 0;
+ } else {
+ bbox_x = std::min(bbox_x, o->x());
+ bbox_y = std::min(bbox_y, o->y());
+ bbox_r = std::max(bbox_r, o->x() + o->w());
+ bbox_b = std::max(bbox_b, o->y() + o->h());
+ }
+ }
+ }
+}
+
+static int vars_cx_cb(const fld::widget::Formula_Input*, void *v) {
+ calculate_bbox((Node*)v);
+ return bbox_x;
+}
+
+static int vars_cy_cb(const fld::widget::Formula_Input*, void *v) {
+ calculate_bbox((Node*)v);
+ return bbox_y;
+}
+
+static int vars_cw_cb(const fld::widget::Formula_Input*, void *v) {
+ calculate_bbox((Node*)v);
+ return bbox_r - bbox_x;
+}
+
+static int vars_ch_cb(const fld::widget::Formula_Input*, void *v) {
+ calculate_bbox((Node*)v);
+ return bbox_b - bbox_y;
+}
+
+fld::widget::Formula_Input_Vars widget_vars[] = {
+ { "i", vars_i_cb }, // zero based counter of selected widgets
+ { "x", vars_x_cb }, // position and size of current widget
+ { "y", vars_y_cb },
+ { "w", vars_w_cb },
+ { "h", vars_h_cb },
+ { "px", vars_px_cb }, // position and size of parent widget
+ { "py", vars_py_cb },
+ { "pw", vars_pw_cb },
+ { "ph", vars_ph_cb },
+ { "sx", vars_sx_cb }, // position and size of previous sibling
+ { "sy", vars_sy_cb },
+ { "sw", vars_sw_cb },
+ { "sh", vars_sh_cb },
+ { "cx", vars_cx_cb }, // position and size of bounding box of all children
+ { "cy", vars_cy_cb },
+ { "cw", vars_cw_cb },
+ { "ch", vars_ch_cb },
+ { nullptr }
+};
+
+
+
+
+
+////////////////////////////////////////////////////////////////
+
+// turn number to string or string to number for saving to file:
+// does not work for hierarchical menus!
+
+const char *item_name(Fl_Menu_Item* m, int i) {
+ if (m) {
+ while (m->label()) {
+ if (m->argument() == i) return m->label();
+ m++;
+ }
+ }
+ static char buffer[20];
+ sprintf(buffer, "%d", i);
+ return buffer;
+}
+int item_number(Fl_Menu_Item* m, const char* i) {
+ if (!i)
+ return 0;
+ if (m && i) {
+ if (i[0]=='F' && i[1]=='L' && i[2]=='_') i += 3;
+ while (m->label()) {
+ if (!strcmp(m->label(), i)) return int(m->argument());
+ m++;
+ }
+ }
+ return atoi(i);
+}
+
+#define ZERO_ENTRY 1000
+
+Fl_Menu_Item boxmenu[] = {
+ {"NO_BOX",0,nullptr,(void *)ZERO_ENTRY},
+ {"boxes",0,nullptr,nullptr,FL_SUBMENU},
+ {"UP_BOX",0,nullptr,(void *)FL_UP_BOX},
+ {"DOWN_BOX",0,nullptr,(void *)FL_DOWN_BOX},
+ {"FLAT_BOX",0,nullptr,(void *)FL_FLAT_BOX},
+ {"BORDER_BOX",0,nullptr,(void *)FL_BORDER_BOX},
+ {"THIN_UP_BOX",0,nullptr,(void *)FL_THIN_UP_BOX},
+ {"THIN_DOWN_BOX",0,nullptr,(void *)FL_THIN_DOWN_BOX},
+ {"ENGRAVED_BOX",0,nullptr,(void *)FL_ENGRAVED_BOX},
+ {"EMBOSSED_BOX",0,nullptr,(void *)FL_EMBOSSED_BOX},
+ {"ROUND_UP_BOX",0,nullptr,(void *)FL_ROUND_UP_BOX},
+ {"ROUND_DOWN_BOX",0,nullptr,(void *)FL_ROUND_DOWN_BOX},
+ {"DIAMOND_UP_BOX",0,nullptr,(void *)FL_DIAMOND_UP_BOX},
+ {"DIAMOND_DOWN_BOX",0,nullptr,(void *)FL_DIAMOND_DOWN_BOX},
+ {"SHADOW_BOX",0,nullptr,(void *)FL_SHADOW_BOX},
+ {"ROUNDED_BOX",0,nullptr,(void *)FL_ROUNDED_BOX},
+ {"RSHADOW_BOX",0,nullptr,(void *)FL_RSHADOW_BOX},
+ {"RFLAT_BOX",0,nullptr,(void *)FL_RFLAT_BOX},
+ {"OVAL_BOX",0,nullptr,(void *)FL_OVAL_BOX},
+ {"OSHADOW_BOX",0,nullptr,(void *)FL_OSHADOW_BOX},
+ {"OFLAT_BOX",0,nullptr,(void *)FL_OFLAT_BOX},
+ {"PLASTIC_UP_BOX",0,nullptr,(void *)FL_PLASTIC_UP_BOX},
+ {"PLASTIC_DOWN_BOX",0,nullptr,(void *)FL_PLASTIC_DOWN_BOX},
+ {"PLASTIC_THIN_UP_BOX",0,nullptr,(void *)FL_PLASTIC_THIN_UP_BOX},
+ {"PLASTIC_THIN_DOWN_BOX",0,nullptr,(void *)FL_PLASTIC_THIN_DOWN_BOX},
+ {"PLASTIC_ROUND_UP_BOX",0,nullptr,(void *)FL_PLASTIC_ROUND_UP_BOX},
+ {"PLASTIC_ROUND_DOWN_BOX",0,nullptr,(void *)FL_PLASTIC_ROUND_DOWN_BOX},
+ {"GTK_UP_BOX",0,nullptr,(void *)FL_GTK_UP_BOX},
+ {"GTK_DOWN_BOX",0,nullptr,(void *)FL_GTK_DOWN_BOX},
+ {"GTK_THIN_UP_BOX",0,nullptr,(void *)FL_GTK_THIN_UP_BOX},
+ {"GTK_THIN_DOWN_BOX",0,nullptr,(void *)FL_GTK_THIN_DOWN_BOX},
+ {"GTK_ROUND_UP_BOX",0,nullptr,(void *)FL_GTK_ROUND_UP_BOX},
+ {"GTK_ROUND_DOWN_BOX",0,nullptr,(void *)FL_GTK_ROUND_DOWN_BOX},
+ {"GLEAM_UP_BOX",0,nullptr,(void *)FL_GLEAM_UP_BOX},
+ {"GLEAM_DOWN_BOX",0,nullptr,(void *)FL_GLEAM_DOWN_BOX},
+ {"GLEAM_THIN_UP_BOX",0,nullptr,(void *)FL_GLEAM_THIN_UP_BOX},
+ {"GLEAM_THIN_DOWN_BOX",0,nullptr,(void *)FL_GLEAM_THIN_DOWN_BOX},
+ {"GLEAM_ROUND_UP_BOX",0,nullptr,(void *)FL_GLEAM_ROUND_UP_BOX},
+ {"GLEAM_ROUND_DOWN_BOX",0,nullptr,(void *)FL_GLEAM_ROUND_DOWN_BOX},
+ {"OXY_UP_BOX",0,nullptr,(void *)FL_OXY_UP_BOX},
+ {"OXY_DOWN_BOX",0,nullptr,(void *)FL_OXY_DOWN_BOX},
+ {"OXY_THIN_UP_BOX",0,nullptr,(void *)FL_OXY_THIN_UP_BOX},
+ {"OXY_THIN_DOWN_BOX",0,nullptr,(void *)FL_OXY_THIN_DOWN_BOX},
+ {"OXY_ROUND_UP_BOX",0,nullptr,(void *)FL_OXY_ROUND_UP_BOX},
+ {"OXY_ROUND_DOWN_BOX",0,nullptr,(void *)FL_OXY_ROUND_DOWN_BOX},
+ {"OXY_BUTTON_UP_BOX",0,nullptr,(void *)FL_OXY_BUTTON_UP_BOX},
+ {"OXY_BUTTON_DOWN_BOX",0,nullptr,(void *)FL_OXY_BUTTON_DOWN_BOX},
+ {nullptr},
+ {"frames",0,nullptr,nullptr,FL_SUBMENU},
+ {"UP_FRAME",0,nullptr,(void *)FL_UP_FRAME},
+ {"DOWN_FRAME",0,nullptr,(void *)FL_DOWN_FRAME},
+ {"THIN_UP_FRAME",0,nullptr,(void *)FL_THIN_UP_FRAME},
+ {"THIN_DOWN_FRAME",0,nullptr,(void *)FL_THIN_DOWN_FRAME},
+ {"ENGRAVED_FRAME",0,nullptr,(void *)FL_ENGRAVED_FRAME},
+ {"EMBOSSED_FRAME",0,nullptr,(void *)FL_EMBOSSED_FRAME},
+ {"BORDER_FRAME",0,nullptr,(void *)FL_BORDER_FRAME},
+ {"SHADOW_FRAME",0,nullptr,(void *)FL_SHADOW_FRAME},
+ {"ROUNDED_FRAME",0,nullptr,(void *)FL_ROUNDED_FRAME},
+ {"OVAL_FRAME",0,nullptr,(void *)FL_OVAL_FRAME},
+ {"PLASTIC_UP_FRAME",0,nullptr,(void *)FL_PLASTIC_UP_FRAME},
+ {"PLASTIC_DOWN_FRAME",0,nullptr,(void *)FL_PLASTIC_DOWN_FRAME},
+ {"GTK_UP_FRAME",0,nullptr,(void *)FL_GTK_UP_FRAME},
+ {"GTK_DOWN_FRAME",0,nullptr,(void *)FL_GTK_DOWN_FRAME},
+ {"GTK_THIN_UP_FRAME",0,nullptr,(void *)FL_GTK_THIN_UP_FRAME},
+ {"GTK_THIN_DOWN_FRAME",0,nullptr,(void *)FL_GTK_THIN_DOWN_FRAME},
+ {"GLEAM_UP_FRAME",0,nullptr,(void *)FL_GLEAM_UP_FRAME},
+ {"GLEAM_DOWN_FRAME",0,nullptr,(void *)FL_GLEAM_DOWN_FRAME},
+ {"OXY_UP_FRAME",0,nullptr,(void *)FL_OXY_UP_FRAME},
+ {"OXY_DOWN_FRAME",0,nullptr,(void *)FL_OXY_DOWN_FRAME},
+ {"OXY_THIN_UP_FRAME",0,nullptr,(void *)FL_OXY_THIN_UP_FRAME},
+ {"OXY_THIN_DOWN_FRAME",0,nullptr,(void *)FL_OXY_THIN_DOWN_FRAME},
+ {nullptr},
+ {nullptr}};
+
+const char *boxname(int i) {
+ if (!i) i = ZERO_ENTRY;
+ for (int j = 0; j < int(sizeof(boxmenu)/sizeof(*boxmenu)); j++)
+ if (boxmenu[j].argument() == i) return boxmenu[j].label();
+ return nullptr;
+}
+
+int boxnumber(const char *i) {
+ if (i[0]=='F' && i[1]=='L' && i[2]=='_') i += 3;
+ for (int j = 0; j < int(sizeof(boxmenu)/sizeof(*boxmenu)); j++)
+ if (boxmenu[j].label() && !strcmp(boxmenu[j].label(), i)) {
+ return int(boxmenu[j].argument());
+ }
+ return 0;
+}
+
+
+
+
+////////////////////////////////////////////////////////////////
+
+Fl_Menu_Item whenmenu[] = {
+ // set individual bits
+ {"FL_WHEN_CHANGED",0,nullptr,(void*)FL_WHEN_CHANGED, FL_MENU_TOGGLE},
+ {"FL_WHEN_NOT_CHANGED",0,nullptr,(void*)FL_WHEN_NOT_CHANGED, FL_MENU_TOGGLE},
+ {"FL_WHEN_RELEASE",0,nullptr,(void*)FL_WHEN_RELEASE, FL_MENU_TOGGLE},
+ {"FL_WHEN_ENTER_KEY",0,nullptr,(void*)FL_WHEN_ENTER_KEY, FL_MENU_TOGGLE},
+ {"FL_WHEN_CLOSED",0,nullptr,(void*)FL_WHEN_CLOSED, FL_MENU_TOGGLE|FL_MENU_DIVIDER},
+ // set bit combinations
+ {"FL_WHEN_NEVER",0,nullptr,(void*)FL_WHEN_NEVER},
+ {"FL_WHEN_RELEASE_ALWAYS",0,nullptr,(void*)FL_WHEN_RELEASE_ALWAYS},
+ {"FL_WHEN_ENTER_KEY_ALWAYS",0,nullptr,(void*)FL_WHEN_ENTER_KEY_ALWAYS},
+ {"FL_WHEN_ENTER_KEY_CHANGED",0,nullptr,(void*)FL_WHEN_ENTER_KEY_CHANGED},
+ {nullptr}};
+
+
+static Fl_Menu_Item whensymbolmenu[] = {
+ /* 0 */ {"FL_WHEN_NEVER",0,nullptr,(void*)FL_WHEN_NEVER},
+ /* 1 */ {"FL_WHEN_CHANGED",0,nullptr,(void*)FL_WHEN_CHANGED},
+ /* 2 */ {"FL_WHEN_NOT_CHANGED",0,nullptr,(void*)FL_WHEN_NOT_CHANGED},
+ /* 3 */ {"FL_WHEN_CHANGED | FL_WHEN_NOT_CHANGED",0,nullptr,(void*)(FL_WHEN_CHANGED|FL_WHEN_NOT_CHANGED)},
+ /* 4 */ {"FL_WHEN_RELEASE",0,nullptr,(void*)FL_WHEN_RELEASE},
+ /* 5 */ {"FL_WHEN_CHANGED | FL_WHEN_RELEASE",0,nullptr,(void*)(FL_WHEN_CHANGED|FL_WHEN_RELEASE)},
+ /* 6 */ {"FL_WHEN_RELEASE_ALWAYS",0,nullptr,(void*)FL_WHEN_RELEASE_ALWAYS},
+ /* 7 */ {"FL_WHEN_CHANGED | FL_WHEN_RELEASE_ALWAYS",0,nullptr,(void*)(FL_WHEN_CHANGED|FL_WHEN_RELEASE_ALWAYS)},
+ /* 8 */ {"FL_WHEN_ENTER_KEY",0,nullptr,(void*)FL_WHEN_ENTER_KEY},
+ /* 9 */ {"FL_WHEN_CHANGED | FL_WHEN_ENTER_KEY",0,nullptr,(void*)(FL_WHEN_CHANGED|FL_WHEN_ENTER_KEY)},
+ /* 10 */ {"FL_WHEN_ENTER_KEY_ALWAYS",0,nullptr,(void*)FL_WHEN_ENTER_KEY_ALWAYS},
+ /* 11 */ {"FL_WHEN_ENTER_KEY_CHANGED",0,nullptr,(void*)FL_WHEN_ENTER_KEY_CHANGED},
+ /* 12 */ {"FL_WHEN_RELEASE | FL_WHEN_ENTER_KEY",0,nullptr,(void*)(FL_WHEN_RELEASE|FL_WHEN_ENTER_KEY)},
+ /* 13 */ {"FL_WHEN_RELEASE | FL_WHEN_CHANGED | FL_WHEN_ENTER_KEY",0,nullptr,(void*)(FL_WHEN_RELEASE|FL_WHEN_CHANGED|FL_WHEN_ENTER_KEY)},
+ /* 14 */ {"FL_WHEN_RELEASE | FL_WHEN_ENTER_KEY_ALWAYS",0,nullptr,(void*)(FL_WHEN_RELEASE|FL_WHEN_ENTER_KEY_ALWAYS)},
+ /* 15 */ {"FL_WHEN_RELEASE | FL_WHEN_ENTER_KEY_CHANGED",0,nullptr,(void*)(FL_WHEN_RELEASE|FL_WHEN_ENTER_KEY_CHANGED)},
+ {nullptr}
+};
+
+// Return a text string representing the Fl_When value n
+const char* when_symbol_name(int n) {
+ static char sym[128];
+ if (n == FL_WHEN_CLOSED) {
+ strcpy(sym, "FL_WHEN_CLOSED");
+ } else {
+ strcpy(sym, whensymbolmenu[n&15].label());
+ if (n & FL_WHEN_CLOSED)
+ strcat(sym, " | FL_WHEN_CLOSED");
+ }
+ return sym;
+}
+
+// Set the check marks in the "when()" menu according to the Fl_When value n
+void set_whenmenu(int n) {
+ if (n&FL_WHEN_CHANGED) whenmenu[0].set(); else whenmenu[0].clear();
+ if (n&FL_WHEN_NOT_CHANGED) whenmenu[1].set(); else whenmenu[1].clear();
+ if (n&FL_WHEN_RELEASE) whenmenu[2].set(); else whenmenu[2].clear();
+ if (n&FL_WHEN_ENTER_KEY) whenmenu[3].set(); else whenmenu[3].clear();
+ if (n&FL_WHEN_CLOSED) whenmenu[4].set(); else whenmenu[4].clear();
+}
+
+
+uchar Widget_Node::resizable() const {
+ if (is_a(Type::Window)) return ((Fl_Window*)o)->resizable() != nullptr;
+ Fl_Group* p = (Fl_Group*)o->parent();
+ if (p) return p->resizable() == o;
+ else return 0;
+}
+
+void Widget_Node::resizable(uchar v) {
+ if (v) {
+ if (resizable()) return;
+ if (is_a(Type::Window)) ((Fl_Window*)o)->resizable(o);
+ else {
+ Fl_Group* p = (Fl_Group*)o->parent();
+ if (p) p->resizable(o);
+ }
+ } else {
+ if (!resizable()) return;
+ if (is_a(Type::Window)) {
+ ((Fl_Window*)o)->resizable(nullptr);
+ } else {
+ Fl_Group* p = (Fl_Group*)o->parent();
+ if (p) p->resizable(nullptr);
+ }
+ }
+}
+
+
+
+////////////////////////////////////////////////////////////////
+
+Fl_Menu_Item fontmenu[] = {
+ {"Helvetica"},
+ {"Helvetica bold"},
+ {"Helvetica italic"},
+ {"Helvetica bold italic"},
+ {"Courier"},
+ {"Courier bold"},
+ {"Courier italic"},
+ {"Courier bold italic"},
+ {"Times"},
+ {"Times bold"},
+ {"Times italic"},
+ {"Times bold italic"},
+ {"Symbol"},
+ {"Terminal"},
+ {"Terminal Bold"},
+ {"Zapf Dingbats"},
+ {nullptr}
+};
+
+Fl_Menu_Item fontmenu_w_default[] = {
+ {"<default>", 0, nullptr, nullptr, FL_MENU_DIVIDER},
+ {"Helvetica"},
+ {"Helvetica bold"},
+ {"Helvetica italic"},
+ {"Helvetica bold italic"},
+ {"Courier"},
+ {"Courier bold"},
+ {"Courier italic"},
+ {"Courier bold italic"},
+ {"Times"},
+ {"Times bold"},
+ {"Times italic"},
+ {"Times bold italic"},
+ {"Symbol"},
+ {"Terminal"},
+ {"Terminal Bold"},
+ {"Zapf Dingbats"},
+ {nullptr}
+};
+
+
+
+extern const char *ui_find_image_name;
+
+Fl_Menu_Item labeltypemenu[] = {
+ {"NORMAL_LABEL",0,nullptr,(void*)nullptr},
+ {"SHADOW_LABEL",0,nullptr,(void*)FL_SHADOW_LABEL},
+ {"ENGRAVED_LABEL",0,nullptr,(void*)FL_ENGRAVED_LABEL},
+ {"EMBOSSED_LABEL",0,nullptr,(void*)FL_EMBOSSED_LABEL},
+ {"NO_LABEL",0,nullptr,(void*)(FL_NO_LABEL)},
+ {nullptr}};
+
+void labeltype_cb(Fl_Choice* i, void *v) {
+ if (v == LOAD) {
+ int n;
+ n = current_widget->o->labeltype();
+ i->when(FL_WHEN_RELEASE);
+ for (int j = 0; j < int(sizeof(labeltypemenu)/sizeof(*labeltypemenu)); j++)
+ if (labeltypemenu[j].argument() == n) {i->value(j); break;}
+ } else {
+ int mod = 0;
+ int m = i->value();
+ int n = int(labeltypemenu[m].argument());
+ if (n<0) return; // should not happen
+ for (Node *o = Fluid.proj.tree.first; o; o = o->next) {
+ if (o->selected && o->is_widget()) {
+ Widget_Node* p = (Widget_Node*)o;
+ p->o->labeltype((Fl_Labeltype)n);
+ p->redraw();
+ mod = 1;
+ }
+ }
+ if (mod) Fluid.proj.set_modflag(1);
+ }
+}
+
+////////////////////////////////////////////////////////////////
+
+Fl_Menu_Item colormenu[] = {
+ { "Foreground Color", 0, nullptr, (void*)(fl_intptr_t)FL_FOREGROUND_COLOR, 0, 0, FL_HELVETICA, 11},
+ { "Background Color", 0, nullptr, (void*)(fl_intptr_t)FL_BACKGROUND_COLOR, 0, 0, FL_HELVETICA, 11},
+ { "Background Color 2", 0, nullptr, (void*)(fl_intptr_t)FL_BACKGROUND2_COLOR, 0, 0, FL_HELVETICA, 11},
+ { "Selection Color", 0, nullptr, (void*)(fl_intptr_t)FL_SELECTION_COLOR, 0, 0, FL_HELVETICA, 11},
+ { "Inactive Color", 0, nullptr, (void*)(fl_intptr_t)FL_INACTIVE_COLOR, FL_MENU_DIVIDER, 0, FL_HELVETICA, 11},
+ { "Black", 0, nullptr, (void*)(fl_intptr_t)FL_BLACK, 0, 0, FL_HELVETICA, 11},
+ { "White", 0, nullptr, (void*)(fl_intptr_t)FL_WHITE, FL_MENU_DIVIDER, 0, FL_HELVETICA, 11},
+ { "Gray 0", 0, nullptr, (void*)(fl_intptr_t)FL_GRAY0, 0, 0, FL_HELVETICA, 11},
+ { "Dark 3", 0, nullptr, (void*)(fl_intptr_t)FL_DARK3, 0, 0, FL_HELVETICA, 11},
+ { "Dark 2", 0, nullptr, (void*)(fl_intptr_t)FL_DARK2, 0, 0, FL_HELVETICA, 11},
+ { "Dark 1", 0, nullptr, (void*)(fl_intptr_t)FL_DARK1, 0, 0, FL_HELVETICA, 11},
+ { "Light 1", 0, nullptr, (void*)(fl_intptr_t)FL_LIGHT1, 0, 0, FL_HELVETICA, 11},
+ { "Light 2", 0, nullptr, (void*)(fl_intptr_t)FL_LIGHT2, 0, 0, FL_HELVETICA, 11},
+ { "Light 3", 0, nullptr, (void*)(fl_intptr_t)FL_LIGHT3, 0, 0, FL_HELVETICA, 11},
+ { nullptr }
+};
+
+void color_common(Fl_Color c) {
+ int mod = 0;
+ for (Node *o = Fluid.proj.tree.first; o; o = o->next) {
+ if (o->selected && o->is_widget()) {
+ Widget_Node* q = (Widget_Node*)o;
+ q->o->color(c); q->o->redraw();
+ if (q->parent && q->parent->is_a(Type::Tabs)) {
+ if (q->o->parent()) q->o->parent()->redraw();
+ }
+ mod = 1;
+ }
+ }
+ if (mod) Fluid.proj.set_modflag(1);
+}
+
+
+
+void color2_common(Fl_Color c) {
+ int mod = 0;
+ for (Node *o = Fluid.proj.tree.first; o; o = o->next) {
+ if (o->selected && o->is_widget()) {
+ Widget_Node* q = (Widget_Node*)o;
+ q->o->selection_color(c); q->o->redraw();
+ mod = 1;
+ }
+ }
+ if (mod) Fluid.proj.set_modflag(1);
+}
+
+
+
+void labelcolor_common(Fl_Color c) {
+ int mod = 0;
+ for (Node *o = Fluid.proj.tree.first; o; o = o->next) {
+ if (o->selected && o->is_widget()) {
+ Widget_Node* q = (Widget_Node*)o;
+ q->o->labelcolor(c); q->redraw();
+ mod = 1;
+ }
+ }
+ if (mod) Fluid.proj.set_modflag(1);
+}
+
+
+
+static Fl_Button* relative(Fl_Widget* o, int i) {
+ Fl_Group* g = (Fl_Group*)(o->parent());
+ return (Fl_Button*)(g->child(g->find(*o)+i));
+}
+
+static Fl_Menu_Item alignmenu[] = {
+ {"FL_ALIGN_CENTER",0,nullptr,(void*)(fl_intptr_t)(FL_ALIGN_CENTER)},
+ {"FL_ALIGN_TOP",0,nullptr,(void*)(fl_intptr_t)(FL_ALIGN_TOP)},
+ {"FL_ALIGN_BOTTOM",0,nullptr,(void*)(fl_intptr_t)(FL_ALIGN_BOTTOM)},
+ {"FL_ALIGN_LEFT",0,nullptr,(void*)(fl_intptr_t)(FL_ALIGN_LEFT)},
+ {"FL_ALIGN_RIGHT",0,nullptr,(void*)(fl_intptr_t)(FL_ALIGN_RIGHT)},
+ {"FL_ALIGN_INSIDE",0,nullptr,(void*)(fl_intptr_t)(FL_ALIGN_INSIDE)},
+ {"FL_ALIGN_CLIP",0,nullptr,(void*)(fl_intptr_t)(FL_ALIGN_CLIP)},
+ {"FL_ALIGN_WRAP",0,nullptr,(void*)(fl_intptr_t)(FL_ALIGN_WRAP)},
+ {"FL_ALIGN_TEXT_OVER_IMAGE",0,nullptr,(void*)(fl_intptr_t)(FL_ALIGN_TEXT_OVER_IMAGE)},
+ {"FL_ALIGN_TOP_LEFT",0,nullptr,(void*)(fl_intptr_t)(FL_ALIGN_TOP_LEFT)},
+ {"FL_ALIGN_TOP_RIGHT",0,nullptr,(void*)(fl_intptr_t)(FL_ALIGN_TOP_RIGHT)},
+ {"FL_ALIGN_BOTTOM_LEFT",0,nullptr,(void*)(fl_intptr_t)(FL_ALIGN_BOTTOM_LEFT)},
+ {"FL_ALIGN_BOTTOM_RIGHT",0,nullptr,(void*)(fl_intptr_t)(FL_ALIGN_BOTTOM_RIGHT)},
+ {"FL_ALIGN_LEFT_TOP",0,nullptr,(void*)(fl_intptr_t)(FL_ALIGN_LEFT_TOP)},
+ {"FL_ALIGN_RIGHT_TOP",0,nullptr,(void*)(fl_intptr_t)(FL_ALIGN_RIGHT_TOP)},
+ {"FL_ALIGN_LEFT_BOTTOM",0,nullptr,(void*)(fl_intptr_t)(FL_ALIGN_LEFT_BOTTOM)},
+ {"FL_ALIGN_RIGHT_BOTTOM",0,nullptr,(void*)(fl_intptr_t)(FL_ALIGN_RIGHT_BOTTOM)},
+ {nullptr}};
+
+void align_cb(Fl_Button* i, void *v) {
+ Fl_Align b = Fl_Align(fl_uintptr_t(i->user_data()));
+ if (v == LOAD) {
+ if (current_widget->is_a(Type::Menu_Item)) {i->deactivate(); return;} else i->activate();
+ i->value(current_widget->o->align() & b);
+ } else {
+ int mod = 0;
+ Fluid.proj.undo.checkpoint();
+ for (Node *o = Fluid.proj.tree.first; o; o = o->next) {
+ if (o->selected && o->is_widget()) {
+ Widget_Node* q = (Widget_Node*)o;
+ Fl_Align x = q->o->align();
+ Fl_Align y;
+ if (i->value()) {
+ y = x | b;
+ if (b == FL_ALIGN_LEFT || b == FL_ALIGN_TOP) {
+ Fl_Button *b1 = relative(i,+1);
+ b1->clear();
+ y = y & ~(b1->argument());
+ }
+ if (b == FL_ALIGN_RIGHT || b == FL_ALIGN_BOTTOM) {
+ Fl_Button *b1 = relative(i,-1);
+ b1->clear();
+ y = y & ~(b1->argument());
+ }
+ } else {
+ y = x & ~b;
+ }
+ if (x != y) {
+ q->o->align(y);
+ q->redraw();
+ mod = 1;
+ }
+ }
+ }
+ if (mod) Fluid.proj.set_modflag(1);
+ }
+}
+
+void align_position_cb(Fl_Choice *i, void *v) {
+ if (v == LOAD) {
+ if (current_widget->is_a(Type::Menu_Item)) {i->deactivate(); return;} else i->activate();
+ Fl_Menu_Item *mi = (Fl_Menu_Item*)i->menu();
+ Fl_Align b = current_widget->o->align() & FL_ALIGN_POSITION_MASK;
+ for (;mi->text;mi++) {
+ if ((Fl_Align)(mi->argument())==b)
+ i->value(mi);
+ }
+ } else {
+ const Fl_Menu_Item *mi = i->menu() + i->value();
+ Fl_Align b = Fl_Align(fl_uintptr_t(mi->user_data()));
+ int mod = 0;
+ Fluid.proj.undo.checkpoint();
+ for (Node *o = Fluid.proj.tree.first; o; o = o->next) {
+ if (o->selected && o->is_widget()) {
+ Widget_Node* q = (Widget_Node*)o;
+ Fl_Align x = q->o->align();
+ Fl_Align y = (x & ~FL_ALIGN_POSITION_MASK) | b;
+ if (x != y) {
+ q->o->align(y);
+ q->redraw();
+ mod = 1;
+ }
+ }
+ }
+ if (mod) Fluid.proj.set_modflag(1);
+ }
+}
+
+void align_text_image_cb(Fl_Choice *i, void *v) {
+ if (v == LOAD) {
+ if (current_widget->is_a(Type::Menu_Item)) {i->deactivate(); return;} else i->activate();
+ Fl_Menu_Item *mi = (Fl_Menu_Item*)i->menu();
+ Fl_Align b = current_widget->o->align() & FL_ALIGN_IMAGE_MASK;
+ for (;mi->text;mi++) {
+ if ((Fl_Align)(mi->argument())==b)
+ i->value(mi);
+ }
+ } else {
+ const Fl_Menu_Item *mi = i->menu() + i->value();
+ Fl_Align b = Fl_Align(fl_uintptr_t(mi->user_data()));
+ int mod = 0;
+ Fluid.proj.undo.checkpoint();
+ for (Node *o = Fluid.proj.tree.first; o; o = o->next) {
+ if (o->selected && o->is_widget()) {
+ Widget_Node* q = (Widget_Node*)o;
+ Fl_Align x = q->o->align();
+ Fl_Align y = (x & ~FL_ALIGN_IMAGE_MASK) | b;
+ if (x != y) {
+ q->o->align(y);
+ q->redraw();
+ mod = 1;
+ }
+ }
+ }
+ if (mod) Fluid.proj.set_modflag(1);
+ }
+}
+
+////////////////////////////////////////////////////////////////
+
+
+
+
+
+////////////////////////////////////////////////////////////////
+
+// textstuff: set textfont, textsize, textcolor attributes:
+
+// default widget returns 0 to indicate not-implemented:
+// The first parameter specifies the operation:
+// 0: get all values
+// 1: set the text font
+// 2: set the text size
+// 3: set the text color
+// 4: get all default values for this type
+int Widget_Node::textstuff(int, Fl_Font&, int&, Fl_Color&) {
+ return 0;
+}
+
+
+
+void textcolor_common(Fl_Color c) {
+ Fl_Font n; int s;
+ int mod = 0;
+ for (Node *o = Fluid.proj.tree.first; o; o = o->next) {
+ if (o->selected && o->is_widget()) {
+ Widget_Node* q = (Widget_Node*)o;
+ q->textstuff(3,n,s,c); q->o->redraw();
+ mod = 1;
+ }
+ }
+ if (mod) Fluid.proj.set_modflag(1);
+}
+
+////////////////////////////////////////////////////////////////
+// Kludges to the panel for subclasses:
+
+
+
+
+//static void flex_margin_cb(Fl_Value_Input* i, void* v,
+// void (*load_margin)(Fl_Flex*,Fl_Value_Input*),
+// int (*update_margin)(Fl_Flex*,int)) {
+// if (v == LOAD) {
+// if (current_widget->is_a(Type::Flex)) {
+// load_margin((Fl_Flex*)current_widget->o, i);
+// }
+// } else {
+// int mod = 0;
+// int new_value = (int)i->value();
+// for (Node *o = Fluid.proj.tree.first; o; o = o->next) {
+// if (o->selected && o->is_a(Type::Flex)) {
+// Flex_Node* q = (Flex_Node*)o;
+// Fl_Flex* w = (Fl_Flex*)q->o;
+// if (update_margin(w, new_value)) {
+// w->layout();
+// mod = 1;
+// }
+// }
+// }
+// if (mod) Fluid.proj.set_modflag(1);
+// }
+//}
+
+
+
+
+static void load_gap(Fl_Flex *w, Fl_Value_Input* i)
+{
+ int v = w->gap();
+ i->value((double)v);
+}
+
+static int update_gap(Fl_Flex *w, int new_value)
+{
+ int g = w->gap();
+ if (new_value!=g) {
+ w->gap(new_value);
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+void flex_margin_gap_cb(Fl_Value_Input* i, void* v) {
+ flex_margin_cb(i, v, load_gap, update_gap);
+}
+
+void position_group_cb(Fl_Group* g, void* v) {
+ if (v == LOAD) {
+ if (Flex_Node::parent_is_flex(current_widget)) {
+ g->hide();
+ } else {
+ g->show();
+ }
+ }
+ propagate_load(g, v);
+}
+
+
+
+////////////////////////////////////////////////////////////////
+
+// subtypes:
+
+Fl_Menu_Item *Widget_Node::subtypes() {return nullptr;}
+
+
+////////////////////////////////////////////////////////////////
+
+void propagate_load(Fl_Group* g, void* v) {
+ if (v == LOAD) {
+ Fl_Widget*const* a = g->array();
+ for (int i=g->children(); i--;) {
+ Fl_Widget* o = *a++;
+ o->do_callback(o, LOAD, FL_REASON_USER);
+ }
+ }
+}
+
+void set_cb(Fl_Button*, void*) {
+ haderror = 0;
+ Fl_Widget*const* a = the_panel->array();
+ for (int i=the_panel->children(); i--;) {
+ Fl_Widget* o = *a++;
+ if (o->changed()) {
+ o->do_callback();
+ if (haderror) return;
+ o->clear_changed();
+ }
+ }
+}
+
+void ok_cb(Fl_Return_Button* o, void* v) {
+ set_cb(o,v);
+ if (!haderror) the_panel->hide();
+}
+
+void toggle_overlays(Fl_Widget *,void *); // in Window_Node.cxx
+void overlay_cb(Fl_Button*o,void *v) {
+ toggle_overlays(o,v);
+}
+
+void leave_live_mode_cb(Fl_Widget*, void*);
+
+void live_mode_cb(Fl_Button*o,void *) {
+ /// \todo live mode should end gracefully when the application quits
+ /// or when the user closes the live widget
+ static Node *live_type = nullptr;
+ static Fl_Widget *live_widget = nullptr;
+ static Fl_Window *live_window = nullptr;
+ // if 'o' is 0, we must quit live mode
+ if (!o) {
+ o = wLiveMode;
+ o->value(0);
+ }
+ if (o->value()) {
+ if (numselected == 1) {
+ Fl_Group::current(nullptr);
+ live_widget = current_widget->enter_live_mode(1);
+ if (live_widget) {
+ live_type = current_widget;
+ Fl_Group::current(nullptr);
+ int w = live_widget->w();
+ int h = live_widget->h();
+ live_window = new Fl_Double_Window(w+20, h+55, "Fluid Live Resize");
+ live_window->box(FL_FLAT_BOX);
+ live_window->color(FL_GREEN);
+ Fl_Group *rsz = new Fl_Group(0, h+20, 130, 35);
+ rsz->box(FL_NO_BOX);
+ Fl_Box *rsz_dummy = new Fl_Box(110, h+20, 1, 25);
+ rsz_dummy->box(FL_NO_BOX);
+ rsz->resizable(rsz_dummy);
+ Fl_Button *btn = new Fl_Button(10, h+20, 100, 25, "Exit Live Resize");
+ btn->labelsize(12);
+ btn->callback(leave_live_mode_cb);
+ rsz->end();
+ live_window->add(live_widget);
+ live_widget->position(10, 10);
+ live_window->resizable(live_widget);
+ live_window->set_modal(); // block all other UI
+ live_window->callback(leave_live_mode_cb);
+ if (current_widget->is_a(Type::Window)) {
+ Window_Node *w = (Window_Node*)current_widget;
+ int mw = w->sr_min_w; if (mw>0) mw += 20;
+ int mh = w->sr_min_h; if (mh>0) mh += 55;
+ int MW = w->sr_max_w; if (MW>0) MW += 20;
+ int MH = w->sr_max_h; if (MH>2) MH += 55;
+ if (mw || mh || MW || MH)
+ live_window->size_range(mw, mh, MW, MH);
+ }
+ live_window->show();
+ live_widget->show();
+ } else o->value(0);
+ } else o->value(0);
+ } else {
+ if (live_type)
+ live_type->leave_live_mode();
+ if (live_window) {
+ live_window->hide();
+ Fl::delete_widget(live_window);
+ }
+ live_type = nullptr;
+ live_widget = nullptr;
+ live_window = nullptr;
+ }
+}
+
+// update the panel according to current widget set:
+void load_panel() {
+ if (!the_panel) return;
+
+ // find all the Fl_Widget subclasses currently selected:
+ numselected = 0;
+ current_widget = nullptr;
+ if (Fluid.proj.tree.current) {
+ if (Fluid.proj.tree.current->is_widget())
+ current_widget=(Widget_Node*)Fluid.proj.tree.current;
+ for (Node *o = Fluid.proj.tree.first; o; o = o->next) {
+ if (o->is_widget() && o->selected) {
+ numselected++;
+ if (!current_widget) current_widget = (Widget_Node*)o;
+ }
+ }
+ }
+ if (current_widget && current_widget->is_a(Type::Grid)) {
+ if (widget_tab_grid->parent()!=widget_tabs)
+ widget_tabs->add(widget_tab_grid);
+ } else {
+ if (widget_tab_grid->parent()==widget_tabs) {
+ widget_tabs_repo->add(widget_tab_grid);
+ }
+ }
+ if (current_widget && current_widget->parent && current_widget->parent->is_a(Type::Grid)) {
+ if (widget_tab_grid_child->parent()!=widget_tabs)
+ widget_tabs->add(widget_tab_grid_child);
+ } else {
+ if (widget_tab_grid_child->parent()==widget_tabs) {
+ widget_tabs_repo->add(widget_tab_grid_child);
+ }
+ }
+ if (numselected)
+ propagate_load(the_panel, LOAD);
+ else
+ the_panel->hide();
+}
+
+extern Fl_Window *widgetbin_panel;
+
+// This is called when user double-clicks an item, open or update the panel:
+void Widget_Node::open() {
+ bool adjust_position = false;
+ if (!the_panel) {
+ the_panel = make_widget_panel();
+ adjust_position = true;
+ }
+ load_panel();
+ if (numselected) {
+ the_panel->show();
+ if (adjust_position) {
+ if (widgetbin_panel && widgetbin_panel->visible()) {
+ if ( (the_panel->x()+the_panel->w() > widgetbin_panel->x())
+ && (the_panel->x() < widgetbin_panel->x()+widgetbin_panel->w())
+ && (the_panel->y()+the_panel->h() > widgetbin_panel->y())
+ && (the_panel->y() < widgetbin_panel->y()+widgetbin_panel->h()) )
+ {
+ if (widgetbin_panel->y()+widgetbin_panel->h()+the_panel->h() > Fl::h())
+ the_panel->position(the_panel->x(), widgetbin_panel->y()-the_panel->h()-30);
+ else
+ the_panel->position(the_panel->x(), widgetbin_panel->y()+widgetbin_panel->h()+30);
+ }
+ }
+ }
+ }
+}
+
+extern void redraw_overlays();
+extern void check_redraw_corresponding_parent(Node*);
+extern void redraw_browser();
+extern void update_codeview_position();
+
+// Called when ui changes what objects are selected:
+// p is selected object, null for all deletions (we must throw away
+// old panel in that case, as the object may no longer exist)
+void selection_changed(Node *p) {
+ // store all changes to the current selected objects:
+ if (p && the_panel && the_panel->visible()) {
+ set_cb(nullptr,nullptr);
+ // if there was an error, we try to leave the selected set unchanged:
+ if (haderror) {
+ Node *q = nullptr;
+ for (Node *o = Fluid.proj.tree.first; o; o = o->next) {
+ o->new_selected = o->selected;
+ if (!q && o->selected) q = o;
+ }
+ if (!p || !p->selected) p = q;
+ Fluid.proj.tree.current = p;
+ redraw_browser();
+ return;
+ }
+ }
+ // update the selected flags to new set:
+ Node *q = nullptr;
+ for (Node *o = Fluid.proj.tree.first; o; o = o->next) {
+ o->selected = o->new_selected;
+ if (!q && o->selected) q = o;
+ }
+ if (!p || !p->selected) p = q;
+ Fluid.proj.tree.current = p;
+ check_redraw_corresponding_parent(p);
+ redraw_overlays();
+ // load the panel with the new settings:
+ load_panel();
+ // update the code viewer to show the code for the selected object
+ update_codeview_position();
+}
+
+////////////////////////////////////////////////////////////////
+// Writing the C code:
+
+// test to see if user named a function, or typed in code:
+int is_name(const char *c) {
+ for (; *c; c++)
+ if ((ispunct(*c)||*c=='\n') && *c!='_' && *c!=':') return 0;
+ return 1;
+}
+
+// Test to see if name() is an array entry. If so, and this is the
+// highest number, return name[num+1]. Return null if not the highest
+// number or a field or function. Return name() if not an array entry.
+const char *array_name(Widget_Node *o) {
+ const char *c = o->name();
+ if (!c) return nullptr;
+ const char *d;
+ for (d = c; *d != '['; d++) {
+ if (!*d) return c;
+ if (ispunct(*d) && *d!='_') return nullptr;
+ }
+ int num = atoi(d+1);
+ int sawthis = 0;
+ Node *t = o->prev;
+ Node *tp = o;
+ const char *cn = o->class_name(1);
+ for (; t && t->class_name(1) == cn; tp = t, t = t->prev) {/*empty*/}
+ for (t = tp; t && t->class_name(1) == cn; t = t->next) {
+ if (t == o) {sawthis=1; continue;}
+ const char *e = t->name();
+ if (!e) continue;
+ if (strncmp(c,e,d-c)) continue;
+ int n1 = atoi(e+(d-c)+1);
+ if (n1 > num || (n1==num && sawthis)) return nullptr;
+ }
+ static char buffer[128];
+ // MRS: we want strncpy() here...
+ strncpy(buffer,c,d-c+1);
+ snprintf(buffer+(d-c+1),sizeof(buffer) - (d-c+1), "%d]",num+1);
+ return buffer;
+}
+
+// Test to see if extra code is a declaration:
+int isdeclare(const char *c) {
+ while (isspace(*c)) c++;
+ if (*c == '#') return 1;
+ if (!strncmp(c,"extern",6)) return 1;
+ if (!strncmp(c,"typedef",7)) return 1;
+ if (!strncmp(c,"using",5)) return 1;
+ return 0;
+}
+
+void Widget_Node::write_static(fld::io::Code_Writer& f) {
+ const char* t = subclassname(this);
+ if (!subclass() || (is_class() && !strncmp(t, "Fl_", 3))) {
+ f.write_h_once("#include <FL/Fl.H>");
+ f.write_h_once("#include <FL/%s.H>", t);
+ }
+ for (int n=0; n < NUM_EXTRA_CODE; n++) {
+ if (extra_code(n) && isdeclare(extra_code(n)))
+ f.write_h_once("%s", extra_code(n));
+ }
+ if (callback() && is_name(callback())) {
+ int write_extern_declaration = 1;
+ char buf[1024]; snprintf(buf, 1023, "%s(*)", callback());
+ if (is_in_class()) {
+ if (has_function("static void", buf))
+ write_extern_declaration = 0;
+ } else {
+ if (has_toplevel_function(nullptr, buf))
+ write_extern_declaration = 0;
+ }
+ if (write_extern_declaration)
+ f.write_h_once("extern void %s(%s*, %s);", callback(), t,
+ user_data_type() ? user_data_type() : "void*");
+ }
+ const char* k = class_name(1);
+ const char* c = array_name(this);
+ if (c && !k && !is_class()) {
+ f.write_c("\n");
+ if (!public_) f.write_c("static ");
+ else f.write_h("extern %s *%s;\n", t, c);
+ if (strchr(c, '[') == nullptr) f.write_c("%s *%s=(%s *)0;\n", t, c, t);
+ else f.write_c("%s *%s={(%s *)0};\n", t, c, t);
+ }
+ if (callback() && !is_name(callback())) {
+ // see if 'o' or 'v' used, to prevent unused argument warnings:
+ int use_o = 0;
+ int use_v = 0;
+ const char *d;
+ for (d = callback(); *d;) {
+ if (*d == 'o' && !is_id(d[1])) use_o = 1;
+ if (*d == 'v' && !is_id(d[1])) use_v = 1;
+ do d++; while (is_id(*d));
+ while (*d && !is_id(*d)) d++;
+ }
+ const char* cn = callback_name(f);
+ if (k) {
+ f.write_c("\nvoid %s::%s_i(%s*", k, cn, t);
+ } else {
+ f.write_c("\nstatic void %s(%s*", cn, t);
+ }
+ if (use_o) f.write_c(" o");
+ const char* ut = user_data_type() ? user_data_type() : "void*";
+ f.write_c(", %s", ut);
+ if (use_v) f.write_c(" v");
+ f.write_c(") {\n");
+ // Matt: disabled f.tag(FD_TAG_GENERIC, 0);
+ f.write_c_indented(callback(), 1, 0);
+ if (*(d-1) != ';' && *(d-1) != '}') {
+ const char *p = strrchr(callback(), '\n');
+ if (p) p ++;
+ else p = callback();
+ // Only add trailing semicolon if the last line is not a preprocessor
+ // statement...
+ if (*p != '#' && *p) f.write_c(";");
+ }
+ f.write_c("\n");
+ // Matt: disabled f.tag(FD_TAG_WIDGET_CALLBACK, get_uid());
+ f.write_c("}\n");
+ if (k) {
+ f.write_c("void %s::%s(%s* o, %s v) {\n", k, cn, t, ut);
+ f.write_c("%s((%s*)(o", f.indent(1), k);
+ Node *q = nullptr;
+ for (Node* p = parent; p && p->is_widget(); q = p, p = p->parent)
+ f.write_c("->parent()");
+ if (!q || !q->is_a(Type::Widget_Class))
+ f.write_c("->user_data()");
+ f.write_c("))->%s_i(o,v);\n}\n", cn);
+ }
+ }
+ if (image) {
+ if (!f.c_contains(image))
+ image->write_static(f, compress_image_);
+ }
+ if (inactive) {
+ if (!f.c_contains(inactive))
+ inactive->write_static(f, compress_deimage_);
+ }
+}
+
+void Widget_Node::write_code1(fld::io::Code_Writer& f) {
+ const char* t = subclassname(this);
+ const char *c = array_name(this);
+ if (c) {
+ if (class_name(1)) {
+ f.write_public(public_);
+ f.write_h("%s%s *%s;\n", f.indent(1), t, c);
+ }
+ }
+ if (class_name(1) && callback() && !is_name(callback())) {
+ const char* cn = callback_name(f);
+ const char* ut = user_data_type() ? user_data_type() : "void*";
+ f.write_public(0);
+ f.write_h("%sinline void %s_i(%s*, %s);\n", f.indent(1), cn, t, ut);
+ f.write_h("%sstatic void %s(%s*, %s);\n", f.indent(1), cn, t, ut);
+ }
+ // figure out if local variable will be used (prevent compiler warnings):
+ int wused = !name() && is_a(Type::Window);
+ const char *ptr;
+
+ f.varused = wused;
+
+ if (!name() && !f.varused) {
+ f.varused |= can_have_children();
+
+ if (!f.varused) {
+ f.varused_test = 1;
+ write_widget_code(f);
+ f.varused_test = 0;
+ }
+ }
+
+ if (!f.varused) {
+ for (int n=0; n < NUM_EXTRA_CODE; n++)
+ if (extra_code(n) && !isdeclare(extra_code(n)))
+ {
+ int instring = 0;
+ int inname = 0;
+ int incomment = 0;
+ int incppcomment = 0;
+ for (ptr = extra_code(n); *ptr; ptr ++) {
+ if (instring) {
+ if (*ptr == '\\') ptr++;
+ else if (*ptr == '\"') instring = 0;
+ } else if (inname && !isalnum(*ptr & 255)) {
+ inname = 0;
+ } else if (*ptr == '/' && ptr[1]=='*') {
+ incomment = 1; ptr++;
+ } else if (incomment) {
+ if (*ptr == '*' && ptr[1]=='/') {
+ incomment = 0; ptr++;
+ }
+ } else if (*ptr == '/' && ptr[1]=='/') {
+ incppcomment = 1; ptr++;
+ } else if (incppcomment) {
+ if (*ptr == '\n')
+ incppcomment = 0;
+ } else if (*ptr == '\"') {
+ instring = 1;
+ } else if (isalnum(*ptr & 255) || *ptr == '_') {
+ size_t len = strspn(ptr, "0123456789_"
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
+ if (!strncmp(ptr, "o", len)) {
+ f.varused = 1;
+ break;
+ } else {
+ ptr += len - 1;
+ }
+ }
+ }
+ }
+ }
+
+ f.write_c("%s{ ", f.indent());
+ write_comment_inline_c(f);
+ if (f.varused) f.write_c("%s* o = ", t);
+ if (name()) f.write_c("%s = ", name());
+ if (is_a(Type::Window)) {
+ // Handle special case where user is faking a Fl_Group type as a window,
+ // there is no 2-argument constructor in that case:
+ if (!strstr(t, "Window"))
+ f.write_c("new %s(0, 0, %d, %d", t, o->w(), o->h());
+ else
+ f.write_c("new %s(%d, %d", t, o->w(), o->h());
+ } else if (is_a(Type::Menu_Bar)
+ && ((Menu_Bar_Node*)this)->is_sys_menu_bar()
+ && is_in_class()) {
+ f.write_c("(%s*)new %s(%d, %d, %d, %d",
+ t, ((Menu_Bar_Node*)this)->sys_menubar_proxy_name(),
+ o->x(), o->y(), o->w(), o->h());
+ } else {
+ f.write_c("new %s(%d, %d, %d, %d", t, o->x(), o->y(), o->w(), o->h());
+ }
+ if (label() && *label()) {
+ f.write_c(", ");
+ switch (Fluid.proj.i18n_type) {
+ case fld::I18n_Type::NONE : /* None */
+ f.write_cstring(label());
+ break;
+ case fld::I18n_Type::GNU : /* GNU gettext */
+ f.write_c("%s(", Fluid.proj.i18n_gnu_function.c_str());
+ f.write_cstring(label());
+ f.write_c(")");
+ break;
+ case fld::I18n_Type::POSIX : /* POSIX catgets */
+ f.write_c("catgets(%s,%s,%d,",
+ Fluid.proj.i18n_pos_file.empty() ? "_catalog" : Fluid.proj.i18n_pos_file.c_str(),
+ Fluid.proj.i18n_pos_set.c_str(), msgnum());
+ f.write_cstring(label());
+ f.write_c(")");
+ break;
+ }
+ }
+ f.write_c(");\n");
+
+ f.indentation++;
+
+ // Avoid compiler warning for unused variable.
+ // Also avoid quality control warnings about incorrect allocation error handling.
+ if (wused) f.write_c("%sw = o; (void)w;\n", f.indent());
+
+ write_widget_code(f);
+}
+
+void Widget_Node::write_color(fld::io::Code_Writer& f, const char* field, Fl_Color color) {
+ const char* color_name = nullptr;
+ switch (color) {
+ case FL_FOREGROUND_COLOR: color_name = "FL_FOREGROUND_COLOR"; break;
+ case FL_BACKGROUND2_COLOR: color_name = "FL_BACKGROUND2_COLOR"; break;
+ case FL_INACTIVE_COLOR: color_name = "FL_INACTIVE_COLOR"; break;
+ case FL_SELECTION_COLOR: color_name = "FL_SELECTION_COLOR"; break;
+ case FL_GRAY0: color_name = "FL_GRAY0"; break;
+ case FL_DARK3: color_name = "FL_DARK3"; break;
+ case FL_DARK2: color_name = "FL_DARK2"; break;
+ case FL_DARK1: color_name = "FL_DARK1"; break;
+ case FL_BACKGROUND_COLOR: color_name = "FL_BACKGROUND_COLOR"; break;
+ case FL_LIGHT1: color_name = "FL_LIGHT1"; break;
+ case FL_LIGHT2: color_name = "FL_LIGHT2"; break;
+ case FL_LIGHT3: color_name = "FL_LIGHT3"; break;
+ case FL_BLACK: color_name = "FL_BLACK"; break;
+ case FL_RED: color_name = "FL_RED"; break;
+ case FL_GREEN: color_name = "FL_GREEN"; break;
+ case FL_YELLOW: color_name = "FL_YELLOW"; break;
+ case FL_BLUE: color_name = "FL_BLUE"; break;
+ case FL_MAGENTA: color_name = "FL_MAGENTA"; break;
+ case FL_CYAN: color_name = "FL_CYAN"; break;
+ case FL_DARK_RED: color_name = "FL_DARK_RED"; break;
+ case FL_DARK_GREEN: color_name = "FL_DARK_GREEN"; break;
+ case FL_DARK_YELLOW: color_name = "FL_DARK_YELLOW"; break;
+ case FL_DARK_BLUE: color_name = "FL_DARK_BLUE"; break;
+ case FL_DARK_MAGENTA: color_name = "FL_DARK_MAGENTA"; break;
+ case FL_DARK_CYAN: color_name = "FL_DARK_CYAN"; break;
+ case FL_WHITE: color_name = "FL_WHITE"; break;
+ }
+ const char *var = is_class() ? "this" : name() ? name() : "o";
+ if (color_name) {
+ f.write_c("%s%s->%s(%s);\n", f.indent(), var, field, color_name);
+ } else {
+ f.write_c("%s%s->%s((Fl_Color)%d);\n", f.indent(), var, field, color);
+ }
+}
+
+// this is split from write_code1(fld::io::Code_Writer& f) for Window_Node:
+void Widget_Node::write_widget_code(fld::io::Code_Writer& f) {
+ Fl_Widget* tplate = ((Widget_Node*)factory)->o;
+ const char *var = is_class() ? "this" : name() ? name() : "o";
+
+ if (tooltip() && *tooltip()) {
+ f.write_c("%s%s->tooltip(",f.indent(), var);
+ switch (Fluid.proj.i18n_type) {
+ case fld::I18n_Type::NONE : /* None */
+ f.write_cstring(tooltip());
+ break;
+ case fld::I18n_Type::GNU : /* GNU gettext */
+ f.write_c("%s(", Fluid.proj.i18n_gnu_function.c_str());
+ f.write_cstring(tooltip());
+ f.write_c(")");
+ break;
+ case fld::I18n_Type::POSIX : /* POSIX catgets */
+ f.write_c("catgets(%s,%s,%d,",
+ Fluid.proj.i18n_pos_file.empty() ? "_catalog" : Fluid.proj.i18n_pos_file.c_str(),
+ Fluid.proj.i18n_pos_set.c_str(),
+ msgnum() + 1);
+ f.write_cstring(tooltip());
+ f.write_c(")");
+ break;
+ }
+ f.write_c(");\n");
+ }
+
+ if (is_a(Type::Spinner) && ((Fl_Spinner*)o)->type() != ((Fl_Spinner*)tplate)->type())
+ f.write_c("%s%s->type(%d);\n", f.indent(), var, ((Fl_Spinner*)o)->type());
+ else if (o->type() != tplate->type() && !is_a(Type::Window))
+ f.write_c("%s%s->type(%d);\n", f.indent(), var, o->type());
+ if (o->box() != tplate->box() || subclass())
+ f.write_c("%s%s->box(FL_%s);\n", f.indent(), var, boxname(o->box()));
+
+ // write shortcut command if needed
+ int shortcut = 0;
+ if (is_button()) shortcut = ((Fl_Button*)o)->shortcut();
+ else if (is_a(Type::Input)) shortcut = ((Fl_Input_*)o)->shortcut();
+ else if (is_a(Type::Value_Input)) shortcut = ((Fl_Value_Input*)o)->shortcut();
+ else if (is_a(Type::Text_Display)) shortcut = ((Fl_Text_Display*)o)->shortcut();
+ if (shortcut) {
+ int s = shortcut;
+ f.write_c("%s%s->shortcut(", f.indent(), var);
+ if (Fluid.proj.use_FL_COMMAND) {
+ if (s & FL_CTRL) { f.write_c("FL_CONTROL|"); s &= ~FL_CTRL; }
+ if (s & FL_META) { f.write_c("FL_COMMAND|"); s &= ~FL_META; }
+ } else {
+ if (s & FL_CTRL) { f.write_c("FL_CTRL|"); s &= ~FL_CTRL; }
+ if (s & FL_META) { f.write_c("FL_META|"); s &= ~FL_META; }
+ }
+ if (s & FL_SHIFT) { f.write_c("FL_SHIFT|"); s &= ~FL_SHIFT; }
+ if (s & FL_ALT) { f.write_c("FL_ALT|"); s &= ~FL_ALT; }
+ if ((s < 127) && isprint(s))
+ f.write_c("'%c');\n", s);
+ else
+ f.write_c("0x%x);\n", s);
+ }
+
+ if (is_a(Type::Button)) {
+ Fl_Button* b = (Fl_Button*)o;
+ if (b->down_box()) f.write_c("%s%s->down_box(FL_%s);\n", f.indent(), var,
+ boxname(b->down_box()));
+ if (b->value()) f.write_c("%s%s->value(1);\n", f.indent(), var);
+ if (b->compact()) f.write_c("%s%s->compact(%d);\n", f.indent(), var, b->compact());
+ } else if (is_a(Type::Input_Choice)) {
+ Fl_Input_Choice* b = (Fl_Input_Choice*)o;
+ if (b->down_box()) f.write_c("%s%s->down_box(FL_%s);\n", f.indent(), var,
+ boxname(b->down_box()));
+ } else if (is_a(Type::Menu_Manager_)) {
+ Fl_Menu_* b = (Fl_Menu_*)o;
+ if (b->down_box()) f.write_c("%s%s->down_box(FL_%s);\n", f.indent(), var,
+ boxname(b->down_box()));
+ }
+ if (o->color() != tplate->color() || subclass())
+ write_color(f, "color", o->color());
+ if (o->selection_color() != tplate->selection_color() || subclass())
+ write_color(f, "selection_color", o->selection_color());
+ if (image) {
+ image->write_code(f, bind_image_, var);
+ if (scale_image_w_ || scale_image_h_) {
+ f.write_c("%s%s->image()->scale(", f.indent(), var);
+ if (scale_image_w_>0)
+ f.write_c("%d, ", scale_image_w_);
+ else
+ f.write_c("%s->image()->data_w(), ", var);
+ if (scale_image_h_>0)
+ f.write_c("%d, 0, 1);\n", scale_image_h_);
+ else
+ f.write_c("%s->image()->data_h(), 0, 1);\n", var);
+ }
+ }
+ if (inactive) {
+ inactive->write_code(f, bind_deimage_, var, 1);
+ if (scale_deimage_w_ || scale_deimage_h_) {
+ f.write_c("%s%s->deimage()->scale(", f.indent(), var);
+ if (scale_deimage_w_>0)
+ f.write_c("%d, ", scale_deimage_w_);
+ else
+ f.write_c("%s->deimage()->data_w(), ", var);
+ if (scale_deimage_h_>0)
+ f.write_c("%d, 0, 1);\n", scale_deimage_h_);
+ else
+ f.write_c("%s->deimage()->data_h(), 0, 1);\n", var);
+ }
+ }
+ if (o->labeltype() != tplate->labeltype() || subclass())
+ f.write_c("%s%s->labeltype(FL_%s);\n", f.indent(), var,
+ item_name(labeltypemenu, o->labeltype()));
+ if (o->labelfont() != tplate->labelfont() || subclass())
+ f.write_c("%s%s->labelfont(%d);\n", f.indent(), var, o->labelfont());
+ if (o->labelsize() != tplate->labelsize() || subclass())
+ f.write_c("%s%s->labelsize(%d);\n", f.indent(), var, o->labelsize());
+ if (o->labelcolor() != tplate->labelcolor() || subclass())
+ write_color(f, "labelcolor", o->labelcolor());
+ if (o->horizontal_label_margin() != tplate->horizontal_label_margin())
+ f.write_c("%s%s->horizontal_label_margin(%d);\n", f.indent(), var, o->horizontal_label_margin());
+ if (o->vertical_label_margin() != tplate->vertical_label_margin())
+ f.write_c("%s%s->vertical_label_margin(%d);\n", f.indent(), var, o->vertical_label_margin());
+ if (o->label_image_spacing() != tplate->label_image_spacing())
+ f.write_c("%s%s->label_image_spacing(%d);\n", f.indent(), var, o->label_image_spacing());
+ if (is_a(Type::Valuator_)) {
+ Fl_Valuator* v = (Fl_Valuator*)o;
+ Fl_Valuator* t = (Fl_Valuator*)(tplate);
+ if (v->minimum()!=t->minimum())
+ f.write_c("%s%s->minimum(%g);\n", f.indent(), var, v->minimum());
+ if (v->maximum()!=t->maximum())
+ f.write_c("%s%s->maximum(%g);\n", f.indent(), var, v->maximum());
+ if (v->step()!=t->step())
+ f.write_c("%s%s->step(%g);\n", f.indent(), var, v->step());
+ if (v->value()) {
+ if (is_a(Type::Scrollbar)) { // Fl_Scrollbar::value(double) is not available
+ f.write_c("%s%s->Fl_Slider::value(%g);\n", f.indent(), var, v->value());
+ } else {
+ f.write_c("%s%s->value(%g);\n", f.indent(), var, v->value());
+ }
+ }
+ if (is_a(Type::Slider)) {
+ double x = ((Fl_Slider*)v)->slider_size();
+ double y = ((Fl_Slider*)t)->slider_size();
+ if (x != y) f.write_c("%s%s->slider_size(%g);\n", f.indent(), var, x);
+ }
+ }
+ if (is_a(Type::Spinner)) {
+ Fl_Spinner* v = (Fl_Spinner*)o;
+ Fl_Spinner* t = (Fl_Spinner*)(tplate);
+ if (v->minimum()!=t->minimum())
+ f.write_c("%s%s->minimum(%g);\n", f.indent(), var, v->minimum());
+ if (v->maximum()!=t->maximum())
+ f.write_c("%s%s->maximum(%g);\n", f.indent(), var, v->maximum());
+ if (v->step()!=t->step())
+ f.write_c("%s%s->step(%g);\n", f.indent(), var, v->step());
+ if (v->value()!=1.0f)
+ f.write_c("%s%s->value(%g);\n", f.indent(), var, v->value());
+ }
+
+ {Fl_Font ff; int fs; Fl_Color fc; if (textstuff(4,ff,fs,fc)) {
+ Fl_Font g; int s; Fl_Color c; textstuff(0,g,s,c);
+ if (g != ff) f.write_c("%s%s->textfont(%d);\n", f.indent(), var, g);
+ if (s != fs) f.write_c("%s%s->textsize(%d);\n", f.indent(), var, s);
+ if (c != fc) write_color(f, "textcolor", c);
+ }}
+ const char* ud = user_data();
+ if (class_name(1) && !parent->is_widget()) ud = "this";
+ if (callback()) {
+ f.write_c("%s%s->callback((Fl_Callback*)%s", f.indent(), var, callback_name(f));
+ if (ud)
+ f.write_c(", (void*)(%s));\n", ud);
+ else
+ f.write_c(");\n");
+ } else if (ud) {
+ f.write_c("%s%s->user_data((void*)(%s));\n", f.indent(), var, ud);
+ }
+ if (o->align() != tplate->align() || subclass()) {
+ int i = o->align();
+ f.write_c("%s%s->align(Fl_Align(%s", f.indent(), var,
+ item_name(alignmenu, i & ~FL_ALIGN_INSIDE));
+ if (i & FL_ALIGN_INSIDE) f.write_c("|FL_ALIGN_INSIDE");
+ f.write_c("));\n");
+ }
+ Fl_When ww = o->when();
+ if (ww != tplate->when() || subclass())
+ f.write_c("%s%s->when(%s);\n", f.indent(), var, when_symbol_name(ww));
+ if (!o->visible() && o->parent())
+ 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_a(Type::Group) && resizable())
+ f.write_c("%sFl_Group::current()->resizable(%s);\n", f.indent(), var);
+ if (hotspot()) {
+ if (is_class())
+ f.write_c("%shotspot(%s);\n", f.indent(), var);
+ else if (is_a(Type::Window))
+ f.write_c("%s%s->hotspot(%s);\n", f.indent(), var, var);
+ else
+ f.write_c("%s%s->window()->hotspot(%s);\n", f.indent(), var, var);
+ }
+}
+
+void Widget_Node::write_extra_code(fld::io::Code_Writer& f) {
+ for (int n=0; n < NUM_EXTRA_CODE; n++)
+ if (extra_code(n) && !isdeclare(extra_code(n)))
+ f.write_c("%s%s\n", f.indent(), extra_code(n));
+}
+
+void Widget_Node::write_block_close(fld::io::Code_Writer& f) {
+ f.indentation--;
+ f.write_c("%s} // %s* %s\n", f.indent(), subclassname(this),
+ name() ? name() : "o");
+}
+
+void Widget_Node::write_code2(fld::io::Code_Writer& f) {
+ write_extra_code(f);
+ write_block_close(f);
+}
+
+////////////////////////////////////////////////////////////////
+
+void Widget_Node::write_properties(fld::io::Project_Writer &f) {
+ Node::write_properties(f);
+ f.write_indent(level+1);
+ switch (public_) {
+ case 0: f.write_string("private"); break;
+ case 1: break;
+ case 2: f.write_string("protected"); break;
+ }
+ if (tooltip() && *tooltip()) {
+ f.write_string("tooltip");
+ f.write_word(tooltip());
+ }
+ if (image_name() && *image_name()) {
+ if (scale_image_w_ || scale_image_h_)
+ f.write_string("scale_image {%d %d}", scale_image_w_, scale_image_h_);
+ f.write_string("image");
+ f.write_word(image_name());
+ f.write_string("compress_image %d", compress_image_);
+ }
+ if (bind_image_) f.write_string("bind_image 1");
+ if (inactive_name() && *inactive_name()) {
+ if (scale_deimage_w_ || scale_deimage_h_)
+ f.write_string("scale_deimage {%d %d}", scale_deimage_w_, scale_deimage_h_);
+ f.write_string("deimage");
+ f.write_word(inactive_name());
+ f.write_string("compress_deimage %d", compress_deimage_);
+ }
+ if (bind_deimage_) f.write_string("bind_deimage 1");
+ f.write_string("xywh {%d %d %d %d}", o->x(), o->y(), o->w(), o->h());
+ Fl_Widget* tplate = ((Widget_Node*)factory)->o;
+ if (is_a(Type::Spinner) && ((Fl_Spinner*)o)->type() != ((Fl_Spinner*)tplate)->type()) {
+ f.write_string("type");
+ f.write_word(item_name(subtypes(), ((Fl_Spinner*)o)->type()));
+ } else if (subtypes() && (o->type() != tplate->type() || is_a(Type::Window))) {
+ f.write_string("type");
+ f.write_word(item_name(subtypes(), o->type()));
+ }
+ if (o->box() != tplate->box()) {
+ f.write_string("box"); f.write_word(boxname(o->box()));}
+ if (is_a(Type::Input)) {
+ Fl_Input_* b = (Fl_Input_*)o;
+ if (b->shortcut()) f.write_string("shortcut 0x%x", b->shortcut());
+ }
+ if (is_a(Type::Value_Input)) {
+ Fl_Value_Input* b = (Fl_Value_Input*)o;
+ if (b->shortcut()) f.write_string("shortcut 0x%x", b->shortcut());
+ }
+ if (is_a(Type::Text_Display)) {
+ Fl_Text_Display* b = (Fl_Text_Display*)o;
+ if (b->shortcut()) f.write_string("shortcut 0x%x", b->shortcut());
+ }
+ if (is_a(Type::Button)) {
+ Fl_Button* b = (Fl_Button*)o;
+ if (b->down_box()) {
+ f.write_string("down_box"); f.write_word(boxname(b->down_box()));}
+ if (b->shortcut()) f.write_string("shortcut 0x%x", b->shortcut());
+ if (b->value()) f.write_string("value 1");
+ } else if (is_a(Type::Input_Choice)) {
+ Fl_Input_Choice* b = (Fl_Input_Choice*)o;
+ if (b->down_box()) {
+ f.write_string("down_box"); f.write_word(boxname(b->down_box()));}
+ } else if (is_a(Type::Menu_)) {
+ Fl_Menu_* b = (Fl_Menu_*)o;
+ if (b->down_box()) {
+ f.write_string("down_box"); f.write_word(boxname(b->down_box()));}
+ }
+ if (o->color()!=tplate->color())
+ f.write_string("color %d", o->color());
+ if (o->selection_color()!=tplate->selection_color())
+ f.write_string("selection_color %d", o->selection_color());
+ if (o->labeltype()!=tplate->labeltype()) {
+ f.write_string("labeltype");
+ f.write_word(item_name(labeltypemenu, o->labeltype()));
+ }
+ if (o->labelfont()!=tplate->labelfont())
+ f.write_string("labelfont %d", o->labelfont());
+ if (o->labelsize()!=tplate->labelsize())
+ f.write_string("labelsize %d", o->labelsize());
+ if (o->labelcolor()!=tplate->labelcolor())
+ f.write_string("labelcolor %d", o->labelcolor());
+ if (o->align()!=tplate->align())
+ f.write_string("align %d", o->align());
+ if (o->horizontal_label_margin()!=tplate->horizontal_label_margin())
+ f.write_string("h_label_margin %d", o->horizontal_label_margin());
+ if (o->vertical_label_margin()!=tplate->vertical_label_margin())
+ f.write_string("v_label_margin %d", o->vertical_label_margin());
+ if (o->label_image_spacing()!=tplate->label_image_spacing())
+ f.write_string("image_spacing %d", o->label_image_spacing());
+ if (o->when() != tplate->when())
+ f.write_string("when %d", o->when());
+ if (is_a(Type::Valuator_)) {
+ Fl_Valuator* v = (Fl_Valuator*)o;
+ Fl_Valuator* t = (Fl_Valuator*)(tplate);
+ if (v->minimum()!=t->minimum()) f.write_string("minimum %g",v->minimum());
+ if (v->maximum()!=t->maximum()) f.write_string("maximum %g",v->maximum());
+ if (v->step()!=t->step()) f.write_string("step %g",v->step());
+ if (v->value()!=0.0) f.write_string("value %g",v->value());
+ if (is_a(Type::Slider)) {
+ double x = ((Fl_Slider*)v)->slider_size();
+ double y = ((Fl_Slider*)t)->slider_size();
+ if (x != y) f.write_string("slider_size %g", x);
+ }
+ }
+ if (is_a(Type::Spinner)) {
+ Fl_Spinner* v = (Fl_Spinner*)o;
+ Fl_Spinner* t = (Fl_Spinner*)(tplate);
+ if (v->minimum()!=t->minimum()) f.write_string("minimum %g",v->minimum());
+ if (v->maximum()!=t->maximum()) f.write_string("maximum %g",v->maximum());
+ if (v->step()!=t->step()) f.write_string("step %g",v->step());
+ if (v->value()!=1.0) f.write_string("value %g",v->value());
+ }
+ {Fl_Font ff; int fs; Fl_Color fc; if (textstuff(4,ff,fs,fc)) {
+ Fl_Font ft; int s; Fl_Color c; textstuff(0,ft,s,c);
+ if (ft != ff) f.write_string("textfont %d", ft);
+ if (s != fs) f.write_string("textsize %d", s);
+ if (c != fc) f.write_string("textcolor %d", c);
+ }}
+ if (!o->visible() && !override_visible_) f.write_string("hide");
+ if (!o->active()) f.write_string("deactivate");
+ if (resizable()) f.write_string("resizable");
+ if (hotspot()) f.write_string(is_a(Type::Menu_Item) ? "divider" : "hotspot");
+ for (int n=0; n < NUM_EXTRA_CODE; n++) if (extra_code(n)) {
+ f.write_indent(level+1);
+ f.write_string("code%d",n);
+ f.write_word(extra_code(n));
+ }
+ if (subclass()) {
+ f.write_indent(level+1);
+ f.write_string("class");
+ f.write_word(subclass());
+ }
+}
+
+void Widget_Node::read_property(fld::io::Project_Reader &f, const char *c) {
+ int x,y,w,h; Fl_Font ft; int s; Fl_Color cc;
+ if (!strcmp(c,"private")) {
+ public_ = 0;
+ } else if (!strcmp(c,"protected")) {
+ public_ = 2;
+ } else if (!strcmp(c,"xywh")) {
+ if (sscanf(f.read_word(),"%d %d %d %d",&x,&y,&w,&h) == 4) {
+ x += Fluid.pasteoffset;
+ y += Fluid.pasteoffset;
+ // FIXME temporary change!
+ if (f.read_version>=2.0 && o->parent() && o->parent()!=o->window()) {
+ x += o->parent()->x();
+ y += o->parent()->y();
+ }
+ o->resize(x,y,w,h);
+ }
+ } else if (!strcmp(c,"tooltip")) {
+ tooltip(f.read_word());
+ } else if (!strcmp(c,"scale_image")) {
+ if (sscanf(f.read_word(),"%d %d",&w,&h) == 2) {
+ scale_image_w_ = w;
+ scale_image_h_ = h;
+ }
+ } else if (!strcmp(c,"image")) {
+ image_name(f.read_word());
+ // starting in 2023, `image` is always followed by `compress_image`
+ // the code below is for compatibility with older .fl files
+ const char *ext = fl_filename_ext(image_name_);
+ if ( strcmp(ext, ".jpg")
+ && strcmp(ext, ".png")
+ && strcmp(ext, ".svg")
+ && strcmp(ext, ".svgz"))
+ compress_image_ = 0; // if it is neither of those, default to uncompressed
+ } else if (!strcmp(c,"bind_image")) {
+ bind_image_ = (int)atol(f.read_word());
+ } else if (!strcmp(c,"compress_image")) {
+ compress_image_ = (int)atol(f.read_word());
+ } else if (!strcmp(c,"scale_deimage")) {
+ if (sscanf(f.read_word(),"%d %d",&w,&h) == 2) {
+ scale_deimage_w_ = w;
+ scale_deimage_h_ = h;
+ }
+ } else if (!strcmp(c,"deimage")) {
+ inactive_name(f.read_word());
+ // starting in 2023, `deimage` is always followed by `compress_deimage`
+ // the code below is for compatibility with older .fl files
+ const char *ext = fl_filename_ext(inactive_name_);
+ if ( strcmp(ext, ".jpg")
+ && strcmp(ext, ".png")
+ && strcmp(ext, ".svg")
+ && strcmp(ext, ".svgz"))
+ compress_deimage_ = 0; // if it is neither of those, default to uncompressed
+ } else if (!strcmp(c,"bind_deimage")) {
+ bind_deimage_ = (int)atol(f.read_word());
+ } else if (!strcmp(c,"compress_deimage")) {
+ compress_deimage_ = (int)atol(f.read_word());
+ } else if (!strcmp(c,"type")) {
+ if (is_a(Type::Spinner))
+ ((Fl_Spinner*)o)->type(item_number(subtypes(), f.read_word()));
+ else
+ o->type(item_number(subtypes(), f.read_word()));
+ } else if (!strcmp(c,"box")) {
+ const char* value = f.read_word();
+ if ((x = boxnumber(value))) {
+ if (x == ZERO_ENTRY) x = 0;
+ o->box((Fl_Boxtype)x);
+ } else if (sscanf(value,"%d",&x) == 1) o->box((Fl_Boxtype)x);
+ } else if (is_a(Type::Button) && !strcmp(c,"down_box")) {
+ const char* value = f.read_word();
+ if ((x = boxnumber(value))) {
+ if (x == ZERO_ENTRY) x = 0;
+ ((Fl_Button*)o)->down_box((Fl_Boxtype)x);
+ }
+ } else if (is_a(Type::Input_Choice) && !strcmp(c,"down_box")) {
+ const char* value = f.read_word();
+ if ((x = boxnumber(value))) {
+ if (x == ZERO_ENTRY) x = 0;
+ ((Fl_Input_Choice*)o)->down_box((Fl_Boxtype)x);
+ }
+ } else if (is_a(Type::Menu_) && !strcmp(c,"down_box")) {
+ const char* value = f.read_word();
+ if ((x = boxnumber(value))) {
+ if (x == ZERO_ENTRY) x = 0;
+ ((Fl_Menu_*)o)->down_box((Fl_Boxtype)x);
+ }
+ } else if (is_button() && !strcmp(c,"value")) {
+ const char* value = f.read_word();
+ ((Fl_Button*)o)->value(atoi(value));
+ } else if (!strcmp(c,"color")) {
+ const char *cw = f.read_word();
+ if (cw[0]=='0' && cw[1]=='x') {
+ sscanf(cw,"0x%x",&x);
+ o->color(x);
+ } else {
+ int n = sscanf(cw,"%d %d",&x,&y);
+ if (n == 2) { // back compatibility...
+ if (x != 47) o->color(x);
+ o->selection_color(y);
+ } else {
+ o->color(x);
+ }
+ }
+ } else if (!strcmp(c,"selection_color")) {
+ if (sscanf(f.read_word(),"%d",&x)) o->selection_color(x);
+ } else if (!strcmp(c,"labeltype")) {
+ c = f.read_word();
+ if (!strcmp(c,"image")) {
+ Image_Asset *i = Image_Asset::find(label());
+ if (!i) f.read_error("Image file '%s' not found", label());
+ else setimage(i);
+ image_name(label());
+ label("");
+ } else {
+ o->labeltype((Fl_Labeltype)item_number(labeltypemenu,c));
+ }
+ } else if (!strcmp(c,"labelfont")) {
+ if (sscanf(f.read_word(),"%d",&x) == 1) o->labelfont(x);
+ } else if (!strcmp(c,"labelsize")) {
+ if (sscanf(f.read_word(),"%d",&x) == 1) o->labelsize(x);
+ } else if (!strcmp(c,"labelcolor")) {
+ if (sscanf(f.read_word(),"%d",&x) == 1) o->labelcolor(x);
+ } else if (!strcmp(c,"align")) {
+ if (sscanf(f.read_word(),"%d",&x) == 1) o->align(x);
+ } else if (!strcmp(c,"h_label_margin")) {
+ if (sscanf(f.read_word(),"%d",&x) == 1) o->horizontal_label_margin(x);
+ } else if (!strcmp(c,"v_label_margin")) {
+ if (sscanf(f.read_word(),"%d",&x) == 1) o->vertical_label_margin(x);
+ } else if (!strcmp(c,"image_spacing")) {
+ if (sscanf(f.read_word(),"%d",&x) == 1) o->label_image_spacing(x);
+ } else if (!strcmp(c,"when")) {
+ if (sscanf(f.read_word(),"%d",&x) == 1) o->when(x);
+ } else if (!strcmp(c,"minimum")) {
+ if (is_a(Type::Valuator_)) ((Fl_Valuator*)o)->minimum(strtod(f.read_word(),nullptr));
+ if (is_a(Type::Spinner)) ((Fl_Spinner*)o)->minimum(strtod(f.read_word(),nullptr));
+ } else if (!strcmp(c,"maximum")) {
+ if (is_a(Type::Valuator_)) ((Fl_Valuator*)o)->maximum(strtod(f.read_word(),nullptr));
+ if (is_a(Type::Spinner)) ((Fl_Spinner*)o)->maximum(strtod(f.read_word(),nullptr));
+ } else if (!strcmp(c,"step")) {
+ if (is_a(Type::Valuator_)) ((Fl_Valuator*)o)->step(strtod(f.read_word(),nullptr));
+ if (is_a(Type::Spinner)) ((Fl_Spinner*)o)->step(strtod(f.read_word(),nullptr));
+ } else if (!strcmp(c,"value")) {
+ if (is_a(Type::Valuator_)) ((Fl_Valuator*)o)->value(strtod(f.read_word(),nullptr));
+ if (is_a(Type::Spinner)) ((Fl_Spinner*)o)->value(strtod(f.read_word(),nullptr));
+ } else if ( (!strcmp(c,"slider_size") || !strcmp(c,"size")) && is_a(Type::Slider)) {
+ ((Fl_Slider*)o)->slider_size(strtod(f.read_word(),nullptr));
+ } else if (!strcmp(c,"textfont")) {
+ if (sscanf(f.read_word(),"%d",&x) == 1) {ft=(Fl_Font)x; textstuff(1,ft,s,cc);}
+ } else if (!strcmp(c,"textsize")) {
+ if (sscanf(f.read_word(),"%d",&x) == 1) {s=x; textstuff(2,ft,s,cc);}
+ } else if (!strcmp(c,"textcolor")) {
+ if (sscanf(f.read_word(),"%d",&x) == 1) {cc=(Fl_Color)x;textstuff(3,ft,s,cc);}
+ } else if (!strcmp(c,"hide")) {
+ o->hide();
+ } else if (!strcmp(c,"deactivate")) {
+ o->deactivate();
+ } else if (!strcmp(c,"resizable")) {
+ resizable(1);
+ } else if (!strcmp(c,"hotspot") || !strcmp(c, "divider")) {
+ hotspot(1);
+ } else if (!strcmp(c,"class")) {
+ subclass(f.read_word());
+ } else if (!strcmp(c,"shortcut")) {
+ int shortcut = (int)strtol(f.read_word(),nullptr,0);
+ if (is_button()) ((Fl_Button*)o)->shortcut(shortcut);
+ else if (is_a(Type::Input)) ((Fl_Input_*)o)->shortcut(shortcut);
+ else if (is_a(Type::Value_Input)) ((Fl_Value_Input*)o)->shortcut(shortcut);
+ else if (is_a(Type::Text_Display)) ((Fl_Text_Display*)o)->shortcut(shortcut);
+ } else {
+ if (!strncmp(c,"code",4)) {
+ int n = atoi(c+4);
+ if (n >= 0 && n <= NUM_EXTRA_CODE) {
+ extra_code(n,f.read_word());
+ return;
+ }
+ } else if (!strcmp(c,"extra_code")) {
+ extra_code(0,f.read_word());
+ return;
+ }
+ Node::read_property(f, c);
+ }
+}
+
+Fl_Menu_Item boxmenu1[] = {
+ // these extra ones are for looking up fdesign saved strings:
+ {"NO_FRAME", 0,nullptr,(void *)FL_NO_BOX},
+ {"ROUNDED3D_UPBOX", 0,nullptr,(void *)_FL_ROUND_UP_BOX},
+ {"ROUNDED3D_DOWNBOX", 0,nullptr,(void *)_FL_ROUND_DOWN_BOX},
+ {"OVAL3D_UPBOX", 0,nullptr,(void *)_FL_ROUND_UP_BOX},
+ {"OVAL3D_DOWNBOX", 0,nullptr,(void *)_FL_ROUND_DOWN_BOX},
+ {"0", 0,nullptr,(void *)ZERO_ENTRY},
+ {"1", 0,nullptr,(void *)FL_UP_BOX},
+ {"2", 0,nullptr,(void *)FL_DOWN_BOX},
+ {"3", 0,nullptr,(void *)FL_FLAT_BOX},
+ {"4", 0,nullptr,(void *)FL_BORDER_BOX},
+ {"5", 0,nullptr,(void *)FL_SHADOW_BOX},
+ {"6", 0,nullptr,(void *)FL_FRAME_BOX},
+ {"7", 0,nullptr,(void *)FL_ROUNDED_BOX},
+ {"8", 0,nullptr,(void *)FL_RFLAT_BOX},
+ {"9", 0,nullptr,(void *)FL_RSHADOW_BOX},
+ {"10", 0,nullptr,(void *)FL_UP_FRAME},
+ {"11", 0,nullptr,(void *)FL_DOWN_FRAME},
+ {nullptr}};
+
+int lookup_symbol(const char *, int &, int numberok = 0);
+
+int Widget_Node::read_fdesign(const char* propname, const char* value) {
+ int v;
+ if (!strcmp(propname,"box")) {
+ float x,y,w,h;
+ if (sscanf(value,"%f %f %f %f",&x,&y,&w,&h) == 4) {
+ if (fld::io::fdesign_flip) {
+ Node *p;
+ for (p = parent; p && !p->is_a(Type::Window); p = p->parent) {/*empty*/}
+ if (p && p->is_widget()) y = ((Widget_Node*)p)->o->h()-(y+h);
+ }
+ x += Fluid.pasteoffset;
+ y += Fluid.pasteoffset;
+ o->resize(int(x),int(y),int(w),int(h));
+ }
+ } else if (!strcmp(propname,"label")) {
+ label(value);
+ } else if (!strcmp(propname,"name")) {
+ this->name(value);
+ } else if (!strcmp(propname,"callback")) {
+ callback(value); user_data_type("long");
+ } else if (!strcmp(propname,"argument")) {
+ user_data(value);
+ } else if (!strcmp(propname,"shortcut")) {
+ if (value[0]) {
+ char buf[128]; sprintf(buf,"o->shortcut(\"%s\");",value);
+ extra_code(0,buf);
+ }
+ } else if (!strcmp(propname,"style")) {
+ if (!strncmp(value,"FL_NORMAL",9)) return 1;
+ if (!lookup_symbol(value,v,1)) return 0;
+ o->labelfont(v); o->labeltype((Fl_Labeltype)(v>>8));
+ } else if (!strcmp(propname,"size")) {
+ if (!lookup_symbol(value,v,1)) return 0;
+ o->labelsize(v);
+ } else if (!strcmp(propname,"type")) {
+ if (!strncmp(value,"NORMAL",6)) return 1;
+ if (lookup_symbol(value,v,1)) {o->type(v); return 1;}
+ if (!strcmp(value+strlen(value)-5,"FRAME")) goto TRY_BOXTYPE;
+ if (!strcmp(value+strlen(value)-3,"BOX")) goto TRY_BOXTYPE;
+ return 0;
+ } else if (!strcmp(propname,"lcol")) {
+ if (!lookup_symbol(value,v,1)) return 0;
+ o->labelcolor(v);
+ } else if (!strcmp(propname,"return")) {
+ if (!lookup_symbol(value,v,0)) return 0;
+ o->when(v|FL_WHEN_RELEASE);
+ } else if (!strcmp(propname,"alignment")) {
+ if (!lookup_symbol(value,v)) {
+ // convert old numeric values:
+ int v1 = atoi(value); if (v1 <= 0 && strcmp(value,"0")) return 0;
+ v = 0;
+ if (v1 >= 5) {v = FL_ALIGN_INSIDE; v1 -= 5;}
+ switch (v1) {
+ case 0: v += FL_ALIGN_TOP; break;
+ case 1: v += FL_ALIGN_BOTTOM; break;
+ case 2: v += FL_ALIGN_LEFT; break;
+ case 3: v += FL_ALIGN_RIGHT; break;
+ case 4: v += FL_ALIGN_CENTER; break;
+ default: return 0;
+ }
+ }
+ o->align(v);
+ } else if (!strcmp(propname,"resizebox")) {
+ resizable(1);
+ } else if (!strcmp(propname,"colors")) {
+ char* p = (char*)value;
+ while (*p != ' ') {if (!*p) return 0; p++;}
+ *p = 0;
+ int v1;
+ if (!lookup_symbol(value,v,1) || !lookup_symbol(p+1,v1,1)) {
+ *p=' '; return 0;}
+ o->color(v,v1);
+ } else if (!strcmp(propname,"resize")) {
+ return !strcmp(value,"FL_RESIZE_ALL");
+ } else if (!strcmp(propname,"gravity")) {
+ return !strcmp(value,"FL_NoGravity FL_NoGravity");
+ } else if (!strcmp(propname,"boxtype")) {
+ TRY_BOXTYPE:
+ int x = boxnumber(value);
+ if (!x) {x = item_number(boxmenu1, value); if (x < 0) return 0;}
+ if (x == ZERO_ENTRY) {
+ x = 0;
+ if (o->box() != ((Widget_Node*)factory)->o->box()) return 1; // kludge for frame
+ }
+ o->box((Fl_Boxtype)x);
+ } else {
+ return 0;
+ }
+ return 1;
+}
+
+void leave_live_mode_cb(Fl_Widget*, void*) {
+ live_mode_cb(nullptr, nullptr);
+}
+
+Fl_Widget *Widget_Node::enter_live_mode(int) {
+ live_widget = widget(o->x(), o->y(), o->w(), o->h());
+ if (live_widget)
+ copy_properties();
+ return live_widget;
+}
+
+Fl_Widget* Widget_Node::propagate_live_mode(Fl_Group* grp) {
+ live_widget = grp;
+ copy_properties();
+ Node *n;
+ for (n = next; n && n->level > level; n = n->next) {
+ if (n->level == level+1) {
+ Fl_Widget* proxy_child = n->enter_live_mode();
+ if (proxy_child && n->is_widget() && ((Widget_Node*)n)->resizable()) {
+ grp->resizable(proxy_child);
+ }
+ }
+ }
+ grp->end();
+ live_widget = grp;
+ copy_properties_for_children();
+ return live_widget;
+}
+
+
+void Widget_Node::leave_live_mode() {
+}
+
+/**
+ copy all properties from the edit widget to the live widget
+ */
+void Widget_Node::copy_properties() {
+ if (!live_widget)
+ return;
+
+ Fl_Font ff = 0;
+ int fs = 0;
+ Fl_Color fc = 0;
+ textstuff(0, ff, fs, fc);
+
+ // copy all attributes common to all widget types
+ Fl_Widget *w = live_widget;
+ w->label(o->label());
+ w->tooltip(tooltip());
+ w->type(o->type());
+ w->box(o->box());
+ w->color(o->color());
+ w->selection_color(o->selection_color());
+ w->labeltype(o->labeltype());
+ w->labelfont(o->labelfont());
+ w->labelsize(o->labelsize());
+ w->labelcolor(o->labelcolor());
+ w->align(o->align());
+ w->when(o->when());
+
+ // copy all attributes specific to widgets derived from Fl_Button
+ if (is_button()) {
+ Fl_Button* d = (Fl_Button*)live_widget, *s = (Fl_Button*)o;
+ d->down_box(s->down_box());
+ d->shortcut(s->shortcut());
+ d->value(s->value());
+ }
+
+ // copy all attributes specific to widgets derived from Fl_Input_
+ if (is_a(Type::Input)) {
+ Fl_Input_* d = (Fl_Input_*)live_widget, *s = (Fl_Input_*)o;
+ d->shortcut(s->shortcut());
+ d->textfont(ff);
+ d->textsize(fs);
+ d->textcolor(fc);
+ }
+
+ // copy all attributes specific to widgets derived from Fl_Value_Input
+ if (is_a(Type::Value_Input)) {
+ Fl_Value_Input* d = (Fl_Value_Input*)live_widget, *s = (Fl_Value_Input*)o;
+ d->shortcut(s->shortcut());
+ d->textfont(ff);
+ d->textsize(fs);
+ d->textcolor(fc);
+ }
+
+ // copy all attributes specific to widgets derived from Fl_Text_Display
+ if (is_a(Type::Text_Display)) {
+ Fl_Text_Display* d = (Fl_Text_Display*)live_widget, *s = (Fl_Text_Display*)o;
+ d->shortcut(s->shortcut());
+ d->textfont(ff);
+ d->textsize(fs);
+ d->textcolor(fc);
+ }
+
+ // copy all attributes specific to Fl_Valuator and derived classes
+ if (is_a(Type::Valuator_)) {
+ Fl_Valuator* d = (Fl_Valuator*)live_widget, *s = (Fl_Valuator*)o;
+ d->minimum(s->minimum());
+ d->maximum(s->maximum());
+ d->step(s->step());
+ d->value(s->value());
+ if (is_a(Type::Slider)) {
+ Fl_Slider *d = (Fl_Slider*)live_widget, *s = (Fl_Slider*)o;
+ d->slider_size(s->slider_size());
+ }
+ }
+
+ // copy all attributes specific to Fl_Spinner and derived classes
+ if (is_a(Type::Spinner)) {
+ Fl_Spinner* d = (Fl_Spinner*)live_widget, *s = (Fl_Spinner*)o;
+ d->minimum(s->minimum());
+ d->maximum(s->maximum());
+ d->step(s->step());
+ d->value(s->value());
+ }
+
+ if (!o->visible())
+ w->hide();
+ if (!o->active())
+ w->deactivate();
+}
+
diff --git a/fluid/nodes/Fl_Widget_Type.h b/fluid/nodes/Widget_Node.h
index 6a26921cc..261005590 100644
--- a/fluid/nodes/Fl_Widget_Type.h
+++ b/fluid/nodes/Widget_Node.h
@@ -1,11 +1,7 @@
//
-// Widget type header file for the Fast Light Tool Kit (FLTK).
+// Widget Node header file for the Fast Light Tool Kit (FLTK).
//
-// Type for creating all subclasses of Fl_Widget
-// This should have the widget pointer in it, but it is still in the
-// Fl_Type base class.
-//
-// Copyright 1998-2023 by Bill Spitzak and others.
+// Copyright 1998-2025 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
@@ -18,32 +14,35 @@
// https://www.fltk.org/bugs.php
//
-#ifndef _FLUID_FL_WIDGET_TYPE_H
-#define _FLUID_FL_WIDGET_TYPE_H
+// Type for creating all subclasses of Fl_Widget
+// This should have the widget pointer in it, but it is still in the
+// Node base class.
+
+#ifndef FLUID_NODES_WIDGET_NODE_H
+#define FLUID_NODES_WIDGET_NODE_H
-#include "nodes/Fl_Type.h"
+#include "nodes/Node.h"
#define NUM_EXTRA_CODE 4
-class Fl_Widget_Type;
-class Fluid_Image;
+class Widget_Node;
+class Image_Asset;
extern void* const LOAD;
-extern Fl_Widget_Type *current_widget; // one of the selected ones
+extern Widget_Node *current_widget; // one of the selected ones
-extern const char* subclassname(Fl_Type* l);
+extern const char* subclassname(Node* l);
extern int is_name(const char *c);
-void selection_changed(Fl_Type* new_current);
-Fl_Type *sort(Fl_Type *parent);
-void comment_cb(class Fl_Text_Editor* i, void *v);
+void selection_changed(Node* new_current);
+Node *sort(Node *parent);
-class Fl_Widget_Type : public Fl_Type
+class Widget_Node : public Node
{
- typedef Fl_Type super;
+ typedef Node super;
virtual Fl_Widget *widget(int,int,int,int) = 0;
- virtual Fl_Widget_Type *_make() = 0; // virtual constructor
- void setlabel(const char *) FL_OVERRIDE;
+ virtual Widget_Node *_make() = 0; // virtual constructor
+ void setlabel(const char *) override;
const char *extra_code_[NUM_EXTRA_CODE];
const char *subclass_;
@@ -60,12 +59,12 @@ protected:
/// disabling the output of the "hide" property by the Widget Type.
uchar override_visible_;
- void write_static(fld::io::Code_Writer& f) FL_OVERRIDE;
- void write_code1(fld::io::Code_Writer& f) FL_OVERRIDE;
+ void write_static(fld::io::Code_Writer& f) override;
+ void write_code1(fld::io::Code_Writer& f) override;
void write_widget_code(fld::io::Code_Writer& f);
void write_extra_code(fld::io::Code_Writer& f);
void write_block_close(fld::io::Code_Writer& f);
- void write_code2(fld::io::Code_Writer& f) FL_OVERRIDE;
+ void write_code2(fld::io::Code_Writer& f) override;
void write_color(fld::io::Code_Writer& f, const char*, Fl_Color);
Fl_Widget *live_widget;
@@ -79,14 +78,14 @@ public:
int scale_image_w_, scale_image_h_;
int scale_deimage_w_, scale_deimage_h_;
- Fluid_Image *image;
- void setimage(Fluid_Image *);
- Fluid_Image *inactive;
- void setinactive(Fluid_Image *);
+ Image_Asset *image;
+ void setimage(Image_Asset *);
+ Image_Asset *inactive;
+ void setinactive(Image_Asset *);
- Fl_Widget_Type();
- Fl_Type *make(Strategy strategy) FL_OVERRIDE;
- void open() FL_OVERRIDE;
+ Widget_Node();
+ Node *make(Strategy strategy) override;
+ void open() override;
const char *extra_code(int n) const {return extra_code_[n];}
void extra_code(int n,const char *);
@@ -106,27 +105,27 @@ public:
virtual int textstuff(int what, Fl_Font &, int &, Fl_Color &);
virtual Fl_Menu_Item *subtypes();
- ID id() const FL_OVERRIDE { return ID_Widget_; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Widget_) ? true : super::is_a(inID); }
- int is_widget() const FL_OVERRIDE;
- int is_true_widget() const FL_OVERRIDE { return 1; }
- int is_public() const FL_OVERRIDE;
+ Type type() const override { return Type::Widget_; }
+ bool is_a(Type inType) const override { return (inType==Type::Widget_) ? true : super::is_a(inType); }
+ int is_widget() const override;
+ int is_true_widget() const override { return 1; }
+ int is_public() const override;
- void write_properties(fld::io::Project_Writer &f) FL_OVERRIDE;
- void read_property(fld::io::Project_Reader &f, const char *) FL_OVERRIDE;
- int read_fdesign(const char*, const char*) FL_OVERRIDE;
+ void write_properties(fld::io::Project_Writer &f) override;
+ void read_property(fld::io::Project_Reader &f, const char *) override;
+ int read_fdesign(const char*, const char*) override;
- Fl_Widget *enter_live_mode(int top=0) FL_OVERRIDE;
+ Fl_Widget *enter_live_mode(int top=0) override;
Fl_Widget *propagate_live_mode(Fl_Group* grp);
- void leave_live_mode() FL_OVERRIDE;
- void copy_properties() FL_OVERRIDE;
+ void leave_live_mode() override;
+ void copy_properties() override;
virtual void ideal_size(int &w, int &h);
- ~Fl_Widget_Type();
+ ~Widget_Node();
void redraw();
};
extern Fl_Window *the_panel;
-#endif // _FLUID_FL_WIDGET_TYPE_H
+#endif // FLUID_NODES_WIDGET_NODE_H
diff --git a/fluid/nodes/Fl_Window_Type.cxx b/fluid/nodes/Window_Node.cxx
index 3f68f7980..d6cbe80e6 100644
--- a/fluid/nodes/Fl_Window_Type.cxx
+++ b/fluid/nodes/Window_Node.cxx
@@ -1,9 +1,5 @@
//
-// Window type code file for the Fast Light Tool Kit (FLTK).
-//
-// The widget describing an Fl_Window. This is also all the code
-// for interacting with the overlay, which allows the user to
-// select, move, and resize the children widgets.
+// Window Node code file for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-2025 by Bill Spitzak and others.
//
@@ -18,18 +14,23 @@
// https://www.fltk.org/bugs.php
//
-#include "nodes/Fl_Window_Type.h"
+//
+// The widget describing an Fl_Window. This is also all the code
+// for interacting with the overlay, which allows the user to
+// select, move, and resize the children widgets.
+
+#include "nodes/Window_Node.h"
-#include "app/Fd_Snap_Action.h"
-#include "app/fluid.h"
-#include "app/project.h"
-#include "app/undo.h"
+#include "app/Snap_Action.h"
+#include "Fluid.h"
+#include "Project.h"
+#include "proj/undo.h"
#include "io/Project_Reader.h"
#include "io/Project_Writer.h"
#include "io/Code_Writer.h"
#include "nodes/factory.h"
-#include "nodes/Fl_Group_Type.h"
-#include "nodes/Fl_Grid_Type.h"
+#include "nodes/Group_Node.h"
+#include "nodes/Grid_Node.h"
#include "panels/settings_panel.h"
#include "panels/widget_panel.h"
#include "widgets/Node_Browser.h"
@@ -48,46 +49,47 @@
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
+#undef min
+#undef max
+#include <algorithm>
extern Fl_Window *the_panel;
extern void draw_width(int x, int y, int r, Fl_Align a);
extern void draw_height(int x, int y, int b, Fl_Align a);
-extern Fl_Preferences fluid_prefs;
-
// Update the XYWH values in the widget panel...
static void update_xywh() {
if (current_widget && current_widget->is_widget()) {
- Fl_Widget *o = ((Fl_Widget_Type *)current_widget)->o;
+ Fl_Widget *o = ((Widget_Node *)current_widget)->o;
widget_x_input->value(o->x());
widget_y_input->value(o->y());
widget_w_input->value(o->w());
widget_h_input->value(o->h());
- if (Fl_Flex_Type::parent_is_flex(current_widget)) {
- widget_flex_size->value(Fl_Flex_Type::size(current_widget));
- widget_flex_fixed->value(Fl_Flex_Type::is_fixed(current_widget));
+ if (Flex_Node::parent_is_flex(current_widget)) {
+ widget_flex_size->value(Flex_Node::size(current_widget));
+ widget_flex_fixed->value(Flex_Node::is_fixed(current_widget));
}
}
}
void i18n_type_cb(Fl_Choice *c, void *v) {
if (v == LOAD) {
- c->value(g_project.i18n_type);
+ c->value(static_cast<int>(Fluid.proj.i18n_type));
} else {
- undo_checkpoint();
- g_project.i18n_type = static_cast<Fd_I18n_Type>(c->value());
- set_modflag(1);
+ Fluid.proj.undo.checkpoint();
+ Fluid.proj.i18n_type = static_cast<fld::I18n_Type>(c->value());
+ Fluid.proj.set_modflag(1);
}
- switch (g_project.i18n_type) {
- case FD_I18N_NONE : /* None */
+ switch (Fluid.proj.i18n_type) {
+ case fld::I18n_Type::NONE : /* None */
i18n_gnu_group->hide();
i18n_posix_group->hide();
break;
- case FD_I18N_GNU : /* GNU gettext */
+ case fld::I18n_Type::GNU : /* GNU gettext */
i18n_gnu_group->show();
i18n_posix_group->hide();
break;
- case FD_I18N_POSIX : /* POSIX cat */
+ case fld::I18n_Type::POSIX : /* POSIX cat */
i18n_gnu_group->hide();
i18n_posix_group->show();
break;
@@ -109,9 +111,9 @@ void show_settings_cb(Fl_Widget *, void *) {
////////////////////////////////////////////////////////////////
Fl_Menu_Item window_type_menu[] = {
- {"Single",0,0,(void*)FL_WINDOW},
- {"Double",0,0,(void*)(FL_DOUBLE_WINDOW)},
- {0}};
+ {"Single",0,nullptr,(void*)FL_WINDOW},
+ {"Double",0,nullptr,(void*)(FL_DOUBLE_WINDOW)},
+ {nullptr}};
static int overlays_invisible;
@@ -119,17 +121,17 @@ static int overlays_invisible;
// an overlay for the fluid ui, and special-cases the FL_NO_BOX.
class Overlay_Window : public Fl_Overlay_Window {
- void draw() FL_OVERRIDE;
- void draw_overlay() FL_OVERRIDE;
+ void draw() override;
+ void draw_overlay() override;
static void close_cb(Overlay_Window *self, void*);
public:
- Fl_Window_Type *window;
- int handle(int) FL_OVERRIDE;
+ Window_Node *window;
+ int handle(int) override;
Overlay_Window(int W,int H) : Fl_Overlay_Window(W,H) {
- Fl_Group::current(0);
+ Fl_Group::current(nullptr);
callback((Fl_Callback*)close_cb);
}
- void resize(int,int,int,int) FL_OVERRIDE;
+ void resize(int,int,int,int) override;
uchar *read_image(int &ww, int &hh);
};
@@ -140,7 +142,7 @@ public:
*/
void Overlay_Window::close_cb(Overlay_Window *self, void*) {
if (self->visible())
- set_modflag(1, -2);
+ Fluid.proj.set_modflag(1, -2);
self->hide();
}
@@ -164,7 +166,7 @@ void Overlay_Window::draw() {
fl_rectf(X,Y,CHECKSIZE,CHECKSIZE);
}
}
- if (show_ghosted_outline) {
+ if (Fluid.show_ghosted_outline) {
Fl_Box_Draw_F *old_flat_box = Fl::get_boxtype(FL_FLAT_BOX);
Fl::set_boxtype(FL_FLAT_BOX, fd_flat_box_ghosted, 0, 0, 0, 0);
Fl_Overlay_Window::draw();
@@ -174,12 +176,10 @@ void Overlay_Window::draw() {
}
}
-extern Fl_Window *main_window;
-
// Read an image of the overlay window
uchar *Overlay_Window::read_image(int &ww, int &hh) {
// Create an off-screen buffer for the window...
- //main_window->make_current();
+ //Fluid.main_window->make_current();
make_current();
ww = w();
@@ -197,13 +197,13 @@ uchar *Overlay_Window::read_image(int &ww, int &hh) {
draw();
// Read the screen image...
- pixels = fl_read_image(0, 0, 0, ww, hh);
+ pixels = fl_read_image(nullptr, 0, 0, ww, hh);
fl_end_offscreen();
// Cleanup and return...
fl_delete_offscreen(offscreen);
- main_window->make_current();
+ Fluid.main_window->make_current();
return pixels;
}
@@ -228,22 +228,22 @@ int Overlay_Window::handle(int e) {
\param[in] strategy is Strategy::AS_LAST_CHILD or Strategy::AFTER_CURRENT
\return new node
*/
-Fl_Type *Fl_Window_Type::make(Strategy strategy) {
- Fl_Type *anchor = Fl_Type::current, *p = anchor;
+Node *Window_Node::make(Strategy strategy) {
+ Node *anchor = Fluid.proj.tree.current, *p = anchor;
if (p && (strategy.placement() == Strategy::AFTER_CURRENT)) p = p->parent;
- while (p && (!p->is_code_block() || p->is_a(ID_Widget_Class))) {
+ while (p && (!p->is_code_block() || p->is_a(Type::Widget_Class))) {
anchor = p;
strategy.placement(Strategy::AFTER_CURRENT);
p = p->parent;
}
if (!p) {
fl_message("Please select a function");
- return 0;
+ return nullptr;
}
- Fl_Window_Type *myo = new Fl_Window_Type();
+ Window_Node *myo = new Window_Node();
if (!this->o) {// template widget
this->o = new Fl_Window(100,100);
- Fl_Group::current(0);
+ Fl_Group::current(nullptr);
}
myo->factory = this;
myo->drag = 0;
@@ -258,24 +258,24 @@ Fl_Type *Fl_Window_Type::make(Strategy strategy) {
return myo;
}
-void Fl_Window_Type::add_child(Fl_Type* cc, Fl_Type* before) {
+void Window_Node::add_child(Node* cc, Node* before) {
if (!cc->is_widget()) return;
- Fl_Widget_Type* c = (Fl_Widget_Type*)cc;
- Fl_Widget* b = before ? ((Fl_Widget_Type*)before)->o : 0;
+ Widget_Node* c = (Widget_Node*)cc;
+ Fl_Widget* b = before ? ((Widget_Node*)before)->o : nullptr;
((Fl_Window*)o)->insert(*(c->o), b);
o->redraw();
}
-void Fl_Window_Type::remove_child(Fl_Type* cc) {
- Fl_Widget_Type* c = (Fl_Widget_Type*)cc;
+void Window_Node::remove_child(Node* cc) {
+ Widget_Node* c = (Widget_Node*)cc;
((Fl_Window*)o)->remove(c->o);
o->redraw();
}
-void Fl_Window_Type::move_child(Fl_Type* cc, Fl_Type* before) {
- Fl_Widget_Type* c = (Fl_Widget_Type*)cc;
+void Window_Node::move_child(Node* cc, Node* before) {
+ Widget_Node* c = (Widget_Node*)cc;
((Fl_Window*)o)->remove(c->o);
- Fl_Widget* b = before ? ((Fl_Widget_Type*)before)->o : 0;
+ Fl_Widget* b = before ? ((Widget_Node*)before)->o : nullptr;
((Fl_Window*)o)->insert(*(c->o), b);
o->redraw();
}
@@ -284,13 +284,13 @@ void Fl_Window_Type::move_child(Fl_Type* cc, Fl_Type* before) {
/**
\brief Show the Window Type editor window without setting the modified flag.
- \see Fl_Window_Type::open()
+ \see Window_Node::open()
*/
-void Fl_Window_Type::open_() {
+void Window_Node::open_() {
Overlay_Window *w = (Overlay_Window *)o;
if (w->shown()) {
w->show();
- Fl_Widget_Type::open();
+ Widget_Node::open();
} else {
Fl_Widget *p = w->resizable();
if (!p) w->resizable(w);
@@ -304,18 +304,18 @@ void Fl_Window_Type::open_() {
\brief Show the Window Type editor window and set the modified flag if needed.
Double-click on window widget shows the window, or if already shown, it shows
the control panel.
- \see Fl_Window_Type::open_()
+ \see Window_Node::open_()
*/
-void Fl_Window_Type::open() {
+void Window_Node::open() {
Overlay_Window *w = (Overlay_Window *)o;
if (!w->visible()) {
- set_modflag(1, -2);
+ Fluid.proj.set_modflag(1, -2);
}
open_();
}
// Read an image of the window
-uchar *Fl_Window_Type::read_image(int &ww, int &hh) {
+uchar *Window_Node::read_image(int &ww, int &hh) {
Overlay_Window *w = (Overlay_Window *)o;
int hidden = !w->shown();
@@ -328,91 +328,28 @@ uchar *Fl_Window_Type::read_image(int &ww, int &hh) {
return idata;
}
-void Fl_Window_Type::ideal_size(int &w, int &h) {
+void Window_Node::ideal_size(int &w, int &h) {
w = 480; h = 320;
- if (main_window) {
+ if (Fluid.main_window) {
int sx, sy, sw, sh;
- Fl_Window *win = main_window;
+ Fl_Window *win = Fluid.main_window;
int screen = Fl::screen_num(win->x(), win->y());
Fl::screen_work_area(sx, sy, sw, sh, screen);
- w = fd_min(w, sw*3/4); h = fd_min(h, sh*3/4);
- }
- Fd_Snap_Action::better_size(w, h);
-}
-
-
-// control panel items:
-
-void modal_cb(Fl_Light_Button* i, void* v) {
- if (v == LOAD) {
- if (!current_widget->is_a(ID_Window)) {i->hide(); return;}
- i->show();
- i->value(((Fl_Window_Type *)current_widget)->modal);
- } else {
- undo_checkpoint();
- ((Fl_Window_Type *)current_widget)->modal = i->value();
- set_modflag(1);
- }
-}
-
-void non_modal_cb(Fl_Light_Button* i, void* v) {
- if (v == LOAD) {
- if (!current_widget->is_a(ID_Window)) {i->hide(); return;}
- i->show();
- i->value(((Fl_Window_Type *)current_widget)->non_modal);
- } else {
- undo_checkpoint();
- ((Fl_Window_Type *)current_widget)->non_modal = i->value();
- set_modflag(1);
+ w = std::min(w, sw*3/4); h = std::min(h, sh*3/4);
}
+ fld::app::Snap_Action::better_size(w, h);
}
-void border_cb(Fl_Light_Button* i, void* v) {
- if (v == LOAD) {
- if (!current_widget->is_a(ID_Window)) {i->hide(); return;}
- i->show();
- i->value(((Fl_Window*)(current_widget->o))->border());
- } else {
- undo_checkpoint();
- ((Fl_Window*)(current_widget->o))->border(i->value());
- set_modflag(1);
- }
-}
-void xclass_cb(Fl_Input* i, void* v) {
- if (v == LOAD) {
- if (current_widget->is_a(ID_Window)) {
- i->show();
- i->parent()->show();
- i->value(((Fl_Window_Type *)current_widget)->xclass);
- } else {
- i->hide();
- i->parent()->hide(); // hides the "X Class:" label as well
- }
- } else {
- int mod = 0;
- undo_checkpoint();
- for (Fl_Type *o = Fl_Type::first; o; o = o->next) {
- if (o->selected && o->is_a(ID_Window)) {
- mod = 1;
- Fl_Window_Type *wt = (Fl_Window_Type *)o;
- storestring(i->value(), wt->xclass);
- ((Fl_Window*)(wt->o))->xclass(wt->xclass);
- }
- }
- if (mod) set_modflag(1);
- }
-}
////////////////////////////////////////////////////////////////
-void Fl_Window_Type::setlabel(const char *n) {
+Window_Node Window_Node::prototype;
+
+void Window_Node::setlabel(const char *n) {
if (o) ((Fl_Window *)o)->label(n);
}
-// make() is called on this widget when user picks window off New menu:
-Fl_Window_Type Fl_Window_type;
-
// Resize from window manager...
void Overlay_Window::resize(int X,int Y,int W,int H) {
// Make sure we don't create undo checkpoints if the window does not actually change.
@@ -420,20 +357,20 @@ void Overlay_Window::resize(int X,int Y,int W,int H) {
if (X!=x() || Y!=y() || W!=w() || H!=h()) {
// Set a checkpoint on the first resize event, ignore further resizes until
// a different type of checkpoint is triggered.
- if (undo_checkpoint_once(kUndoWindowResize))
- set_modflag(1);
+ if (Fluid.proj.undo.checkpoint(fld::proj::Undo::OnceType::WINDOW_RESIZE))
+ Fluid.proj.set_modflag(1);
}
Fl_Widget* t = resizable();
- if (Fl_Type::allow_layout == 0) {
- resizable(0);
+ if (Fluid.proj.tree.allow_layout == 0) {
+ resizable(nullptr);
}
// do not set the mod flag if the window was not resized. In FLUID, all
// windows are opened without a given x/y position, so modifying x/y
// should not mark the project as dirty
if (W!=w() || H!=h())
- set_modflag(1);
+ Fluid.proj.set_modflag(1);
Fl_Overlay_Window::resize(X,Y,W,H);
resizable(t);
@@ -442,7 +379,7 @@ void Overlay_Window::resize(int X,int Y,int W,int H) {
// calculate actual move by moving mouse position (mx,my) to
// nearest multiple of gridsize, and snap to original position
-void Fl_Window_Type::newdx() {
+void Window_Node::newdx() {
int mydx, mydy;
mydx = mx-x1;
mydy = my-y1;
@@ -457,16 +394,16 @@ void Fl_Window_Type::newdx() {
dy = 0;
}
- if (show_guides && (drag & (FD_DRAG|FD_TOP|FD_LEFT|FD_BOTTOM|FD_RIGHT))) {
- Fl_Type *selection = 0L; // special power for the first selected widget
- for (Fl_Type *q=next; q && q->level>level; q = q->next) {
+ if (Fluid.show_guides && (drag & (FD_DRAG|FD_TOP|FD_LEFT|FD_BOTTOM|FD_RIGHT))) {
+ Node *selection = nullptr; // special power for the first selected widget
+ for (Node *q=next; q && q->level>level; q = q->next) {
if (q->selected && q->is_true_widget()) {
selection = q;
break;
}
}
- Fd_Snap_Data data = { mydx, mydy, bx, by, br, bt, drag, 4, 4, mydx, mydy, (Fl_Widget_Type*)selection, this };
- Fd_Snap_Action::check_all(data);
+ fld::app::Snap_Data data = { mydx, mydy, bx, by, br, bt, drag, 4, 4, mydx, mydy, (Widget_Node*)selection, this };
+ fld::app::Snap_Action::check_all(data);
if (data.x_dist < 4) mydx = data.dx_out;
if (data.y_dist < 4) mydy = data.dy_out;
}
@@ -478,7 +415,7 @@ void Fl_Window_Type::newdx() {
}
// Move a widget according to dx and dy calculated above
-void Fl_Window_Type::newposition(Fl_Widget_Type *myo,int &X,int &Y,int &R,int &T) {
+void Window_Node::newposition(Widget_Node *myo,int &X,int &Y,int &R,int &T) {
X = myo->o->x();
Y = myo->o->y();
R = X+myo->o->w();
@@ -548,10 +485,10 @@ void fd_hatch(int x, int y, int w, int h, int size=6, int offset=0, int pad=3) {
\param[in] group check all children of this group
\param[in] x, y, w, h bounding box of this group
*/
-void Fl_Window_Type::draw_out_of_bounds(Fl_Widget_Type *group, int x, int y, int w, int h) {
- for (Fl_Type *p = group->next; p && p->level>group->level; p = p->next) {
+void Window_Node::draw_out_of_bounds(Widget_Node *group, int x, int y, int w, int h) {
+ for (Node *p = group->next; p && p->level>group->level; p = p->next) {
if (p->level == group->level+1 && p->is_true_widget()) {
- Fl_Widget *o = ((Fl_Widget_Type*)p)->o;
+ Fl_Widget *o = ((Widget_Node*)p)->o;
if (o->x() < x) fd_hatch(o->x(), o->y(), x-o->x(), o->h());
if (o->y() < y) fd_hatch(o->x(), o->y(), o->w(), y-o->y());
if (o->x()+o->w() > x+w) fd_hatch(x+w, o->y(), (o->x()+o->w())-(x+w), o->h());
@@ -563,14 +500,14 @@ void Fl_Window_Type::draw_out_of_bounds(Fl_Widget_Type *group, int x, int y, int
/**
\brief Draw a hatch pattern for all groups that have out of bounds children.
*/
-void Fl_Window_Type::draw_out_of_bounds() {
+void Window_Node::draw_out_of_bounds() {
// get every group in the hierarchy, then draw any overlap of a direct child with that group
fl_color(FL_DARK_RED);
draw_out_of_bounds(this, 0, 0, o->w(), o->h());
- for (Fl_Type *q=next; q && q->level>level; q = q->next) {
+ for (Node *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_a(ID_Group) && !q->is_a(ID_Scroll)) {
- Fl_Widget_Type *w = (Fl_Widget_Type*)q;
+ if (q->is_a(Type::Group) && !q->is_a(Type::Scroll)) {
+ Widget_Node *w = (Widget_Node*)q;
draw_out_of_bounds(w, w->o->x(), w->o->y(), w->o->w(), w->o->h());
}
}
@@ -580,25 +517,25 @@ void Fl_Window_Type::draw_out_of_bounds() {
/**
\brief Compare all children in the same level and hatch overlapping areas.
*/
-void Fl_Window_Type::draw_overlaps() {
+void Window_Node::draw_overlaps() {
fl_color(FL_DARK_YELLOW);
// loop through all widgets in this window
- for (Fl_Type *q=next; q && q->level>level; q = q->next) {
+ for (Node *q=next; q && q->level>level; q = q->next) {
// is it a valid widget
if (q->is_true_widget()) {
- Fl_Widget_Type *w = (Fl_Widget_Type*)q;
+ Widget_Node *w = (Widget_Node*)q;
// is the widget visible
if (w->o->visible()) {
int x = w->o->x(), y = w->o->y();
int r = x + w->o->w(), b = y + w->o->h();
- for (Fl_Type *p=q->next; p && p->level>=q->level; p = p->next) {
+ for (Node *p=q->next; p && p->level>=q->level; p = p->next) {
if (p->level==q->level && p->is_true_widget()) {
- Fl_Widget_Type *wp = (Fl_Widget_Type*)p;
+ Widget_Node *wp = (Widget_Node*)p;
if (wp->o->visible()) {
- int px = fd_max(x, wp->o->x());
- int py = fd_max(y, wp->o->y());
- int pr = fd_min(r, wp->o->x() + wp->o->w());
- int pb = fd_min(b, wp->o->y() + wp->o->h());
+ int px = std::max(x, wp->o->x());
+ int py = std::max(y, wp->o->y());
+ int pr = std::min(r, wp->o->x() + wp->o->w());
+ int pb = std::min(b, wp->o->y() + wp->o->h());
if (pr > px && pb > py)
fd_hatch(px, py, pr-px, pb-py);
}
@@ -613,14 +550,14 @@ void Fl_Window_Type::draw_overlaps() {
fl_color(FL_RED);
}
-void Fl_Window_Type::draw_overlay() {
+void Window_Node::draw_overlay() {
if (recalc) {
bx = o->w(); by = o->h(); br = 0; bt = 0;
numselected = 0;
- for (Fl_Type *q=next; q && q->level>level; q=q->next)
+ for (Node *q=next; q && q->level>level; q=q->next)
if (q->selected && q->is_true_widget()) {
numselected++;
- Fl_Widget_Type* myo = (Fl_Widget_Type*)q;
+ Widget_Node* myo = (Widget_Node*)q;
if (myo->o->x() < bx) bx = myo->o->x();
if (myo->o->y() < by) by = myo->o->y();
if (myo->o->x()+myo->o->w() > br) br = myo->o->x()+myo->o->w();
@@ -637,7 +574,7 @@ void Fl_Window_Type::draw_overlay() {
}
if (overlays_invisible && !drag) return;
- if (show_restricted) {
+ if (Fluid.show_restricted) {
draw_out_of_bounds();
draw_overlaps();
// TODO: for Fl_Tile, find all areas that are not covered by visible children
@@ -648,31 +585,31 @@ void Fl_Window_Type::draw_overlay() {
int mybx,myby,mybr,mybt;
int mysx,mysy,mysr,myst;
mybx = mysx = o->w(); myby = mysy = o->h(); mybr = mysr = 0; mybt = myst = 0;
- Fl_Type *selection = 0L; // special power for the first selected widget
- for (Fl_Type *q=next; q && q->level>level; q = q->next)
+ Node *selection = nullptr; // special power for the first selected widget
+ for (Node *q=next; q && q->level>level; q = q->next)
if (q->selected && q->is_true_widget()) {
if (!selection) selection = q;
- Fl_Widget_Type* myo = (Fl_Widget_Type*)q;
+ Widget_Node* myo = (Widget_Node*)q;
int x,y,r,t;
newposition(myo,x,y,r,t);
- if (show_guides) {
+ if (Fluid.show_guides) {
// If we are in a drag operation, and the parent is a grid, show the grid overlay
- if (drag && q->parent && q->parent->is_a(ID_Grid)) {
- Fl_Grid_Proxy *grid = ((Fl_Grid_Proxy*)((Fl_Grid_Type*)q->parent)->o);
+ if (drag && q->parent && q->parent->is_a(Type::Grid)) {
+ Fl_Grid_Proxy *grid = ((Fl_Grid_Proxy*)((Grid_Node*)q->parent)->o);
grid->draw_overlay();
}
}
- if (!show_guides || !drag || numselected != 1) {
- if (Fl_Flex_Type::parent_is_flex(q) && Fl_Flex_Type::is_fixed(q)) {
- Fl_Flex *flex = ((Fl_Flex*)((Fl_Flex_Type*)q->parent)->o);
+ if (!Fluid.show_guides || !drag || numselected != 1) {
+ if (Flex_Node::parent_is_flex(q) && Flex_Node::is_fixed(q)) {
+ Fl_Flex *flex = ((Fl_Flex*)((Flex_Node*)q->parent)->o);
Fl_Widget *wgt = myo->o;
if (flex->horizontal()) {
draw_width(wgt->x(), wgt->y()+15, wgt->x()+wgt->w(), FL_ALIGN_CENTER);
} else {
draw_height(wgt->x()+15, wgt->y(), wgt->y()+wgt->h(), FL_ALIGN_CENTER);
}
- } else if (q->is_a(ID_Grid)) {
- Fl_Grid_Proxy *grid = ((Fl_Grid_Proxy*)((Fl_Grid_Type*)q)->o);
+ } else if (q->is_a(Type::Grid)) {
+ Fl_Grid_Proxy *grid = ((Fl_Grid_Proxy*)((Grid_Node*)q)->o);
grid->draw_overlay();
}
fl_rect(x,y,r-x,t-y);
@@ -712,17 +649,15 @@ void Fl_Window_Type::draw_overlay() {
fl_rectf(mysr-5,myst-5,5,5);
fl_rectf(mysx,myst-5,5,5);
- if (show_guides && (drag & (FD_DRAG|FD_TOP|FD_LEFT|FD_BOTTOM|FD_RIGHT))) {
- Fd_Snap_Data data = { dx, dy, sx, sy, sr, st, drag, 4, 4, dx, dy, (Fl_Widget_Type*)selection, this};
- Fd_Snap_Action::draw_all(data);
+ if (Fluid.show_guides && (drag & (FD_DRAG|FD_TOP|FD_LEFT|FD_BOTTOM|FD_RIGHT))) {
+ fld::app::Snap_Data data = { dx, dy, sx, sy, sr, st, drag, 4, 4, dx, dy, (Widget_Node*)selection, this};
+ fld::app::Snap_Action::draw_all(data);
}
}
-extern Fl_Menu_Item Main_Menu[];
-
// Calculate new bounding box of selected widgets:
-void Fl_Window_Type::fix_overlay() {
- overlay_item->label("Hide O&verlays");
+void Window_Node::fix_overlay() {
+ Fluid.overlay_item->label("Hide O&verlays");
if (overlay_button) overlay_button->label("Hide &Overlays");
overlays_invisible = 0;
recalc = 1;
@@ -730,45 +665,45 @@ void Fl_Window_Type::fix_overlay() {
}
// check if we must redraw any parent of tabs/wizard type
-void check_redraw_corresponding_parent(Fl_Type *s) {
- Fl_Widget_Type * prev_parent = 0;
+void check_redraw_corresponding_parent(Node *s) {
+ Widget_Node * prev_parent = nullptr;
if( !s || !s->selected || !s->is_widget()) return;
- for (Fl_Type *i=s; i && i->parent; i=i->parent) {
- if (i->is_a(ID_Group) && prev_parent) {
- if (i->is_a(ID_Tabs)) {
- ((Fl_Tabs*)((Fl_Widget_Type*)i)->o)->value(prev_parent->o);
+ for (Node *i=s; i && i->parent; i=i->parent) {
+ if (i->is_a(Type::Group) && prev_parent) {
+ if (i->is_a(Type::Tabs)) {
+ ((Fl_Tabs*)((Widget_Node*)i)->o)->value(prev_parent->o);
return;
}
- if (i->is_a(ID_Wizard)) {
- ((Fl_Wizard*)((Fl_Widget_Type*)i)->o)->value(prev_parent->o);
+ if (i->is_a(Type::Wizard)) {
+ ((Fl_Wizard*)((Widget_Node*)i)->o)->value(prev_parent->o);
return;
}
}
- if (i->is_a(ID_Group) && s->is_widget())
- prev_parent = (Fl_Widget_Type*)i;
+ if (i->is_a(Type::Group) && s->is_widget())
+ prev_parent = (Widget_Node*)i;
}
}
// do that for every window (when selected set changes):
void redraw_overlays() {
- for (Fl_Type *o=Fl_Type::first; o; o=o->next)
- if (o->is_a(ID_Window)) ((Fl_Window_Type*)o)->fix_overlay();
+ for (Node *o=Fluid.proj.tree.first; o; o=o->next)
+ if (o->is_a(Type::Window)) ((Window_Node*)o)->fix_overlay();
}
void toggle_overlays(Fl_Widget *,void *) {
overlays_invisible = !overlays_invisible;
if (overlays_invisible) {
- overlay_item->label("Show O&verlays");
+ Fluid.overlay_item->label("Show O&verlays");
if (overlay_button) overlay_button->label("Show &Overlays");
} else {
- overlay_item->label("Hide O&verlays");
+ Fluid.overlay_item->label("Hide O&verlays");
if (overlay_button) overlay_button->label("Hide &Overlays");
}
- for (Fl_Type *o=Fl_Type::first; o; o=o->next)
- if (o->is_a(ID_Window)) {
- Fl_Widget_Type* w = (Fl_Widget_Type*)o;
+ for (Node *o=Fluid.proj.tree.first; o; o=o->next)
+ if (o->is_a(Type::Window)) {
+ Widget_Node* w = (Widget_Node*)o;
((Overlay_Window*)(w->o))->redraw_overlay();
}
}
@@ -779,19 +714,19 @@ void toggle_overlays(Fl_Widget *,void *) {
dialog.
*/
void toggle_guides(Fl_Widget *,void *) {
- show_guides = !show_guides;
- fluid_prefs.set("show_guides", show_guides);
+ Fluid.show_guides = !Fluid.show_guides;
+ Fluid.preferences.set("Fluid.show_guides", Fluid.show_guides);
- if (show_guides)
- guides_item->label("Hide Guides");
+ if (Fluid.show_guides)
+ Fluid.guides_item->label("Hide Guides");
else
- guides_item->label("Show Guides");
+ Fluid.guides_item->label("Show Guides");
if (guides_button)
- guides_button->value(show_guides);
+ guides_button->value(Fluid.show_guides);
- for (Fl_Type *o=Fl_Type::first; o; o=o->next) {
- if (o->is_a(ID_Window)) {
- Fl_Widget_Type* w = (Fl_Widget_Type*)o;
+ for (Node *o=Fluid.proj.tree.first; o; o=o->next) {
+ if (o->is_a(Type::Window)) {
+ Widget_Node* w = (Widget_Node*)o;
((Overlay_Window*)(w->o))->redraw_overlay();
}
}
@@ -802,7 +737,7 @@ void toggle_guides(Fl_Widget *,void *) {
This is called from the check button in the Settings dialog.
*/
void toggle_guides_cb(Fl_Check_Button *o, void *v) {
- toggle_guides(NULL, NULL);
+ toggle_guides(nullptr, nullptr);
}
/**
@@ -811,19 +746,19 @@ void toggle_guides_cb(Fl_Check_Button *o, void *v) {
dialog.
*/
void toggle_restricted(Fl_Widget *,void *) {
- show_restricted = !show_restricted;
- fluid_prefs.set("show_restricted", show_restricted);
+ Fluid.show_restricted = !Fluid.show_restricted;
+ Fluid.preferences.set("Fluid.show_restricted", Fluid.show_restricted);
- if (show_restricted)
- restricted_item->label("Hide Restricted");
+ if (Fluid.show_restricted)
+ Fluid.restricted_item->label("Hide Restricted");
else
- restricted_item->label("Show Restricted");
+ Fluid.restricted_item->label("Show Restricted");
if (restricted_button)
- restricted_button->value(show_restricted);
+ restricted_button->value(Fluid.show_restricted);
- for (Fl_Type *o=Fl_Type::first; o; o=o->next) {
- if (o->is_a(ID_Window)) {
- Fl_Widget_Type* w = (Fl_Widget_Type*)o;
+ for (Node *o=Fluid.proj.tree.first; o; o=o->next) {
+ if (o->is_a(Type::Window)) {
+ Widget_Node* w = (Widget_Node*)o;
((Overlay_Window*)(w->o))->redraw_overlay();
}
}
@@ -833,11 +768,11 @@ void toggle_restricted(Fl_Widget *,void *) {
\brief User changes settings to show low contrast groups with a ghosted outline.
*/
void toggle_ghosted_outline_cb(Fl_Check_Button *,void *) {
- show_ghosted_outline = !show_ghosted_outline;
- fluid_prefs.set("show_ghosted_outline", show_ghosted_outline);
- for (Fl_Type *o=Fl_Type::first; o; o=o->next) {
- if (o->is_a(ID_Window)) {
- Fl_Widget_Type* w = (Fl_Widget_Type*)o;
+ Fluid.show_ghosted_outline = !Fluid.show_ghosted_outline;
+ Fluid.preferences.set("Fluid.show_ghosted_outline", Fluid.show_ghosted_outline);
+ for (Node *o=Fluid.proj.tree.first; o; o=o->next) {
+ if (o->is_a(Type::Window)) {
+ Widget_Node* w = (Widget_Node*)o;
((Overlay_Window*)(w->o))->redraw();
}
}
@@ -848,16 +783,15 @@ void toggle_ghosted_outline_cb(Fl_Check_Button *,void *) {
This is called from the check button in the Settings dialog.
*/
void toggle_restricted_cb(Fl_Check_Button *o, void *v) {
- toggle_restricted(NULL, NULL);
+ toggle_restricted(nullptr, nullptr);
}
-extern void select(Fl_Type *,int);
-extern void select_only(Fl_Type *);
+extern void select(Node *,int);
+extern void select_only(Node *);
extern void deselect();
-extern Fl_Type* in_this_only;
-extern void fix_group_size(Fl_Type *t);
+extern Node* in_this_only;
+extern void fix_group_size(Node *t);
-extern Fl_Menu_Item Main_Menu[];
extern Fl_Menu_Item New_Menu[];
/**
@@ -875,30 +809,30 @@ extern Fl_Menu_Item New_Menu[];
\param[in] key if key is not 0, it contains the code of the keypress that
caused this call. This must only be set when handle FL_KEYBOARD events.
*/
-void Fl_Window_Type::moveallchildren(int key)
+void Window_Node::moveallchildren(int key)
{
bool update_widget_panel = false;
- undo_checkpoint();
- Fl_Type *i;
+ Fluid.proj.undo.checkpoint();
+ Node *i;
for (i=next; i && i->level>level;) {
if (i->selected && i->is_true_widget()) {
- Fl_Widget_Type* myo = (Fl_Widget_Type*)i;
+ Widget_Node* myo = (Widget_Node*)i;
int x,y,r,t,ow=myo->o->w(),oh=myo->o->h();
newposition(myo,x,y,r,t);
- if (myo->is_a(ID_Flex) || myo->is_a(ID_Grid)) {
+ if (myo->is_a(Type::Flex) || myo->is_a(Type::Grid)) {
// Flex and Grid need to be able to layout their children.
- allow_layout++;
+ Fluid.proj.tree.allow_layout++;
myo->o->resize(x,y,r-x,t-y);
- allow_layout--;
+ Fluid.proj.tree.allow_layout--;
} else {
// Other groups are resized without affecting their children, however
// they move their children if the entire widget is moved.
myo->o->resize(x,y,r-x,t-y);
}
- if (Fl_Flex_Type::parent_is_flex(myo)) {
+ if (Flex_Node::parent_is_flex(myo)) {
// If the border of a Flex child is move, give that child a fixed size
// so that the user request is reflected.
- Fl_Flex_Type* ft = (Fl_Flex_Type*)myo->parent;
+ Flex_Node* ft = (Flex_Node*)myo->parent;
Fl_Flex* f = (Fl_Flex*)ft->o;
if (key) {
ft->keyboard_move_child(myo, key);
@@ -918,11 +852,11 @@ void Fl_Window_Type::moveallchildren(int key)
}
}
// relayout the Flex parent
- allow_layout++;
+ Fluid.proj.tree.allow_layout++;
f->layout();
- allow_layout--;
- } else if (myo->parent && myo->parent->is_a(ID_Grid)) {
- Fl_Grid_Type* gt = (Fl_Grid_Type*)myo->parent;
+ Fluid.proj.tree.allow_layout--;
+ } else if (myo->parent && myo->parent->is_a(Type::Grid)) {
+ Grid_Node* gt = (Grid_Node*)myo->parent;
Fl_Grid* g = (Fl_Grid*)gt->o;
if (key) {
gt->keyboard_move_child(myo, key);
@@ -933,19 +867,19 @@ void Fl_Window_Type::moveallchildren(int key)
gt->child_resized(myo);
}
}
- allow_layout++;
+ Fluid.proj.tree.allow_layout++;
g->layout();
- allow_layout--;
+ Fluid.proj.tree.allow_layout--;
update_widget_panel = true;
- } else if (myo->parent && myo->parent->is_a(ID_Group)) {
- Fl_Group_Type* gt = (Fl_Group_Type*)myo->parent;
+ } else if (myo->parent && myo->parent->is_a(Type::Group)) {
+ Group_Node* gt = (Group_Node*)myo->parent;
((Fl_Group*)gt->o)->init_sizes();
}
// move all the children, whether selected or not:
- Fl_Type* p;
+ Node* p;
for (p = myo->next; p && p->level>myo->level; p = p->next)
- if (p->is_true_widget() && !myo->is_a(ID_Flex) && !myo->is_a(ID_Grid)) {
- Fl_Widget_Type* myo2 = (Fl_Widget_Type*)p;
+ if (p->is_true_widget() && !myo->is_a(Type::Flex) && !myo->is_a(Type::Grid)) {
+ Widget_Node* myo2 = (Widget_Node*)p;
int X,Y,R,T;
newposition(myo2,X,Y,R,T);
myo2->o->resize(X,Y,R-X,T-Y);
@@ -960,7 +894,7 @@ void Fl_Window_Type::moveallchildren(int key)
o->redraw();
recalc = 1;
((Overlay_Window *)(this->o))->redraw_overlay();
- set_modflag(1);
+ Fluid.proj.set_modflag(1);
dx = dy = 0;
update_xywh();
@@ -969,11 +903,11 @@ void Fl_Window_Type::moveallchildren(int key)
}
}
-int Fl_Window_Type::popupx = 0x7FFFFFFF; // mark as invalid (MAXINT)
-int Fl_Window_Type::popupy = 0x7FFFFFFF;
+int Window_Node::popupx = 0x7FFFFFFF; // mark as invalid (MAXINT)
+int Window_Node::popupy = 0x7FFFFFFF;
-int Fl_Window_Type::handle(int event) {
- static Fl_Type* selection = NULL;
+int Window_Node::handle(int event) {
+ static Node* selection = nullptr;
switch (event) {
case FL_DND_ENTER:
// printf("DND enter\n");
@@ -982,9 +916,9 @@ 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_a(ID_Group)) {
- Fl_Widget_Type* myo = (Fl_Widget_Type*)i;
+ for (Node* i=next; i && i->level>level; i=i->next)
+ if (i->is_a(Type::Group)) {
+ Widget_Node* myo = (Widget_Node*)i;
if (Fl::event_inside(myo->o) && myo->o->visible_r()) {
selection = myo;
if (Fl::event_clicks()==1)
@@ -1004,12 +938,12 @@ int Fl_Window_Type::handle(int event) {
return 1;
case FL_PASTE:
// printf("DND paste\n");
- { Fl_Type *prototype = typename_to_prototype(Fl::event_text());
- if (prototype==NULL) {
+ { Node *prototype = typename_to_prototype(Fl::event_text());
+ if (prototype==nullptr) {
// it's not a FLUID type, so it could be the filename of an image
const char *cfn = Fl::event_text();
// printf("DND is filename %s?\n", cfn);
- if ((cfn == NULL) || (*cfn == 0)) return 0;
+ if ((cfn == nullptr) || (*cfn == 0)) return 0;
if (strlen(cfn) >= FL_PATH_MAX) return 0;
char fn[FL_PATH_MAX+1];
// some platform prepend "file://" or "computer://" or similar text
@@ -1033,19 +967,19 @@ int Fl_Window_Type::handle(int event) {
if (!img || (img->ld() < 0)) return 0;
// ok, so it is an image - now add it as image() or deimage() to the widget
// printf("DND check for target %s\n", fn);
- Fl_Widget_Type *tgt = NULL;
- for (Fl_Type* i=next; i && i->level>level; i=i->next) {
+ Widget_Node *tgt = nullptr;
+ for (Node* i=next; i && i->level>level; i=i->next) {
if (i->is_widget()) {
- Fl_Widget_Type* myo = (Fl_Widget_Type*)i;
+ Widget_Node* myo = (Widget_Node*)i;
if (Fl::event_inside(myo->o) && myo->o->visible_r())
tgt = myo;
}
}
if (tgt) {
char rel[FL_PATH_MAX+1];
- enter_project_dir();
+ Fluid.proj.enter_project_dir();
fl_filename_relative(rel, FL_PATH_MAX, fn);
- leave_project_dir();
+ Fluid.proj.leave_project_dir();
// printf("DND image = %s\n", fn);
if (Fl::get_key(FL_Alt_L) || Fl::get_key(FL_Alt_R)) {
//if (Fl::event_alt()) { // TODO: X11/Wayland does not set the e_state on DND events
@@ -1069,21 +1003,21 @@ int Fl_Window_Type::handle(int event) {
// If the selected widget at dnd start and the drop target are the same,
// or in the same group, add after selection. Otherwise, just add
// at the end of the selected group.
- if ( Fl_Type::current_dnd->group()
+ if ( Fluid.proj.tree.current_dnd->group()
&& selection && selection->group()
- && Fl_Type::current_dnd->group()==selection->group())
+ && Fluid.proj.tree.current_dnd->group()==selection->group())
{
- Fl_Type *cc = Fl_Type::current;
- Fl_Type::current = Fl_Type::current_dnd;
+ Node *cc = Fluid.proj.tree.current;
+ Fluid.proj.tree.current = Fluid.proj.tree.current_dnd;
add_new_widget_from_user(prototype, Strategy::AS_LAST_CHILD);
- Fl_Type::current = cc;
+ Fluid.proj.tree.current = cc;
} else {
add_new_widget_from_user(prototype, Strategy::AS_LAST_CHILD);
}
popupx = 0x7FFFFFFF;
popupy = 0x7FFFFFFF; // mark as invalid (MAXINT)
- in_this_only = NULL;
- widget_browser->display(Fl_Type::current);
+ in_this_only = nullptr;
+ widget_browser->display(Fluid.proj.tree.current);
widget_browser->rebuild();
return 1;
}
@@ -1099,14 +1033,14 @@ int Fl_Window_Type::handle(int event) {
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 = 0;
+ in_this_only = nullptr;
return 1;
}
// find the innermost item clicked on:
selection = this;
- {for (Fl_Type* i=next; i && i->level>level; i=i->next)
+ {for (Node* i=next; i && i->level>level; i=i->next)
if (i->is_true_widget()) {
- Fl_Widget_Type* myo = (Fl_Widget_Type*)i;
+ Widget_Node* myo = (Widget_Node*)i;
for (Fl_Widget *o1 = myo->o; o1; o1 = o1->parent())
if (!o1->visible()) goto CONTINUE2;
if (Fl::event_inside(myo->o)) {
@@ -1126,7 +1060,7 @@ int Fl_Window_Type::handle(int event) {
if (!drag) drag = FD_DRAG;
}
// do object-specific selection of other objects:
- {Fl_Type* t = selection->click_test(mx, my);
+ {Node* t = selection->click_test(mx, my);
if (t) {
//if (t == selection) return 1; // indicates mouse eaten w/o change
if (Fl::event_state(FL_SHIFT)) {
@@ -1135,7 +1069,7 @@ int Fl_Window_Type::handle(int event) {
} else {
deselect();
select(t, 1);
- if (t->is_a(ID_Menu_Item)) t->open();
+ if (t->is_a(Type::Menu_Item)) t->open();
}
selection = t;
drag = 0;
@@ -1158,7 +1092,7 @@ int Fl_Window_Type::handle(int event) {
if (drag != FD_BOX && (dx || dy || !Fl::event_is_click())) {
if (dx || dy) moveallchildren();
} else if ((Fl::event_clicks() || Fl::event_state(FL_CTRL))) {
- Fl_Widget_Type::open();
+ Widget_Node::open();
} else {
if (mx<x1) {int t = x1; x1 = mx; mx = t;}
if (my<y1) {int t = y1; y1 = my; my = t;}
@@ -1167,9 +1101,9 @@ int Fl_Window_Type::handle(int event) {
// clear selection on everything:
if (!toggle) deselect(); else Fl::event_is_click(0);
// select everything in box:
- for (Fl_Type*i=next; i&&i->level>level; i=i->next)
+ for (Node*i=next; i&&i->level>level; i=i->next)
if (i->is_true_widget()) {
- Fl_Widget_Type* myo = (Fl_Widget_Type*)i;
+ Widget_Node* myo = (Widget_Node*)i;
for (Fl_Widget *o1 = myo->o; o1; o1 = o1->parent())
if (!o1->visible()) goto CONTINUE;
if (Fl::event_inside(myo->o)) selection = myo;
@@ -1201,10 +1135,10 @@ int Fl_Window_Type::handle(int event) {
case FL_Tab: {
if (Fl::event_state(FL_SHIFT)) backtab = 1;
// find current child:
- Fl_Type *i = Fl_Type::current;
+ Node *i = Fluid.proj.tree.current;
while (i && !i->is_true_widget()) i = i->parent;
if (!i) return 0;
- Fl_Type *p = i->parent;
+ Node *p = i->parent;
while (p && p != this) p = p->parent;
if (!p || !p->is_widget()) {
i = next; if (!i || i->level <= level) return 0;
@@ -1227,9 +1161,9 @@ int Fl_Window_Type::handle(int event) {
if (Fl::event_state(FL_COMMAND)) {
int x_step, y_step;
if (drag & (FD_RIGHT|FD_BOTTOM))
- Fd_Snap_Action::get_resize_stepsize(x_step, y_step);
+ fld::app::Snap_Action::get_resize_stepsize(x_step, y_step);
else
- Fd_Snap_Action::get_move_stepsize(x_step, y_step);
+ fld::app::Snap_Action::get_move_stepsize(x_step, y_step);
dx *= x_step;
dy *= y_step;
}
@@ -1238,7 +1172,7 @@ int Fl_Window_Type::handle(int event) {
return 1;
case 'o':
- toggle_overlays(0, 0);
+ toggle_overlays(nullptr, nullptr);
break;
default:
@@ -1247,10 +1181,10 @@ int Fl_Window_Type::handle(int event) {
case FL_SHORTCUT: {
in_this_only = this; // modifies how some menu items work.
- const Fl_Menu_Item* m = Main_Menu->test_shortcut();
+ const Fl_Menu_Item* m = Fluid.main_menu->test_shortcut();
if (m && m->callback()) m->do_callback(this->o);
- in_this_only = 0;
- return (m != 0);}
+ in_this_only = nullptr;
+ return (m != nullptr);}
default:
return 0;
@@ -1264,8 +1198,8 @@ int Fl_Window_Type::handle(int event) {
Write the C++ code that comes before the children of the window are written.
\param f the source code output stream
*/
-void Fl_Window_Type::write_code1(fld::io::Code_Writer& f) {
- Fl_Widget_Type::write_code1(f);
+void Window_Node::write_code1(fld::io::Code_Writer& f) {
+ Widget_Node::write_code1(f);
}
@@ -1273,7 +1207,7 @@ void Fl_Window_Type::write_code1(fld::io::Code_Writer& f) {
Write the C++ code that comes after the children of the window are written.
\param f the source code output stream
*/
-void Fl_Window_Type::write_code2(fld::io::Code_Writer& f) {
+void Window_Node::write_code2(fld::io::Code_Writer& f) {
const char *var = is_class() ? "this" : name() ? name() : "o";
// make the window modal or non-modal
if (modal) {
@@ -1308,8 +1242,8 @@ void Fl_Window_Type::write_code2(fld::io::Code_Writer& f) {
write_block_close(f);
}
-void Fl_Window_Type::write_properties(fld::io::Project_Writer &f) {
- Fl_Widget_Type::write_properties(f);
+void Window_Node::write_properties(fld::io::Project_Writer &f) {
+ Widget_Node::write_properties(f);
if (modal) f.write_string("modal");
else if (non_modal) f.write_string("non_modal");
if (!((Fl_Window*)o)->border()) f.write_string("noborder");
@@ -1319,13 +1253,13 @@ void Fl_Window_Type::write_properties(fld::io::Project_Writer &f) {
if (o->visible() || override_visible_) f.write_string("visible");
}
-void Fl_Window_Type::read_property(fld::io::Project_Reader &f, const char *c) {
+void Window_Node::read_property(fld::io::Project_Reader &f, const char *c) {
if (!strcmp(c,"modal")) {
modal = 1;
} else if (!strcmp(c,"non_modal")) {
non_modal = 1;
} else if (!strcmp(c, "visible")) {
- if (batch_mode) // don't actually open any windows in batch mode
+ if (Fluid.batch_mode) // don't actually open any windows in batch mode
override_visible_ = 1;
else // in interactive mode, we simply show the window
open_();
@@ -1340,14 +1274,14 @@ void Fl_Window_Type::read_property(fld::io::Project_Reader &f, const char *c) {
sr_min_w = mw; sr_min_h = mh; sr_max_w = MW; sr_max_h = MH;
}
} else if (!strcmp(c,"xywh")) {
- Fl_Widget_Type::read_property(f, c);
- pasteoffset = 0; // make it not apply to contents
+ Widget_Node::read_property(f, c);
+ Fluid.pasteoffset = 0; // make it not apply to contents
} else {
- Fl_Widget_Type::read_property(f, c);
+ Widget_Node::read_property(f, c);
}
}
-int Fl_Window_Type::read_fdesign(const char* propname, const char* value) {
+int Window_Node::read_fdesign(const char* propname, const char* value) {
int x;
o->box(FL_NO_BOX); // because fdesign always puts an Fl_Box next
if (!strcmp(propname,"Width")) {
@@ -1361,35 +1295,36 @@ int Fl_Window_Type::read_fdesign(const char* propname, const char* value) {
} else if (!strcmp(propname,"title")) {
label(value);
} else {
- return Fl_Widget_Type::read_fdesign(propname,value);
+ return Widget_Node::read_fdesign(propname,value);
}
return 1;
}
///////////////////////////////////////////////////////////////////////
-Fl_Widget_Class_Type Fl_Widget_Class_type;
-Fl_Widget_Class_Type *current_widget_class = 0;
+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
\return new node
*/
-Fl_Type *Fl_Widget_Class_Type::make(Strategy strategy) {
- Fl_Type *anchor = Fl_Type::current, *p = anchor;
+Node *Widget_Class_Node::make(Strategy strategy) {
+ Node *anchor = Fluid.proj.tree.current, *p = anchor;
if (p && (strategy.placement() == Strategy::AFTER_CURRENT)) p = p->parent;
while (p && (!p->is_decl_block() || (p->is_widget() && p->is_class()))) {
anchor = p;
strategy.placement(Strategy::AFTER_CURRENT);
p = p->parent;
}
- Fl_Widget_Class_Type *myo = new Fl_Widget_Class_Type();
+ Widget_Class_Node *myo = new Widget_Class_Node();
myo->name("UserInterface");
if (!this->o) {// template widget
this->o = new Fl_Window(100,100);
- Fl_Group::current(0);
+ Fl_Group::current(nullptr);
}
myo->factory = this;
myo->drag = 0;
@@ -1406,21 +1341,21 @@ Fl_Type *Fl_Widget_Class_Type::make(Strategy strategy) {
return myo;
}
-void Fl_Widget_Class_Type::write_properties(fld::io::Project_Writer &f) {
- Fl_Window_Type::write_properties(f);
+void Widget_Class_Node::write_properties(fld::io::Project_Writer &f) {
+ Window_Node::write_properties(f);
if (wc_relative==1)
f.write_string("position_relative");
else if (wc_relative==2)
f.write_string("position_relative_rescale");
}
-void Fl_Widget_Class_Type::read_property(fld::io::Project_Reader &f, const char *c) {
+void Widget_Class_Node::read_property(fld::io::Project_Reader &f, const char *c) {
if (!strcmp(c,"position_relative")) {
wc_relative = 1;
} else if (!strcmp(c,"position_relative_rescale")) {
wc_relative = 2;
} else {
- Fl_Window_Type::read_property(f, c);
+ Window_Node::read_property(f, c);
}
}
@@ -1428,7 +1363,7 @@ void Fl_Widget_Class_Type::read_property(fld::io::Project_Reader &f, const char
// This is useful for classes that contain a namespace component
static const char *trimclassname(const char *n) {
if (!n)
- return NULL;
+ return nullptr;
const char *nn;
while((nn = strstr(n, "::"))) {
n = nn + 2;
@@ -1437,9 +1372,9 @@ static const char *trimclassname(const char *n) {
}
-void Fl_Widget_Class_Type::write_code1(fld::io::Code_Writer& f) {
+void Widget_Class_Node::write_code1(fld::io::Code_Writer& f) {
#if 0
- Fl_Widget_Type::write_code1(fld::io::Code_Writer& f);
+ Widget_Node::write_code1(fld::io::Code_Writer& f);
#endif // 0
current_widget_class = this;
@@ -1507,7 +1442,7 @@ void Fl_Widget_Class_Type::write_code1(fld::io::Code_Writer& f) {
Write the C++ code that comes after the children of the window are written.
\param f the source code output stream
*/
-void Fl_Widget_Class_Type::write_code2(fld::io::Code_Writer& f) {
+void Widget_Class_Node::write_code2(fld::io::Code_Writer& f) {
// make the window modal or non-modal
if (modal) {
f.write_c("%sset_modal();\n", f.indent());
@@ -1542,21 +1477,21 @@ void Fl_Widget_Class_Type::write_code2(fld::io::Code_Writer& f) {
////////////////////////////////////////////////////////////////
// live mode support
-Fl_Widget *Fl_Window_Type::enter_live_mode(int) {
+Fl_Widget *Window_Node::enter_live_mode(int) {
Fl_Window *win = new Fl_Window(10, 10, o->w(), o->h());
return propagate_live_mode(win);
}
-void Fl_Window_Type::leave_live_mode() {
+void Window_Node::leave_live_mode() {
}
/**
copy all properties from the edit widget to the live widget
*/
-void Fl_Window_Type::copy_properties() {
+void Window_Node::copy_properties() {
Fl_Window *self = static_cast<Fl_Window*>(o);
Fl_Window *live = static_cast<Fl_Window*>(live_widget);
if (self->resizable() == self)
live->resizable(live);
- Fl_Widget_Type::copy_properties();
+ Widget_Node::copy_properties();
}
diff --git a/fluid/nodes/Window_Node.h b/fluid/nodes/Window_Node.h
new file mode 100644
index 000000000..a6846168b
--- /dev/null
+++ b/fluid/nodes/Window_Node.h
@@ -0,0 +1,163 @@
+//
+// Window type header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2025 by Bill Spitzak and others.
+//
+// This library is free software. Distribution and use rights are outlined in
+// the file "COPYING" which should have been included with this file. If this
+// file is missing or damaged, see the license at:
+//
+// https://www.fltk.org/COPYING.php
+//
+// Please see the following page on how to report bugs and issues:
+//
+// https://www.fltk.org/bugs.php
+//
+
+//
+// Type for creating all subclasses of Fl_Widget
+// This should have the widget pointer in it, but it is still in the
+// Node base class.
+
+#ifndef FLUID_NODES_WINDOW_NODE_H
+#define FLUID_NODES_WINDOW_NODE_H
+
+#include "nodes/Group_Node.h"
+
+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 *);
+void toggle_restricted(Fl_Widget *,void *);
+void show_project_cb(Fl_Widget *, void *);
+void show_grid_cb(Fl_Widget *, void *);
+void show_settings_cb(Fl_Widget *, void *);
+
+enum {
+ FD_LEFT = 1, // user drags the left side of the selection box
+ FD_RIGHT = 2,
+ FD_BOTTOM = 4,
+ FD_TOP = 8,
+ FD_DRAG = 16, // user drags the entire selection
+ FD_BOX = 32 // user creates a new selection box
+};
+
+class Window_Node : public Group_Node
+{
+public:
+ typedef Group_Node super;
+ static Window_Node prototype;
+protected:
+
+ Fl_Menu_Item* subtypes() override {return window_type_menu;}
+
+ friend class Overlay_Window;
+ int mx,my; // mouse position during dragging
+ int x1,y1; // initial position of selection box
+ int bx,by,br,bt; // bounding box of selection before snapping
+ int sx,sy,sr,st; // bounding box of selection after snapping to guides
+ int dx,dy;
+ int drag; // which parts of bbox are being moved
+ int numselected; // number of children selected
+ void draw_out_of_bounds(Widget_Node *group, int x, int y, int w, int h);
+ void draw_out_of_bounds();
+ void draw_overlaps();
+ void draw_overlay();
+ void newdx();
+ void newposition(Widget_Node *,int &x,int &y,int &w,int &h);
+ int handle(int);
+ void setlabel(const char *) override;
+ void write_code1(fld::io::Code_Writer& f) override;
+ void write_code2(fld::io::Code_Writer& f) override;
+ Widget_Node *_make() override {return nullptr;} // we don't call this
+ Fl_Widget *widget(int,int,int,int) override {return nullptr;}
+ int recalc; // set by fix_overlay()
+ void moveallchildren(int key=0);
+ Type type() const override { return Type::Window; }
+ bool is_a(Type inType) const override { return (inType==Type::Window) ? true : super::is_a(inType); }
+ void open_();
+
+public:
+
+ Window_Node() :
+ mx(0), my(0),
+ x1(0), y1(0),
+ bx(0), by(0), br(0), bt(0),
+ sx(0), sy(0), sr(0), st(0),
+ dx(0), dy(0),
+ drag(0),
+ numselected(0),
+ recalc(0),
+ modal(0), non_modal(0),
+ xclass(nullptr),
+ sr_min_w(0), sr_min_h(0), sr_max_w(0), sr_max_h(0)
+ { }
+ uchar modal, non_modal;
+ const char *xclass; // junk string, used for shortcut
+
+ Node *make(Strategy strategy) override;
+ const char *type_name() override {return "Fl_Window";}
+ const char *alt_type_name() override {return "fltk::Window";}
+
+ void open() override;
+ void ideal_size(int &w, int &h) override;
+
+ void fix_overlay(); // Update the bounding box, etc
+ uchar *read_image(int &ww, int &hh); // Read an image of the window
+
+ void write_properties(fld::io::Project_Writer &f) override;
+ void read_property(fld::io::Project_Reader &f, const char *) override;
+ int read_fdesign(const char*, const char*) override;
+
+ void add_child(Node*, Node*) override;
+ void move_child(Node*, Node*) override;
+ void remove_child(Node*) override;
+
+ int can_have_children() const override {return 1;}
+
+ Fl_Widget *enter_live_mode(int top=0) override;
+ void leave_live_mode() override;
+ void copy_properties() override;
+
+ int sr_min_w, sr_min_h, sr_max_w, sr_max_h;
+
+ static int popupx, popupy;
+};
+
+class Widget_Class_Node : private Window_Node
+{
+public:
+ typedef Window_Node super;
+ static Widget_Class_Node prototype;
+
+protected:
+ Fl_Menu_Item* subtypes() override {return nullptr;}
+
+public:
+ Widget_Class_Node() {
+ write_public_state = 0;
+ wc_relative = 0;
+ }
+ // state variables for output:
+ char write_public_state; // true when public: has been printed
+ char wc_relative; // if 1, reposition all children, if 2, reposition and resize
+
+ void write_properties(fld::io::Project_Writer &f) override;
+ void read_property(fld::io::Project_Reader &f, const char *) override;
+
+ void write_code1(fld::io::Code_Writer& f) override;
+ void write_code2(fld::io::Code_Writer& f) override;
+ Node *make(Strategy strategy) override;
+ const char *type_name() override {return "widget_class";}
+ Type type() const override { return Type::Widget_Class; }
+ bool is_a(Type inType) const override { return (inType==Type::Widget_Class) ? true : super::is_a(inType); }
+ int can_have_children() const override {return 1;}
+ int is_code_block() const override {return 1;}
+ int is_decl_block() const override {return 1;}
+ int is_class() const override {return 1;}
+};
+
+#endif // FLUID_NODES_WINDOW_NODE_H
diff --git a/fluid/nodes/callbacks.cxx b/fluid/nodes/callbacks.cxx
new file mode 100644
index 000000000..f53ca2d6c
--- /dev/null
+++ b/fluid/nodes/callbacks.cxx
@@ -0,0 +1,18 @@
+//
+// Fluid Node callbacks code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 2025 by Bill Spitzak and others.
+//
+// This library is free software. Distribution and use rights are outlined in
+// the file "COPYING" which should have been included with this file. If this
+// file is missing or damaged, see the license at:
+//
+// https://www.fltk.org/COPYING.php
+//
+// Please see the following page on how to report bugs and issues:
+//
+// https://www.fltk.org/bugs.php
+//
+
+#include "nodes/callbacks.h"
+
diff --git a/fluid/nodes/callbacks.h b/fluid/nodes/callbacks.h
new file mode 100644
index 000000000..77a38754a
--- /dev/null
+++ b/fluid/nodes/callbacks.h
@@ -0,0 +1,23 @@
+//
+// Fluid Node callbacks header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 2025 by Bill Spitzak and others.
+//
+// This library is free software. Distribution and use rights are outlined in
+// the file "COPYING" which should have been included with this file. If this
+// file is missing or damaged, see the license at:
+//
+// https://www.fltk.org/COPYING.php
+//
+// Please see the following page on how to report bugs and issues:
+//
+// https://www.fltk.org/bugs.php
+//
+
+#ifndef FLUID_NODES_CALLBACKS_H
+#define FLUID_NODES_CALLBACKS_H
+
+#include "nodes/Node.h"
+
+
+#endif // FLUID_NODES_CALLBACKS_H
diff --git a/fluid/nodes/factory.cxx b/fluid/nodes/factory.cxx
index ad5d388e1..8388e0202 100644
--- a/fluid/nodes/factory.cxx
+++ b/fluid/nodes/factory.cxx
@@ -1,13 +1,5 @@
//
-// Widget factory code for the Fast Light Tool Kit (FLTK).
-//
-// Type classes for most of the fltk widgets. Most of the work
-// is done by code in Fl_Widget_Type.cxx. Also a factory instance
-// of each of these type classes.
-//
-// This file also contains the "new" menu, which has a pointer
-// to a factory instance for every class (both the ones defined
-// here and ones in other files)
+// Node Factory code for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-2025 by Bill Spitzak and others.
//
@@ -22,14 +14,41 @@
// https://www.fltk.org/bugs.php
//
+/**
+
+
+ \todo Verify the text
+
+ Type classes for most of the fltk widgets. Most of the work
+ is done by code in Widget_Node.cxx. Also a factory instance
+ of each of these type classes.
+
+ This file also contains the "new" menu, which has a pointer
+ to a factory instance for every class (both the ones defined
+ here and ones in other files)
+
+
+ Type classes for most of the fltk widgets. Most of the work
+ is done by code in Widget_Node.C. Also a factory instance
+ of each of these type classes.
+
+ This file also contains the "new" menu, which has a pointer
+ to a factory instance for every class (both the ones defined
+ here and ones in other files)
+
+ */
#include "nodes/factory.h"
-#include "app/Fd_Snap_Action.h"
-#include "app/fluid.h"
-#include "app/undo.h"
-#include "nodes/Fl_Group_Type.h"
-#include "nodes/Fl_Grid_Type.h"
-#include "nodes/Fl_Menu_Type.h"
+#include "app/Snap_Action.h"
+#include "Fluid.h"
+#include "proj/undo.h"
+#include "nodes/Button_Node.h"
+#include "nodes/Function_Node.h"
+#include "nodes/Grid_Node.h"
+#include "nodes/Group_Node.h"
+#include "nodes/Menu_Node.h"
+#include "nodes/Widget_Node.h"
+#include "nodes/Window_Node.h"
#include "rsrcs/pixmaps.h"
#include <FL/Fl.H>
@@ -70,23 +89,26 @@
// ---- Browser_Base ----
static Fl_Menu_Item browser_base_type_menu[] = {
- {"No Select", 0, 0, (void*)FL_NORMAL_BROWSER},
- {"Select", 0, 0, (void*)FL_SELECT_BROWSER},
- {"Hold", 0, 0, (void*)FL_HOLD_BROWSER},
- {"Multi", 0, 0, (void*)FL_MULTI_BROWSER},
- {0}
+ {"No Select", 0, nullptr, (void*)nullptr},
+ {"Select", 0, nullptr, (void*)FL_SELECT_BROWSER},
+ {"Hold", 0, nullptr, (void*)FL_HOLD_BROWSER},
+ {"Multi", 0, nullptr, (void*)FL_MULTI_BROWSER},
+ {nullptr}
};
/**
\brief This is the base class for some browsers types.
This class will not be instantiated.
*/
-class Fl_Browser_Base_Type : public Fl_Widget_Type
+class Browser_Base_Node : public Widget_Node
{
- typedef Fl_Widget_Type super;
- Fl_Menu_Item *subtypes() FL_OVERRIDE { return browser_base_type_menu; }
- int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) FL_OVERRIDE {
- Fl_Browser_ *myo = (Fl_Browser_*)(w==4 ? ((Fl_Widget_Type*)factory)->o : o);
+public:
+ typedef Widget_Node super;
+ static Browser_Base_Node prototype;
+private:
+ Fl_Menu_Item *subtypes() override { return browser_base_type_menu; }
+ int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) override {
+ Fl_Browser_ *myo = (Fl_Browser_*)(w==4 ? ((Widget_Node*)factory)->o : o);
switch (w) {
case 4:
case 0: f = myo->textfont(); s = myo->textsize(); c = myo->textcolor(); break;
@@ -97,42 +119,44 @@ class Fl_Browser_Base_Type : public Fl_Widget_Type
return 1;
}
public:
- void ideal_size(int &w, int &h) FL_OVERRIDE {
+ void ideal_size(int &w, int &h) override {
w = 120;
h = 160;
- Fd_Snap_Action::better_size(w, h);
+ fld::app::Snap_Action::better_size(w, h);
}
- const char *type_name() FL_OVERRIDE { return "Fl_Browser_"; }
- const char *alt_type_name() FL_OVERRIDE { return "fltk::Browser_"; }
- Fl_Widget *widget(int x, int y, int w, int h) FL_OVERRIDE {
+ const char *type_name() override { return "Fl_Browser_"; }
+ const char *alt_type_name() override { return "fltk::Browser_"; }
+ Fl_Widget *widget(int x, int y, int w, int h) override {
Fl_Browser* b = new Fl_Browser(x, y, w, h);
return b;
}
- Fl_Widget_Type *_make() FL_OVERRIDE { return new Fl_Browser_Base_Type(); }
- ID id() const FL_OVERRIDE { return ID_Browser_; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Browser_) ? true : super::is_a(inID); }
+ Widget_Node *_make() override { return new Browser_Base_Node(); }
+ Type type() const override { return Type::Browser_; }
+ bool is_a(Type inType) const override { return (inType==Type::Browser_) ? true : super::is_a(inType); }
};
-static Fl_Browser_Base_Type Fl_Browser_Base_type;
+Browser_Base_Node Browser_Base_Node::prototype;
// ---- Browser ----
/**
\brief Handle a plain browser widget.
- Most of the work is already done in Fl_Browser_Base_Type.
+ Most of the work is already done in Browser_Base_Node.
*/
-class Fl_Browser_Type : public Fl_Browser_Base_Type
+class Browser_Node : public Browser_Base_Node
{
- typedef Fl_Browser_Base_Type super;
public:
- const char *type_name() FL_OVERRIDE { return "Fl_Browser"; }
- const char *alt_type_name() FL_OVERRIDE { return "fltk::Browser"; }
- Fl_Widget *widget(int x, int y, int w, int h) FL_OVERRIDE {
+ typedef Browser_Base_Node super;
+ static Browser_Node prototype;
+public:
+ const char *type_name() override { return "Fl_Browser"; }
+ const char *alt_type_name() override { return "fltk::Browser"; }
+ Fl_Widget *widget(int x, int y, int w, int h) override {
Fl_Browser* b = new Fl_Browser(x, y, w, h);
// Fl_Browser::add calls fl_height(), which requires the X display open.
// Avoid this when compiling so it works w/o a display:
- if (!batch_mode) {
+ if (!Fluid.batch_mode) {
char buffer[20];
for (int i = 1; i <= 20; i++) {
sprintf(buffer,"Browser Line %d",i);
@@ -141,12 +165,12 @@ public:
}
return b;
}
- Fl_Widget_Type *_make() FL_OVERRIDE { return new Fl_Browser_Type(); }
- ID id() const FL_OVERRIDE { return ID_Browser; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Browser) ? true : super::is_a(inID); }
+ Widget_Node *_make() override { return new Browser_Node(); }
+ Type type() const override { return Type::Browser; }
+ bool is_a(Type inType) const override { return (inType==Type::Browser) ? true : super::is_a(inType); }
};
-static Fl_Browser_Type Fl_Browser_type;
+Browser_Node Browser_Node::prototype;
// ---- Check Browser ----
@@ -155,17 +179,19 @@ static Fl_Browser_Type Fl_Browser_type;
\brief Manage the Check Browser.
The Fl_Check_Browser is derived form Fl_Browser_ (underline!), not Fl_Browser.
*/
-class Fl_Check_Browser_Type : public Fl_Browser_Base_Type
+class Check_Browser_Node : public Browser_Base_Node
{
- typedef Fl_Browser_Base_Type super;
public:
- const char *type_name() FL_OVERRIDE { return "Fl_Check_Browser"; }
- const char *alt_type_name() FL_OVERRIDE { return "fltk::CheckBrowser"; }
- Fl_Widget *widget(int x, int y, int w, int h) FL_OVERRIDE {
+ typedef Browser_Base_Node super;
+ static Check_Browser_Node prototype;
+public:
+ const char *type_name() override { return "Fl_Check_Browser"; }
+ const char *alt_type_name() override { return "fltk::CheckBrowser"; }
+ Fl_Widget *widget(int x, int y, int w, int h) override {
Fl_Check_Browser* b = new Fl_Check_Browser(x, y, w, h);
// Fl_Check_Browser::add calls fl_height(), which requires the X display open.
// Avoid this when compiling so it works w/o a display:
- if (!batch_mode) {
+ if (!Fluid.batch_mode) {
char buffer[20];
for (int i = 1; i <= 20; i++) {
sprintf(buffer,"Browser Line %d",i);
@@ -174,12 +200,12 @@ public:
}
return b;
}
- Fl_Widget_Type *_make() FL_OVERRIDE { return new Fl_Check_Browser_Type(); }
- ID id() const FL_OVERRIDE { return ID_Check_Browser; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Check_Browser) ? true : super::is_a(inID); }
+ Widget_Node *_make() override { return new Check_Browser_Node(); }
+ Type type() const override { return Type::Check_Browser; }
+ bool is_a(Type inType) const override { return (inType==Type::Check_Browser) ? true : super::is_a(inType); }
};
-static Fl_Check_Browser_Type Fl_Check_Browser_type;
+Check_Browser_Node Check_Browser_Node::prototype;
// ---- File Browser ----
@@ -189,23 +215,25 @@ static Fl_Check_Browser_Type Fl_Check_Browser_type;
As oppoesed to the Hold, Multi, and Select Browser, this is not a subclass, but
its own implementation, based on Fl_Browser.
*/
-class Fl_File_Browser_Type : public Fl_Browser_Type
+class File_Browser_Node : public Browser_Node
{
- typedef Fl_Browser_Type super;
public:
- const char *type_name() FL_OVERRIDE { return "Fl_File_Browser"; }
- const char *alt_type_name() FL_OVERRIDE { return "fltk::FileBrowser"; }
- Fl_Widget *widget(int x, int y, int w, int h) FL_OVERRIDE {
+ typedef Browser_Node super;
+ static File_Browser_Node prototype;
+public:
+ const char *type_name() override { return "Fl_File_Browser"; }
+ const char *alt_type_name() override { return "fltk::FileBrowser"; }
+ Fl_Widget *widget(int x, int y, int w, int h) override {
Fl_File_Browser* b = new Fl_File_Browser(x, y, w, h);
- if (!batch_mode) b->load(".");
+ if (!Fluid.batch_mode) b->load(".");
return b;
}
- Fl_Widget_Type *_make() FL_OVERRIDE { return new Fl_File_Browser_Type(); }
- ID id() const FL_OVERRIDE { return ID_File_Browser; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_File_Browser) ? true : super::is_a(inID); }
+ Widget_Node *_make() override { return new File_Browser_Node(); }
+ Type type() const override { return Type::File_Browser; }
+ bool is_a(Type inType) const override { return (inType==Type::File_Browser) ? true : super::is_a(inType); }
};
-static Fl_File_Browser_Type Fl_File_Browser_type;
+File_Browser_Node File_Browser_Node::prototype;
// ---- Tree Type ------------------------------------------------------ MARK: -
@@ -213,25 +241,27 @@ static Fl_File_Browser_Type Fl_File_Browser_type;
/**
\brief Handle the Tree widget.
Fl_Tree is derived from Fl_Group, but FLUID does not support extended Fl_Tree
- functionality, so we derive the Type from Fl_Widget_Type.
+ functionality, so we derive the Type from Widget_Node.
\note Updating item_labelfont etc. does not refresh any of the existing
items in the tree, so I decided against implementig those via
the labelfont UI.
*/
-class Fl_Tree_Type : public Fl_Widget_Type
+class Tree_Node : public Widget_Node
{
- typedef Fl_Widget_Type super;
public:
- void ideal_size(int &w, int &h) FL_OVERRIDE {
+ typedef Widget_Node super;
+ static Tree_Node prototype;
+public:
+ void ideal_size(int &w, int &h) override {
w = 120;
h = 160;
- Fd_Snap_Action::better_size(w, h);
+ fld::app::Snap_Action::better_size(w, h);
}
- const char *type_name() FL_OVERRIDE { return "Fl_Tree"; }
- const char *alt_type_name() FL_OVERRIDE { return "fltk::TreeBrowser"; }
- Fl_Widget *widget(int x, int y, int w, int h) FL_OVERRIDE {
+ const char *type_name() override { return "Fl_Tree"; }
+ const char *alt_type_name() override { return "fltk::TreeBrowser"; }
+ Fl_Widget *widget(int x, int y, int w, int h) override {
Fl_Tree* b = new Fl_Tree(x, y, w, h);
- if (!batch_mode) {
+ if (!Fluid.batch_mode) {
b->add("/A1/B1/C1");
b->add("/A1/B1/C2");
b->add("/A1/B2/C1");
@@ -243,12 +273,12 @@ public:
}
return b;
}
- Fl_Widget_Type *_make() FL_OVERRIDE { return new Fl_Tree_Type(); }
- ID id() const FL_OVERRIDE { return ID_Tree; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Tree) ? true : super::is_a(inID); }
+ Widget_Node *_make() override { return new Tree_Node(); }
+ Type type() const override { return Type::Tree; }
+ bool is_a(Type inType) const override { return (inType==Type::Tree) ? true : super::is_a(inType); }
};
-static Fl_Tree_Type Fl_Tree_type;
+Tree_Node Tree_Node::prototype;
@@ -257,13 +287,16 @@ static Fl_Tree_Type Fl_Tree_type;
/**
\brief Handle the Help View widget.
Fl_Help_View is derived from Fl_Group, but supporting children is not useful,
- so we derive from Fl_Widget_Type.
+ so we derive from Widget_Node.
*/
-class Fl_Help_View_Type : public Fl_Widget_Type
+class Help_View_Node : public Widget_Node
{
- typedef Fl_Widget_Type super;
- int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) FL_OVERRIDE {
- Fl_Help_View *myo = (Fl_Help_View*)(w==4 ? ((Fl_Widget_Type*)factory)->o : o);
+public:
+ typedef Widget_Node super;
+ static Help_View_Node prototype;
+private:
+ int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) override {
+ Fl_Help_View *myo = (Fl_Help_View*)(w==4 ? ((Widget_Node*)factory)->o : o);
switch (w) {
case 4:
case 0: f = myo->textfont(); s = myo->textsize(); c = myo->textcolor(); break;
@@ -274,27 +307,27 @@ class Fl_Help_View_Type : public Fl_Widget_Type
return 1;
}
public:
- void ideal_size(int &w, int &h) FL_OVERRIDE {
+ void ideal_size(int &w, int &h) override {
w = 160;
h = 120;
- Fd_Snap_Action::better_size(w, h);
+ fld::app::Snap_Action::better_size(w, h);
}
- const char *type_name() FL_OVERRIDE { return "Fl_Help_View"; }
- const char *alt_type_name() FL_OVERRIDE { return "fltk::HelpView"; }
- Fl_Widget *widget(int x, int y, int w, int h) FL_OVERRIDE {
+ const char *type_name() override { return "Fl_Help_View"; }
+ const char *alt_type_name() override { return "fltk::HelpView"; }
+ Fl_Widget *widget(int x, int y, int w, int h) override {
Fl_Help_View *myo = new Fl_Help_View(x, y, w, h);
- if (!batch_mode) {
+ if (!Fluid.batch_mode) {
myo->value("<HTML><BODY><H1>Fl_Help_View Widget</H1>"
"<P>This is a Fl_Help_View widget.</P></BODY></HTML>");
}
return myo;
}
- Fl_Widget_Type *_make() FL_OVERRIDE { return new Fl_Help_View_Type(); }
- ID id() const FL_OVERRIDE { return ID_Help_View; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Help_View) ? true : super::is_a(inID); }
+ Widget_Node *_make() override { return new Help_View_Node(); }
+ Type type() const override { return Type::Help_View; }
+ bool is_a(Type inType) const override { return (inType==Type::Help_View) ? true : super::is_a(inType); }
};
-static Fl_Help_View_Type Fl_Help_View_type;
+Help_View_Node Help_View_Node::prototype;
@@ -306,41 +339,46 @@ static Fl_Help_View_Type Fl_Help_View_type;
/**
\brief Just a base class for all valuators.
*/
-class Fl_Valuator_Type : public Fl_Widget_Type
+class Valuator_Node : public Widget_Node
{
- typedef Fl_Widget_Type super;
public:
- const char *type_name() FL_OVERRIDE { return "Fl_Valuator"; }
- const char *alt_type_name() FL_OVERRIDE { return "fltk::Valuator"; }
- Fl_Widget *widget(int x, int y, int w, int h) FL_OVERRIDE {
+ typedef Widget_Node super;
+ static Valuator_Node prototype;
+public:
+ const char *type_name() override { return "Fl_Valuator"; }
+ const char *alt_type_name() override { return "fltk::Valuator"; }
+ Fl_Widget *widget(int x, int y, int w, int h) override {
return new Fl_Slider(x, y, w, h, "Valuator");
}
- Fl_Widget_Type *_make() FL_OVERRIDE { return new Fl_Valuator_Type(); }
- ID id() const FL_OVERRIDE { return ID_Valuator_; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Valuator_) ? true : super::is_a(inID); }
+ Widget_Node *_make() override { return new Valuator_Node(); }
+ Type type() const override { return Type::Valuator_; }
+ bool is_a(Type inType) const override { return (inType==Type::Valuator_) ? true : super::is_a(inType); }
};
-static Fl_Valuator_Type Fl_Valuator_type;
+Valuator_Node Valuator_Node::prototype;
// ---- Counter ----
static Fl_Menu_Item counter_type_menu[] = {
- { "Normal", 0, 0, (void*)FL_NORMAL_COUNTER },
- { "Simple", 0, 0, (void*)FL_SIMPLE_COUNTER },
- { 0 }
+ { "Normal", 0, nullptr, (void*)nullptr },
+ { "Simple", 0, nullptr, (void*)FL_SIMPLE_COUNTER },
+ { nullptr }
};
/**
\brief Manage the Counter widget.
Strictly speaking, the ideal size should derive from the textsize not the labelsize.
*/
-class Fl_Counter_Type : public Fl_Valuator_Type
+class Counter_Node : public Valuator_Node
{
- typedef Fl_Valuator_Type super;
- Fl_Menu_Item *subtypes() FL_OVERRIDE { return counter_type_menu; }
- int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) FL_OVERRIDE {
- Fl_Counter *myo = (Fl_Counter*)(w==4 ? ((Fl_Widget_Type*)factory)->o : o);
+public:
+ typedef Valuator_Node super;
+ static Counter_Node prototype;
+private:
+ Fl_Menu_Item *subtypes() override { return counter_type_menu; }
+ int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) override {
+ Fl_Counter *myo = (Fl_Counter*)(w==4 ? ((Widget_Node*)factory)->o : o);
switch (w) {
case 4:
case 0: f = myo->textfont(); s = myo->textsize(); c = myo->textcolor(); break;
@@ -351,22 +389,23 @@ class Fl_Counter_Type : public Fl_Valuator_Type
return 1;
}
public:
- void ideal_size(int &w, int &h) FL_OVERRIDE {
+ void ideal_size(int &w, int &h) override {
+ auto layout = Fluid.proj.layout;
h = layout->textsize_not_null() + 8;
w = layout->textsize_not_null() * 4 + 4 * h; // make room for the arrows
- Fd_Snap_Action::better_size(w, h);
+ fld::app::Snap_Action::better_size(w, h);
}
- const char *type_name() FL_OVERRIDE { return "Fl_Counter"; }
- const char *alt_type_name() FL_OVERRIDE { return "fltk::Counter"; }
- Fl_Widget *widget(int x, int y, int w, int h) FL_OVERRIDE {
+ const char *type_name() override { return "Fl_Counter"; }
+ const char *alt_type_name() override { return "fltk::Counter"; }
+ Fl_Widget *widget(int x, int y, int w, int h) override {
return new Fl_Counter(x, y, w, h, "counter:");
}
- Fl_Widget_Type *_make() FL_OVERRIDE { return new Fl_Counter_Type(); }
- ID id() const FL_OVERRIDE { return ID_Counter; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Counter) ? true : super::is_a(inID); }
+ Widget_Node *_make() override { return new Counter_Node(); }
+ Type type() const override { return Type::Counter; }
+ bool is_a(Type inType) const override { return (inType==Type::Counter) ? true : super::is_a(inType); }
};
-static Fl_Counter_Type Fl_Counter_type;
+Counter_Node Counter_Node::prototype;
// ---- Adjuster ----
@@ -374,105 +413,116 @@ static Fl_Counter_Type Fl_Counter_type;
/**
\brief Handle Adjuster widgets which are derived from valuators.
*/
-class Fl_Adjuster_Type : public Fl_Valuator_Type
+class Adjuster_Node : public Valuator_Node
{
- typedef Fl_Valuator_Type super;
public:
- void ideal_size(int &w, int &h) FL_OVERRIDE {
+ typedef Valuator_Node super;
+ static Adjuster_Node prototype;
+public:
+ void ideal_size(int &w, int &h) override {
+ auto layout = Fluid.proj.layout;
h = layout->labelsize + 8;
w = 3 * h;
- Fd_Snap_Action::better_size(w, h);
+ fld::app::Snap_Action::better_size(w, h);
}
- const char *type_name() FL_OVERRIDE { return "Fl_Adjuster"; }
- const char *alt_type_name() FL_OVERRIDE { return "fltk::Adjuster"; }
- Fl_Widget *widget(int x, int y, int w, int h) FL_OVERRIDE {
+ const char *type_name() override { return "Fl_Adjuster"; }
+ const char *alt_type_name() override { return "fltk::Adjuster"; }
+ Fl_Widget *widget(int x, int y, int w, int h) override {
return new Fl_Adjuster(x, y, w, h);
}
- Fl_Widget_Type *_make() FL_OVERRIDE { return new Fl_Adjuster_Type(); }
- ID id() const FL_OVERRIDE { return ID_Adjuster; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Adjuster) ? true : super::is_a(inID); }
+ Widget_Node *_make() override { return new Adjuster_Node(); }
+ Type type() const override { return Type::Adjuster; }
+ bool is_a(Type inType) const override { return (inType==Type::Adjuster) ? true : super::is_a(inType); }
};
-static Fl_Adjuster_Type Fl_Adjuster_type;
+Adjuster_Node Adjuster_Node::prototype;
// ---- Dial ----
static Fl_Menu_Item dial_type_menu[] = {
- { "Dot", 0, 0, (void*)0 },
- { "Line", 0, 0, (void*)FL_LINE_DIAL },
- { "Fill", 0, 0, (void*)FL_FILL_DIAL },
- { 0 }
+ { "Dot", 0, nullptr, (void*)nullptr },
+ { "Line", 0, nullptr, (void*)FL_LINE_DIAL },
+ { "Fill", 0, nullptr, (void*)FL_FILL_DIAL },
+ { nullptr }
};
/**
\brief Manage dials.
*/
-class Fl_Dial_Type : public Fl_Valuator_Type
+class Dial_Node : public Valuator_Node
{
- typedef Fl_Valuator_Type super;
- Fl_Menu_Item *subtypes() FL_OVERRIDE { return dial_type_menu; }
public:
- void ideal_size(int &w, int &h) FL_OVERRIDE {
+ typedef Valuator_Node super;
+ static Dial_Node prototype;
+private:
+ Fl_Menu_Item *subtypes() override { return dial_type_menu; }
+public:
+ void ideal_size(int &w, int &h) override {
w = 60; h = 60;
- Fd_Snap_Action::better_size(w, h);
+ fld::app::Snap_Action::better_size(w, h);
}
- const char *type_name() FL_OVERRIDE { return "Fl_Dial"; }
- const char *alt_type_name() FL_OVERRIDE { return "fltk::Dial"; }
- Fl_Widget *widget(int x, int y, int w, int h) FL_OVERRIDE {
+ const char *type_name() override { return "Fl_Dial"; }
+ const char *alt_type_name() override { return "fltk::Dial"; }
+ Fl_Widget *widget(int x, int y, int w, int h) override {
return new Fl_Dial(x, y, w, h);
}
- Fl_Widget_Type *_make() FL_OVERRIDE { return new Fl_Dial_Type(); }
- ID id() const FL_OVERRIDE { return ID_Dial; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Dial) ? true : super::is_a(inID); }
+ Widget_Node *_make() override { return new Dial_Node(); }
+ Type type() const override { return Type::Dial; }
+ bool is_a(Type inType) const override { return (inType==Type::Dial) ? true : super::is_a(inType); }
};
-static Fl_Dial_Type Fl_Dial_type;
+
+Dial_Node Dial_Node::prototype;
// ---- Roller ----
static Fl_Menu_Item roller_type_menu[] = {
- { "Vertical", 0, 0, (void*)0 },
- { "Horizontal", 0, 0, (void*)FL_HORIZONTAL },
- { 0 }
+ { "Vertical", 0, nullptr, (void*)nullptr },
+ { "Horizontal", 0, nullptr, (void*)FL_HORIZONTAL },
+ { nullptr }
};
/**
\brief Manage Roller widgets. They are vertical by default.
*/
-class Fl_Roller_Type : public Fl_Valuator_Type
+class Roller_Node : public Valuator_Node
{
- typedef Fl_Valuator_Type super;
- Fl_Menu_Item *subtypes() FL_OVERRIDE { return roller_type_menu; }
public:
- void ideal_size(int &w, int &h) FL_OVERRIDE {
+ typedef Valuator_Node super;
+ static Roller_Node prototype;
+private:
+ Fl_Menu_Item *subtypes() override { return roller_type_menu; }
+public:
+ void ideal_size(int &w, int &h) override {
+ auto layout = Fluid.proj.layout;
w = layout->labelsize + 8;
h = 4 * w;
- Fd_Snap_Action::better_size(w, h);
+ fld::app::Snap_Action::better_size(w, h);
}
- const char *type_name() FL_OVERRIDE { return "Fl_Roller"; }
- const char *alt_type_name() FL_OVERRIDE { return "fltk::Roller"; }
- Fl_Widget *widget(int x, int y, int w, int h) FL_OVERRIDE {
+ const char *type_name() override { return "Fl_Roller"; }
+ const char *alt_type_name() override { return "fltk::Roller"; }
+ Fl_Widget *widget(int x, int y, int w, int h) override {
return new Fl_Roller(x, y, w, h);
}
- Fl_Widget_Type *_make() FL_OVERRIDE { return new Fl_Roller_Type(); }
- ID id() const FL_OVERRIDE { return ID_Roller; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Roller) ? true : super::is_a(inID); }
+ Widget_Node *_make() override { return new Roller_Node(); }
+ Type type() const override { return Type::Roller; }
+ bool is_a(Type inType) const override { return (inType==Type::Roller) ? true : super::is_a(inType); }
};
-static Fl_Roller_Type Fl_Roller_type;
+Roller_Node Roller_Node::prototype;
// ---- Slider ----
static Fl_Menu_Item slider_type_menu[] = {
- { "Vertical", 0, 0, (void*)FL_VERT_SLIDER },
- { "Horizontal", 0, 0, (void*)FL_HOR_SLIDER },
- { "Vert Fill", 0, 0, (void*)FL_VERT_FILL_SLIDER },
- { "Horz Fill", 0, 0, (void*)FL_HOR_FILL_SLIDER },
- { "Vert Knob", 0, 0, (void*)FL_VERT_NICE_SLIDER },
- { "Horz Knob", 0, 0, (void*)FL_HOR_NICE_SLIDER },
- { 0 }
+ { "Vertical", 0, nullptr, (void*)nullptr },
+ { "Horizontal", 0, nullptr, (void*)FL_HOR_SLIDER },
+ { "Vert Fill", 0, nullptr, (void*)FL_VERT_FILL_SLIDER },
+ { "Horz Fill", 0, nullptr, (void*)FL_HOR_FILL_SLIDER },
+ { "Vert Knob", 0, nullptr, (void*)FL_VERT_NICE_SLIDER },
+ { "Horz Knob", 0, nullptr, (void*)FL_HOR_NICE_SLIDER },
+ { nullptr }
};
/**
@@ -480,55 +530,63 @@ static Fl_Menu_Item slider_type_menu[] = {
They are vertical by default.
Fl_Value_Slider has its own type.
*/
-class Fl_Slider_Type : public Fl_Valuator_Type
+class Slider_Node : public Valuator_Node
{
- typedef Fl_Valuator_Type super;
- Fl_Menu_Item *subtypes() FL_OVERRIDE { return slider_type_menu; }
public:
- void ideal_size(int &w, int &h) FL_OVERRIDE {
+ typedef Valuator_Node super;
+ static Slider_Node prototype;
+private:
+ Fl_Menu_Item *subtypes() override { return slider_type_menu; }
+public:
+ void ideal_size(int &w, int &h) override {
+ auto layout = Fluid.proj.layout;
w = layout->labelsize + 8;
h = 4 * w;
- Fd_Snap_Action::better_size(w, h);
+ fld::app::Snap_Action::better_size(w, h);
}
- const char *type_name() FL_OVERRIDE { return "Fl_Slider"; }
- const char *alt_type_name() FL_OVERRIDE { return "fltk::Slider"; }
- Fl_Widget *widget(int x, int y, int w, int h) FL_OVERRIDE {
+ const char *type_name() override { return "Fl_Slider"; }
+ const char *alt_type_name() override { return "fltk::Slider"; }
+ Fl_Widget *widget(int x, int y, int w, int h) override {
return new Fl_Slider(x, y, w, h, "slider:");
}
- Fl_Widget_Type *_make() FL_OVERRIDE { return new Fl_Slider_Type(); }
- ID id() const FL_OVERRIDE { return ID_Slider; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Slider) ? true : super::is_a(inID); }
+ Widget_Node *_make() override { return new Slider_Node(); }
+ Type type() const override { return Type::Slider; }
+ bool is_a(Type inType) const override { return (inType==Type::Slider) ? true : super::is_a(inType); }
};
-static Fl_Slider_Type Fl_Slider_type;
+Slider_Node Slider_Node::prototype;
// ---- Scrollbar ----
static Fl_Menu_Item scrollbar_type_menu[] = {
- { "Vertical", 0, 0, (void*)FL_VERT_SLIDER },
- { "Horizontal", 0, 0, (void*)FL_HOR_SLIDER },
- { 0 }
+ { "Vertical", 0, nullptr, (void*)nullptr },
+ { "Horizontal", 0, nullptr, (void*)FL_HOR_SLIDER },
+ { nullptr }
};
/**
\brief Manage Scrollbars which are derived from Sliders.
*/
-class Fl_Scrollbar_Type : public Fl_Slider_Type
+class Scrollbar_Node : public Slider_Node
{
- typedef Fl_Slider_Type super;
- Fl_Menu_Item *subtypes() FL_OVERRIDE { return scrollbar_type_menu; }
public:
- const char *type_name() FL_OVERRIDE { return "Fl_Scrollbar"; }
- const char *alt_type_name() FL_OVERRIDE { return "fltk::Scrollbar"; }
- Fl_Widget *widget(int x, int y, int w, int h) FL_OVERRIDE {
+ typedef Slider_Node super;
+ static Scrollbar_Node prototype;
+private:
+ Fl_Menu_Item *subtypes() override { return scrollbar_type_menu; }
+public:
+ const char *type_name() override { return "Fl_Scrollbar"; }
+ const char *alt_type_name() override { return "fltk::Scrollbar"; }
+ Fl_Widget *widget(int x, int y, int w, int h) override {
return new Fl_Scrollbar(x, y, w, h);
}
- Fl_Widget_Type *_make() FL_OVERRIDE { return new Fl_Scrollbar_Type(); }
- ID id() const FL_OVERRIDE { return ID_Scrollbar; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Scrollbar) ? true : super::is_a(inID); }
+ Widget_Node *_make() override { return new Scrollbar_Node(); }
+ Type type() const override { return Type::Scrollbar; }
+ bool is_a(Type inType) const override { return (inType==Type::Scrollbar) ? true : super::is_a(inType); }
};
-static Fl_Scrollbar_Type Fl_Scrollbar_type;
+
+Scrollbar_Node Scrollbar_Node::prototype;
// ---- Value Slider ----
@@ -536,11 +594,14 @@ static Fl_Scrollbar_Type Fl_Scrollbar_type;
/**
\brief Manage Value Sliders and their text settings.
*/
-class Fl_Value_Slider_Type : public Fl_Slider_Type
+class Value_Slider_Node : public Slider_Node
{
- typedef Fl_Slider_Type super;
- int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) FL_OVERRIDE {
- Fl_Value_Slider *myo = (Fl_Value_Slider*)(w==4 ? ((Fl_Widget_Type*)factory)->o : o);
+public:
+ typedef Slider_Node super;
+ static Value_Slider_Node prototype;
+private:
+ int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) override {
+ Fl_Value_Slider *myo = (Fl_Value_Slider*)(w==4 ? ((Widget_Node*)factory)->o : o);
switch (w) {
case 4:
case 0: f = myo->textfont(); s = myo->textsize(); c = myo->textcolor(); break;
@@ -551,17 +612,17 @@ class Fl_Value_Slider_Type : public Fl_Slider_Type
return 1;
}
public:
- const char *type_name() FL_OVERRIDE { return "Fl_Value_Slider"; }
- const char *alt_type_name() FL_OVERRIDE { return "fltk::ValueSlider"; }
- Fl_Widget *widget(int x, int y, int w, int h) FL_OVERRIDE {
+ const char *type_name() override { return "Fl_Value_Slider"; }
+ const char *alt_type_name() override { return "fltk::ValueSlider"; }
+ Fl_Widget *widget(int x, int y, int w, int h) override {
return new Fl_Value_Slider(x, y, w, h, "slider:");
}
- Fl_Widget_Type *_make() FL_OVERRIDE { return new Fl_Value_Slider_Type(); }
- ID id() const FL_OVERRIDE { return ID_Value_Slider; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Value_Slider) ? true : super::is_a(inID); }
+ Widget_Node *_make() override { return new Value_Slider_Node(); }
+ Type type() const override { return Type::Value_Slider; }
+ bool is_a(Type inType) const override { return (inType==Type::Value_Slider) ? true : super::is_a(inType); }
};
-static Fl_Value_Slider_Type Fl_Value_Slider_type;
+Value_Slider_Node Value_Slider_Node::prototype;
// ---- Value Input ----
@@ -569,11 +630,14 @@ static Fl_Value_Slider_Type Fl_Value_Slider_type;
/**
\brief Manage Value Inputs and their text settings.
*/
-class Fl_Value_Input_Type : public Fl_Valuator_Type
+class Value_Input_Node : public Valuator_Node
{
- typedef Fl_Valuator_Type super;
- int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) FL_OVERRIDE {
- Fl_Value_Input *myo = (Fl_Value_Input*)(w==4 ? ((Fl_Widget_Type*)factory)->o : o);
+public:
+ typedef Valuator_Node super;
+ static Value_Input_Node prototype;
+private:
+ int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) override {
+ Fl_Value_Input *myo = (Fl_Value_Input*)(w==4 ? ((Widget_Node*)factory)->o : o);
switch (w) {
case 4:
case 0: f = myo->textfont(); s = myo->textsize(); c = myo->textcolor(); break;
@@ -584,23 +648,24 @@ class Fl_Value_Input_Type : public Fl_Valuator_Type
return 1;
}
public:
- void ideal_size(int &w, int &h) FL_OVERRIDE {
+ void ideal_size(int &w, int &h) override {
+ auto layout = Fluid.proj.layout;
h = layout->textsize_not_null() + 8;
w = layout->textsize_not_null() * 4 + 8;
- Fd_Snap_Action::better_size(w, h);
+ fld::app::Snap_Action::better_size(w, h);
}
- const char *type_name() FL_OVERRIDE { return "Fl_Value_Input"; }
- const char *alt_type_name() FL_OVERRIDE { return "fltk::ValueInput"; }
- Fl_Widget *widget(int x, int y, int w, int h) FL_OVERRIDE {
+ const char *type_name() override { return "Fl_Value_Input"; }
+ const char *alt_type_name() override { return "fltk::ValueInput"; }
+ Fl_Widget *widget(int x, int y, int w, int h) override {
Fl_Value_Input *myo = new Fl_Value_Input(x, y, w, h, "value:");
return myo;
}
- Fl_Widget_Type *_make() FL_OVERRIDE { return new Fl_Value_Input_Type(); }
- ID id() const FL_OVERRIDE { return ID_Value_Input; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Value_Input) ? true : super::is_a(inID); }
+ Widget_Node *_make() override { return new Value_Input_Node(); }
+ Type type() const override { return Type::Value_Input; }
+ bool is_a(Type inType) const override { return (inType==Type::Value_Input) ? true : super::is_a(inType); }
};
-static Fl_Value_Input_Type Fl_Value_Input_type;
+Value_Input_Node Value_Input_Node::prototype;
// ---- Value Output ----
@@ -608,11 +673,14 @@ static Fl_Value_Input_Type Fl_Value_Input_type;
/**
\brief Handle Value Output widgets, no shortcut with Value Input unfortunately.
*/
-class Fl_Value_Output_Type : public Fl_Valuator_Type
+class Value_Output_Node : public Valuator_Node
{
- typedef Fl_Valuator_Type super;
- int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) FL_OVERRIDE {
- Fl_Value_Output *myo = (Fl_Value_Output*)(w==4 ? ((Fl_Widget_Type*)factory)->o : o);
+public:
+ typedef Valuator_Node super;
+ static Value_Output_Node prototype;
+private:
+ int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) override {
+ Fl_Value_Output *myo = (Fl_Value_Output*)(w==4 ? ((Widget_Node*)factory)->o : o);
switch (w) {
case 4:
case 0: f = myo->textfont(); s = myo->textsize(); c = myo->textcolor(); break;
@@ -623,23 +691,24 @@ class Fl_Value_Output_Type : public Fl_Valuator_Type
return 1;
}
public:
- void ideal_size(int &w, int &h) FL_OVERRIDE {
+ void ideal_size(int &w, int &h) override {
+ auto layout = Fluid.proj.layout;
h = layout->textsize_not_null() + 8;
w = layout->textsize_not_null() * 4 + 8;
- Fd_Snap_Action::better_size(w, h);
+ fld::app::Snap_Action::better_size(w, h);
}
- const char *type_name() FL_OVERRIDE { return "Fl_Value_Output"; }
- const char *alt_type_name() FL_OVERRIDE { return "fltk::ValueOutput"; }
- Fl_Widget *widget(int x, int y, int w, int h) FL_OVERRIDE {
+ const char *type_name() override { return "Fl_Value_Output"; }
+ const char *alt_type_name() override { return "fltk::ValueOutput"; }
+ Fl_Widget *widget(int x, int y, int w, int h) override {
Fl_Value_Output *myo = new Fl_Value_Output(x, y, w, h, "value:");
return myo;
}
- Fl_Widget_Type *_make() FL_OVERRIDE { return new Fl_Value_Output_Type(); }
- ID id() const FL_OVERRIDE { return ID_Value_Output; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Value_Output) ? true : super::is_a(inID); }
+ Widget_Node *_make() override { return new Value_Output_Node(); }
+ Type type() const override { return Type::Value_Output; }
+ bool is_a(Type inType) const override { return (inType==Type::Value_Output) ? true : super::is_a(inType); }
};
-static Fl_Value_Output_Type Fl_Value_Output_type;
+Value_Output_Node Value_Output_Node::prototype;
@@ -649,25 +718,28 @@ static Fl_Value_Output_Type Fl_Value_Output_type;
// ---- Input ----
static Fl_Menu_Item input_type_menu[] = {
- { "Normal", 0, 0, (void*)FL_NORMAL_INPUT },
- { "Multiline", 0, 0, (void*)FL_MULTILINE_INPUT },
- { "Secret", 0, 0, (void*)FL_SECRET_INPUT },
- { "Int", 0, 0, (void*)FL_INT_INPUT },
- { "Float", 0, 0, (void*)FL_FLOAT_INPUT },
- {0}
+ { "Normal", 0, nullptr, (void*)nullptr },
+ { "Multiline", 0, nullptr, (void*)FL_MULTILINE_INPUT },
+ { "Secret", 0, nullptr, (void*)FL_SECRET_INPUT },
+ { "Int", 0, nullptr, (void*)FL_INT_INPUT },
+ { "Float", 0, nullptr, (void*)FL_FLOAT_INPUT },
+ {nullptr}
};
/**
\brief Manage simple text input widgets.
The managed class is derived from Fl_Input_, but for simplicity, deriving from
- Fl_Widget_Type seems sufficient here.
+ Widget_Node seems sufficient here.
*/
-class Fl_Input_Type : public Fl_Widget_Type
+class Input_Node : public Widget_Node
{
- typedef Fl_Widget_Type super;
- Fl_Menu_Item *subtypes() FL_OVERRIDE { return input_type_menu; }
- int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) FL_OVERRIDE {
- Fl_Input_ *myo = (Fl_Input_*)(w==4 ? ((Fl_Widget_Type*)factory)->o : o);
+public:
+ typedef Widget_Node super;
+ static Input_Node prototype;
+private:
+ Fl_Menu_Item *subtypes() override { return input_type_menu; }
+ int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) override {
+ Fl_Input_ *myo = (Fl_Input_*)(w==4 ? ((Widget_Node*)factory)->o : o);
switch (w) {
case 4:
case 0: f = myo->textfont(); s = myo->textsize(); c = myo->textcolor(); break;
@@ -678,23 +750,24 @@ class Fl_Input_Type : public Fl_Widget_Type
return 1;
}
public:
- void ideal_size(int &w, int &h) FL_OVERRIDE {
+ void ideal_size(int &w, int &h) override {
+ auto layout = Fluid.proj.layout;
h = layout->textsize_not_null() + 8;
w = layout->textsize_not_null() * 6 + 8;
- Fd_Snap_Action::better_size(w, h);
+ fld::app::Snap_Action::better_size(w, h);
}
- const char *type_name() FL_OVERRIDE { return "Fl_Input"; }
- const char *alt_type_name() FL_OVERRIDE { return "fltk::Input"; }
- Fl_Widget *widget(int x, int y, int w, int h) FL_OVERRIDE {
+ const char *type_name() override { return "Fl_Input"; }
+ const char *alt_type_name() override { return "fltk::Input"; }
+ Fl_Widget *widget(int x, int y, int w, int h) override {
Fl_Input *myo = new Fl_Input(x, y, w, h, "input:");
myo->value("Text Input");
return myo;
}
- Fl_Widget_Type *_make() FL_OVERRIDE { return new Fl_Input_Type(); }
- ID id() const FL_OVERRIDE { return ID_Input; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Input) ? true : super::is_a(inID); }
- void copy_properties() FL_OVERRIDE {
- Fl_Widget_Type::copy_properties();
+ Widget_Node *_make() override { return new Input_Node(); }
+ Type type() const override { return Type::Input; }
+ bool is_a(Type inType) const override { return (inType==Type::Input) ? true : super::is_a(inType); }
+ void copy_properties() override {
+ Widget_Node::copy_properties();
Fl_Input_ *d = (Fl_Input_*)live_widget, *s = (Fl_Input_*)o;
d->textfont(s->textfont());
d->textsize(s->textsize());
@@ -702,7 +775,8 @@ public:
d->shortcut(s->shortcut());
}
};
-static Fl_Input_Type Fl_Input_type;
+
+Input_Node Input_Node::prototype;
// ---- File Input ----
@@ -710,60 +784,67 @@ static Fl_Input_Type Fl_Input_type;
/**
\brief Manage file name input widgets.
*/
-class Fl_File_Input_Type : public Fl_Input_Type
+class File_Input_Node : public Input_Node
{
- typedef Fl_Input_Type super;
- Fl_Menu_Item *subtypes() FL_OVERRIDE { return NULL; } // Don't inherit.
public:
- void ideal_size(int &w, int &h) FL_OVERRIDE {
+ typedef Input_Node super;
+ static File_Input_Node prototype;
+private:
+ Fl_Menu_Item *subtypes() override { return nullptr; } // Don't inherit.
+public:
+ void ideal_size(int &w, int &h) override {
+ auto layout = Fluid.proj.layout;
h = layout->textsize_not_null() + 8 + 10; // Directoy bar is additional 10 pixels high
w = layout->textsize_not_null() * 10 + 8;
- Fd_Snap_Action::better_size(w, h);
+ fld::app::Snap_Action::better_size(w, h);
}
- const char *type_name() FL_OVERRIDE { return "Fl_File_Input"; }
- const char *alt_type_name() FL_OVERRIDE { return "fltk::FileInput"; }
- Fl_Widget *widget(int x, int y, int w, int h) FL_OVERRIDE {
+ const char *type_name() override { return "Fl_File_Input"; }
+ const char *alt_type_name() override { return "fltk::FileInput"; }
+ Fl_Widget *widget(int x, int y, int w, int h) override {
Fl_File_Input *myo = new Fl_File_Input(x, y, w, h, "file:");
myo->value("/usr/include/FL/Fl.H");
return myo;
}
- Fl_Widget_Type *_make() FL_OVERRIDE { return new Fl_File_Input_Type(); }
- ID id() const FL_OVERRIDE { return ID_File_Input; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_File_Input) ? true : super::is_a(inID); }
+ Widget_Node *_make() override { return new File_Input_Node(); }
+ Type type() const override { return Type::File_Input; }
+ bool is_a(Type inType) const override { return (inType==Type::File_Input) ? true : super::is_a(inType); }
};
-static Fl_File_Input_Type Fl_File_Input_type;
+File_Input_Node File_Input_Node::prototype;
// ---- Output ----
static Fl_Menu_Item output_type_menu[] = {
- { "Normal", 0, 0, (void*)FL_NORMAL_OUTPUT },
- { "Multiline", 0, 0, (void*)FL_MULTILINE_OUTPUT },
- { 0 }
+ { "Normal", 0, nullptr, (void*)FL_NORMAL_OUTPUT },
+ { "Multiline", 0, nullptr, (void*)FL_MULTILINE_OUTPUT },
+ { nullptr }
};
/**
\brief Manage Output widgets, derived from Input.
*/
-class Fl_Output_Type : public Fl_Input_Type
+class Output_Node : public Input_Node
{
- typedef Fl_Input_Type super;
- Fl_Menu_Item *subtypes() FL_OVERRIDE { return output_type_menu; }
public:
- const char *type_name() FL_OVERRIDE { return "Fl_Output"; }
- const char *alt_type_name() FL_OVERRIDE { return "fltk::Output"; }
- Fl_Widget *widget(int x, int y, int w, int h) FL_OVERRIDE {
+ typedef Input_Node super;
+ static Output_Node prototype;
+private:
+ Fl_Menu_Item *subtypes() override { return output_type_menu; }
+public:
+ const char *type_name() override { return "Fl_Output"; }
+ const char *alt_type_name() override { return "fltk::Output"; }
+ Fl_Widget *widget(int x, int y, int w, int h) override {
Fl_Output *myo = new Fl_Output(x, y, w, h, "output:");
myo->value("Text Output");
return myo;
}
- Fl_Widget_Type *_make() FL_OVERRIDE { return new Fl_Output_Type(); }
- ID id() const FL_OVERRIDE { return ID_Output; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Output) ? true : super::is_a(inID); }
+ Widget_Node *_make() override { return new Output_Node(); }
+ Type type() const override { return Type::Output; }
+ bool is_a(Type inType) const override { return (inType==Type::Output) ? true : super::is_a(inType); }
};
-static Fl_Output_Type Fl_Output_type;
+Output_Node Output_Node::prototype;
@@ -777,11 +858,14 @@ static Fl_Output_Type Fl_Output_type;
Fl_Text_Display is actually derived from Fl_Group, but for FLUID, deriving
the type from Widget is better.
*/
-class Fl_Text_Display_Type : public Fl_Widget_Type
+class Text_Display_Node : public Widget_Node
{
- typedef Fl_Widget_Type super;
- int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) FL_OVERRIDE {
- Fl_Text_Display *myo = (Fl_Text_Display*)(w==4 ? ((Fl_Widget_Type*)factory)->o : o);
+public:
+ typedef Widget_Node super;
+ static Text_Display_Node prototype;
+private:
+ int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) override {
+ Fl_Text_Display *myo = (Fl_Text_Display*)(w==4 ? ((Widget_Node*)factory)->o : o);
switch (w) {
case 4:
case 0: f = myo->textfont(); s = myo->textsize(); c = myo->textcolor(); break;
@@ -792,27 +876,29 @@ class Fl_Text_Display_Type : public Fl_Widget_Type
return 1;
}
public:
- void ideal_size(int &w, int &h) FL_OVERRIDE {
+ void ideal_size(int &w, int &h) override {
+ auto layout = Fluid.proj.layout;
h = layout->textsize_not_null() * 4 + 8;
w = layout->textsize_not_null() * 10 + 8;
- Fd_Snap_Action::better_size(w, h);
+ fld::app::Snap_Action::better_size(w, h);
}
- const char *type_name() FL_OVERRIDE { return "Fl_Text_Display"; }
- const char *alt_type_name() FL_OVERRIDE { return "fltk::TextDisplay"; }
- Fl_Widget *widget(int x, int y, int w, int h) FL_OVERRIDE {
+ const char *type_name() override { return "Fl_Text_Display"; }
+ const char *alt_type_name() override { return "fltk::TextDisplay"; }
+ Fl_Widget *widget(int x, int y, int w, int h) override {
Fl_Text_Display *myo = new Fl_Text_Display(x, y, w, h);
- if (!batch_mode) {
+ if (!Fluid.batch_mode) {
Fl_Text_Buffer *b = new Fl_Text_Buffer();
b->text("Lorem ipsum dolor\nsit amet, consetetur\nsadipscing elitr");
myo->buffer(b);
}
return myo;
}
- Fl_Widget_Type *_make() FL_OVERRIDE { return new Fl_Text_Display_Type(); }
- ID id() const FL_OVERRIDE { return ID_Text_Display; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Text_Display) ? true : super::is_a(inID); }
+ Widget_Node *_make() override { return new Text_Display_Node(); }
+ Type type() const override { return Type::Text_Display; }
+ bool is_a(Type inType) const override { return (inType==Type::Text_Display) ? true : super::is_a(inType); }
};
-static Fl_Text_Display_Type Fl_Text_Display_type;
+
+Text_Display_Node Text_Display_Node::prototype;
// ---- Text Editor ----
@@ -820,27 +906,29 @@ static Fl_Text_Display_Type Fl_Text_Display_type;
/**
\brief Manage Text Editors based on Text Display.
*/
-class Fl_Text_Editor_Type : public Fl_Text_Display_Type
+class Text_Editor_Node : public Text_Display_Node
{
- typedef Fl_Text_Display_Type super;
public:
- const char *type_name() FL_OVERRIDE {return "Fl_Text_Editor";}
- const char *alt_type_name() FL_OVERRIDE {return "fltk::TextEditor";}
- Fl_Widget *widget(int x, int y, int w, int h) FL_OVERRIDE {
+ typedef Text_Display_Node super;
+ static Text_Editor_Node prototype;
+public:
+ const char *type_name() override {return "Fl_Text_Editor";}
+ const char *alt_type_name() override {return "fltk::TextEditor";}
+ Fl_Widget *widget(int x, int y, int w, int h) override {
Fl_Text_Editor *myo = new Fl_Text_Editor(x, y, w, h);
- if (!batch_mode) {
+ if (!Fluid.batch_mode) {
Fl_Text_Buffer *b = new Fl_Text_Buffer();
b->text("Lorem ipsum dolor\nsit amet, consetetur\nsadipscing elitr");
myo->buffer(b);
}
return myo;
}
- Fl_Widget_Type *_make() FL_OVERRIDE { return new Fl_Text_Editor_Type(); }
- ID id() const FL_OVERRIDE { return ID_Text_Editor; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Text_Editor) ? true : super::is_a(inID); }
+ Widget_Node *_make() override { return new Text_Editor_Node(); }
+ Type type() const override { return Type::Text_Editor; }
+ bool is_a(Type inType) const override { return (inType==Type::Text_Editor) ? true : super::is_a(inType); }
};
-static Fl_Text_Editor_Type Fl_Text_Editor_type;
+Text_Editor_Node Text_Editor_Node::prototype;
// ---- Terminal ----
@@ -848,13 +936,13 @@ static Fl_Text_Editor_Type Fl_Text_Editor_type;
/** Use this terminal instead of Fl_Terminal to capture resize actions. */
class Fl_Terminal_Proxy : public Fl_Terminal {
public:
- Fl_Terminal_Proxy(int x, int y, int w, int h, const char *l=NULL)
+ Fl_Terminal_Proxy(int x, int y, int w, int h, const char *l=nullptr)
: Fl_Terminal(x, y, w, h, l) { }
void print_sample_text() {
clear_screen_home(false);
append("> ls -als");
}
- void resize(int x, int y, int w, int h) FL_OVERRIDE {
+ void resize(int x, int y, int w, int h) override {
Fl_Terminal::resize(x, y, w, h);
// After a resize, the top text vanishes, so make sure we redraw it.
print_sample_text();
@@ -867,7 +955,7 @@ public:
Fl_Font tfont_;
int tsize_;
Fl_Color tcolor_;
- Fl_Batchmode_Terminal(int x, int y, int w, int h, const char *l=NULL)
+ Fl_Batchmode_Terminal(int x, int y, int w, int h, const char *l=nullptr)
: Fl_Group(x, y, w, h, l)
{ // set the defaults that Fl_Terminal would set
box(FL_DOWN_BOX);
@@ -889,16 +977,18 @@ public:
/**
\brief Manage a terminal widget.
*/
-class Fl_Terminal_Type : public Fl_Widget_Type
+class Terminal_Node : public Widget_Node
{
- typedef Fl_Widget_Type super;
public:
- const char *type_name() FL_OVERRIDE { return "Fl_Terminal"; }
+ typedef Widget_Node super;
+ static Terminal_Node prototype;
+public:
+ const char *type_name() override { return "Fl_Terminal"; }
// Older .fl files with Fl_Simple_Terminal will create a Fl_Terminal instead.
- const char *alt_type_name() FL_OVERRIDE { return "Fl_Simple_Terminal"; }
- Fl_Widget *widget(int x, int y, int w, int h) FL_OVERRIDE {
- Fl_Widget *ret = NULL;
- if (batch_mode) {
+ const char *alt_type_name() override { return "Fl_Simple_Terminal"; }
+ Fl_Widget *widget(int x, int y, int w, int h) override {
+ Fl_Widget *ret = nullptr;
+ if (Fluid.batch_mode) {
ret = new Fl_Batchmode_Terminal(x, y, w, h);
} else {
Fl_Terminal_Proxy *term = new Fl_Terminal_Proxy(x, y, w+100, h);
@@ -906,9 +996,9 @@ public:
}
return ret;
}
- int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) FL_OVERRIDE {
- if (batch_mode) {
- Fl_Batchmode_Terminal *myo = (Fl_Batchmode_Terminal*)(w==4 ? ((Fl_Widget_Type*)factory)->o : o);
+ int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) override {
+ if (Fluid.batch_mode) {
+ Fl_Batchmode_Terminal *myo = (Fl_Batchmode_Terminal*)(w==4 ? ((Widget_Node*)factory)->o : o);
switch (w) {
case 4:
case 0: f = (Fl_Font)myo->tfont_; s = myo->tsize_; c = myo->tcolor_; break;
@@ -917,7 +1007,7 @@ public:
case 3: myo->tcolor_ = c; break;
}
} else {
- Fl_Terminal_Proxy *myo = (Fl_Terminal_Proxy*)(w==4 ? ((Fl_Widget_Type*)factory)->o : o);
+ Fl_Terminal_Proxy *myo = (Fl_Terminal_Proxy*)(w==4 ? ((Widget_Node*)factory)->o : o);
switch (w) {
case 4:
case 0: f = (Fl_Font)myo->textfont(); s = myo->textsize(); c = myo->textcolor(); break;
@@ -928,12 +1018,12 @@ public:
}
return 1;
}
- Fl_Widget_Type *_make() FL_OVERRIDE {return new Fl_Terminal_Type();}
- ID id() const FL_OVERRIDE { return ID_Terminal; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Terminal) ? true : super::is_a(inID); }
+ Widget_Node *_make() override {return new Terminal_Node();}
+ Type type() const override { return Type::Terminal; }
+ bool is_a(Type inType) const override { return (inType==Type::Terminal) ? true : super::is_a(inType); }
};
-static Fl_Terminal_Type Fl_Terminal_type;
+Terminal_Node Terminal_Node::prototype;
// ---- Other ---------------------------------------------------------- MARK: -
@@ -945,25 +1035,27 @@ static Fl_Terminal_Type Fl_Terminal_type;
\brief Manage box widgets.
Ideal size is set to 100x100, snapped to layout.
*/
-class Fl_Box_Type : public Fl_Widget_Type
+class Box_Node : public Widget_Node
{
- typedef Fl_Widget_Type super;
public:
- void ideal_size(int &w, int &h) FL_OVERRIDE {
+ typedef Widget_Node super;
+ static Box_Node prototype;
+public:
+ void ideal_size(int &w, int &h) override {
w = 100; h = 100;
- Fd_Snap_Action::better_size(w, h);
+ fld::app::Snap_Action::better_size(w, h);
}
- const char *type_name() FL_OVERRIDE { return "Fl_Box"; }
- const char *alt_type_name() FL_OVERRIDE { return "fltk::Widget"; }
- Fl_Widget *widget(int x, int y, int w, int h) FL_OVERRIDE {
+ const char *type_name() override { return "Fl_Box"; }
+ const char *alt_type_name() override { return "fltk::Widget"; }
+ Fl_Widget *widget(int x, int y, int w, int h) override {
return new Fl_Box(x, y, w, h, "label");
}
- Fl_Widget_Type *_make() FL_OVERRIDE { return new Fl_Box_Type(); }
- ID id() const FL_OVERRIDE { return ID_Box; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Box) ? true : super::is_a(inID); }
+ Widget_Node *_make() override { return new Box_Node(); }
+ Type type() const override { return Type::Box; }
+ bool is_a(Type inType) const override { return (inType==Type::Box) ? true : super::is_a(inType); }
};
-static Fl_Box_Type Fl_Box_type;
+Box_Node Box_Node::prototype;
// ---- Clock ----
@@ -972,25 +1064,27 @@ static Fl_Box_Type Fl_Box_type;
\brief Manage Clock widgets.
Ideal size is set to 80x80 snapped to layout.
*/
-class Fl_Clock_Type : public Fl_Widget_Type
+class Clock_Node : public Widget_Node
{
- typedef Fl_Widget_Type super;
public:
- void ideal_size(int &w, int &h) FL_OVERRIDE {
+ typedef Widget_Node super;
+ static Clock_Node prototype;
+public:
+ void ideal_size(int &w, int &h) override {
w = 80; h = 80;
- Fd_Snap_Action::better_size(w, h);
+ fld::app::Snap_Action::better_size(w, h);
}
- const char *type_name() FL_OVERRIDE { return "Fl_Clock"; }
- const char *alt_type_name() FL_OVERRIDE { return "fltk::Clock"; }
- Fl_Widget *widget(int x, int y, int w, int h) FL_OVERRIDE {
+ const char *type_name() override { return "Fl_Clock"; }
+ const char *alt_type_name() override { return "fltk::Clock"; }
+ Fl_Widget *widget(int x, int y, int w, int h) override {
return new Fl_Clock(x, y, w, h);
}
- Fl_Widget_Type *_make() FL_OVERRIDE { return new Fl_Clock_Type(); }
- ID id() const FL_OVERRIDE { return ID_Clock; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Clock) ? true : super::is_a(inID); }
+ Widget_Node *_make() override { return new Clock_Node(); }
+ Type type() const override { return Type::Clock; }
+ bool is_a(Type inType) const override { return (inType==Type::Clock) ? true : super::is_a(inType); }
};
-static Fl_Clock_Type Fl_Clock_type;
+Clock_Node Clock_Node::prototype;
// ---- Progress ----
@@ -1000,35 +1094,38 @@ static Fl_Clock_Type Fl_Clock_type;
Ideal size is set to match the label font and label text width times 3.
\note minimum, maximum, and value must be set via extra code fields.
*/
-class Fl_Progress_Type : public Fl_Widget_Type
+class Progress_Node : public Widget_Node
{
- typedef Fl_Widget_Type super;
public:
- void ideal_size(int &w, int &h) FL_OVERRIDE {
+ typedef Widget_Node super;
+ static Progress_Node prototype;
+public:
+ void ideal_size(int &w, int &h) override {
+ auto layout = Fluid.proj.layout;
h = layout->labelsize + 8;
w = layout->labelsize * 12;
- Fd_Snap_Action::better_size(w, h);
+ fld::app::Snap_Action::better_size(w, h);
}
- const char *type_name() FL_OVERRIDE { return "Fl_Progress"; }
- const char *alt_type_name() FL_OVERRIDE { return "fltk::ProgressBar"; }
- Fl_Widget *widget(int x, int y, int w, int h) FL_OVERRIDE {
+ const char *type_name() override { return "Fl_Progress"; }
+ const char *alt_type_name() override { return "fltk::ProgressBar"; }
+ Fl_Widget *widget(int x, int y, int w, int h) override {
Fl_Progress *myo = new Fl_Progress(x, y, w, h, "label");
myo->value(50);
return myo;
}
- Fl_Widget_Type *_make() FL_OVERRIDE { return new Fl_Progress_Type(); }
- ID id() const FL_OVERRIDE { return ID_Progress; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Progress) ? true : super::is_a(inID); }
+ Widget_Node *_make() override { return new Progress_Node(); }
+ Type type() const override { return Type::Progress; }
+ bool is_a(Type inType) const override { return (inType==Type::Progress) ? true : super::is_a(inType); }
};
-static Fl_Progress_Type Fl_Progress_type;
+Progress_Node Progress_Node::prototype;
// ---- Spinner ----
static Fl_Menu_Item spinner_type_menu[] = {
- { "Integer", 0, 0, (void*)FL_INT_INPUT },
- { "Float", 0, 0, (void*)FL_FLOAT_INPUT },
- { 0 }
+ { "Integer", 0, nullptr, (void*)FL_INT_INPUT },
+ { "Float", 0, nullptr, (void*)FL_FLOAT_INPUT },
+ { nullptr }
};
/**
@@ -1036,12 +1133,15 @@ static Fl_Menu_Item spinner_type_menu[] = {
\note Fl_Spinner is derived from Fl_Group, *not* Fl_Valuator as one may expect.
For FLUID, this means some special handling and no Group support.
*/
-class Fl_Spinner_Type : public Fl_Widget_Type
+class Spinner_Node : public Widget_Node
{
- typedef Fl_Widget_Type super;
- Fl_Menu_Item *subtypes() FL_OVERRIDE { return spinner_type_menu; }
- int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) FL_OVERRIDE {
- Fl_Spinner *myo = (Fl_Spinner*)(w==4 ? ((Fl_Widget_Type*)factory)->o : o);
+public:
+ typedef Widget_Node super;
+ static Spinner_Node prototype;
+private:
+ Fl_Menu_Item *subtypes() override { return spinner_type_menu; }
+ int textstuff(int w, Fl_Font& f, int& s, Fl_Color& c) override {
+ Fl_Spinner *myo = (Fl_Spinner*)(w==4 ? ((Widget_Node*)factory)->o : o);
switch (w) {
case 4:
case 0: f = (Fl_Font)myo->textfont(); s = myo->textsize(); c = myo->textcolor(); break;
@@ -1052,64 +1152,30 @@ class Fl_Spinner_Type : public Fl_Widget_Type
return 1;
}
public:
- void ideal_size(int &w, int &h) FL_OVERRIDE {
+ void ideal_size(int &w, int &h) override {
+ auto layout = Fluid.proj.layout;
h = layout->textsize_not_null() + 8;
w = layout->textsize_not_null() * 4 + 8;
- Fd_Snap_Action::better_size(w, h);
+ fld::app::Snap_Action::better_size(w, h);
}
- const char *type_name() FL_OVERRIDE { return "Fl_Spinner"; }
- const char *alt_type_name() FL_OVERRIDE { return "fltk::Spinner"; }
- Fl_Widget *widget(int x, int y, int w, int h) FL_OVERRIDE {
+ const char *type_name() override { return "Fl_Spinner"; }
+ const char *alt_type_name() override { return "fltk::Spinner"; }
+ Fl_Widget *widget(int x, int y, int w, int h) override {
return new Fl_Spinner(x, y, w, h, "spinner:");
}
- Fl_Widget_Type *_make() FL_OVERRIDE { return new Fl_Spinner_Type(); }
- ID id() const FL_OVERRIDE { return ID_Spinner; }
- bool is_a(ID inID) const FL_OVERRIDE { return (inID==ID_Spinner) ? true : super::is_a(inID); }
+ Widget_Node *_make() override { return new Spinner_Node(); }
+ Type type() const override { return Type::Spinner; }
+ bool is_a(Type inType) const override { return (inType==Type::Spinner) ? true : super::is_a(inType); }
};
-static Fl_Spinner_Type Fl_Spinner_type;
+Spinner_Node Spinner_Node::prototype;
// ---- Type Factory --------------------------------------------------- MARK: -
-extern class Fl_Function_Type Fl_Function_type;
-extern class Fl_Code_Type Fl_Code_type;
-extern class Fl_CodeBlock_Type Fl_CodeBlock_type;
-extern class Fl_Data_Type Fl_Data_type;
-extern class Fl_Decl_Type Fl_Decl_type;
-extern class Fl_DeclBlock_Type Fl_DeclBlock_type;
-extern class Fl_Comment_Type Fl_Comment_type;
-extern class Fl_Class_Type Fl_Class_type;
-extern class Fl_Window_Type Fl_Window_type;
-extern class Fl_Widget_Class_Type Fl_Widget_Class_type;
-extern class Fl_Group_Type Fl_Group_type;
-extern class Fl_Pack_Type Fl_Pack_type;
-extern class Fl_Flex_Type Fl_Flex_type;
-extern class Fl_Grid_Type Fl_Grid_type;
-extern class Fl_Tabs_Type Fl_Tabs_type;
-extern class Fl_Scroll_Type Fl_Scroll_type;
-extern class Fl_Table_Type Fl_Table_type;
-extern class Fl_Tile_Type Fl_Tile_type;
-extern class Fl_Input_Choice_Type Fl_Input_Choice_type;
-extern class Fl_Choice_Type Fl_Choice_type;
-extern class Fl_Menu_Bar_Type Fl_Menu_Bar_type;
-extern class Fl_Menu_Button_Type Fl_Menu_Button_type;
-extern class Fl_Menu_Item_Type Fl_Menu_Item_type;
-extern class Fl_Checkbox_Menu_Item_Type Fl_Checkbox_Menu_Item_type;
-extern class Fl_Radio_Menu_Item_Type Fl_Radio_Menu_Item_type;
-extern class Fl_Submenu_Type Fl_Submenu_type;
-extern class Fl_Wizard_Type Fl_Wizard_type;
-
-extern class Fl_Button_Type Fl_Button_type;
-extern class Fl_Return_Button_Type Fl_Return_Button_type;
-extern class Fl_Light_Button_Type Fl_Light_Button_type;
-extern class Fl_Check_Button_Type Fl_Check_Button_type;
-extern class Fl_Repeat_Button_Type Fl_Repeat_Button_type;
-extern class Fl_Round_Button_Type Fl_Round_Button_type;
-
-extern void select(Fl_Type *,int);
-extern void select_only(Fl_Type *);
+extern void select(Node *,int);
+extern void select_only(Node *);
/**
List all known types.
@@ -1120,72 +1186,72 @@ extern void select_only(Fl_Type *);
\note Make sure that this array stays synchronized to `Fl_Menu_Item New_Menu[]`
further down in this file.
*/
-static Fl_Type *known_types[] = {
+static Node *known_types[] = {
// functions
- (Fl_Type*)&Fl_Function_type,
- (Fl_Type*)&Fl_Code_type,
- (Fl_Type*)&Fl_CodeBlock_type,
- (Fl_Type*)&Fl_Decl_type,
- (Fl_Type*)&Fl_DeclBlock_type,
- (Fl_Type*)&Fl_Class_type,
- (Fl_Type*)&Fl_Widget_Class_type,
- (Fl_Type*)&Fl_Comment_type,
- (Fl_Type*)&Fl_Data_type,
+ (Node*)&Function_Node::prototype,
+ (Node*)&Code_Node::prototype,
+ (Node*)&CodeBlock_Node::prototype,
+ (Node*)&Decl_Node::prototype,
+ (Node*)&DeclBlock_Node::prototype,
+ (Node*)&Class_Node::prototype,
+ (Node*)&Widget_Class_Node::prototype,
+ (Node*)&Comment_Node::prototype,
+ (Node*)&Data_Node::prototype,
// groups
- (Fl_Type*)&Fl_Window_type,
- (Fl_Type*)&Fl_Group_type,
- (Fl_Type*)&Fl_Pack_type,
- (Fl_Type*)&Fl_Flex_type,
- (Fl_Type*)&Fl_Tabs_type,
- (Fl_Type*)&Fl_Scroll_type,
- (Fl_Type*)&Fl_Tile_type,
- (Fl_Type*)&Fl_Wizard_type,
- (Fl_Type*)&Fl_Grid_type,
+ (Node*)&Window_Node::prototype,
+ (Node*)&Group_Node::prototype,
+ (Node*)&Pack_Node::prototype,
+ (Node*)&Flex_Node::prototype,
+ (Node*)&Tabs_Node::prototype,
+ (Node*)&Scroll_Node::prototype,
+ (Node*)&Tile_Node::prototype,
+ (Node*)&Wizard_Node::prototype,
+ (Node*)&Grid_Node::prototype,
// buttons
- (Fl_Type*)&Fl_Button_type,
- (Fl_Type*)&Fl_Return_Button_type,
- (Fl_Type*)&Fl_Light_Button_type,
- (Fl_Type*)&Fl_Check_Button_type,
- (Fl_Type*)&Fl_Repeat_Button_type,
- (Fl_Type*)&Fl_Round_Button_type,
+ (Node*)&Button_Node::prototype,
+ (Node*)&Return_Button_Node::prototype,
+ (Node*)&Light_Button_Node::prototype,
+ (Node*)&Check_Button_Node::prototype,
+ (Node*)&Repeat_Button_Node::prototype,
+ (Node*)&Round_Button_Node::prototype,
// valuators
- (Fl_Type*)&Fl_Slider_type,
- (Fl_Type*)&Fl_Scrollbar_type,
- (Fl_Type*)&Fl_Value_Slider_type,
- (Fl_Type*)&Fl_Adjuster_type,
- (Fl_Type*)&Fl_Counter_type,
- (Fl_Type*)&Fl_Spinner_type,
- (Fl_Type*)&Fl_Dial_type,
- (Fl_Type*)&Fl_Roller_type,
- (Fl_Type*)&Fl_Value_Input_type,
- (Fl_Type*)&Fl_Value_Output_type,
+ (Node*)&Slider_Node::prototype,
+ (Node*)&Scrollbar_Node::prototype,
+ (Node*)&Value_Slider_Node::prototype,
+ (Node*)&Adjuster_Node::prototype,
+ (Node*)&Counter_Node::prototype,
+ (Node*)&Spinner_Node::prototype,
+ (Node*)&Dial_Node::prototype,
+ (Node*)&Roller_Node::prototype,
+ (Node*)&Value_Input_Node::prototype,
+ (Node*)&Value_Output_Node::prototype,
// text
- (Fl_Type*)&Fl_Input_type,
- (Fl_Type*)&Fl_Output_type,
- (Fl_Type*)&Fl_Text_Editor_type,
- (Fl_Type*)&Fl_Text_Display_type,
- (Fl_Type*)&Fl_File_Input_type,
- (Fl_Type*)&Fl_Terminal_type,
+ (Node*)&Input_Node::prototype,
+ (Node*)&Output_Node::prototype,
+ (Node*)&Text_Editor_Node::prototype,
+ (Node*)&Text_Display_Node::prototype,
+ (Node*)&File_Input_Node::prototype,
+ (Node*)&Terminal_Node::prototype,
// menus
- (Fl_Type*)&Fl_Menu_Bar_type,
- (Fl_Type*)&Fl_Menu_Button_type,
- (Fl_Type*)&Fl_Choice_type,
- (Fl_Type*)&Fl_Input_Choice_type,
- (Fl_Type*)&Fl_Submenu_type,
- (Fl_Type*)&Fl_Menu_Item_type,
- (Fl_Type*)&Fl_Checkbox_Menu_Item_type,
- (Fl_Type*)&Fl_Radio_Menu_Item_type,
+ (Node*)&Menu_Bar_Node::prototype,
+ (Node*)&Menu_Button_Node::prototype,
+ (Node*)&Choice_Node::prototype,
+ (Node*)&Input_Choice_Node::prototype,
+ (Node*)&Submenu_Node::prototype,
+ (Node*)&Menu_Item_Node::prototype,
+ (Node*)&Checkbox_Menu_Item_Node::prototype,
+ (Node*)&Radio_Menu_Item_Node::prototype,
// browsers
- (Fl_Type*)&Fl_Browser_type,
- (Fl_Type*)&Fl_Check_Browser_type,
- (Fl_Type*)&Fl_File_Browser_type,
- (Fl_Type*)&Fl_Tree_type,
- (Fl_Type*)&Fl_Help_View_type,
- (Fl_Type*)&Fl_Table_type,
+ (Node*)&Browser_Node::prototype,
+ (Node*)&Check_Browser_Node::prototype,
+ (Node*)&File_Browser_Node::prototype,
+ (Node*)&Tree_Node::prototype,
+ (Node*)&Help_View_Node::prototype,
+ (Node*)&Table_Node::prototype,
// misc
- (Fl_Type*)&Fl_Box_type,
- (Fl_Type*)&Fl_Clock_type,
- (Fl_Type*)&Fl_Progress_type,
+ (Node*)&Box_Node::prototype,
+ (Node*)&Clock_Node::prototype,
+ (Node*)&Progress_Node::prototype,
};
/**
@@ -1207,19 +1273,21 @@ static Fl_Type *known_types[] = {
lower case 't' in type.
\param[in] strategy add after current or as last child
\param[in] and_open if set to true, call open() on the widget after creating it
- \return the newly created type or NULL
+ \return the newly created type or nullptr
\see add_new_widget_from_file(const char*, int)
- add_new_widget_from_user(Fl_Type*, int)
+ add_new_widget_from_user(Node*, int)
add_new_widget_from_user(const char*, int)
*/
-Fl_Type *add_new_widget_from_user(Fl_Type *inPrototype, Strategy strategy, bool and_open) {
- undo_checkpoint();
- undo_suspend();
- Fl_Type *t = ((Fl_Type*)inPrototype)->make(strategy);
+Node *add_new_widget_from_user(Node *inPrototype, Strategy strategy, bool and_open) {
+ Fluid.proj.undo.checkpoint();
+ Fluid.proj.undo.suspend();
+ auto layout = Fluid.proj.layout;
+ Node *t = ((Node*)inPrototype)->make(strategy);
if (t) {
- if (t->is_widget() && !t->is_a(ID_Window)) {
- Fl_Widget_Type *wt = (Fl_Widget_Type *)t;
+ if (t->is_widget() && !t->is_a(Type::Window)) {
+ auto layout = Fluid.proj.layout;
+ Widget_Node *wt = (Widget_Node *)t;
bool changed = false;
// Set font sizes...
@@ -1244,71 +1312,71 @@ Fl_Type *add_new_widget_from_user(Fl_Type *inPrototype, Strategy strategy, bool
wt->textstuff(2, f, s, c);
}
- if (changed && t->is_a(ID_Menu_Item)) {
- Fl_Type * tt = t->parent;
- while (tt && !tt->is_a(ID_Menu_Manager_)) tt = tt->parent;
+ if (changed && t->is_a(Type::Menu_Item)) {
+ Node * tt = t->parent;
+ while (tt && !tt->is_a(Type::Menu_Manager_)) tt = tt->parent;
if (tt)
- ((Fl_Menu_Manager_Type*)tt)->build_menu();
+ ((Menu_Manager_Node*)tt)->build_menu();
}
}
- if (t->is_true_widget() && !t->is_a(ID_Window)) {
+ if (t->is_true_widget() && !t->is_a(Type::Window)) {
// Resize and/or reposition new widget...
- Fl_Widget_Type *wt = (Fl_Widget_Type *)t;
+ Widget_Node *wt = (Widget_Node *)t;
// The parent field is already set at this point, so we can use that
// inside ideal_size().
int w = 0, h = 0;
wt->ideal_size(w, h);
- if ((t->parent && t->parent->is_a(ID_Flex))) {
- if (Fl_Window_Type::popupx != 0x7FFFFFFF)
- ((Fl_Flex_Type*)t->parent)->insert_child_at(((Fl_Widget_Type*)t)->o, Fl_Window_Type::popupx, Fl_Window_Type::popupy);
+ if ((t->parent && t->parent->is_a(Type::Flex))) {
+ if (Window_Node::popupx != 0x7FFFFFFF)
+ ((Flex_Node*)t->parent)->insert_child_at(((Widget_Node*)t)->o, Window_Node::popupx, Window_Node::popupy);
t->parent->layout_widget();
- } else if ( wt->is_a(ID_Group)
+ } else if ( wt->is_a(Type::Group)
&& wt->parent
- && wt->parent->is_a(ID_Tabs)
- //&& (Fl_Window_Type::popupx == 0x7FFFFFFF)
+ && wt->parent->is_a(Type::Tabs)
+ //&& (Window_Node::popupx == 0x7FFFFFFF)
&& (layout->top_tabs_margin > 0)) {
// If the widget is a group and the parent is tabs and the top tabs
// margin is set (and the user is not requesting a specific position)
// then prefit the group correctly to the Tabs container.
- Fl_Widget *po = ((Fl_Tabs_Type*)wt->parent)->o;
+ Fl_Widget *po = ((Tabs_Node*)wt->parent)->o;
wt->o->resize(po->x(), po->y() + layout->top_tabs_margin,
po->w(), po->h() - layout->top_tabs_margin);
- } else if ( wt->is_a(ID_Menu_Bar)
+ } else if ( wt->is_a(Type::Menu_Bar)
&& wt->parent
- && wt->parent->is_a(ID_Window)
+ && wt->parent->is_a(Type::Window)
&& (wt->prev == wt->parent)) {
// If this is the first child of a window, make the menu bar as wide as
// the window and drop it at 0, 0. Otherwise just use the suggested size.
w = wt->o->window()->w();
wt->o->resize(0, 0, w, h);
} else {
- if (Fl_Window_Type::popupx != 0x7FFFFFFF) {
+ if (Window_Node::popupx != 0x7FFFFFFF) {
// If this callback was called from the RMB popup menu in a window,
// popupx and popupy will contain the mouse coordinates at RMB event.
- wt->o->resize(Fl_Window_Type::popupx, Fl_Window_Type::popupy, w, h);
+ wt->o->resize(Window_Node::popupx, Window_Node::popupy, w, h);
} else {
// If popupx is invalid, use the default position and find a good
// size for the widget.
wt->o->size(w, h);
}
}
- if (t->parent && t->parent->is_a(ID_Grid)) {
- if (Fl_Window_Type::popupx != 0x7FFFFFFF) {
- ((Fl_Grid_Type*)t->parent)->insert_child_at(((Fl_Widget_Type*)t)->o, Fl_Window_Type::popupx, Fl_Window_Type::popupy);
+ if (t->parent && t->parent->is_a(Type::Grid)) {
+ if (Window_Node::popupx != 0x7FFFFFFF) {
+ ((Grid_Node*)t->parent)->insert_child_at(((Widget_Node*)t)->o, Window_Node::popupx, Window_Node::popupy);
} else {
- ((Fl_Grid_Type*)t->parent)->insert_child_at_next_free_cell(((Fl_Widget_Type*)t)->o);
+ ((Grid_Node*)t->parent)->insert_child_at_next_free_cell(((Widget_Node*)t)->o);
}
}
}
- if (t->is_a(ID_Window)) {
+ if (t->is_a(Type::Window)) {
int x = 0, y = 0, w = 480, h = 320;
- Fl_Window_Type *wt = (Fl_Window_Type *)t;
+ Window_Node *wt = (Window_Node *)t;
wt->ideal_size(w, h);
- if (main_window) {
+ if (Fluid.main_window) {
int sx, sy, sw, sh;
- Fl_Window *win = main_window;
+ Fl_Window *win = Fluid.main_window;
int screen = Fl::screen_num(win->x(), win->y());
Fl::screen_work_area(sx, sy, sw, sh, screen);
x = sx + sw/2 - w/2;
@@ -1318,14 +1386,14 @@ Fl_Type *add_new_widget_from_user(Fl_Type *inPrototype, Strategy strategy, bool
}
// make the new widget visible
select_only(t);
- set_modflag(1);
+ Fluid.proj.set_modflag(1);
if (and_open)
t->open();
} else {
- undo_current --;
- undo_last --;
+ Fluid.proj.undo.current_ --;
+ Fluid.proj.undo.last_ --;
}
- undo_resume();
+ Fluid.proj.undo.resume();
return t;
}
@@ -1335,126 +1403,126 @@ Fl_Type *add_new_widget_from_user(Fl_Type *inPrototype, Strategy strategy, bool
\param[in] inName find the right prototype by this name
\param[in] strategy where to add the node
\param[in] and_open if set to true, call open() on the widget after creating it
- \return the newly created type or NULL
+ \return the newly created type or nullptr
\see add_new_widget_from_file(const char*, int)
- add_new_widget_from_user(Fl_Type*, int)
+ add_new_widget_from_user(Node*, int)
add_new_widget_from_user(const char*, int)
*/
-Fl_Type *add_new_widget_from_user(const char *inName, Strategy strategy, bool and_open) {
- Fl_Type *prototype = typename_to_prototype(inName);
+Node *add_new_widget_from_user(const char *inName, Strategy strategy, bool and_open) {
+ Node *prototype = typename_to_prototype(inName);
if (prototype)
return add_new_widget_from_user(prototype, strategy, and_open);
else
- return NULL;
+ return nullptr;
}
/**
Callback for all non-widget menu items.
*/
static void cbf(Fl_Widget *, void *v) {
- Fl_Type *t = NULL;
- if (Fl_Type::current && Fl_Type::current->can_have_children())
- t = ((Fl_Type*)v)->make(Strategy::AS_LAST_CHILD);
+ Node *t = nullptr;
+ if (Fluid.proj.tree.current && Fluid.proj.tree.current->can_have_children())
+ t = ((Node*)v)->make(Strategy::AS_LAST_CHILD);
else
- t = ((Fl_Type*)v)->make(Strategy::AFTER_CURRENT);
+ t = ((Node*)v)->make(Strategy::AFTER_CURRENT);
select_only(t);
}
/**
Callback for all widget menu items.
- \param[in] v cast to Fl_Type to get the prototype of the type that the user
+ \param[in] v cast to Node to get the prototype of the type that the user
wants to create.
*/
static void cb(Fl_Widget *, void *v) {
- Fl_Type *t = NULL;
- if (Fl_Type::current && Fl_Type::current->can_have_children())
- t = add_new_widget_from_user((Fl_Type*)v, Strategy::AS_LAST_CHILD);
+ Node *t = nullptr;
+ if (Fluid.proj.tree.current && Fluid.proj.tree.current->can_have_children())
+ t = add_new_widget_from_user((Node*)v, Strategy::AS_LAST_CHILD);
else
- t = add_new_widget_from_user((Fl_Type*)v, Strategy::AFTER_CURRENT);
+ t = add_new_widget_from_user((Node*)v, Strategy::AFTER_CURRENT);
select_only(t);
}
/**
- \note Make sure that this menu stays synchronized to `Fl_Type *known_types[]`
+ \note Make sure that this menu stays synchronized to `Node *known_types[]`
defined further up in this file.
*/
Fl_Menu_Item New_Menu[] = {
-{"Code",0,0,0,FL_SUBMENU},
- {"Function/Method",0,cbf,(void*)&Fl_Function_type},
- {"Code",0,cbf,(void*)&Fl_Code_type},
- {"Code Block",0,cbf,(void*)&Fl_CodeBlock_type},
- {"Declaration",0,cbf,(void*)&Fl_Decl_type},
- {"Declaration Block",0,cbf,(void*)&Fl_DeclBlock_type},
- {"Class",0,cbf,(void*)&Fl_Class_type},
- {"Widget Class",0,cb,(void*)&Fl_Widget_Class_type},
- {"Comment",0,cbf,(void*)&Fl_Comment_type},
- {"Inlined Data",0,cbf,(void*)&Fl_Data_type},
-{0},
-{"Group",0,0,0,FL_SUBMENU},
- {0,0,cb,(void*)&Fl_Window_type},
- {0,0,cb,(void*)&Fl_Group_type},
- {0,0,cb,(void*)&Fl_Pack_type},
- {0,0,cb,(void*)&Fl_Flex_type},
- {0,0,cb,(void*)&Fl_Tabs_type},
- {0,0,cb,(void*)&Fl_Scroll_type},
- {0,0,cb,(void*)&Fl_Tile_type},
- {0,0,cb,(void*)&Fl_Wizard_type},
- {0,0,cb,(void*)&Fl_Grid_type},
-{0},
-{"Buttons",0,0,0,FL_SUBMENU},
- {0,0,cb,(void*)&Fl_Button_type},
- {0,0,cb,(void*)&Fl_Return_Button_type},
- {0,0,cb,(void*)&Fl_Light_Button_type},
- {0,0,cb,(void*)&Fl_Check_Button_type},
- {0,0,cb,(void*)&Fl_Repeat_Button_type},
- {0,0,cb,(void*)&Fl_Round_Button_type},
-{0},
-{"Valuators",0,0,0,FL_SUBMENU},
- {0,0,cb,(void*)&Fl_Slider_type},
- {0,0,cb,(void*)&Fl_Scrollbar_type},
- {0,0,cb,(void*)&Fl_Value_Slider_type},
- {0,0,cb,(void*)&Fl_Adjuster_type},
- {0,0,cb,(void*)&Fl_Counter_type},
- {0,0,cb,(void*)&Fl_Spinner_type},
- {0,0,cb,(void*)&Fl_Dial_type},
- {0,0,cb,(void*)&Fl_Roller_type},
- {0,0,cb,(void*)&Fl_Value_Input_type},
- {0,0,cb,(void*)&Fl_Value_Output_type},
-{0},
-{"Text",0,0,0,FL_SUBMENU},
- {0,0,cb,(void*)&Fl_Input_type},
- {0,0,cb,(void*)&Fl_Output_type},
- {0,0,cb,(void*)&Fl_Text_Editor_type},
- {0,0,cb,(void*)&Fl_Text_Display_type},
- {0,0,cb,(void*)&Fl_File_Input_type},
- {0,0,cb,(void*)&Fl_Terminal_type},
-{0},
-{"Menus",0,0,0,FL_SUBMENU},
- {0,0,cb,(void*)&Fl_Menu_Bar_type},
- {0,0,cb,(void*)&Fl_Menu_Button_type},
- {0,0,cb,(void*)&Fl_Choice_type},
- {0,0,cb,(void*)&Fl_Input_Choice_type},
- {0,0,cb, (void*)&Fl_Submenu_type},
- {0,0,cb, (void*)&Fl_Menu_Item_type},
- {"Checkbox Menu Item",0,cb, (void*)&Fl_Checkbox_Menu_Item_type},
- {"Radio Menu Item",0,cb, (void*)&Fl_Radio_Menu_Item_type},
-{0},
-{"Browsers",0,0,0,FL_SUBMENU},
- {0,0,cb,(void*)&Fl_Browser_type},
- {0,0,cb,(void*)&Fl_Check_Browser_type},
- {0,0,cb,(void*)&Fl_File_Browser_type},
- {0,0,cb,(void*)&Fl_Tree_type},
- {0,0,cb,(void*)&Fl_Help_View_type},
- {0,0,cb,(void*)&Fl_Table_type},
-{0},
-{"Other",0,0,0,FL_SUBMENU},
- {0,0,cb,(void*)&Fl_Box_type},
- {0,0,cb,(void*)&Fl_Clock_type},
- {0,0,cb,(void*)&Fl_Progress_type},
-{0},
-{0}};
+ {"Code",0,nullptr,nullptr,FL_SUBMENU},
+ {"Function/Method",0,cbf,(void*)&Function_Node::prototype},
+ {"Code",0,cbf,(void*)&Code_Node::prototype},
+ {"Code Block",0,cbf,(void*)&CodeBlock_Node::prototype},
+ {"Declaration",0,cbf,(void*)&Decl_Node::prototype},
+ {"Declaration Block",0,cbf,(void*)&DeclBlock_Node::prototype},
+ {"Class",0,cbf,(void*)&Class_Node::prototype},
+ {"Widget Class",0,cb,(void*)&Widget_Class_Node::prototype},
+ {"Comment",0,cbf,(void*)&Comment_Node::prototype},
+ {"Inlined Data",0,cbf,(void*)&Data_Node::prototype},
+ {nullptr},
+ {"Group",0,nullptr,nullptr,FL_SUBMENU},
+ {nullptr,0,cb,(void*)&Window_Node::prototype},
+ {nullptr,0,cb,(void*)&Group_Node::prototype},
+ {nullptr,0,cb,(void*)&Pack_Node::prototype},
+ {nullptr,0,cb,(void*)&Flex_Node::prototype},
+ {nullptr,0,cb,(void*)&Tabs_Node::prototype},
+ {nullptr,0,cb,(void*)&Scroll_Node::prototype},
+ {nullptr,0,cb,(void*)&Tile_Node::prototype},
+ {nullptr,0,cb,(void*)&Wizard_Node::prototype},
+ {nullptr,0,cb,(void*)&Grid_Node::prototype},
+ {nullptr},
+ {"Buttons",0,nullptr,nullptr,FL_SUBMENU},
+ {nullptr,0,cb,(void*)&Button_Node::prototype},
+ {nullptr,0,cb,(void*)&Return_Button_Node::prototype},
+ {nullptr,0,cb,(void*)&Light_Button_Node::prototype},
+ {nullptr,0,cb,(void*)&Check_Button_Node::prototype},
+ {nullptr,0,cb,(void*)&Repeat_Button_Node::prototype},
+ {nullptr,0,cb,(void*)&Round_Button_Node::prototype},
+ {nullptr},
+ {"Valuators",0,nullptr,nullptr,FL_SUBMENU},
+ {nullptr,0,cb,(void*)&Slider_Node::prototype},
+ {nullptr,0,cb,(void*)&Scrollbar_Node::prototype},
+ {nullptr,0,cb,(void*)&Value_Slider_Node::prototype},
+ {nullptr,0,cb,(void*)&Adjuster_Node::prototype},
+ {nullptr,0,cb,(void*)&Counter_Node::prototype},
+ {nullptr,0,cb,(void*)&Spinner_Node::prototype},
+ {nullptr,0,cb,(void*)&Dial_Node::prototype},
+ {nullptr,0,cb,(void*)&Roller_Node::prototype},
+ {nullptr,0,cb,(void*)&Value_Input_Node::prototype},
+ {nullptr,0,cb,(void*)&Value_Output_Node::prototype},
+ {nullptr},
+ {"Text",0,nullptr,nullptr,FL_SUBMENU},
+ {nullptr,0,cb,(void*)&Input_Node::prototype},
+ {nullptr,0,cb,(void*)&Output_Node::prototype},
+ {nullptr,0,cb,(void*)&Text_Editor_Node::prototype},
+ {nullptr,0,cb,(void*)&Text_Display_Node::prototype},
+ {nullptr,0,cb,(void*)&File_Input_Node::prototype},
+ {nullptr,0,cb,(void*)&Terminal_Node::prototype},
+ {nullptr},
+ {"Menus",0,nullptr,nullptr,FL_SUBMENU},
+ {nullptr,0,cb,(void*)&Menu_Bar_Node::prototype},
+ {nullptr,0,cb,(void*)&Menu_Button_Node::prototype},
+ {nullptr,0,cb,(void*)&Choice_Node::prototype},
+ {nullptr,0,cb,(void*)&Input_Choice_Node::prototype},
+ {nullptr,0,cb, (void*)&Submenu_Node::prototype},
+ {nullptr,0,cb, (void*)&Menu_Item_Node::prototype},
+ {"Checkbox Menu Item",0,cb, (void*)&Checkbox_Menu_Item_Node::prototype},
+ {"Radio Menu Item",0,cb, (void*)&Radio_Menu_Item_Node::prototype},
+ {nullptr},
+ {"Browsers",0,nullptr,nullptr,FL_SUBMENU},
+ {nullptr,0,cb,(void*)&Browser_Node::prototype},
+ {nullptr,0,cb,(void*)&Check_Browser_Node::prototype},
+ {nullptr,0,cb,(void*)&File_Browser_Node::prototype},
+ {nullptr,0,cb,(void*)&Tree_Node::prototype},
+ {nullptr,0,cb,(void*)&Help_View_Node::prototype},
+ {nullptr,0,cb,(void*)&Table_Node::prototype},
+ {nullptr},
+ {"Other",0,nullptr,nullptr,FL_SUBMENU},
+ {nullptr,0,cb,(void*)&Box_Node::prototype},
+ {nullptr,0,cb,(void*)&Clock_Node::prototype},
+ {nullptr,0,cb,(void*)&Progress_Node::prototype},
+ {nullptr},
+ {nullptr}};
#include <FL/Fl_Multi_Label.H>
@@ -1464,8 +1532,8 @@ Fl_Menu_Item New_Menu[] = {
The icon may be null. If ic is null only the text is assigned
to the label and Fl_Multi_Label is not used.
\param[in] mi pointer to tme menu item that will be modified
- \param[in] ic icon for the menu, may be NULL
- \param[in] txt new label text, may *not* be NULL, will not be copied
+ \param[in] ic icon for the menu, may be nullptr
+ \param[in] txt new label text, may *not* be nullptr, will not be copied
*/
static void make_iconlabel(Fl_Menu_Item *mi, Fl_Image *ic, const char *txt)
{
@@ -1495,14 +1563,14 @@ void fill_in_New_Menu() {
for (unsigned i = 0; i < sizeof(New_Menu)/sizeof(*New_Menu); i++) {
Fl_Menu_Item *m = New_Menu+i;
if (m->user_data()) {
- Fl_Type *t = (Fl_Type*)m->user_data();
+ Node *t = (Node*)m->user_data();
if (m->text) {
- make_iconlabel( m, pixmap[t->id()], m->label() );
+ make_iconlabel( m, pixmap[(int)t->type()], m->label() );
} else {
const char *n = t->type_name();
if (!strncmp(n,"Fl_",3)) n += 3;
if (!strncmp(n,"fltk::",6)) n += 6;
- make_iconlabel( m, pixmap[t->id()], n );
+ make_iconlabel( m, pixmap[(int)t->type()], n );
}
}
}
@@ -1511,21 +1579,21 @@ void fill_in_New_Menu() {
/**
Find the correct prototype for a given type name.
\param[in] inName a C string that must match type_name() or alt_type_name() of
- one of the known Fl_Type classes.
- \return the matching prototype or NULL
+ one of the known Node classes.
+ \return the matching prototype or nullptr
*/
-Fl_Type *typename_to_prototype(const char *inName)
+Node *typename_to_prototype(const char *inName)
{
- if (inName==NULL || *inName==0)
- return NULL;
+ if (inName==nullptr || *inName==0)
+ return nullptr;
for (unsigned i = 0; i < sizeof(known_types)/sizeof(*known_types); i++) {
- Fl_Type *prototype = known_types[i];
+ Node *prototype = known_types[i];
if (fl_ascii_strcasecmp(inName, prototype->type_name())==0)
return prototype;
if (fl_ascii_strcasecmp(inName, prototype->alt_type_name())==0)
return prototype;
}
- return NULL;
+ return nullptr;
}
/**
@@ -1537,16 +1605,16 @@ Fl_Type *typename_to_prototype(const char *inName)
\param[in] inName a C string that described the type we want
\param[in] strategy add after current or as last child
- \return the type node that was created or NULL
+ \return the type node that was created or nullptr
\see add_new_widget_from_file(const char*, int)
- add_new_widget_from_user(Fl_Type*, int)
+ add_new_widget_from_user(Node*, int)
add_new_widget_from_user(const char*, int)
*/
-Fl_Type *add_new_widget_from_file(const char *inName, Strategy strategy) {
- Fl_Type *prototype = typename_to_prototype(inName);
+Node *add_new_widget_from_file(const char *inName, Strategy strategy) {
+ Node *prototype = typename_to_prototype(inName);
if (!prototype)
- return NULL;
- Fl_Type *new_node = prototype->make(strategy);
+ return nullptr;
+ Node *new_node = prototype->make(strategy);
return new_node;
}
diff --git a/fluid/nodes/factory.h b/fluid/nodes/factory.h
index f1968b167..172f7e5d4 100644
--- a/fluid/nodes/factory.h
+++ b/fluid/nodes/factory.h
@@ -1,5 +1,5 @@
//
-// Widget type header file for the Fast Light Tool Kit (FLTK).
+// Node Factory header file for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-2021 by Bill Spitzak and others.
//
@@ -14,21 +14,21 @@
// https://www.fltk.org/bugs.php
//
-#ifndef _FLUID_FACTORY_H
-#define _FLUID_FACTORY_H
+#ifndef FLUID_NODES_FACTORY_H
+#define FLUID_NODES_FACTORY_H
-#include "nodes/Fl_Type.h"
+#include "nodes/Node.h"
struct Fl_Menu_Item;
extern Fl_Menu_Item New_Menu[];
void fill_in_New_Menu();
-Fl_Type *typename_to_prototype(const char *inName);
+Node *typename_to_prototype(const char *inName);
-Fl_Type *add_new_widget_from_file(const char *inName, Strategy strategy);
-Fl_Type *add_new_widget_from_user(Fl_Type *inPrototype, Strategy strategy, bool and_open=true);
-Fl_Type *add_new_widget_from_user(const char *inName, Strategy strategy, bool and_open=true);
+Node *add_new_widget_from_file(const char *inName, Strategy strategy);
+Node *add_new_widget_from_user(Node *inPrototype, Strategy strategy, bool and_open=true);
+Node *add_new_widget_from_user(const char *inName, Strategy strategy, bool and_open=true);
-#endif // _FLUID_FACTORY_H
+#endif // FLUID_NODES_FACTORY_H