diff --git a/.github/workflows/build_fluid_docs.yml b/.github/workflows/build_fluid_docs.yml new file mode 100644 index 000000000..57b30aff3 --- /dev/null +++ b/.github/workflows/build_fluid_docs.yml @@ -0,0 +1,84 @@ +# +# This script builds the FLUID User Handbook as html directory and pdf +# document on a Linux machine. +# + +name: 'Build FLUID User Handbook' + +# This job must be called explicitly form the 'Actions' tab in GitHub +on: [workflow_dispatch] + +permissions: + contents: read + +jobs: + build-html: + runs-on: ubuntu-latest + +## This can also run on macOS, but BasicTeX will not generate the pdf document +# runs-on: macos-latest + + steps: + - uses: actions/checkout@v2 + + - name: Install prerequisites + run: | + sudo apt-get update -y + sudo apt-get install -y libwayland-dev wayland-protocols libdbus-1-dev libxkbcommon-dev libpango1.0-dev libgtk-3-dev + sudo apt-get install -y doxygen + sudo apt-get install -y doxygen-latex + sudo apt-get install -y xvfb + sudo apt-get install -y x11-xkb-utils xfonts-100dpi xfonts-75dpi xfonts-scalable xfonts-cyrillic x11-apps + +## Use the following line when 1.10.0 becomes available on Ubuntu. On 4/14/24 it's 1.9.2 +# sudo apt-get install -y doxygen=1.10.0 + +## xvfb creates a headless X server for us, so we can render snapshot with FLUID + +## We need at least Doxygen on macOS. BasicTeX is not enough though. +# brew install doxygen +# brew install --cask basictex +# eval "$(/usr/libexec/path_helper)" + + - name: Create Build Environment + run: cmake -E make_directory ${{github.workspace}}/build + + - name: Configure CMake + shell: bash + working-directory: ${{github.workspace}}/build + run: | + cmake $GITHUB_WORKSPACE \ + -D CMAKE_BUILD_TYPE=Debug \ + -D CMAKE_CXX_STANDARD=11 \ + -D CMAKE_CXX_EXTENSIONS=OFF \ + -D CMAKE_C_FLAGS_INIT="-Wall -Wunused" \ + -D CMAKE_CXX_FLAGS_INIT="-Wall -Wunused -Wsuggest-override" \ + -D FLTK_BUILD_FLTK_OPTIONS=OFF \ + -D FLTK_BUILD_FLUID=ON \ + -D FLTK_BUILD_GL=OFF \ + -D FLTK_BUILD_TEST=OFF \ + -D FLTK_BUILD_FLUID_DOCS=ON + + - name: Build + working-directory: ${{github.workspace}}/build + shell: bash + run: | + Xvfb :19 -screen 0 1024x768x16 & + export DISPLAY=:19 + cmake --build . --config Debug --target fluid_docs + cmake --build . --config Debug --target fluid_pdf + - name: Store html docs as an artifact + uses: actions/upload-artifact@v4 + with: + name: fluid-html + path: build/fluid/documentation/html + retention-days: 3 + overwrite: true + - name: Store pdf docs as an artifact + uses: actions/upload-artifact@v4 + with: + name: fluid-pdf + path: build/fluid/documentation/fluid.pdf + retention-days: 3 + overwrite: true + diff --git a/CMake/options.cmake b/CMake/options.cmake index b242c5f40..c1aa0dcea 100644 --- a/CMake/options.cmake +++ b/CMake/options.cmake @@ -459,6 +459,8 @@ endif() if(DOXYGEN_FOUND) option(FLTK_BUILD_HTML_DOCS "build html docs" ON) option(FLTK_INSTALL_HTML_DOCS "install html docs" OFF) + option(FLTK_BUILD_FLUID_DOCS "build FLUID docs" OFF) + option(FLTK_INSTALL_FLUID_DOCS "install FLUID docs" OFF) option(FLTK_INCLUDE_DRIVER_DOCS "include driver (developer) docs" OFF) mark_as_advanced(FLTK_INCLUDE_DRIVER_DOCS) @@ -473,6 +475,10 @@ if(FLTK_BUILD_HTML_DOCS OR FLTK_BUILD_PDF_DOCS) add_subdirectory(documentation) endif(FLTK_BUILD_HTML_DOCS OR FLTK_BUILD_PDF_DOCS) +if(FLTK_BUILD_FLUID_DOCS) + add_subdirectory(fluid/documentation) +endif(FLTK_BUILD_FLUID_DOCS) + ####################################################################### # Include optional Cairo support ####################################################################### diff --git a/README.CMake.txt b/README.CMake.txt index b117b6b9f..a915b3b23 100644 --- a/README.CMake.txt +++ b/README.CMake.txt @@ -325,6 +325,12 @@ FLTK_BUILD_PDF_DOCS - default ON You can safely leave these two options ON if you want to save build time because the docs are not built automatically. +FLTK_BUILD_FLUID_DOCS - default OFF + If this option is ON, the FLUID user documentation will be built. If + FLTK_BUILD_PDF_DOCS is ON, the FLUID documentation will be generated + in PDF forma. To generate the screen shots used in the handbook, + the CMake build mode must be set to "Debug". + FLTK_INCLUDE_DRIVER_DOCS - default OFF This option adds driver documentation to HTML and PDF docs (if ON). This option is marked as "advanced" since it is only useful for FLTK developers @@ -332,9 +338,10 @@ FLTK_INCLUDE_DRIVER_DOCS - default OFF options above is ON as well. FLTK_INSTALL_HTML_DOCS - default OFF +FLTK_INSTALL_FLUID_DOCS - default OFF FLTK_INSTALL_PDF_DOCS - default OFF - If these options are ON then the HTML and/or PDF docs are installed - when the 'install' target is executed, e.g. with `make install'. You + If these options are ON then the HTML, FLUID, and/or PDF docs are installed + when the 'install' target is executed, e.g. with `make install'. You need to select above options FLTK_BUILD_*_DOCS as well. diff --git a/documentation/CMakeLists.txt b/documentation/CMakeLists.txt index 4d7b5174a..cf9699449 100644 --- a/documentation/CMakeLists.txt +++ b/documentation/CMakeLists.txt @@ -52,7 +52,7 @@ if(GENERATE_DOCS) # find git revision # FIXME: This must also work with tarballs where git is not available. - # For now we just ignore errors and set GIT_REVISION = "unkown". + # For now we just ignore errors and set GIT_REVISION = "unknown". # In the future tarball/zip generation should create a file # that contains the git revision. diff --git a/documentation/Doxyfile.in b/documentation/Doxyfile.in index 130dd1845..56df6bdcd 100644 --- a/documentation/Doxyfile.in +++ b/documentation/Doxyfile.in @@ -794,7 +794,6 @@ INPUT = @CMAKE_CURRENT_SOURCE_DIR@/src/index.dox \ @CMAKE_CURRENT_SOURCE_DIR@/src/events.dox \ @CMAKE_CURRENT_SOURCE_DIR@/src/subclassing.dox \ @CMAKE_CURRENT_SOURCE_DIR@/src/opengl.dox \ - @CMAKE_CURRENT_SOURCE_DIR@/src/fluid.dox \ @CMAKE_CURRENT_SOURCE_DIR@/src/fltk-options.dox \ @CMAKE_CURRENT_SOURCE_DIR@/src/advanced.dox \ @CMAKE_CURRENT_SOURCE_DIR@/src/unicode.dox \ diff --git a/documentation/Makefile b/documentation/Makefile index 0b176246b..6760e4622 100644 --- a/documentation/Makefile +++ b/documentation/Makefile @@ -36,7 +36,6 @@ HTMLFILES = \ $(SRC_DOCDIR)/events.dox \ $(SRC_DOCDIR)/subclassing.dox \ $(SRC_DOCDIR)/opengl.dox \ - $(SRC_DOCDIR)/fluid.dox \ $(SRC_DOCDIR)/fltk-options.dox \ $(SRC_DOCDIR)/advanced.dox \ $(SRC_DOCDIR)/unicode.dox \ diff --git a/documentation/src/examples.dox b/documentation/src/examples.dox index fa7bcd9e3..992b85523 100644 --- a/documentation/src/examples.dox +++ b/documentation/src/examples.dox @@ -252,7 +252,7 @@ and shows OpenGL text. \subsection examples_CubeView CubeView \par -\c CubeView shows how to create a UI containing OpenGL with Fluid. +\c CubeView shows how to create a UI containing OpenGL with FLUID. \subsection examples_cursor cursor @@ -577,7 +577,7 @@ come in handy. They remember any kind of data between program launches. \subsection examples_radio radio \par -The \c radio tool was created entirely with fluid. It +The \c radio tool was created entirely with FLUID. It shows some of the available button types and tests radio button behavior. @@ -658,7 +658,7 @@ The \c table demo shows the features of the Fl_Table widget. \subsection examples_tabs tabs \par -The \c tabs tool was created with fluid. It tests +The \c tabs tool was created with FLUID. It tests correct hiding and redisplaying of tabs, navigation across tabs, resize behavior, and no unneeded redrawing of invisible widgets. @@ -733,13 +733,13 @@ font draws each of the Unicode code points ranging between U+0020 and U+FFFF. while the focus stays in the original window. -\subsection examples_fluid fluid +\subsection examples_fluid FLUID \par -\c fluid is not only a big test program, but also a very -useful visual UI designer. Many parts of \c fluid were -created using \c fluid. See the \link fluid Fluid Tutorial \endlink -for more details. +\c FLUID is not only a big test program, but also a very +useful visual UI designer. Many parts of \c FLUID were +created using \c FLUID. Check out the FLUID User Manual and +the tutorials that come with it at https://www.fltk.org/documentation.php . diff --git a/documentation/src/fltk-options.dox b/documentation/src/fltk-options.dox index 047801507..20365d12c 100644 --- a/documentation/src/fltk-options.dox +++ b/documentation/src/fltk-options.dox @@ -41,8 +41,8 @@ tool called fltk-options. `fltk-options` is a hybrid app that is part of FLTK and can be installed on the target system. It includes an up-to-date man page. -\image html fluid-edit-global-fltk-settings.png "fltk-options Application" -\image latex fluid-edit-global-fltk-settings.png "fltk-options Application" width=10cm +\image html fltk-options.png "fltk-options Application" +\image latex fltk-options.png "fltk-options Application" width=10cm When fltk-options is called without any command-line arguments, it opens in interactive mode and provides a user interface to view and alter all @@ -67,9 +67,9 @@ A full list of options can be found in the manual at Fl::Fl_Option. diff --git a/documentation/src/osissues.dox b/documentation/src/osissues.dox index faf7178b7..43e29463e 100644 --- a/documentation/src/osissues.dox +++ b/documentation/src/osissues.dox @@ -968,7 +968,7 @@ internally in the same way. \subsection osissues_mac_files Mac File System Specifics -\par Resource Forks +\par Resource Forks (OS X pre 10.6) FLTK does not access the resource fork of an application. However, a minimal resource fork must be created for OS X diff --git a/documentation/src/preface.dox b/documentation/src/preface.dox index 67304fbd2..0bfc54c55 100644 --- a/documentation/src/preface.dox +++ b/documentation/src/preface.dox @@ -31,7 +31,6 @@ This manual is organized into the following chapters and appendices: \li \ref events \li \ref subclassing \li \ref opengl -\li \ref fluid \li \ref fltk-options \li \ref advanced \li \ref unicode diff --git a/documentation/src/subclassing.dox b/documentation/src/subclassing.dox index bbf750b15..e37924bf9 100644 --- a/documentation/src/subclassing.dox +++ b/documentation/src/subclassing.dox @@ -40,9 +40,7 @@ The constructor should have the following arguments: MyClass(int x, int y, int w, int h, const char *label = 0); \endcode -This will allow the class to be used in -\ref fluid "FLUID" -without problems. +This will allow the class to be used in FLUID without problems. The constructor must call the constructor for the base class and pass the same arguments: diff --git a/fluid/CMakeLists.txt b/fluid/CMakeLists.txt index bb3b9fe51..b9065616b 100644 --- a/fluid/CMakeLists.txt +++ b/fluid/CMakeLists.txt @@ -37,7 +37,8 @@ set(CPPFILES Fluid_Image.cxx about_panel.cxx align_widget.cxx - alignment_panel.cxx + settings_panel.cxx + autodoc.cxx code.cxx custom_widgets.cxx factory.cxx @@ -47,7 +48,7 @@ set(CPPFILES mergeback.cxx pixmaps.cxx shell_command.cxx - sourceview_panel.cxx + codeview_panel.cxx template_panel.cxx undo.cxx widget_browser.cxx @@ -71,19 +72,19 @@ set(HEADERFILES StyleParse.h about_panel.h align_widget.h - alignment_panel.h + settings_panel.h + autodoc.h code.h comments.h custom_widgets.h factory.h file.h - fluid.h function_panel.h mergeback.h print_panel.h pixmaps.h shell_command.h - sourceview_panel.h + codeview_panel.h template_panel.h undo.h widget_browser.h diff --git a/fluid/CodeEditor.h b/fluid/CodeEditor.h index 9886705aa..9cfa50abe 100644 --- a/fluid/CodeEditor.h +++ b/fluid/CodeEditor.h @@ -72,7 +72,7 @@ public: /** A widget derived from CodeEditor with highlighting for code blocks. - This widget is used by the SourceView system to show the design's + This widget is used by the codeview system to show the design's source and header code. The secondary highlighting show the text part that corresponds to the selected widget(s). */ diff --git a/fluid/Fd_Snap_Action.cxx b/fluid/Fd_Snap_Action.cxx index ffd944cd8..ce3d6f082 100644 --- a/fluid/Fd_Snap_Action.cxx +++ b/fluid/Fd_Snap_Action.cxx @@ -17,7 +17,7 @@ #include "Fd_Snap_Action.h" #include "Fl_Group_Type.h" -#include "alignment_panel.h" +#include "settings_panel.h" #include "shell_command.h" // get and set Fl_String preferences #include "file.h" diff --git a/fluid/Fl_Function_Type.cxx b/fluid/Fl_Function_Type.cxx index 6dc9fc927..22bcf7265 100644 --- a/fluid/Fl_Function_Type.cxx +++ b/fluid/Fl_Function_Type.cxx @@ -1279,7 +1279,7 @@ void Fl_Data_Type::write_code1(Fd_Code_Writer& f) { int nData = -1; int uncompressedDataSize = 0; // path should be set correctly already - if (filename_ && !f.write_sourceview) { + if (filename_ && !f.write_codeview) { enter_project_dir(); FILE *f = fl_fopen(filename_, "rb"); leave_project_dir(); @@ -1395,8 +1395,8 @@ void Fl_Data_Type::write_code1(Fd_Code_Writer& f) { } } // if we are in interactive mode, we pop up a warning dialog - // giving the error: (batch_mode && !write_sourceview) ??? - if (message && !f.write_sourceview) { + // giving the error: (batch_mode && !write_codeview) ??? + if (message && !f.write_codeview) { if (batch_mode) fprintf(stderr, "FLUID ERROR: %s %s\n", message, fn); else @@ -1535,9 +1535,11 @@ BREAK2: */ void Fl_DeclBlock_Type::write_code1(Fd_Code_Writer& f) { const char* c = name(); - if (public_) - f.write_h("%s\n", c); - f.write_c("%s\n", c); + if (c && *c) { + if (public_) + f.write_h("%s\n", c); + f.write_c("%s\n", c); + } } /** @@ -1545,9 +1547,11 @@ void Fl_DeclBlock_Type::write_code1(Fd_Code_Writer& f) { */ void Fl_DeclBlock_Type::write_code2(Fd_Code_Writer& f) { const char* c = after; - if (public_) - f.write_h("%s\n", c); - f.write_c("%s\n", c); + if (c && *c) { + if (public_) + f.write_h("%s\n", c); + f.write_c("%s\n", c); + } } // ---- Fl_Comment_Type declaration diff --git a/fluid/Fl_Type.cxx b/fluid/Fl_Type.cxx index e1b184327..a649ea311 100644 --- a/fluid/Fl_Type.cxx +++ b/fluid/Fl_Type.cxx @@ -696,8 +696,8 @@ void Fl_Type::move_before(Fl_Type* g) { // write a widget and all its children: void Fl_Type::write(Fd_Project_Writer &f) { - if (f.write_sourceview()) proj1_start = (int)ftell(f.file()) + 1; - if (f.write_sourceview()) proj2_start = (int)ftell(f.file()) + 1; + 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()); @@ -712,9 +712,9 @@ void Fl_Type::write(Fd_Project_Writer &f) { write_properties(f); if (parent) parent->write_parent_properties(f, this, true); f.write_close(level); - if (f.write_sourceview()) proj1_end = (int)ftell(f.file()); + if (f.write_codeview()) proj1_end = (int)ftell(f.file()); if (!is_parent()) { - if (f.write_sourceview()) proj2_end = (int)ftell(f.file()); + if (f.write_codeview()) proj2_end = (int)ftell(f.file()); return; } // now do children: @@ -722,9 +722,9 @@ void Fl_Type::write(Fd_Project_Writer &f) { Fl_Type *child; for (child = next; child && child->level > level; child = child->next) if (child->level == level+1) child->write(f); - if (f.write_sourceview()) proj2_start = (int)ftell(f.file()) + 1; + if (f.write_codeview()) proj2_start = (int)ftell(f.file()) + 1; f.write_close(level); - if (f.write_sourceview()) proj2_end = (int)ftell(f.file()); + if (f.write_codeview()) proj2_end = (int)ftell(f.file()); } void Fl_Type::write_properties(Fd_Project_Writer &f) { @@ -1092,7 +1092,7 @@ Fl_Type *Fl_Type::find_by_uid(unsigned short uid) { return NULL; } -/** Find a type node by using the sourceview text positions. +/** 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 diff --git a/fluid/Fl_Type.h b/fluid/Fl_Type.h index 39a9bb30b..67e7c8965 100644 --- a/fluid/Fl_Type.h +++ b/fluid/Fl_Type.h @@ -146,7 +146,7 @@ public: // things that should not be public: Fl_Type *factory; const char *callback_name(Fd_Code_Writer& f); - // text positions of this type in code, header, and project file (see SourceView) + // text positions of this type in code, header, and project file (see codeview) int code_static_start, code_static_end; int code1_start, code1_end; int code2_start, code2_end; diff --git a/fluid/Fl_Widget_Type.cxx b/fluid/Fl_Widget_Type.cxx index 310792d0c..485cb8d8f 100644 --- a/fluid/Fl_Widget_Type.cxx +++ b/fluid/Fl_Widget_Type.cxx @@ -24,7 +24,7 @@ #include "file.h" #include "code.h" #include "Fluid_Image.h" -#include "alignment_panel.h" +#include "settings_panel.h" #include "widget_panel.h" #include "undo.h" #include "mergeback.h" @@ -383,7 +383,7 @@ void name_public_cb(Fl_Choice* i, void* v) { /* 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). Source View does deferred updates, and + (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. @@ -2727,7 +2727,7 @@ void Fl_Widget_Type::open() { extern void redraw_overlays(); extern void check_redraw_corresponding_parent(Fl_Type*); extern void redraw_browser(); -extern void update_sourceview_position(); +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 @@ -2761,8 +2761,8 @@ void selection_changed(Fl_Type *p) { redraw_overlays(); // load the panel with the new settings: load_panel(); - // update the source viewer to show the code for the selected object - update_sourceview_position(); + // update the code viewer to show the code for the selected object + update_codeview_position(); } //////////////////////////////////////////////////////////////// diff --git a/fluid/Fl_Widget_Type.h b/fluid/Fl_Widget_Type.h index b1773a501..40470c544 100644 --- a/fluid/Fl_Widget_Type.h +++ b/fluid/Fl_Widget_Type.h @@ -127,5 +127,6 @@ public: void redraw(); }; +extern Fl_Window *the_panel; #endif // _FLUID_FL_WIDGET_TYPE_H diff --git a/fluid/Fl_Window_Type.cxx b/fluid/Fl_Window_Type.cxx index bc848ed75..b68af4406 100644 --- a/fluid/Fl_Window_Type.cxx +++ b/fluid/Fl_Window_Type.cxx @@ -25,7 +25,7 @@ #include "fluid.h" #include "widget_browser.h" #include "undo.h" -#include "alignment_panel.h" +#include "settings_panel.h" #include "file.h" #include "code.h" #include "widget_panel.h" diff --git a/fluid/Makefile b/fluid/Makefile index 75a785e71..eb5b8c192 100644 --- a/fluid/Makefile +++ b/fluid/Makefile @@ -31,7 +31,8 @@ CPPFILES = \ Fluid_Image.cxx \ about_panel.cxx \ align_widget.cxx \ - alignment_panel.cxx \ + settings_panel.cxx \ + autodoc.cxx \ code.cxx \ custom_widgets.cxx \ factory.cxx \ @@ -42,7 +43,7 @@ CPPFILES = \ mergeback.cxx \ pixmaps.cxx \ shell_command.cxx \ - sourceview_panel.cxx \ + codeview_panel.cxx \ template_panel.cxx \ undo.cxx \ widget_browser.cxx \ @@ -141,9 +142,9 @@ uninstall-osx: rebuild: fluid$(EXEEXT) echo 'Rebuilding fluid (.fl) and .cxx/.h files from .fl files ...' ./fluid$(EXEEXT) -u -c about_panel.fl - ./fluid$(EXEEXT) -u -c alignment_panel.fl + ./fluid$(EXEEXT) -u -c settings_panel.fl ./fluid$(EXEEXT) -u -c function_panel.fl ./fluid$(EXEEXT) -u -c print_panel.fl - ./fluid$(EXEEXT) -u -c sourceview_panel.fl + ./fluid$(EXEEXT) -u -c codeview_panel.fl ./fluid$(EXEEXT) -u -c template_panel.fl ./fluid$(EXEEXT) -u -c widget_panel.fl diff --git a/fluid/autodoc.cxx b/fluid/autodoc.cxx new file mode 100644 index 000000000..63818d8af --- /dev/null +++ b/fluid/autodoc.cxx @@ -0,0 +1,602 @@ +// +// Self-generate snapshots of user interface for FLUID documentation. +// +// Copyright 2024 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 NDEBUG + +#include "autodoc.h" +#include "fluid.h" +#include "factory.h" +#include "widget_browser.h" +#include "widget_panel.h" +#include "Fl_Widget_Type.h" +#include "Fl_Window_Type.h" +#include "function_panel.h" +#include "settings_panel.h" +#include "codeview_panel.h" + +#include +#include +#include +#include +#include + +extern Fl_Double_Window *settings_window; + +/** \file autodoc.cxx + + \todo Implement a function to snapshot a window including decoration + - see: void Fl_Widget_Surface::draw_decorated_window(Fl_Window *win, int win_offset_x, int win_offset_y) + - see: void Fl_Widget_Surface::origin(int x, int y) + - see: void Fl_Widget_Surface::draw(Fl_Widget* widget, int delta_x, int delta_y) + - see: void Fl_Widget_Surface::print_window_part(Fl_Window *win, int x, int y, int w, int h, int delta_x, int delta_y) + + \todo Implement a version that snaps multiple windows in a desktop style situation. + + \todo a version that takes snapshots of a range of menu items + + \todo implement FL_SNAP_TO_GROUP, possibly with a number on how many groups up in the hierarchy + */ + +/** \addtogroup fl_drawings + @{ + */ + +const int FL_SNAP_TO_WINDOW = 0x7f000000; + +static Fl_Box snap_clear_(0, 0, 0, 0); +Fl_Widget *FL_SNAP_AREA_CLEAR = &snap_clear_; + +static inline int fl_min(int a, int b) { return a < b ? a : b; } +static inline uchar fl_min(uchar a, uchar b) { return a < b ? a : b; } +static inline int fl_max(int a, int b) { return a > b ? a : b; } + +/** + Create a rect by providing a margin around a zero size rectangle. + \param[in] dx, dy positive integers, move margin up and left + \param[in] dr, db move margin to the right and down + */ +Fl_Margin::Fl_Margin(int dx, int dy, int dr, int db) + : Fl_Rect(-dx, -dy, dx+dr, dy+db) +{ +} + +/** + Convert an RGB image into an RGBA image. + \param[inout] image pointer to an RGB image, deletes the RGB image, returns the RGBA image + \return 0 if the image is now in RGBA format, or -1 if it can't be converted + */ +static int convert_RGB_to_RGBA(Fl_RGB_Image *&img) { + if (img->d() == 4) + return 0; + if (img->d() != 3) + return -1; + + // Copy pixel data from RGB to RGBA raw data + int img_w = img->w(); + int img_h = img->h(); + uchar *data = new uchar[img_w * img_h * 4], *dst = data; + int ld = img->ld(); if (ld == 0) ld = img_w * 3; + int i, j; + for (i=0; idata()[0] + i * ld; + for (j=0; jd() != 4) + return; + if (dx > img->w()) + return; + if (dx > 0) { + int max_x = dx, max_y = img->h(); + int ld = img->ld(); if (ld == 0) ld = img->w() * img->d(); + float a = 255/max_x; + for (int i = 0; i < max_x; i++) { + uchar *rgba = (uchar*)img->data()[0] + i * img->d(); + uchar alpha = static_cast(i * a); + for (int j = 0; j < max_y; j++) { + rgba[3] = fl_min(alpha, rgba[3]); + rgba += ld; + } + } + } +} + +/** + Blend the top lines of the alpha channel of an RBGA image to full transparency. + \param[in] img must be an RGBA image + \param[in] dy number of lines to blend + */ +void blend_alpha_top(const Fl_RGB_Image *img, int dy) { + if (img->d() != 4) + return; + if (dy > img->h()) + return; + if (dy > 0) { + int max_x = img->w(), max_y = dy; + int ld = img->ld(); if (ld == 0) ld = img->w() * img->d(); + float a = 255/max_y; + for (int i = 0; i < max_y; i++) { + uchar *rgba = (uchar*)img->data()[0] + i * ld; + uchar alpha = static_cast(i * a); + for (int j = 0; j < max_x; j++) { + rgba[3] = fl_min(alpha, rgba[3]); + rgba += 4; + } + } + } +} + +/** + Blend the right side lines of the alpha channel of an RBGA image to full transparency. + \param[in] img must be an RGBA image + \param[in] dx number of lines to blend + */ +void blend_alpha_right(const Fl_RGB_Image *img, int dx) { + if (img->d() != 4) + return; + if (dx > img->w()) + return; + if (dx > 0) { + int max_x = dx, max_y = img->h(); + int ld = img->ld(); if (ld == 0) ld = img->w() * img->d(); + float a = 255/max_x; + for (int i = 0; i < max_x; i++) { + uchar *rgba = (uchar*)img->data()[0] + (img->w()-i-1) * img->d(); + uchar alpha = static_cast(i * a); + for (int j = 0; j < max_y; j++) { + rgba[3] = fl_min(alpha, rgba[3]); + rgba += ld; + } + } + } +} + +/** + Blend the bottom lines of the alpha channel of an RBGA image to full transparency. + \param[in] img must be an RGBA image + \param[in] dy number of lines to blend + */ +void blend_alpha_bottom(const Fl_RGB_Image *img, int dy) { + if (img->d() != 4) + return; + if (dy > img->h()) + return; + if (dy > 0) { + int max_x = img->w(), max_y = dy; + int ld = img->ld(); if (ld == 0) ld = img->w() * img->d(); + float a = 255/max_y; + for (int i = 0; i < max_y; i++) { + uchar *rgba = (uchar*)img->data()[0] + (img->h()-i-1) * ld; + uchar alpha = static_cast(i * a); + for (int j = 0; j < max_x; j++) { + rgba[3] = fl_min(alpha, rgba[3]); + rgba += 4; + } + } + } +} + +/** + Take a snapshot of a number of widgets and save it as a png image. + + Draw a rectangular snapshot that fits around all widgets inside a window. + All widgets must be inside the same window. It's up to the caller to ensure + that widgets are visible. This includes children of `Fl_Tabs`. + + Outside labels of widgets are not taken into account, but a `frame` can be + provided to grow the snapshot rectangle. Setting individual parameters of the + frame to `FL_SNAP_TO_WINDOW` will extend the snapshot to the borders of the + top level window. + + Another `blend` frame can be added around the image that fades to full + transparency on selected sides. + + Use `Fl_Margin` to create `frame` and `blend` using positive integers to grow + the rectangle to the left, top, right, and bottom. + + The image can be scaled after all processing. Note that snapshot is always + created in FLTK resolution, even if the screen uses a higher resolution. + + \param[in] filename the snapshot will be written to this file in png format + \param[in] w draw a bounding box around all widgets in the NULL terminated list + \param[in] frame add a margin around the bounding box + \param[in] blend add another margin around the bounding box that fades to full transparency + \param[in] scale scale everything by this factor before saving it + \return the result of fl_write_png or -3 if another error occurred + */ +int fl_snapshot(const char *filename, Fl_Widget **w, + const Fl_Rect &frame, + const Fl_Rect &blend, + double scale) +{ + int i, min_x = 0, min_y = 0, max_x = 0, max_y = 0, bb_w, bb_h, img_w, img_h; + + // Get the bounding box for all widgets and make sure that all widgets are shown + for (i=0; w[i]; i++) { + int x, y; + Fl_Widget *ww = w[i]; + if (ww == FL_SNAP_AREA_CLEAR) { + min_x = max_x = 0; + min_y = max_y = 0; + } else { + ww->top_window_offset(x, y); + if (i==0) { + min_x = x; max_x = x + ww->w(); + min_y = y; max_y = y + ww->h(); + } else { + min_x = fl_min(min_x, x); max_x = fl_max(max_x, x + ww->w()); + min_y = fl_min(min_y, y); max_y = fl_max(max_y, y + ww->h()); + } + } + + // this does not help us with Fl_Tab groups + while (ww) { ww->show(); ww = ww->parent(); } + } + + // Check for special values in frame and adjust bounding box + Fl_Rect c_frame = frame; + if (frame.x() == -FL_SNAP_TO_WINDOW) c_frame.x(-min_x); + if (frame.y() == -FL_SNAP_TO_WINDOW) c_frame.y(-min_y); + if (frame.r() == FL_SNAP_TO_WINDOW) c_frame.r(w[0]->top_window()->w()-max_x); + if (frame.b() == FL_SNAP_TO_WINDOW) c_frame.b(w[0]->top_window()->h()-max_y); + + min_x += c_frame.x(); max_x += c_frame.r(); + min_y += c_frame.y(); max_y += c_frame.b(); + bb_w = max_x - min_x; bb_h = max_y - min_y; + img_w = bb_w + blend.w(); + img_h = bb_h + blend.h(); + + // Generate the Image Surface + Fl_Image_Surface *srfc = new Fl_Image_Surface(img_w, img_h); + Fl_Image_Surface::push_current(srfc); + + // Draw the background + fl_rectf(0, 0, img_w, img_h, 0x1395bf00); + + // Draw the top level window + srfc->draw(w[0]->top_window(), -blend.x()-min_x, -blend.y()-min_y); + Fl_Image_Surface::pop_current(); + Fl_RGB_Image *img = srfc->image(); + + // Do we want an alpha blended extension of the frame? + if ((blend.x()<0 || blend.y()<0 || blend.r()>0 || blend.b()>0)) { + if (convert_RGB_to_RGBA(img) == -1) { + delete img; + delete srfc; + return -3; + } + if (blend.x() < 0) blend_alpha_left(img, -blend.x()); + if (blend.y() < 0) blend_alpha_top(img, -blend.y()); + if (blend.r() > 0) blend_alpha_right(img, blend.r()); + if (blend.b() > 0) blend_alpha_bottom(img, blend.b()); + } + + // If scale is set, scale the image + if (scale != 1.0) { + Fl_Image::scaling_algorithm(FL_RGB_SCALING_BILINEAR); + Fl_RGB_Image *scaled_img = (Fl_RGB_Image*)img->copy(img->w()*scale, img->h()*scale); + delete img; + img = scaled_img; + } + + // Write the image to disk + int ret = fl_write_png(filename, img); + + // Clean up + delete img; + delete srfc; + return ret; +} + +/** + Take a snapshot of the size of the bounding box around two widgets and save it as a png image. + + \param[in] filename the snapshot will be written to this file in png format + \param[in] w1, w2 top left and bottom right widget + \param[in] frame add a margin around the bounding box + \param[in] blend add another margin around the bounding box that fades to full transparency + \param[in] scale scale everything by this factor before saving it + \return the result of fl_write_png or -3 if another error occurred + + \see fl_snapshot(const char*, Fl_Widget**, const Fl_Rect&, const Fl_Rect&, double) + */ +int fl_snapshot(const char *filename, Fl_Widget *w1, Fl_Widget *w2, + const Fl_Rect &frame, + const Fl_Rect &blend, + double scale) +{ + Fl_Widget *ww[3] = { w1, w2, NULL }; + return fl_snapshot(filename, ww, frame, blend, scale); +} + +/** + Take a snapshot of a widget inside its window and save it as a png image. + + \param[in] filename the snapshot will be written to this file in png format + \param[in] w snap this window, can also be a groups + \param[in] frame add a margin around the bounding box + \param[in] blend add another margin around the bounding box that fades to full transparency + \param[in] scale scale everything by this factor before saving it + \return the result of fl_write_png or -3 if another error occurred + + \see fl_snapshot(const char*, Fl_Widget**, const Fl_Rect&, const Fl_Rect&, double) + */ +int fl_snapshot(const char *filename, Fl_Widget *w, + const Fl_Rect &frame, + const Fl_Rect &blend, + double scale) +{ + Fl_Widget *ww[2] = { w, NULL }; + return fl_snapshot(filename, ww, frame, blend, scale); +} + +/** @} */ + + +void run_autodoc(const Fl_String &target_dir) { + // A list of all the margins we will use later + Fl_Margin win_margin(0, 0, 0, 0); + Fl_Margin win_blend(10, 10, 10, 10); + Fl_Margin tab_margin(FL_SNAP_TO_WINDOW, 32, FL_SNAP_TO_WINDOW, 4); + Fl_Margin xtab_margin(FL_SNAP_TO_WINDOW, 50, FL_SNAP_TO_WINDOW, 4); + Fl_Margin row_margin(FL_SNAP_TO_WINDOW, 4, FL_SNAP_TO_WINDOW, 4); + Fl_Margin xrow_margin(FL_SNAP_TO_WINDOW, 14, FL_SNAP_TO_WINDOW, 4); + Fl_Margin row_blend(0, 10, 0, 10); + +// Fl::scheme("gtk+"); + + // Create a silly project that contains all widgets that we want to document + new_project(false); + + /*Fl_Type *t_func = */ add_new_widget_from_user("Function", kAddAsLastChild, false); + Fl_Window_Type *t_win = (Fl_Window_Type*)add_new_widget_from_user("Fl_Window", kAddAsLastChild, false); + t_win->label("My Main Window"); + Fl_Widget_Type *t_grp = (Fl_Widget_Type*)add_new_widget_from_user("Fl_Group", kAddAsLastChild, false); + t_grp->public_ = 0; + Fl_Widget_Type *t_btn = (Fl_Widget_Type*)add_new_widget_from_user("Fl_Button", kAddAsLastChild, false); + t_btn->comment("Don't press this button!"); + t_btn->name("emergency_btn"); + ((Fl_Button*)t_btn->o)->shortcut(FL_COMMAND|'g'); + Fl_Type *t_sldr = add_new_widget_from_user("Fl_Slider", kAddAsLastChild, false); + Fl_Type *t_inp = add_new_widget_from_user("Fl_Input", kAddAsLastChild, false); + Fl_Type *t_flx = add_new_widget_from_user("Fl_Flex", kAddAsLastChild, false); + Fl_Type *t_flxc = add_new_widget_from_user("Fl_Button", kAddAsLastChild, false); + select_only(t_grp); + Fl_Type *t_grd = add_new_widget_from_user("Fl_Grid", kAddAsLastChild, false); + Fl_Type *t_grdc = add_new_widget_from_user("Fl_Button", kAddAsLastChild, false); + + widget_browser->rebuild(); + g_project.update_settings_dialog(); + + // TODO: FLUID overview + + // TODO: explain FLUID command line usage + + // TODO: take a snapshot of FLUID in a desktop situation + // (main, toolbar, document, widget editor, code view) + + // ---- main window + // explain titlebar + // explain menubar? + // explain widget browser + // explain widget browser entry + main_window->size(350, 320); + fl_snapshot((target_dir + "main_window.png").c_str(), main_window, win_margin, win_blend); + fl_snapshot((target_dir + "main_menubar.png").c_str(), main_menubar, row_margin, row_blend); + fl_snapshot((target_dir + "main_browser.png").c_str(), widget_browser, FL_SNAP_AREA_CLEAR, + Fl_Rect(0, 30, FL_SNAP_TO_WINDOW, 100), row_blend, 2.0); + + + // TODO: document view + // explain dnd + // explain selection, multiple selection, keyboard shortcuts + // explain mouse functionality and alignment + // explain live resize + // arrow: move by 1 + // shift: resize by one + // Meta: move by Widget Gap + // Shift Meta: resize by Widget Increment + + // ---- widget bin + // show grouping + // explain non-widget types and where they will be located + // explain widgets types an their dnd option + // explain menu arrays + // list exceptions (subwindow, scroll) + if (!widgetbin_panel) make_widgetbin(); + fl_snapshot((target_dir + "widgetbin_panel.png").c_str(), widgetbin_panel, win_margin, win_blend); + + // ---- code view + // explain functionality + // explain live update and choices + // show various tabs + // explain find and locate + if (!codeview_panel) make_codeview(); + update_codeview_cb(NULL, NULL); + cv_tab->value(cv_source_tab); + fl_snapshot((target_dir + "codeview_panel.png").c_str(), codeview_panel, win_margin, win_blend); + fl_snapshot((target_dir + "cv_find_row.png").c_str(), cv_find_row, row_margin, row_blend); + fl_snapshot((target_dir + "cv_settings_row.png").c_str(), cv_settings_row, row_margin, row_blend); + + // ---- settings dialog + // show and explain all tabs + fl_snapshot((target_dir + "w_settings.png").c_str(), settings_window, win_margin, win_blend); + fl_snapshot((target_dir + "w_settings_general_tab.png").c_str(), w_settings_general_tab, xtab_margin, row_blend); + w_settings_tabs->value(w_settings_project_tab); + fl_snapshot((target_dir + "w_settings_project_tab.png").c_str(), w_settings_project_tab, xtab_margin, row_blend); + w_settings_tabs->value(w_settings_layout_tab); + fl_snapshot((target_dir + "w_settings_layout_tab.png").c_str(), w_settings_layout_tab, xtab_margin, row_blend); + w_settings_tabs->value(w_settings_shell_tab); + w_settings_shell_list->value(1); + w_settings_shell_list->do_callback(); + fl_snapshot((target_dir + "w_settings_shell_tab.png").c_str(), w_settings_shell_tab, xtab_margin, row_blend); + w_settings_tabs->value(w_settings_i18n_tab); + i18n_type_chooser->value(1); + i18n_type_chooser->do_callback(); + fl_snapshot((target_dir + "w_settings_i18n_gnu.png").c_str(), i18n_type_chooser, i18n_gnu_static_function_input, row_margin, row_blend); + i18n_type_chooser->value(2); + i18n_type_chooser->do_callback(); + fl_snapshot((target_dir + "w_settings_i18n_psx.png").c_str(), i18n_type_chooser, i18n_pos_set_input, row_margin, row_blend); + w_settings_tabs->value(w_settings_user_tab); + fl_snapshot((target_dir + "w_settings_user_tab.png").c_str(), w_settings_user_tab, xtab_margin, row_blend); + + + // ---- dialog types + // list and show all non-widget types and their respective dialog boxes + + // -- ID_Function + Fl_Window *adoc_function_panel = make_function_panel(); + f_name_input->value("count_trees(const char *forest_name)"); + f_return_type_input->value("unsigned int"); + fl_snapshot((target_dir + "function_panel.png").c_str(), adoc_function_panel, win_margin, win_blend); + adoc_function_panel->hide(); + + // -- ID_Code + Fl_Window *adoc_code_panel = make_code_panel(); + code_input->buffer()->text("// increment user count\nif (new_user) {\n user_count++;\n}\n"); + fl_snapshot((target_dir + "code_panel.png").c_str(), adoc_code_panel, win_margin, win_blend); + adoc_code_panel->hide(); + + // -- ID_CodeBlock + Fl_Window *adoc_codeblock_panel = make_codeblock_panel(); + code_before_input->value("if (test())"); + code_after_input->value("// test widgets added..."); + fl_snapshot((target_dir + "codeblock_panel.png").c_str(), adoc_codeblock_panel, win_margin, win_blend); + adoc_codeblock_panel->hide(); + + // -- ID_Decl + Fl_Window *adoc_decl_panel = make_decl_panel(); + decl_class_choice->hide(); + decl_input->buffer()->text("const char *damage = \"'tis but a scratch\";"); + fl_snapshot((target_dir + "decl_panel.png").c_str(), adoc_decl_panel, win_margin, win_blend); + adoc_decl_panel->hide(); + + // -- ID_DeclBlock + Fl_Window *adoc_declblock_panel = make_declblock_panel(); + decl_before_input->value("#ifdef NDEBUG"); + decl_after_input->value("#endif // NDEBUG"); + fl_snapshot((target_dir + "declblock_panel.png").c_str(), adoc_declblock_panel, win_margin, win_blend); + adoc_declblock_panel->hide(); + + // -- ID_Class + Fl_Window *adoc_class_panel = make_class_panel(); + decl_class_choice->hide(); + c_name_input->value("Zoo_Giraffe"); + c_subclass_input->value("Zoo_Animal"); + fl_snapshot((target_dir + "class_panel.png").c_str(), adoc_class_panel, win_margin, win_blend); + adoc_class_panel->hide(); + + // -- ID_Widget_Class is handled like Fl_Window_Type + + // -- ID_Comment + Fl_Window *adoc_comment_panel = make_comment_panel(); + comment_input->buffer()->text("Make sure that the giraffe gets enough hay,\nbut the monkey can't reach it."); + fl_snapshot((target_dir + "comment_panel.png").c_str(), adoc_comment_panel, win_margin, win_blend); + adoc_comment_panel->hide(); + + // -- ID_Data + Fl_Window *adoc_data_panel = make_data_panel(); + data_class_choice->hide(); + data_input->value("emulated_ROM"); + data_filename->value("./ROM.bin"); + fl_snapshot((target_dir + "data_panel.png").c_str(), adoc_data_panel, win_margin, win_blend); + adoc_data_panel->hide(); + + + // ---- widget dialog + t_win->open(); // open the window + t_win->open(); // open the panel + select_only(t_win); + + // -- snapshot of the widget properties panel + fl_snapshot((target_dir + "widget_panel.png").c_str(), the_panel, win_margin, win_blend); + fl_snapshot((target_dir + "wLiveMode.png").c_str(), wLiveMode, row_margin, row_blend); + + // -- snapshot of the GUI tab + widget_tabs->value(wp_gui_tab); + fl_snapshot((target_dir + "wp_gui_tab.png").c_str(), wp_gui_tab, tab_margin, row_blend); + fl_snapshot((target_dir + "wp_gui_label.png").c_str(), wp_gui_label, row_margin, row_blend); + select_only(t_btn); + fl_snapshot((target_dir + "wp_gui_image.png").c_str(), widget_image_input, widget_deimage_input, row_margin, row_blend); + fl_snapshot((target_dir + "wp_gui_alignment.png").c_str(), wp_gui_alignment, row_margin, row_blend); + fl_snapshot((target_dir + "wp_gui_size.png").c_str(), widget_x_input, xrow_margin, row_blend); + select_only(t_sldr); + fl_snapshot((target_dir + "wp_gui_values.png").c_str(), wp_gui_values, xrow_margin, row_blend); + select_only(t_flxc); + fl_snapshot((target_dir + "wp_gui_flexp.png").c_str(), wp_gui_flexp, xrow_margin, row_blend); + select_only(t_flx); + fl_snapshot((target_dir + "wp_gui_margins.png").c_str(), wp_gui_margins, xrow_margin, row_blend); + select_only(t_win); + fl_snapshot((target_dir + "wp_gui_sizerange.png").c_str(), wp_gui_sizerange, xrow_margin, row_blend); + select_only(t_btn); + fl_snapshot((target_dir + "wp_gui_shortcut.png").c_str(), wp_gui_shortcut, row_margin, row_blend); + select_only(t_win); + fl_snapshot((target_dir + "wp_gui_xclass.png").c_str(), wp_gui_xclass, row_margin, row_blend); + select_only(t_btn); + fl_snapshot((target_dir + "wp_gui_attributes.png").c_str(), wp_gui_attributes, row_margin, row_blend); + fl_snapshot((target_dir + "wp_gui_tooltip.png").c_str(), wp_gui_tooltip, row_margin, row_blend); + + // -- snapshot of the style tab + widget_tabs->value(wp_style_tab); + select_only(t_inp); + fl_snapshot((target_dir + "wp_style_tab.png").c_str(), wp_style_tab, tab_margin, row_blend); + fl_snapshot((target_dir + "wp_style_label.png").c_str(), wp_style_label, row_margin, row_blend); + select_only(t_btn); + fl_snapshot((target_dir + "wp_style_box.png").c_str(), wp_style_box, wp_style_downbox, row_margin, row_blend); + select_only(t_inp); + fl_snapshot((target_dir + "wp_style_text.png").c_str(), wp_style_text, row_margin, row_blend); + + // -- snapshot of the C++ tab + widget_tabs->value(wp_cpp_tab); + select_only(t_btn); + fl_snapshot((target_dir + "wp_cpp_tab.png").c_str(), wp_cpp_tab, tab_margin, row_blend); + fl_snapshot((target_dir + "wp_cpp_class.png").c_str(), wp_cpp_class, row_margin, row_blend); + fl_snapshot((target_dir + "wp_cpp_name.png").c_str(), wp_cpp_name, row_margin, row_blend); + fl_snapshot((target_dir + "v_input.png").c_str(), v_input[0], v_input[3], row_margin, row_blend); + fl_snapshot((target_dir + "wComment.png").c_str(), wComment, row_margin, row_blend); + fl_snapshot((target_dir + "wp_cpp_callback.png").c_str(), wCallback, w_when_box, row_margin, row_blend); + + // -- snapshot of the Grid tab + select_only(t_grd); + widget_tabs->value(widget_tab_grid); + fl_snapshot((target_dir + "wp_grid_tab.png").c_str(), widget_tab_grid, tab_margin, row_blend); + + // -- snapshot of the Grid Child tab + select_only(t_grdc); + widget_tabs->value(widget_tab_grid_child); + fl_snapshot((target_dir + "wp_gridc_tab.png").c_str(), widget_tab_grid_child, tab_margin, row_blend); +} + + +#endif // NDEBUG diff --git a/fluid/autodoc.h b/fluid/autodoc.h new file mode 100644 index 000000000..060b166ab --- /dev/null +++ b/fluid/autodoc.h @@ -0,0 +1,59 @@ +// +// Widget snapshot header-only file for the Fast Light Tool Kit (FLTK). +// +// Copyright 2023-2024 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 autodoc.h + \brief tools to take snapshots of UI elements for documentation purposes + */ + +#ifndef fl_screenshot_H +#define fl_screenshot_H + +#include "../src/Fl_String.H" + +#include +#include +#include + +/** Class to initialize a Rect by providing the margin around a rect. */ +class Fl_Margin : public Fl_Rect { +public: + Fl_Margin(int dx, int dy, int dr, int db); +}; + +int fl_snapshot(const char *filename, Fl_Widget **w, + const Fl_Rect &frame = Fl_Margin(4, 4, 4, 4), + const Fl_Rect &blend = Fl_Margin(4, 4, 4, 4), + double scale=1.0); + +int fl_snapshot(const char *filename, Fl_Widget *w1, Fl_Widget *w2, + const Fl_Rect &frame = Fl_Margin(4, 4, 4, 4), + const Fl_Rect &blend = Fl_Margin(4, 4, 4, 4), + double scale=1.0); + +int fl_snapshot(const char *filename, Fl_Widget *w, + const Fl_Rect &frame = Fl_Margin(4, 4, 4, 4), + const Fl_Rect &blend = Fl_Margin(4, 4, 4, 4), + double scale=1.0); + +extern const int FL_SNAP_TO_WINDOW; + +extern Fl_Widget *FL_SNAP_AREA_CLEAR; + +extern void run_autodoc(const Fl_String &target_dir); + +#endif + diff --git a/fluid/code.cxx b/fluid/code.cxx index eef2aac47..24088ca11 100644 --- a/fluid/code.cxx +++ b/fluid/code.cxx @@ -414,7 +414,7 @@ void Fd_Code_Writer::write_cstring(const char *s, int length) { } // if we are rendering to the source code preview window, and the text is // longer than four lines, we only render a placeholder. - if (write_sourceview && ((s==NULL) || (length>300))) { + if (write_codeview && ((s==NULL) || (length>300))) { if (length>=0) crc_printf("\" ... %d bytes of text... \"", length); else @@ -523,7 +523,7 @@ void Fd_Code_Writer::write_cdata(const char *s, int length) { varused = 1; return; } - if (write_sourceview) { + if (write_codeview) { if (length>=0) crc_printf("{ /* ... %d bytes of binary data... */ }", length); else @@ -707,11 +707,11 @@ Fl_Type* Fd_Code_Writer::write_code(Fl_Type* p) { // write all code that comes before the children code // (but don't write the last comment until the very end) if (!(p==Fl_Type::last && p->is_a(ID_Comment))) { - if (write_sourceview) p->code1_start = (int)ftell(code_file); - if (write_sourceview) p->header1_start = (int)ftell(header_file); + if (write_codeview) p->code1_start = (int)ftell(code_file); + if (write_codeview) p->header1_start = (int)ftell(header_file); p->write_code1(*this); - if (write_sourceview) p->code1_end = (int)ftell(code_file); - if (write_sourceview) p->header1_end = (int)ftell(header_file); + if (write_codeview) p->code1_end = (int)ftell(code_file); + if (write_codeview) p->header1_end = (int)ftell(header_file); } // recursively write the code of all children Fl_Type* q; @@ -730,11 +730,11 @@ Fl_Type* Fd_Code_Writer::write_code(Fl_Type* p) { } // write all code that come after the children - if (write_sourceview) p->code2_start = (int)ftell(code_file); - if (write_sourceview) p->header2_start = (int)ftell(header_file); + if (write_codeview) p->code2_start = (int)ftell(code_file); + if (write_codeview) p->header2_start = (int)ftell(header_file); p->write_code2(*this); - if (write_sourceview) p->code2_end = (int)ftell(code_file); - if (write_sourceview) p->header2_end = (int)ftell(header_file); + if (write_codeview) p->code2_end = (int)ftell(code_file); + if (write_codeview) p->header2_end = (int)ftell(header_file); for (q = p->next; q && q->level > p->level;) { if (is_class_member(q) || is_comment_before_class_member(q)) { @@ -752,11 +752,11 @@ Fl_Type* Fd_Code_Writer::write_code(Fl_Type* p) { } else { for (q = p->next; q && q->level > p->level;) q = write_code(q); // write all code that come after the children - if (write_sourceview) p->code2_start = (int)ftell(code_file); - if (write_sourceview) p->header2_start = (int)ftell(header_file); + if (write_codeview) p->code2_start = (int)ftell(code_file); + if (write_codeview) p->header2_start = (int)ftell(header_file); p->write_code2(*this); - if (write_sourceview) p->code2_end = (int)ftell(code_file); - if (write_sourceview) p->header2_end = (int)ftell(header_file); + if (write_codeview) p->code2_end = (int)ftell(code_file); + if (write_codeview) p->header2_end = (int)ftell(header_file); } return q; } @@ -772,8 +772,8 @@ Fl_Type* Fd_Code_Writer::write_code(Fl_Type* p) { \param[in] t filename of the header file \return 0 if the operation failed, 1 if it was successful */ -int Fd_Code_Writer::write_code(const char *s, const char *t, bool to_sourceview) { - write_sourceview = to_sourceview; +int Fd_Code_Writer::write_code(const char *s, const char *t, bool to_codeview) { + write_codeview = to_codeview; delete id_root; id_root = 0; indentation = 0; current_class = 0L; @@ -791,7 +791,7 @@ int Fd_Code_Writer::write_code(const char *s, const char *t, bool to_sourceview) header_file = f; } // Remember the last code file location for MergeBack - if (s && g_project.write_mergeback_data && !to_sourceview) { + if (s && g_project.write_mergeback_data && !to_codeview) { Fl_String proj_filename = g_project.projectfile_path() + g_project.projectfile_name(); int i, n = proj_filename.size(); for (i=0; iis_a(ID_Comment)) { - if (write_sourceview) { + if (write_codeview) { first_type->code1_start = first_type->code2_start = (int)ftell(code_file); first_type->header1_start = first_type->header2_start = (int)ftell(header_file); } // it is ok to write non-recursive code here, because comments have no children or code2 blocks first_type->write_code1(*this); - if (write_sourceview) { + if (write_codeview) { first_type->code1_end = first_type->code2_end = (int)ftell(code_file); first_type->header1_end = first_type->header2_end = (int)ftell(header_file); } @@ -835,7 +835,7 @@ int Fd_Code_Writer::write_code(const char *s, const char *t, bool to_sourceview) write_h_once("#include "); } if (t && g_project.include_H_from_C) { - if (to_sourceview) { + if (to_codeview) { write_c("#include \"CodeView.h\"\n"); } else if (g_project.header_file_name[0] == '.' && strchr(g_project.header_file_name.c_str(), '/') == NULL) { write_c("#include \"%s\"\n", fl_filename_name(t)); @@ -896,17 +896,17 @@ int Fd_Code_Writer::write_code(const char *s, const char *t, bool to_sourceview) } for (Fl_Type* p = first_type; p;) { // write all static data for this & all children first - if (write_sourceview) p->header_static_start = (int)ftell(header_file); - if (write_sourceview) p->code_static_start = (int)ftell(code_file); + if (write_codeview) p->header_static_start = (int)ftell(header_file); + if (write_codeview) p->code_static_start = (int)ftell(code_file); p->write_static(*this); - if (write_sourceview) p->code_static_end = (int)ftell(code_file); - if (write_sourceview) p->header_static_end = (int)ftell(header_file); + if (write_codeview) p->code_static_end = (int)ftell(code_file); + if (write_codeview) p->header_static_end = (int)ftell(header_file); for (Fl_Type* q = p->next; q && q->level > p->level; q = q->next) { - if (write_sourceview) q->header_static_start = (int)ftell(header_file); - if (write_sourceview) q->code_static_start = (int)ftell(code_file); + if (write_codeview) q->header_static_start = (int)ftell(header_file); + if (write_codeview) q->code_static_start = (int)ftell(code_file); q->write_static(*this); - if (write_sourceview) q->code_static_end = (int)ftell(code_file); - if (write_sourceview) q->header_static_end = (int)ftell(header_file); + if (write_codeview) q->code_static_end = (int)ftell(code_file); + if (write_codeview) q->header_static_end = (int)ftell(header_file); } // then write the nested code: p = write_code(p); @@ -918,12 +918,12 @@ int Fd_Code_Writer::write_code(const char *s, const char *t, bool to_sourceview) Fl_Type* last_type = Fl_Type::last; if (last_type && (last_type != Fl_Type::first) && last_type->is_a(ID_Comment)) { - if (write_sourceview) { + if (write_codeview) { last_type->code1_start = last_type->code2_start = (int)ftell(code_file); last_type->header1_start = last_type->header2_start = (int)ftell(header_file); } last_type->write_code1(*this); - if (write_sourceview) { + if (write_codeview) { last_type->code1_end = last_type->code2_end = (int)ftell(code_file); last_type->header1_end = last_type->header2_end = (int)ftell(header_file); } @@ -973,7 +973,7 @@ Fd_Code_Writer::Fd_Code_Writer() block_buffer_(NULL), block_buffer_size_(0), indentation(0), - write_sourceview(false), + write_codeview(false), varused_test(0), varused(0) { diff --git a/fluid/code.h b/fluid/code.h index bac7bc756..8581c90f8 100644 --- a/fluid/code.h +++ b/fluid/code.h @@ -68,7 +68,7 @@ public: int indentation; /// set if we write abbreviated file for the source code previewer /// (disables binary data blocks, for example) - bool write_sourceview; + bool write_codeview; /// silly thing to prevent declaring unused variables: /// When this symbol is on, all attempts to write code don't write /// anything, but set a variable if it looks like the variable "o" is used: @@ -100,7 +100,7 @@ public: void write_hc(const char *, int, const char*, const char*); void write_c_indented(const char *textlines, int inIndent, char inTrailwWith); Fl_Type* write_code(Fl_Type* p); - int write_code(const char *cfile, const char *hfile, bool to_sourceview=false); + int write_code(const char *cfile, const char *hfile, bool to_codeview=false); void write_public(int state); // writes pubic:/private: as needed void tag(int type, unsigned short uid); diff --git a/fluid/codeview_panel.cxx b/fluid/codeview_panel.cxx new file mode 100644 index 000000000..0ca8c0d3a --- /dev/null +++ b/fluid/codeview_panel.cxx @@ -0,0 +1,548 @@ +// +// Code dialogs 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 +// + +// generated by Fast Light User Interface Designer (fluid) version 1.0400 + +#include "codeview_panel.h" +#include "fluid.h" +#include "file.h" +#include "../src/flstring.h" +#include +#include +static char *cv_source_filename = NULL; +static char *cv_header_filename = NULL; +static char *cv_design_filename = NULL; +int cv_code_choice; +extern void select_only(Fl_Type *o); +extern void reveal_in_browser(Fl_Type *t); + +/** + Update the header and source code highlighting depending on the + currently selected object + + The Code View system offers an immediate preview of the code + files that will be generated by FLUID. It also marks the code + generated for the last selected item in the header and the source + file. +*/ +void update_codeview_position() { + if (!codeview_panel || !codeview_panel->visible()) + return; + if (cv_autoposition->value()==0) + return; + if (codeview_panel && codeview_panel->visible() && Fl_Type::current) { + int pos0 = 0, pos1 = 0; + if (cv_source->visible_r()) { + switch (cv_code_choice) { + case 0: // prolog: not yet (include statements) + pos0 = Fl_Type::current->code1_start; + pos1 = Fl_Type::current->code2_end; + break; + case 1: // static: callbacks, menu declarations + pos0 = Fl_Type::current->code_static_start; + pos1 = Fl_Type::current->code_static_end; + break; + case 2: // code: entire implementation block including children + pos0 = Fl_Type::current->code1_start; + pos1 = Fl_Type::current->code2_end; + break; + case 3: // code1: all implementation code before the children + pos0 = Fl_Type::current->code1_start; + pos1 = Fl_Type::current->code1_end; + break; + case 4: // code1: all implementation code before the children + pos0 = Fl_Type::current->code2_start; + pos1 = Fl_Type::current->code2_end; + break; + } + if (pos0>=0) { + if (pos1buffer()->line_end(pos0); + cv_source->buffer()->highlight(pos0, pos1); + int line = cv_source->buffer()->count_lines(0, pos0); + cv_source->scroll(line, 0); + } + } + if (cv_header->visible_r()) { + switch (cv_code_choice) { + case 0: // prolog: not yet (include statements) + case 1: // static: callbacks, menu declarations + pos0 = Fl_Type::current->header_static_start; + pos1 = Fl_Type::current->header_static_end; + break; + case 2: // code: entire implementation block including children + pos0 = Fl_Type::current->header1_start; + pos1 = Fl_Type::current->header2_end; + break; + case 3: // code1: all implementation code before the children + pos0 = Fl_Type::current->header1_start; + pos1 = Fl_Type::current->header1_end; + break; + case 4: // code1: all implementation code before the children + pos0 = Fl_Type::current->header2_start; + pos1 = Fl_Type::current->header2_end; + break; + } + if (pos0>=0) { + if (pos1buffer()->line_end(pos0); + cv_header->buffer()->highlight(pos0, pos1); + int line = cv_header->buffer()->count_lines(0, pos0); + cv_header->scroll(line, 0); + } + } + if (cv_project->visible_r()) { + switch (cv_code_choice) { + case 0: // prolog: not yet (include statements) + case 1: // static: callbacks, menu declarations + case 2: // code: entire implementation block including children + pos0 = Fl_Type::current->proj1_start; + pos1 = Fl_Type::current->proj2_end; + break; + case 3: // code1: all implementation code before the children + pos0 = Fl_Type::current->proj1_start; + pos1 = Fl_Type::current->proj1_end; + break; + case 4: // code1: all implementation code before the children + pos0 = Fl_Type::current->proj2_start; + pos1 = Fl_Type::current->proj2_end; + break; + } + if (pos0>=0) { + if (pos1buffer()->line_end(pos0); + cv_project->buffer()->highlight(pos0, pos1); + int line = cv_project->buffer()->count_lines(0, pos0); + cv_project->scroll(line, 0); + } + } + } +} + +/** + Callback to update the codeview position. +*/ +void update_codeview_position_cb(class Fl_Tabs*, void*) { + // make sure that the selected tab shows the current view + update_codeview_cb(0,0); + // highlight the selected widget in the selected tab + update_codeview_position(); +} + +/** + Generate a header, source, strings, or design file in a temporary directory + and load those into the Code Viewer widgets. +*/ +void update_codeview_cb(class Fl_Button*, void*) { + if (!codeview_panel || !codeview_panel->visible()) + return; + + if (!cv_source_filename) { + cv_source_filename = (char*)malloc(FL_PATH_MAX); + fl_strlcpy(cv_source_filename, get_tmpdir().c_str(), FL_PATH_MAX); + fl_strlcat(cv_source_filename, "codeview_tmp.cxx", FL_PATH_MAX); + } + if (!cv_header_filename) { + cv_header_filename = (char*)malloc(FL_PATH_MAX); + fl_strlcpy(cv_header_filename, get_tmpdir().c_str(), FL_PATH_MAX); + fl_strlcat(cv_header_filename, "codeview_tmp.h", FL_PATH_MAX); + } + if (!cv_design_filename) { + cv_design_filename = (char*)malloc(FL_PATH_MAX); + fl_strlcpy(cv_design_filename, get_tmpdir().c_str(), FL_PATH_MAX); + fl_strlcat(cv_design_filename, "codeview_tmp.fl", FL_PATH_MAX); + } + + if (cv_project->visible_r()) { + write_file(cv_design_filename, false, true); + int top = cv_project->top_line(); + cv_project->buffer()->loadfile(cv_design_filename); + cv_project->scroll(top, 0); + } else if (cv_strings->visible_r()) { + static const char *exts[] = { ".txt", ".po", ".msg" }; + char fn[FL_PATH_MAX+1]; + fl_strlcpy(fn, get_tmpdir().c_str(), FL_PATH_MAX); + fl_strlcat(fn, "strings", FL_PATH_MAX); + fl_filename_setext(fn, FL_PATH_MAX, exts[g_project.i18n_type]); + write_strings(fn); + int top = cv_strings->top_line(); + cv_strings->buffer()->loadfile(fn); + cv_strings->scroll(top, 0); + } else if (cv_source->visible_r() || cv_header->visible_r()) { + Fl_String code_file_name_bak = g_project.code_file_name; + g_project.code_file_name = cv_source_filename; + Fl_String header_file_name_bak = g_project.header_file_name; + g_project.header_file_name = cv_header_filename; + + // generate the code and load the files + Fd_Code_Writer f; + // generate files + if (f.write_code(cv_source_filename, cv_header_filename, true)) + { + // load file into source editor + int pos = cv_source->top_line(); + cv_source->buffer()->loadfile(cv_source_filename); + cv_source->scroll(pos, 0); + // load file into header editor + pos = cv_header->top_line(); + cv_header->buffer()->loadfile(cv_header_filename); + cv_header->scroll(pos, 0); + // update the source code highlighting + update_codeview_position(); + } + + g_project.code_file_name = code_file_name_bak; + g_project.header_file_name = header_file_name_bak; + } +} + +/** + This is called by the timer itself +*/ +void update_codeview_timer(void*) { + update_codeview_cb(0,0); +} + +void codeview_defer_update() { + // we will only update earliest 0.5 seconds after the last change, and only + // if no other change was made, so dragging a widget will not generate any + // CPU load + Fl::remove_timeout(update_codeview_timer, 0); + Fl::add_timeout(0.5, update_codeview_timer, 0); +} + +/** + Show or hide the source code preview. + The state is stored in the app preferences. +*/ +void codeview_toggle_visibility() { + if (!codeview_panel) { + make_codeview(); + codeview_panel->callback((Fl_Callback*)toggle_codeview_cb); + Fl_Preferences svp(fluid_prefs, "codeview"); + int autorefresh; + svp.get("autorefresh", autorefresh, 1); + cv_autorefresh->value(autorefresh); + int autoposition; + svp.get("autoposition", autoposition, 1); + cv_autoposition->value(autoposition); + int tab; + svp.get("tab", tab, 0); + if (tab>=0 && tabchildren()) cv_tab->value(cv_tab->child(tab)); + svp.get("code_choice", cv_code_choice, 2); + cv_code_choice_w->value(cv_code_choice_w->find_item_with_argument(cv_code_choice)); + if (!position_window(codeview_panel,"codeview_pos", 0, 320, 120, 550, 500)) return; + } + + if (codeview_panel->visible()) { + codeview_panel->hide(); + codeview_item->label("Show Code View"); + } else { + codeview_panel->show(); + codeview_item->label("Hide Code View"); + update_codeview_cb(0,0); + } +} + +Fl_Double_Window *codeview_panel=(Fl_Double_Window *)0; + +Fl_Tabs *cv_tab=(Fl_Tabs *)0; + +Fl_Group *cv_source_tab=(Fl_Group *)0; + +CodeViewer *cv_source=(CodeViewer *)0; + +CodeViewer *cv_header=(CodeViewer *)0; + +TextViewer *cv_strings=(TextViewer *)0; + +TextViewer *cv_project=(TextViewer *)0; + +Fl_Group *cv_find_row=(Fl_Group *)0; + +Fl_Button *cv_find_text_case=(Fl_Button *)0; + +Fl_Input *cv_find_text=(Fl_Input *)0; + +static void cb_cv_find_text(Fl_Input* o, void*) { + Fl_Text_Display *e = NULL; + if (cv_source->visible_r()) { + e = cv_source; + } else if (cv_header->visible_r()) { + e = cv_header; + } else if (cv_project->visible_r()) { + e = cv_project; + } + if (e) { + Fl_Text_Buffer *b = e->buffer(); + int pos = e->insert_position(); + int found = b->search_forward(pos, o->value(), &pos, cv_find_text_case->value()); + if (found) { + b->select(pos, pos + (int)strlen(o->value())); + e->insert_position(pos); + e->show_insert_position(); + } + } +} + +static void cb_(Fl_Button*, void*) { + Fl_Text_Display *e = NULL; + if (cv_source->visible_r()) { + e = cv_source; + } else if (cv_header->visible_r()) { + e = cv_header; + } else if (cv_project->visible_r()) { + e = cv_project; + } + if (e) { + const char *needle = cv_find_text->value(); + Fl_Text_Buffer *b = e->buffer(); + int pos = e->insert_position()-1; + if (pos < 0) pos = b->length()-1; + int found = b->search_backward(pos, needle, &pos, cv_find_text_case->value()); + if (!found) + found = b->search_backward(b->length()-1, needle, &pos, cv_find_text_case->value()); + if (found) { + b->select(pos, pos + (int)strlen(needle)); + e->insert_position(pos); + e->show_insert_position(); + } + } +} + +static void cb_1(Fl_Button*, void*) { + Fl_Text_Display *e = NULL; + if (cv_source->visible_r()) { + e = cv_source; + } else if (cv_header->visible_r()) { + e = cv_header; + } else if (cv_project->visible_r()) { + e = cv_project; + } + if (e) { + const char *needle = cv_find_text->value(); + Fl_Text_Buffer *b = e->buffer(); + int pos = e->insert_position() + 1; + if (pos+1 >= b->length()) pos = 0; + int found = b->search_forward(pos, needle, &pos, cv_find_text_case->value()); + if (!found && (pos > 0)) + found = b->search_forward(0, needle, &pos, cv_find_text_case->value()); + if (found) { + b->select(pos, pos + (int)strlen(needle)); + e->insert_position(pos); + e->show_insert_position(); + } + } +} + +static void cb_Reveal(Fl_Button*, void*) { + if (codeview_panel && codeview_panel->visible()) { + Fl_Type *node = NULL; + if (cv_source->visible_r()) + node = Fl_Type::find_in_text(0, cv_source->insert_position()); + else if (cv_header->visible_r()) + node = Fl_Type::find_in_text(1, cv_header->insert_position()); + else if (cv_project->visible_r()) + node = Fl_Type::find_in_text(2, cv_project->insert_position()); + if (node) { + select_only(node); + reveal_in_browser(node); + if (Fl::event_clicks()==1) // double click + node->open(); + } + } +} + +Fl_Group *cv_settings_row=(Fl_Group *)0; + +Fl_Light_Button *cv_autorefresh=(Fl_Light_Button *)0; + +Fl_Light_Button *cv_autoposition=(Fl_Light_Button *)0; + +Fl_Choice *cv_code_choice_w=(Fl_Choice *)0; + +static void cb_cv_code_choice_w(Fl_Choice* o, void*) { + cv_code_choice = (int)o->mvalue()->argument(); + update_codeview_position(); +} + +Fl_Menu_Item menu_cv_code_choice_w[] = { + {"prolog", 0, 0, (void*)(0), 16, (uchar)FL_NORMAL_LABEL, 0, 11, 0}, + {"static", 0, 0, (void*)(1), 0, (uchar)FL_NORMAL_LABEL, 0, 11, 0}, + {"code", 0, 0, (void*)(2), 0, (uchar)FL_NORMAL_LABEL, 0, 11, 0}, + {"code 1", 0, 0, (void*)(3), 0, (uchar)FL_NORMAL_LABEL, 0, 11, 0}, + {"code 2", 0, 0, (void*)(4), 0, (uchar)FL_NORMAL_LABEL, 0, 11, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +Fl_Double_Window* make_codeview() { + { codeview_panel = new Fl_Double_Window(520, 515, "Code View"); + codeview_panel->callback((Fl_Callback*)toggle_codeview_cb); + codeview_panel->align(Fl_Align(FL_ALIGN_CLIP|FL_ALIGN_INSIDE)); + { cv_tab = new Fl_Tabs(10, 10, 500, 440); + cv_tab->selection_color((Fl_Color)4); + cv_tab->labelcolor(FL_BACKGROUND2_COLOR); + cv_tab->callback((Fl_Callback*)update_codeview_position_cb); + { cv_source_tab = new Fl_Group(10, 35, 500, 415, "Source"); + cv_source_tab->labelsize(13); + { CodeViewer* o = cv_source = new CodeViewer(10, 40, 500, 410); + cv_source->box(FL_DOWN_FRAME); + cv_source->color(FL_BACKGROUND2_COLOR); + cv_source->selection_color(FL_SELECTION_COLOR); + cv_source->labeltype(FL_NORMAL_LABEL); + cv_source->labelfont(0); + cv_source->labelsize(14); + cv_source->labelcolor(FL_FOREGROUND_COLOR); + cv_source->textfont(4); + cv_source->textsize(11); + cv_source->align(Fl_Align(FL_ALIGN_TOP)); + cv_source->when(FL_WHEN_RELEASE); + Fl_Group::current()->resizable(cv_source); + o->linenumber_width(60); + o->linenumber_size(o->Fl_Text_Display::textsize()); + } // CodeViewer* cv_source + cv_source_tab->end(); + Fl_Group::current()->resizable(cv_source_tab); + } // Fl_Group* cv_source_tab + { Fl_Group* o = new Fl_Group(10, 35, 500, 415, "Header"); + o->labelsize(13); + o->hide(); + { CodeViewer* o = cv_header = new CodeViewer(10, 40, 500, 410); + cv_header->box(FL_DOWN_FRAME); + cv_header->color(FL_BACKGROUND2_COLOR); + cv_header->selection_color(FL_SELECTION_COLOR); + cv_header->labeltype(FL_NORMAL_LABEL); + cv_header->labelfont(0); + cv_header->labelsize(14); + cv_header->labelcolor(FL_FOREGROUND_COLOR); + cv_header->textfont(4); + cv_header->textsize(11); + cv_header->align(Fl_Align(FL_ALIGN_TOP)); + cv_header->when(FL_WHEN_RELEASE); + Fl_Group::current()->resizable(cv_header); + o->linenumber_width(60); + o->linenumber_size(o->Fl_Text_Display::textsize()); + } // CodeViewer* cv_header + o->end(); + } // Fl_Group* o + { Fl_Group* o = new Fl_Group(10, 35, 500, 415, "Strings"); + o->labelsize(13); + o->hide(); + { TextViewer* o = cv_strings = new TextViewer(10, 40, 500, 410); + cv_strings->box(FL_DOWN_FRAME); + cv_strings->color(FL_BACKGROUND2_COLOR); + cv_strings->selection_color(FL_SELECTION_COLOR); + cv_strings->labeltype(FL_NORMAL_LABEL); + cv_strings->labelfont(0); + cv_strings->labelsize(14); + cv_strings->labelcolor(FL_FOREGROUND_COLOR); + cv_strings->textfont(4); + cv_strings->textsize(11); + cv_strings->align(Fl_Align(FL_ALIGN_TOP)); + cv_strings->when(FL_WHEN_RELEASE); + Fl_Group::current()->resizable(cv_strings); + o->linenumber_width(60); + o->linenumber_size(o->Fl_Text_Display::textsize()); + } // TextViewer* cv_strings + o->end(); + } // Fl_Group* o + { Fl_Group* o = new Fl_Group(10, 35, 500, 415, "Project"); + o->labelsize(13); + o->hide(); + { TextViewer* o = cv_project = new TextViewer(10, 40, 500, 410); + cv_project->box(FL_DOWN_FRAME); + cv_project->color(FL_BACKGROUND2_COLOR); + cv_project->selection_color(FL_SELECTION_COLOR); + cv_project->labeltype(FL_NORMAL_LABEL); + cv_project->labelfont(0); + cv_project->labelsize(14); + cv_project->labelcolor(FL_FOREGROUND_COLOR); + cv_project->textfont(4); + cv_project->textsize(11); + cv_project->align(Fl_Align(FL_ALIGN_TOP)); + cv_project->when(FL_WHEN_RELEASE); + Fl_Group::current()->resizable(cv_project); + o->linenumber_width(60); + o->linenumber_size(o->Fl_Text_Display::textsize()); + } // TextViewer* cv_project + o->end(); + } // Fl_Group* o + cv_tab->end(); + Fl_Group::current()->resizable(cv_tab); + } // Fl_Tabs* cv_tab + { cv_find_row = new Fl_Group(10, 460, 500, 20); + { cv_find_text_case = new Fl_Button(244, 460, 25, 20, "aA"); + cv_find_text_case->type(1); + cv_find_text_case->labelsize(11); + } // Fl_Button* cv_find_text_case + { cv_find_text = new Fl_Input(40, 460, 200, 20, "Find:"); + cv_find_text->labelsize(11); + cv_find_text->textsize(11); + cv_find_text->callback((Fl_Callback*)cb_cv_find_text); + cv_find_text->when(FL_WHEN_RELEASE | FL_WHEN_ENTER_KEY_CHANGED); + } // Fl_Input* cv_find_text + { Fl_Button* o = new Fl_Button(273, 460, 25, 20, "<<"); + o->labelsize(11); + o->callback((Fl_Callback*)cb_); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(298, 460, 25, 20, ">>"); + o->labelsize(11); + o->callback((Fl_Callback*)cb_1); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(327, 460, 61, 20, "Reveal"); + o->labelsize(11); + o->callback((Fl_Callback*)cb_Reveal); + } // Fl_Button* o + { Fl_Box* o = new Fl_Box(490, 460, 20, 20); + Fl_Group::current()->resizable(o); + } // Fl_Box* o + cv_find_row->end(); + } // Fl_Group* cv_find_row + { cv_settings_row = new Fl_Group(10, 485, 500, 20); + { Fl_Button* o = new Fl_Button(10, 485, 61, 20, "Refresh"); + o->labelsize(11); + o->callback((Fl_Callback*)update_codeview_cb); + } // Fl_Button* o + { Fl_Light_Button* o = cv_autorefresh = new Fl_Light_Button(77, 485, 91, 20, "Auto-Refresh"); + cv_autorefresh->labelsize(11); + o->callback((Fl_Callback*)update_codeview_cb); + } // Fl_Light_Button* cv_autorefresh + { cv_autoposition = new Fl_Light_Button(172, 485, 89, 20, "Auto-Position"); + cv_autoposition->labelsize(11); + } // Fl_Light_Button* cv_autoposition + { cv_code_choice_w = new Fl_Choice(265, 485, 70, 20); + cv_code_choice_w->down_box(FL_BORDER_BOX); + cv_code_choice_w->labelsize(11); + cv_code_choice_w->textsize(11); + cv_code_choice_w->callback((Fl_Callback*)cb_cv_code_choice_w); + cv_code_choice_w->menu(menu_cv_code_choice_w); + } // Fl_Choice* cv_code_choice_w + { Fl_Box* o = new Fl_Box(375, 485, 80, 20); + Fl_Group::current()->resizable(o); + } // Fl_Box* o + { Fl_Button* o = new Fl_Button(460, 485, 50, 20, "Close"); + o->labelsize(11); + o->callback((Fl_Callback*)toggle_codeview_b_cb); + } // Fl_Button* o + cv_settings_row->end(); + } // Fl_Group* cv_settings_row + codeview_panel->size_range(384, 120); + codeview_panel->end(); + } // Fl_Double_Window* codeview_panel + return codeview_panel; +} + +// diff --git a/fluid/sourceview_panel.fl b/fluid/codeview_panel.fl similarity index 61% rename from fluid/sourceview_panel.fl rename to fluid/codeview_panel.fl index 2159a065a..51ac5f4ab 100644 --- a/fluid/sourceview_panel.fl +++ b/fluid/codeview_panel.fl @@ -26,7 +26,7 @@ decl {\#include "fluid.h"} {private local decl {\#include "file.h"} {private local } -decl {\#include "../src/flstring.h"} {private local +decl {\#include "../src/flstring.h"} {selected private local } decl {\#include } {private local @@ -35,16 +35,16 @@ decl {\#include } {private local decl {\#include } {private local } -decl {char *sv_source_filename = NULL;} {private local +decl {char *cv_source_filename = NULL;} {private local } -decl {char *sv_header_filename = NULL;} {private local +decl {char *cv_header_filename = NULL;} {private local } -decl {char *sv_design_filename = NULL;} {private local +decl {char *cv_design_filename = NULL;} {private local } -decl {int sv_code_choice;} {public local +decl {int cv_code_choice;} {public local } decl {extern void select_only(Fl_Type *o);} {private global @@ -53,23 +53,23 @@ decl {extern void select_only(Fl_Type *o);} {private global decl {extern void reveal_in_browser(Fl_Type *t);} {private global } -Function {update_sourceview_position()} { +Function {update_codeview_position()} { comment {Update the header and source code highlighting depending on the currently selected object -The Source View system offers an immediate preview of the code +The Code View system offers an immediate preview of the code files that will be generated by FLUID. It also marks the code generated for the last selected item in the header and the source file.} open return_type void } { - code {if (!sourceview_panel || !sourceview_panel->visible()) + code {if (!codeview_panel || !codeview_panel->visible()) return; - if (sv_autoposition->value()==0) + if (cv_autoposition->value()==0) return; - if (sourceview_panel && sourceview_panel->visible() && Fl_Type::current) { + if (codeview_panel && codeview_panel->visible() && Fl_Type::current) { int pos0 = 0, pos1 = 0; - if (sv_source->visible_r()) { - switch (sv_code_choice) { + if (cv_source->visible_r()) { + switch (cv_code_choice) { case 0: // prolog: not yet (include statements) pos0 = Fl_Type::current->code1_start; pos1 = Fl_Type::current->code2_end; @@ -93,14 +93,14 @@ file.} open return_type void } if (pos0>=0) { if (pos1buffer()->line_end(pos0); - sv_source->buffer()->highlight(pos0, pos1); - int line = sv_source->buffer()->count_lines(0, pos0); - sv_source->scroll(line, 0); + pos1 = cv_source->buffer()->line_end(pos0); + cv_source->buffer()->highlight(pos0, pos1); + int line = cv_source->buffer()->count_lines(0, pos0); + cv_source->scroll(line, 0); } } - if (sv_header->visible_r()) { - switch (sv_code_choice) { + if (cv_header->visible_r()) { + switch (cv_code_choice) { case 0: // prolog: not yet (include statements) case 1: // static: callbacks, menu declarations pos0 = Fl_Type::current->header_static_start; @@ -121,14 +121,14 @@ file.} open return_type void } if (pos0>=0) { if (pos1buffer()->line_end(pos0); - sv_header->buffer()->highlight(pos0, pos1); - int line = sv_header->buffer()->count_lines(0, pos0); - sv_header->scroll(line, 0); + pos1 = cv_header->buffer()->line_end(pos0); + cv_header->buffer()->highlight(pos0, pos1); + int line = cv_header->buffer()->count_lines(0, pos0); + cv_header->scroll(line, 0); } } - if (sv_project->visible_r()) { - switch (sv_code_choice) { + if (cv_project->visible_r()) { + switch (cv_code_choice) { case 0: // prolog: not yet (include statements) case 1: // static: callbacks, menu declarations case 2: // code: entire implementation block including children @@ -146,83 +146,83 @@ file.} open return_type void } if (pos0>=0) { if (pos1buffer()->line_end(pos0); - sv_project->buffer()->highlight(pos0, pos1); - int line = sv_project->buffer()->count_lines(0, pos0); - sv_project->scroll(line, 0); + pos1 = cv_project->buffer()->line_end(pos0); + cv_project->buffer()->highlight(pos0, pos1); + int line = cv_project->buffer()->count_lines(0, pos0); + cv_project->scroll(line, 0); } } }} {} } -Function {update_sourceview_position_cb(class Fl_Tabs*, void*)} { - comment {Callback to update the sourceview position.} open return_type void +Function {update_codeview_position_cb(class Fl_Tabs*, void*)} { + comment {Callback to update the codeview position.} open return_type void } { code {// make sure that the selected tab shows the current view - update_sourceview_cb(0,0); + update_codeview_cb(0,0); // highlight the selected widget in the selected tab - update_sourceview_position();} {} + update_codeview_position();} {} } -Function {update_sourceview_cb(class Fl_Button*, void*)} { +Function {update_codeview_cb(class Fl_Button*, void*)} { comment {Generate a header, source, strings, or design file in a temporary directory and load those into the Code Viewer widgets.} open return_type void } { - code {if (!sourceview_panel || !sourceview_panel->visible()) + code {if (!codeview_panel || !codeview_panel->visible()) return; - if (!sv_source_filename) { - sv_source_filename = (char*)malloc(FL_PATH_MAX); - fl_strlcpy(sv_source_filename, get_tmpdir().c_str(), FL_PATH_MAX); - fl_strlcat(sv_source_filename, "source_view_tmp.cxx", FL_PATH_MAX); + if (!cv_source_filename) { + cv_source_filename = (char*)malloc(FL_PATH_MAX); + fl_strlcpy(cv_source_filename, get_tmpdir().c_str(), FL_PATH_MAX); + fl_strlcat(cv_source_filename, "codeview_tmp.cxx", FL_PATH_MAX); } - if (!sv_header_filename) { - sv_header_filename = (char*)malloc(FL_PATH_MAX); - fl_strlcpy(sv_header_filename, get_tmpdir().c_str(), FL_PATH_MAX); - fl_strlcat(sv_header_filename, "source_view_tmp.h", FL_PATH_MAX); + if (!cv_header_filename) { + cv_header_filename = (char*)malloc(FL_PATH_MAX); + fl_strlcpy(cv_header_filename, get_tmpdir().c_str(), FL_PATH_MAX); + fl_strlcat(cv_header_filename, "codeview_tmp.h", FL_PATH_MAX); } - if (!sv_design_filename) { - sv_design_filename = (char*)malloc(FL_PATH_MAX); - fl_strlcpy(sv_design_filename, get_tmpdir().c_str(), FL_PATH_MAX); - fl_strlcat(sv_design_filename, "source_view_tmp.fl", FL_PATH_MAX); + if (!cv_design_filename) { + cv_design_filename = (char*)malloc(FL_PATH_MAX); + fl_strlcpy(cv_design_filename, get_tmpdir().c_str(), FL_PATH_MAX); + fl_strlcat(cv_design_filename, "codeview_tmp.fl", FL_PATH_MAX); } - if (sv_project->visible_r()) { - write_file(sv_design_filename, false, true); - int top = sv_project->top_line(); - sv_project->buffer()->loadfile(sv_design_filename); - sv_project->scroll(top, 0); - } else if (sv_strings->visible_r()) { + if (cv_project->visible_r()) { + write_file(cv_design_filename, false, true); + int top = cv_project->top_line(); + cv_project->buffer()->loadfile(cv_design_filename); + cv_project->scroll(top, 0); + } else if (cv_strings->visible_r()) { static const char *exts[] = { ".txt", ".po", ".msg" }; char fn[FL_PATH_MAX+1]; fl_strlcpy(fn, get_tmpdir().c_str(), FL_PATH_MAX); fl_strlcat(fn, "strings", FL_PATH_MAX); fl_filename_setext(fn, FL_PATH_MAX, exts[g_project.i18n_type]); write_strings(fn); - int top = sv_strings->top_line(); - sv_strings->buffer()->loadfile(fn); - sv_strings->scroll(top, 0); - } else if (sv_source->visible_r() || sv_header->visible_r()) { + int top = cv_strings->top_line(); + cv_strings->buffer()->loadfile(fn); + cv_strings->scroll(top, 0); + } else if (cv_source->visible_r() || cv_header->visible_r()) { Fl_String code_file_name_bak = g_project.code_file_name; - g_project.code_file_name = sv_source_filename; + g_project.code_file_name = cv_source_filename; Fl_String header_file_name_bak = g_project.header_file_name; - g_project.header_file_name = sv_header_filename; + g_project.header_file_name = cv_header_filename; // generate the code and load the files Fd_Code_Writer f; // generate files - if (f.write_code(sv_source_filename, sv_header_filename, true)) + if (f.write_code(cv_source_filename, cv_header_filename, true)) { // load file into source editor - int pos = sv_source->top_line(); - sv_source->buffer()->loadfile(sv_source_filename); - sv_source->scroll(pos, 0); + int pos = cv_source->top_line(); + cv_source->buffer()->loadfile(cv_source_filename); + cv_source->scroll(pos, 0); // load file into header editor - pos = sv_header->top_line(); - sv_header->buffer()->loadfile(sv_header_filename); - sv_header->scroll(pos, 0); + pos = cv_header->top_line(); + cv_header->buffer()->loadfile(cv_header_filename); + cv_header->scroll(pos, 0); // update the source code highlighting - update_sourceview_position(); + update_codeview_position(); } g_project.code_file_name = code_file_name_bak; @@ -230,71 +230,71 @@ and load those into the Code Viewer widgets.} open return_type void }} {} } -Function {update_sourceview_timer(void*)} { +Function {update_codeview_timer(void*)} { comment {This is called by the timer itself } open return_type void } { - code {update_sourceview_cb(0,0);} {} + code {update_codeview_cb(0,0);} {} } -Function {sourceview_defer_update()} {open return_type void +Function {codeview_defer_update()} {open return_type void } { code {// we will only update earliest 0.5 seconds after the last change, and only // if no other change was made, so dragging a widget will not generate any // CPU load - Fl::remove_timeout(update_sourceview_timer, 0); - Fl::add_timeout(0.5, update_sourceview_timer, 0);} {} + Fl::remove_timeout(update_codeview_timer, 0); + Fl::add_timeout(0.5, update_codeview_timer, 0);} {} } -Function {sourceview_toggle_visibility()} { +Function {codeview_toggle_visibility()} { comment {Show or hide the source code preview. The state is stored in the app preferences. } open return_type void } { - code {if (!sourceview_panel) { - make_sourceview(); - sourceview_panel->callback((Fl_Callback*)toggle_sourceview_cb); - Fl_Preferences svp(fluid_prefs, "sourceview"); + code {if (!codeview_panel) { + make_codeview(); + codeview_panel->callback((Fl_Callback*)toggle_codeview_cb); + Fl_Preferences svp(fluid_prefs, "codeview"); int autorefresh; svp.get("autorefresh", autorefresh, 1); - sv_autorefresh->value(autorefresh); + cv_autorefresh->value(autorefresh); int autoposition; svp.get("autoposition", autoposition, 1); - sv_autoposition->value(autoposition); + cv_autoposition->value(autoposition); int tab; svp.get("tab", tab, 0); - if (tab>=0 && tabchildren()) sv_tab->value(sv_tab->child(tab)); - svp.get("code_choice", sv_code_choice, 2); - sv_code_choice_w->value(sv_code_choice_w->find_item_with_argument(sv_code_choice)); - if (!position_window(sourceview_panel,"sourceview_pos", 0, 320, 120, 550, 500)) return; + if (tab>=0 && tabchildren()) cv_tab->value(cv_tab->child(tab)); + svp.get("code_choice", cv_code_choice, 2); + cv_code_choice_w->value(cv_code_choice_w->find_item_with_argument(cv_code_choice)); + if (!position_window(codeview_panel,"codeview_pos", 0, 320, 120, 550, 500)) return; } - if (sourceview_panel->visible()) { - sourceview_panel->hide(); - sourceview_item->label("Show Source Code..."); + if (codeview_panel->visible()) { + codeview_panel->hide(); + codeview_item->label("Show Code View"); } else { - sourceview_panel->show(); - sourceview_item->label("Hide Source Code..."); - update_sourceview_cb(0,0); + codeview_panel->show(); + codeview_item->label("Hide Code View"); + update_codeview_cb(0,0); }} {} } -Function {make_sourceview()} {open +Function {make_codeview()} {open } { - Fl_Window sourceview_panel { + Fl_Window codeview_panel { label {Code View} - callback toggle_sourceview_cb open + callback toggle_codeview_cb open xywh {389 507 520 515} type Double align 80 resizable size_range {384 120 0 0} visible } { - Fl_Tabs sv_tab { - callback update_sourceview_position_cb open + Fl_Tabs cv_tab { + callback update_codeview_position_cb open xywh {10 10 500 440} selection_color 4 labelcolor 7 resizable } { - Fl_Group {} { + Fl_Group cv_source_tab { label Source open xywh {10 35 500 415} labelsize 13 resizable } { - Fl_Text_Editor sv_source { + Fl_Text_Editor cv_source { xywh {10 40 500 410} textfont 4 textsize 11 resizable code0 {\#include "CodeEditor.h"} code1 {o->linenumber_width(60);} @@ -306,7 +306,7 @@ Function {make_sourceview()} {open label Header open xywh {10 35 500 415} labelsize 13 hide } { - Fl_Text_Editor sv_header { + Fl_Text_Editor cv_header { xywh {10 40 500 410} textfont 4 textsize 11 resizable code0 {\#include "CodeEditor.h"} code1 {o->linenumber_width(60);} @@ -318,7 +318,7 @@ Function {make_sourceview()} {open label Strings open xywh {10 35 500 415} labelsize 13 hide } { - Fl_Text_Display sv_strings { + Fl_Text_Display cv_strings { xywh {10 40 500 410} textfont 4 textsize 11 resizable code1 {o->linenumber_width(60);} code2 {o->linenumber_size(o->Fl_Text_Display::textsize());} @@ -329,7 +329,7 @@ Function {make_sourceview()} {open label Project open xywh {10 35 500 415} labelsize 13 hide } { - Fl_Text_Display sv_project { + Fl_Text_Display cv_project { xywh {10 40 500 410} textfont 4 textsize 11 resizable code1 {o->linenumber_width(60);} code2 {o->linenumber_size(o->Fl_Text_Display::textsize());} @@ -337,27 +337,27 @@ Function {make_sourceview()} {open } } } - Fl_Group {} {open + Fl_Group cv_find_row {open xywh {10 460 500 20} } { - Fl_Button sv_find_text_case { + Fl_Button cv_find_text_case { label aA xywh {244 460 25 20} type Toggle labelsize 11 } - Fl_Input sv_find_text { + Fl_Input cv_find_text { label {Find:} callback {Fl_Text_Display *e = NULL; -if (sv_source->visible_r()) { - e = sv_source; -} else if (sv_header->visible_r()) { - e = sv_header; -} else if (sv_project->visible_r()) { - e = sv_project; +if (cv_source->visible_r()) { + e = cv_source; +} else if (cv_header->visible_r()) { + e = cv_header; +} else if (cv_project->visible_r()) { + e = cv_project; } if (e) { Fl_Text_Buffer *b = e->buffer(); int pos = e->insert_position(); - int found = b->search_forward(pos, o->value(), &pos, sv_find_text_case->value()); + int found = b->search_forward(pos, o->value(), &pos, cv_find_text_case->value()); if (found) { b->select(pos, pos + (int)strlen(o->value())); e->insert_position(pos); @@ -369,47 +369,47 @@ if (e) { Fl_Button {} { label {<<} callback {Fl_Text_Display *e = NULL; -if (sv_source->visible_r()) { - e = sv_source; -} else if (sv_header->visible_r()) { - e = sv_header; -} else if (sv_project->visible_r()) { - e = sv_project; +if (cv_source->visible_r()) { + e = cv_source; +} else if (cv_header->visible_r()) { + e = cv_header; +} else if (cv_project->visible_r()) { + e = cv_project; } if (e) { - const char *needle = sv_find_text->value(); + const char *needle = cv_find_text->value(); Fl_Text_Buffer *b = e->buffer(); int pos = e->insert_position()-1; if (pos < 0) pos = b->length()-1; - int found = b->search_backward(pos, needle, &pos, sv_find_text_case->value()); + int found = b->search_backward(pos, needle, &pos, cv_find_text_case->value()); if (!found) - found = b->search_backward(b->length()-1, needle, &pos, sv_find_text_case->value()); + found = b->search_backward(b->length()-1, needle, &pos, cv_find_text_case->value()); if (found) { b->select(pos, pos + (int)strlen(needle)); e->insert_position(pos); e->show_insert_position(); } -}} selected +}} xywh {273 460 25 20} labelsize 11 } Fl_Button {} { label {>>} callback {Fl_Text_Display *e = NULL; -if (sv_source->visible_r()) { - e = sv_source; -} else if (sv_header->visible_r()) { - e = sv_header; -} else if (sv_project->visible_r()) { - e = sv_project; +if (cv_source->visible_r()) { + e = cv_source; +} else if (cv_header->visible_r()) { + e = cv_header; +} else if (cv_project->visible_r()) { + e = cv_project; } if (e) { - const char *needle = sv_find_text->value(); + const char *needle = cv_find_text->value(); Fl_Text_Buffer *b = e->buffer(); int pos = e->insert_position() + 1; if (pos+1 >= b->length()) pos = 0; - int found = b->search_forward(pos, needle, &pos, sv_find_text_case->value()); + int found = b->search_forward(pos, needle, &pos, cv_find_text_case->value()); if (!found && (pos > 0)) - found = b->search_forward(0, needle, &pos, sv_find_text_case->value()); + found = b->search_forward(0, needle, &pos, cv_find_text_case->value()); if (found) { b->select(pos, pos + (int)strlen(needle)); e->insert_position(pos); @@ -420,14 +420,14 @@ if (e) { } Fl_Button {} { label Reveal - callback {if (sourceview_panel && sourceview_panel->visible()) { + callback {if (codeview_panel && codeview_panel->visible()) { Fl_Type *node = NULL; - if (sv_source->visible_r()) - node = Fl_Type::find_in_text(0, sv_source->insert_position()); - else if (sv_header->visible_r()) - node = Fl_Type::find_in_text(1, sv_header->insert_position()); - else if (sv_project->visible_r()) - node = Fl_Type::find_in_text(2, sv_project->insert_position()); + if (cv_source->visible_r()) + node = Fl_Type::find_in_text(0, cv_source->insert_position()); + else if (cv_header->visible_r()) + node = Fl_Type::find_in_text(1, cv_header->insert_position()); + else if (cv_project->visible_r()) + node = Fl_Type::find_in_text(2, cv_project->insert_position()); if (node) { select_only(node); reveal_in_browser(node); @@ -441,26 +441,26 @@ if (e) { xywh {490 460 20 20} resizable } } - Fl_Group {} {open + Fl_Group cv_settings_row {open xywh {10 485 500 20} } { Fl_Button {} { label Refresh - callback update_sourceview_cb + callback update_codeview_cb xywh {10 485 61 20} labelsize 11 } - Fl_Light_Button sv_autorefresh { + Fl_Light_Button cv_autorefresh { label {Auto-Refresh} xywh {77 485 91 20} labelsize 11 - code0 {o->callback((Fl_Callback*)update_sourceview_cb);} + code0 {o->callback((Fl_Callback*)update_codeview_cb);} } - Fl_Light_Button sv_autoposition { + Fl_Light_Button cv_autoposition { label {Auto-Position} xywh {172 485 89 20} labelsize 11 } - Fl_Choice sv_code_choice_w { - callback {sv_code_choice = (int)o->mvalue()->argument(); -update_sourceview_position();} open + Fl_Choice cv_code_choice_w { + callback {cv_code_choice = (int)o->mvalue()->argument(); +update_codeview_position();} open xywh {265 485 70 20} down_box BORDER_BOX labelsize 11 textsize 11 } { MenuItem {} { @@ -494,7 +494,7 @@ update_sourceview_position();} open } Fl_Button {} { label Close - callback toggle_sourceview_b_cb + callback toggle_codeview_b_cb xywh {460 485 50 20} labelsize 11 } } diff --git a/fluid/codeview_panel.h b/fluid/codeview_panel.h new file mode 100644 index 000000000..8fa566346 --- /dev/null +++ b/fluid/codeview_panel.h @@ -0,0 +1,58 @@ +// +// Code dialogs 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 +// + +// generated by Fast Light User Interface Designer (fluid) version 1.0400 + +#ifndef codeview_panel_h +#define codeview_panel_h +#include +extern int cv_code_choice; +void update_codeview_position(); +void update_codeview_position_cb(class Fl_Tabs*, void*); +void update_codeview_cb(class Fl_Button*, void*); +void update_codeview_timer(void*); +void codeview_defer_update(); +void codeview_toggle_visibility(); +#include +extern void toggle_codeview_cb(Fl_Double_Window*, void*); +extern Fl_Double_Window *codeview_panel; +#include +extern Fl_Tabs *cv_tab; +#include +extern Fl_Group *cv_source_tab; +#include "CodeEditor.h" +extern CodeViewer *cv_source; +extern CodeViewer *cv_header; +extern TextViewer *cv_strings; +extern TextViewer *cv_project; +extern Fl_Group *cv_find_row; +#include +extern Fl_Button *cv_find_text_case; +#include +extern Fl_Input *cv_find_text; +#include +extern Fl_Group *cv_settings_row; +#include +extern Fl_Light_Button *cv_autorefresh; +extern Fl_Light_Button *cv_autoposition; +#include +extern Fl_Choice *cv_code_choice_w; +extern void toggle_codeview_b_cb(Fl_Button*, void*); +Fl_Double_Window* make_codeview(); +extern Fl_Menu_Item menu_cv_code_choice_w[]; +#endif + +// diff --git a/fluid/custom_widgets.cxx b/fluid/custom_widgets.cxx index 99cfbbbdf..887e2ba14 100644 --- a/fluid/custom_widgets.cxx +++ b/fluid/custom_widgets.cxx @@ -55,7 +55,7 @@ int Widget_Bin_Button::handle(int inEvent) // fake a drag outside of the widget Fl::e_x = x()-1; Fl_Button::handle(inEvent); - // fake a buttton release + // fake a button release Fl_Button::handle(FL_RELEASE); // make it into a dnd event const char *type_name = (const char*)user_data(); diff --git a/fluid/documentation/CMakeLists.txt b/fluid/documentation/CMakeLists.txt new file mode 100644 index 000000000..fb2fac442 --- /dev/null +++ b/fluid/documentation/CMakeLists.txt @@ -0,0 +1,232 @@ +# +# CMakeLists.txt to build docs for the FLTK project using CMake (www.cmake.org) +# +# Copyright 1998-2024 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 +# + +set(DOCS) +set(GIT_REVISION "") +set(YEAR "") +set(CURRENT_DATE "") + +#------------------------------------------------ +# generate files used for both HTML and PDF docs +#------------------------------------------------ + +if(FLTK_BUILD_FLUID_DOCS OR FLTK_BUILD_PDF_DOCS) + + # create required variables + + execute_process(COMMAND date "+%Y" + OUTPUT_VARIABLE YEAR + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + # note: current locale is used for abbreviated month + execute_process(COMMAND date "+%b %d, %Y" + OUTPUT_VARIABLE CURRENT_DATE + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + # find git revision + + # FIXME: This must also work with tarballs where git is not available. + # For now we just ignore errors and set GIT_REVISION = "unknown". + # In the future tarball/zip generation should create a file + # that contains the git revision. + + execute_process(COMMAND + git rev-parse --short=10 HEAD + OUTPUT_VARIABLE GIT_REVISION + OUTPUT_STRIP_TRAILING_WHITESPACE + WORKING_DIRECTORY ${FLTK_SOURCE_DIR} + ERROR_QUIET + ) + + # set to "'unknown'" if git is not available + if(GIT_REVISION STREQUAL "") + set(GIT_REVISION "'unknown'") + endif() + + # Find "short" doxygen version if it was built from Git + # Note: this is still needed in CMake 3.12.0 but later CMake versions + # (notably 3.25) remove the Git revision in 'DOXYGEN_VERSION'. + # Todo: Find the "first good" CMake version and remove this redundant + # code once we require this as our minimal version and replace the + # variable DOXYGEN_VERSION_SHORT with DOXYGEN_VERSION below. + + if(DOXYGEN_FOUND) + # strip trailing git revision if doxygen was built from source + string(REGEX REPLACE " .*$" "" DOXYGEN_VERSION_SHORT ${DOXYGEN_VERSION}) + endif(DOXYGEN_FOUND) + + # configure copyright.dox (includes current year) + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/copyright.dox.in + ${CMAKE_CURRENT_BINARY_DIR}/copyright.dox + @ONLY + ) + + # configure generated.dox (includes date and versions) + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/generated.dox.in + ${CMAKE_CURRENT_BINARY_DIR}/generated.dox + @ONLY + ) + +endif(FLTK_BUILD_FLUID_DOCS OR FLTK_BUILD_PDF_DOCS) + +#------------------------------- +# build FLUID html documentation +#------------------------------- + +if(FLTK_BUILD_FLUID_DOCS) + + #list(APPEND DOCS html) + + # generate Doxygen file "Doxyfile" + + set(GENERATE_FLUID_HTML YES) + set(GENERATE_LATEX NO) + set(LATEX_HEADER "") + set(FL_HTML_INDEX "FL_HTML_INDEX") + set(DOXYFILE "Doxyfile") + set(LOGFILE "${CMAKE_CURRENT_BINARY_DIR}/${DOXYFILE}_error.log") + + # configure Doxygen input file for HTML docs (Doxyfile.in) + + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in + ${CMAKE_CURRENT_BINARY_DIR}/${DOXYFILE}.in + @ONLY + ) + + # convert Doxyfile to used doxygen version + + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${DOXYFILE} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/convert_doxyfile + ${DOXYGEN_EXECUTABLE} + ${DOXYFILE}.in + ${DOXYFILE} + ${LOGFILE} + BYPRODUCTS ${LOGFILE} + COMMENT "Converting ${DOXYFILE} to doxygen version ${DOXYGEN_VERSION_SHORT}" VERBATIM + ) + + # generate screen shot using FLUID --autodoc target_dir + # generate HTML documentation + + add_custom_target(fluid_docs + COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/src/ + COMMAND fltk::fluid -scheme gtk+ --autodoc ${CMAKE_CURRENT_BINARY_DIR}/src/ + COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYFILE} + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${DOXYFILE} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Generating HTML documentation" VERBATIM + ) + add_dependencies(fluid_docs fltk::fluid) + +endif(FLTK_BUILD_FLUID_DOCS) + +#-------------------------- +# build pdf documentation +#-------------------------- + +if(FLTK_BUILD_PDF_DOCS AND FLTK_BUILD_FLUID_DOCS) + + # generate Doxygen input file "Doxybook" + + set(GENERATE_FLUID_HTML NO) + set(GENERATE_LATEX YES) + set(LATEX_HEADER "${CMAKE_CURRENT_BINARY_DIR}/fluid-book.tex") + set(FL_HTML_INDEX "FL_NO_HTML_INDEX") + set(DOXYFILE "Doxybook") + set(LOGFILE "${CMAKE_CURRENT_BINARY_DIR}/${DOXYFILE}_error.log") + + # configure Doxygen input file for PDF docs (Doxybook.in) + + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in + ${CMAKE_CURRENT_BINARY_DIR}/${DOXYFILE}.in + @ONLY + ) + + # convert Doxybook to current doxygen version + + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${DOXYFILE} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/convert_doxyfile + ${DOXYGEN_EXECUTABLE} + ${DOXYFILE}.in + ${DOXYFILE} + ${LOGFILE} + BYPRODUCTS ${LOGFILE} + COMMENT "Converting ${DOXYFILE} to doxygen version ${DOXYGEN_VERSION_SHORT}" VERBATIM + ) + + # generate LaTeX title fluid-title.tex + + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/src/fluid-title.tex.in + ${CMAKE_CURRENT_BINARY_DIR}/fluid-title.tex + @ONLY + ) + + # generate fluid.pdf + + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/fluid.pdf + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/make_header + ${DOXYGEN_EXECUTABLE} + ${CMAKE_CURRENT_BINARY_DIR}/fluid-title.tex + ${CMAKE_CURRENT_BINARY_DIR}/fluid-book.tex + COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYFILE} + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/make_pdf + COMMAND cp -f latex/refman.pdf fluid.pdf + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${DOXYFILE} + ${CMAKE_CURRENT_BINARY_DIR}/fluid-title.tex + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Generating FLUID PDF documentation" VERBATIM + ) + + # add target 'pdf' + + add_custom_target(fluid_pdf + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/fluid.pdf + ) + add_dependencies(fluid_pdf fluid_docs) + +endif(FLTK_BUILD_PDF_DOCS AND FLTK_BUILD_FLUID_DOCS) + +#--------------------------------------- +# install FLUID html + pdf documentation +#--------------------------------------- + +if(FLTK_INSTALL_FLUID_DOCS AND FLTK_BUILD_FLUID_DOCS) + + install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html + DESTINATION ${FLTK_DATADIR}/doc/fltk/fluid + ) + +endif(FLTK_INSTALL_FLUID_DOCS AND FLTK_BUILD_FLUID_DOCS) + +if(FLTK_INSTALL_PDF_DOCS AND FLTK_BUILD_PDF_DOCS AND FLTK_BUILD_FLUID_DOCS) + + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/fluid.pdf + DESTINATION ${FLTK_DATADIR}/doc/fltk/ + ) + +endif(FLTK_INSTALL_PDF_DOCS AND FLTK_BUILD_PDF_DOCS AND FLTK_BUILD_FLUID_DOCS) diff --git a/fluid/documentation/Doxyfile.in b/fluid/documentation/Doxyfile.in new file mode 100644 index 000000000..f625dd52a --- /dev/null +++ b/fluid/documentation/Doxyfile.in @@ -0,0 +1,2485 @@ +# Doxyfile 1.8.14 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all text +# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv +# built into libc) for the transcoding. See +# https://www.gnu.org/software/libiconv/ for the list of possible encodings. +# The default value is: UTF-8. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + +PROJECT_NAME = "FLUID for FLTK @FLTK_VERSION@" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + +PROJECT_NUMBER = + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. + +OUTPUT_DIRECTORY = . + +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- +# directories (in 2 levels) under the output directory of each output format and +# will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. +# The default value is: NO. + +CREATE_SUBDIRS = NO + +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, +# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), +# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, +# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, +# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, +# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, +# Ukrainian and Vietnamese. +# The default value is: English. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. +# The default value is: YES. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# doxygen will generate a detailed section even if there is only a brief +# description. +# The default value is: NO. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. +# The default value is: NO. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. + +FULL_PATH_NAMES = NO + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. + +JAVADOC_AUTOBRIEF = YES + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new +# page for each member. If set to NO, the documentation of a member will be part +# of the file/class/namespace that contains it. +# The default value is: NO. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:\n" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". You can put \n's in the value part of an alias to insert +# newlines (in the resulting output). You can put ^^ in the value part of an +# alias to insert a newline as if a physical newline was in the original file. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding "class=itcl::class" +# will allow you to use the command class in the itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, Javascript, +# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: +# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: +# Fortran. In the later case the parser tries to guess whether the code is fixed +# or free formatted code, this is the default for Fortran type files), VHDL. For +# instance to make doxygen treat .inc files as Fortran files (default is PHP), +# and .f files as C (default is Fortran), use: inc=Fortran f=C. +# +# Note: For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up +# to that level are automatically included in the table of contents, even if +# they do not have an id attribute. +# Note: This feature currently applies only to Markdown headings. +# Minimum value: 0, maximum value: 99, default value: 0. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +TOC_INCLUDE_HEADINGS = 0 + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + +DISTRIBUTE_GROUP_DOC = NO + +# If one adds a struct or class to a group and this option is enabled, then also +# any nested class or struct is added to the same group. By default this option +# is disabled and one has to add nested compounds explicitly via \ingroup. +# The default value is: NO. + +GROUP_NESTED_COMPOUNDS = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be +# included in the documentation. +# The default value is: NO. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + +EXTRACT_LOCAL_CLASSES = NO + +# This flag is only useful for Objective-C code. If set to YES, local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO, only methods in the interface are +# included. +# The default value is: NO. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO, these classes will be included in the various overviews. This option +# has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# (class|struct|union) declarations. If set to NO, these declarations will be +# included in the documentation. +# The default value is: NO. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO, these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file +# names in lower-case letters. If set to YES, upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. +# The default value is: system dependent. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES, the +# scope will be hidden. +# The default value is: NO. + +HIDE_SCOPE_NAMES = NO + +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +HIDE_COMPOUND_REFERENCE= NO + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + +SHOW_INCLUDE_FILES = YES + +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. +# The default value is: YES. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. + +SORT_BRIEF_DOCS = YES + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. +# The default value is: YES. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. +# The default value is: YES. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if ... \endif and \cond +# ... \endcond blocks. + +ENABLED_SECTIONS = @FL_HTML_INDEX@ + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES, the +# list will mention the files that were used to generate the documentation. +# The default value is: YES. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. See also \cite for info how to create references. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = YES + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + +WARNINGS = YES + +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = NO + +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some parameters +# in a documented function, or documenting parameters that don't exist or using +# markup commands wrongly. +# The default value is: YES. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO, doxygen will only warn about wrong or incomplete +# parameter documentation, but not about the absence of documentation. +# The default value is: NO. + +WARN_NO_PARAMDOC = NO + +# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when +# a warning is encountered. +# The default value is: NO. + +WARN_AS_ERROR = NO + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# The default value is: $file:$line: $text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING +# Note: If this tag is empty the current directory is searched. + +INPUT = @CMAKE_CURRENT_SOURCE_DIR@/src/index.dox \ + @CMAKE_CURRENT_SOURCE_DIR@/src/page_introduction.dox \ + @CMAKE_CURRENT_SOURCE_DIR@/src/page_commandline.dox \ + @CMAKE_CURRENT_SOURCE_DIR@/src/page_interactive.dox \ + @CMAKE_CURRENT_SOURCE_DIR@/src/page_main_window.dox \ + @CMAKE_CURRENT_SOURCE_DIR@/src/page_widgetbin_panel.dox \ + @CMAKE_CURRENT_SOURCE_DIR@/src/page_edit_window.dox \ + @CMAKE_CURRENT_SOURCE_DIR@/src/page_functional_nodes.dox \ + @CMAKE_CURRENT_SOURCE_DIR@/src/page_widget_panel.dox \ + @CMAKE_CURRENT_SOURCE_DIR@/src/page_setting_dialog.dox \ + @CMAKE_CURRENT_SOURCE_DIR@/src/page_codeview_panel.dox \ + @CMAKE_CURRENT_SOURCE_DIR@/src/page_tutorial.dox \ + @CMAKE_CURRENT_SOURCE_DIR@/src/page_appendices.dox + +# @FLTK_SOURCE_DIR@/fluid + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: https://www.gnu.org/software/libiconv/) for the list of +# possible encodings. +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# read by doxygen. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, +# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, +# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, +# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, +# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf. + +FILE_PATTERNS = *.H \ + *.h \ + *.c \ + *.cxx \ + *.dox + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = +# @FLTK_SOURCE_DIR@/src/drivers/ + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = +# */src/*_win32.cxx \ +# */src/*_mac.cxx \ +# */src/*_x.cxx \ +# */src/xdg* \ +# */src/text-input* + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories use the pattern */test/* + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +EXAMPLE_PATH = +# @CMAKE_CURRENT_SOURCE_DIR@/../test \ +# @CMAKE_CURRENT_SOURCE_DIR@/../examples \ +# @CMAKE_CURRENT_BINARY_DIR@ \ +# @CMAKE_CURRENT_SOURCE_DIR@ + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = *.cxx \ + *.h \ + *.H \ + *.fl + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = @CMAKE_CURRENT_SOURCE_DIR@/src \ + @CMAKE_CURRENT_BINARY_DIR@/src + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# +# +# where is the value of the INPUT_FILTER tag, and is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# function all documented functions referencing it will be listed. +# The default value is: NO. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + +REFERENCES_LINK_SOURCE = YES + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see https://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the config file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + +ALPHABETICAL_INDEX = YES + +# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in +# which the alphabetical index list will be split. +# Minimum value: 1, maximum value: 20, default value: 5. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all classes will +# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag +# can be used to specify a prefix (or a list of prefixes) that should be ignored +# while generating the index headers. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +IGNORE_PREFIX = +# fl_ \ +# FL_ \ +# Fl_ + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = @GENERATE_FLUID_HTML@ + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). For an example see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE tag can be used to specify if the generated HTML output +# should be rendered with a dark or light theme. +# Possible values are: LIGHT always generate light mode output, DARK always +# generate dark mode output, AUTO_LIGHT automatically set the mode according to +# the user preference, use light mode if no preference is set (the default), +# AUTO_DARK automatically set the mode according to the user preference, use +# dark mode if no preference is set and TOGGLE allow to user to switch between +# light and dark mode via a button. +# The default value is: AUTO_LIGHT. +# This tag requires that the tag GENERATE_HTML is set to YES. + +# Note: since doxygen 1.9.5 + +HTML_COLORSTYLE = TOGGLE + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the style sheet and background images according to +# this color. Hue is specified as an angle on a colorwheel, see +# https://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use grayscales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting this +# to YES can help to show when doxygen was last run and thus if the +# documentation is up to date. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_TIMESTAMP = NO + +# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML +# documentation will contain a main index with vertical navigation menus that +# are dynamically created via Javascript. If disabled, the navigation index will +# consists of multiple levels of tabs that are statically embedded in every HTML +# page. Disable this option to support browsers that do not have Javascript, +# like the Qt help browser. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_MENUS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: https://developer.apple.com/tools/xcode/), introduced with +# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a +# Makefile in the HTML output directory. Running make will produce the docset in +# that directory and running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See https://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_DOCSET = YES + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on +# Windows. +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_FILE = + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler (hhc.exe). If non-empty, +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the master .chm file (NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: http://doc.qt.io/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: http://doc.qt.io/qt-4.8/qthelpproject.html#virtual-folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://doc.qt.io/qt-4.8/qthelpproject.html#custom-filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://doc.qt.io/qt-4.8/qthelpproject.html#custom-filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# http://doc.qt.io/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location of Qt's +# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the +# generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can +# further fine-tune the look of the index. As an example, the default style +# sheet generated by doxygen has an example that shows how to put an image at +# the root of the tree instead of the PROJECT_NAME. Since the tree basically has +# the same information as the tab index, you could consider setting +# DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_TREEVIEW = YES + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + +TREEVIEW_WIDTH = 250 + +# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANSPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are not +# supported properly for IE 6.0, but are supported on all modern browsers. +# +# Note that when changing this option you need to delete any form_*.png files in +# the HTML output directory before the changes have effect. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# https://www.mathjax.org) which uses client side Javascript for the rendering +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. See the MathJax site (see: +# http://docs.mathjax.org/en/latest/output.html) for more details. +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility), NativeMML (i.e. MathML) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from https://www.mathjax.org before deployment. +# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/ + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use + S +# (what the is depends on the OS and browser, but it is typically +# , /
- + [Prev] - Programming with FLUID + Using OpenGL diff --git a/documentation/src/fluid-edit-global-fltk-settings.png b/documentation/src/fltk-options.png similarity index 100% rename from documentation/src/fluid-edit-global-fltk-settings.png rename to documentation/src/fltk-options.png diff --git a/documentation/src/fluid-catgets.png b/documentation/src/fluid-catgets.png deleted file mode 100644 index e68b42c96..000000000 Binary files a/documentation/src/fluid-catgets.png and /dev/null differ diff --git a/documentation/src/fluid-edit-gui-settings.png b/documentation/src/fluid-edit-gui-settings.png deleted file mode 100644 index ce3cadc9d..000000000 Binary files a/documentation/src/fluid-edit-gui-settings.png and /dev/null differ diff --git a/documentation/src/fluid-edit-proj-settings.png b/documentation/src/fluid-edit-proj-settings.png deleted file mode 100644 index 0b44bb199..000000000 Binary files a/documentation/src/fluid-edit-proj-settings.png and /dev/null differ diff --git a/documentation/src/fluid-gettext.png b/documentation/src/fluid-gettext.png deleted file mode 100644 index 70845f035..000000000 Binary files a/documentation/src/fluid-gettext.png and /dev/null differ diff --git a/documentation/src/fluid-layout-grid-and-size-settings.png b/documentation/src/fluid-layout-grid-and-size-settings.png deleted file mode 100644 index a9f441fd9..000000000 Binary files a/documentation/src/fluid-layout-grid-and-size-settings.png and /dev/null differ diff --git a/documentation/src/fluid-org.png b/documentation/src/fluid-org.png deleted file mode 100644 index dd464597c..000000000 Binary files a/documentation/src/fluid-org.png and /dev/null differ diff --git a/documentation/src/fluid-org.xcf b/documentation/src/fluid-org.xcf deleted file mode 100644 index 09e98e67c..000000000 Binary files a/documentation/src/fluid-org.xcf and /dev/null differ diff --git a/documentation/src/fluid.dox b/documentation/src/fluid.dox deleted file mode 100644 index ebfdaaafe..000000000 --- a/documentation/src/fluid.dox +++ /dev/null @@ -1,1760 +0,0 @@ -/** - - - - - \page fluid Programming with FLUID - -This chapter shows how to use the Fast Light User-Interface Designer -("FLUID") to create your GUIs. - -Subchapters: - -\li \ref fluid_what_is_fluid -\li \ref fluid_fluid_under_unix -\li \ref fluid_fluid_under_windows -\li \ref fluid_compiling_fl_files -\li \ref fluid_tutorial -\li \ref fluid_references -\li \ref fluid_templates -\li \ref fluid_i18n -\li \ref fluid_limitations -\li \ref fluid_hotkeys -\li \ref fluid_licenses - -\section fluid_what_is_fluid What is FLUID? - -The Fast Light User Interface Designer, or FLUID, is a -graphical editor that is used to produce FLTK source code. FLUID -edits and saves its state in .fl files. These files -are text, and you can (with care) edit them in a text editor, -perhaps to get some special effects. The .fl file format is explained -in detail in fluid/README_fl.txt - -FLUID can "compile" the .fl file into a -.cxx and a .h file. The .cxx file -defines all the objects from the .fl file and the -.h file declares all the global ones. FLUID also -supports localization (\ref fluid_i18n "Internationalization") -of label strings and tooltips using message files and the GNU gettext or -POSIX catgets interfaces. - -A simple program can be made by putting all your code (including a -\p main() function) into the .fl file and thus making the -.cxx file a -single source file to compile. Most programs are more complex than -this, so you write other .cxx files that call the FLUID functions. -These .cxx files must -\p \#include -the .h file or they can -\p \#include -the .cxx file so it still appears to be a single source file. - - \image html fluid-org.png "FLUID organization" - \image latex fluid-org.png "FLUID organization" width=12cm - -Normally the FLUID file defines one or more functions or classes which -output C++ code. Each function defines one or more FLTK -windows and all the widgets that go inside those windows. - -Widgets created by FLUID are either "named", "complex named" or -"unnamed". A named widget has a legal C++ variable identifier as its -name (i.e. only alphanumeric and underscore). In this case FLUID -defines a global variable or class member that will point at the widget -after the function defining it is called. A complex named object has -punctuation such as '.' or '->' or any other symbols -in its name. In this case FLUID assigns a pointer to the widget to the name, -but does not attempt to declare it. This can be used to get the widgets into -structures. An unnamed widget has a blank name and no pointer is stored. - -Widgets may either call a named callback function that you write in -another source file, or you can supply a small piece of C++ source and -FLUID will write a private callback function into the .cxx file. - -\section fluid_fluid_under_unix Running FLUID Under UNIX - -To run FLUID under UNIX, type: - -\code -fluid filename.fl & -\endcode - -to edit the .fl file filename.fl. -If the file does not exist -you will get an error pop-up, but if you dismiss it you will be editing -a blank file of that name. You can run FLUID without any name, in -which case you will be editing an unnamed blank setup (but you can use -save-as to write it to a file). - -You can provide any of the standard FLTK switches before the filename: - -\code --display host:n.n --geometry WxH+X+Y --title windowtitle --name classname --iconic --fg color --bg color --bg2 color --scheme schemename -\endcode - -Changing the colors may be useful to see what your interface -will look at if the user calls it with the same switches. -Similarly, using "-scheme plastic" will show how the interface -will look using the "plastic" scheme. - -In the current version, if you don't put FLUID into the -background with '&' then you will be able to abort FLUID by -typing CTRL-C on the terminal. It will exit -immediately, losing any changes. - -\section fluid_fluid_under_windows Running FLUID Under Microsoft Windows - -To run FLUID under Windows, double-click on the \e FLUID.exe -file. You can also run FLUID from the Command Prompt window. -FLUID always runs in the background under Windows. - -\section fluid_compiling_fl_files Compiling .fl Files - -FLUID can also be called as a command-line -"compiler" to create the .cxx and .h -file from a .fl file. To do this type: - -\code -fluid -c filename.fl -\endcode - -This is the same as the menu 'File/Write Code...'. -It will read the filename.fl file and write -filename.cxx and filename.h. Any leading -directory on filename.fl will be stripped, so they are -always written to the current directory. If there are any errors -reading or writing the files, FLUID will print the error and -exit with a non-zero code. You can use the following lines in a -makefile to automate the creation of the source and header -files: - -\code -my_panels.h my_panels.cxx: my_panels.fl - fluid -c my_panels.fl -\endcode - -Most versions of make support rules that cause .fl -files to be compiled: - -\code -.SUFFIXES: .fl .cxx .h -.fl.h .fl.cxx: - fluid -c $< -\endcode - -If you use - -\code -fluid -cs filename.fl -\endcode - -FLUID will also write the "strings" for internationalization in file -'filename.txt' (menu: 'File/Write Strings...'). - -Finally there is another option which is useful for program developers -who have many .fl files and want to upgrade them to the current FLUID -version. FLUID will read the \p filename.fl file, save it, and exit -immediately. This writes the file with current syntax and options and -the current FLTK version in the header of the file. Use - -\code -fluid -u filename.fl -\endcode - -to 'upgrade' \p filename.fl . You may combine this with '-c' or '-cs'. - -\note All these commands overwrite existing files w/o warning. You should -particularly take care when running 'fluid -u' since this overwrites the -original .fl source file. - - -\section fluid_tutorial A Short Tutorial - -FLUID is an amazingly powerful little program. However, this -power comes at a price as it is not always obvious how to -accomplish seemingly simple tasks with it. This tutorial will -show you how to generate a complete user interface class with -FLUID that is used for the CubeView program provided with FLTK. - -\image html cubeview.png "CubeView demo" -\image latex cubeview.png "CubeView demo" width=10cm - -The window is of class CubeViewUI, and is completely generated by FLUID, -including class member functions. The central display of the cube is a -separate subclass of Fl_Gl_Window called CubeView. CubeViewUI manages -CubeView using callbacks from the various sliders and rollers to -manipulate the viewing angle and zoom of CubeView. - -At the completion of this tutorial you will (hopefully) understand how to: - --# Use FLUID to create a complete user interface class, including - constructor and any member functions necessary. --# Use FLUID to set callback member functions of custom widget classes. --# Subclass an Fl_Gl_Window to suit your purposes. - -\subsection fluid_cubeview The CubeView Class - -The CubeView class is a subclass of Fl_Gl_Window. It has methods for -setting the zoom, the \e x and \e y pan, and the rotation angle -about the \e x and \e y axes. - -You can safely skip this section as long as you realize that CubeView -is a sublass of Fl_Gl_Window and will respond to calls from -CubeViewUI, generated by FLUID. - -\par The CubeView Class Definition - -Here is the CubeView class definition, as given by its header file -"test/CubeView.h": -
- - -\code -#include -#include -#include - -class CubeView : public Fl_Gl_Window { - -public: - CubeView(int x, int y, int w, int h, const char *l = 0); - - // This value determines the scaling factor used to draw the cube. - double size; - - /* Set the rotation about the vertical (y) axis. - * - * This function is called by the horizontal roller in - * CubeViewUI and the initialize button in CubeViewUI. - */ - void v_angle(double angle) { vAng = angle; } - - // Return the rotation about the vertical (y) axis. - double v_angle() const { return vAng; } - - /* Set the rotation about the horizontal (x) axis. - * - * This function is called by the vertical roller in - * CubeViewUI and the initialize button in CubeViewUI. - */ - - void h_angle(double angle) { hAng = angle; } - - // The rotation about the horizontal (x) axis. - double h_angle() const { return hAng; } - - /* Sets the x shift of the cube view camera. - * - * This function is called by the slider in CubeViewUI - * and the initialize button in CubeViewUI. - */ - void panx(double x) { xshift = x; } - - /* Sets the y shift of the cube view camera. - * - * This function is called by the slider in CubeViewUI - * and the initialize button in CubeViewUI. - */ - void pany(double y) { yshift = y; } - - /* The widget class draw() override. - * - * The draw() function initializes Gl for another round of - * drawing, then calls specialized functions for drawing each - * of the entities displayed in the cube view. - */ - void draw(); - -private: - /* Draw the cube boundaries. - * - * Draw the faces of the cube using the boxv[] vertices, - * using GL_LINE_LOOP for the faces. - */ - void drawCube(); - - double vAng, hAng; - double xshift, yshift; - - float boxv0[3]; float boxv1[3]; - float boxv2[3]; float boxv3[3]; - float boxv4[3]; float boxv5[3]; - float boxv6[3]; float boxv7[3]; -}; -\endcode - -\par The CubeView Class Implementation - -Here is the CubeView implementation. It is very similar to the -"CubeView" demo included with FLTK. -
- - -\code -#include "CubeView.h" -#include - -CubeView::CubeView(int x, int y, int w, int h, const char *l) - : Fl_Gl_Window(x, y, w, h, l) -{ - Fl::use_high_res_GL(1); - vAng = 0.0; - hAng = 0.0; - size = 10.0; - xshift = 0.0; - yshift = 0.0; - - /* The cube definition. These are the vertices of a unit cube - * centered on the origin.*/ - - boxv0[0] = -0.5; boxv0[1] = -0.5; boxv0[2] = -0.5; - boxv1[0] = 0.5; boxv1[1] = -0.5; boxv1[2] = -0.5; - boxv2[0] = 0.5; boxv2[1] = 0.5; boxv2[2] = -0.5; - boxv3[0] = -0.5; boxv3[1] = 0.5; boxv3[2] = -0.5; - boxv4[0] = -0.5; boxv4[1] = -0.5; boxv4[2] = 0.5; - boxv5[0] = 0.5; boxv5[1] = -0.5; boxv5[2] = 0.5; - boxv6[0] = 0.5; boxv6[1] = 0.5; boxv6[2] = 0.5; - boxv7[0] = -0.5; boxv7[1] = 0.5; boxv7[2] = 0.5; -} - -void CubeView::drawCube() { -/* Draw a colored cube */ -#define ALPHA 0.5 - glShadeModel(GL_FLAT); - - glBegin(GL_QUADS); - glColor4f(0.0, 0.0, 1.0, ALPHA); - glVertex3fv(boxv0); - glVertex3fv(boxv1); - glVertex3fv(boxv2); - glVertex3fv(boxv3); - - glColor4f(1.0, 1.0, 0.0, ALPHA); - glVertex3fv(boxv0); - glVertex3fv(boxv4); - glVertex3fv(boxv5); - glVertex3fv(boxv1); - - glColor4f(0.0, 1.0, 1.0, ALPHA); - glVertex3fv(boxv2); - glVertex3fv(boxv6); - glVertex3fv(boxv7); - glVertex3fv(boxv3); - - glColor4f(1.0, 0.0, 0.0, ALPHA); - glVertex3fv(boxv4); - glVertex3fv(boxv5); - glVertex3fv(boxv6); - glVertex3fv(boxv7); - - glColor4f(1.0, 0.0, 1.0, ALPHA); - glVertex3fv(boxv0); - glVertex3fv(boxv3); - glVertex3fv(boxv7); - glVertex3fv(boxv4); - - glColor4f(0.0, 1.0, 0.0, ALPHA); - glVertex3fv(boxv1); - glVertex3fv(boxv5); - glVertex3fv(boxv6); - glVertex3fv(boxv2); - glEnd(); - - glColor3f(1.0, 1.0, 1.0); - glBegin(GL_LINES); - glVertex3fv(boxv0); - glVertex3fv(boxv1); - - glVertex3fv(boxv1); - glVertex3fv(boxv2); - - glVertex3fv(boxv2); - glVertex3fv(boxv3); - - glVertex3fv(boxv3); - glVertex3fv(boxv0); - - glVertex3fv(boxv4); - glVertex3fv(boxv5); - - glVertex3fv(boxv5); - glVertex3fv(boxv6); - - glVertex3fv(boxv6); - glVertex3fv(boxv7); - - glVertex3fv(boxv7); - glVertex3fv(boxv4); - - glVertex3fv(boxv0); - glVertex3fv(boxv4); - - glVertex3fv(boxv1); - glVertex3fv(boxv5); - - glVertex3fv(boxv2); - glVertex3fv(boxv6); - - glVertex3fv(boxv3); - glVertex3fv(boxv7); - glEnd(); -} // drawCube - -void CubeView::draw() { - if (!valid()) { - glLoadIdentity(); - glViewport(0, 0, pixel_w(), pixel_h()); - glOrtho(-10, 10, -10, 10, -20050, 10000); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glPushMatrix(); - - glTranslatef((GLfloat)xshift, (GLfloat)yshift, 0); - glRotatef((GLfloat)hAng, 0, 1, 0); - glRotatef((GLfloat)vAng, 1, 0, 0); - glScalef(float(size), float(size), float(size)); - - drawCube(); - - glPopMatrix(); -} -\endcode - -\subsection fluid_cubeview_ui The CubeViewUI Class - -We will completely construct a window to display and control the -CubeView defined in the previous section using FLUID. - -\par Defining the CubeViewUI Class - -Once you have started FLUID, the first step in defining a class is to -create a new class within FLUID using the New->Code->Class -menu item. Name the class "CubeViewUI" and leave the subclass blank. -We do not need any inheritance for this window. You should see the -new class declaration in the FLUID browser window. - -\image html fluid1.png "FLUID file for CubeView" -\image latex fluid1.png "FLUID file for CubeView" width=10cm - -\par Adding the Class Constructor - -Click on the CubeViewUI class in the FLUID window and add a new method -by selecting New->Code->Function/Method. The name of the -function will also be CubeViewUI. FLUID will understand that this will -be the constructor for the class and will generate the appropriate -code. Make sure you declare the constructor public. - -Then add a window to the CubeViewUI class. Highlight the name of -the constructor in the FLUID browser window and click on -New->Group->Window. In a similar manner add the -following to the CubeViewUI constructor: - -\li A horizontal roller named \p hrot -\li A vertical roller named \p vrot -\li A horizontal slider named \p xpan -\li A vertical slider named \p ypan -\li A horizontal value slider named \p zoom - -None of these additions need be public. And they shouldn't be -unless you plan to expose them as part of the interface for -CubeViewUI. - -When you are finished you should have something like this: - -\image html fluid2.png "FLUID window containing CubeView demo" -\image latex fluid2.png "FLUID window containing CubeView demo" width=10cm - -We will talk about the \p show() method that is highlighted -shortly. - -\par Adding the CubeView Widget - -What we have is nice, but does little to show our cube. We have already -defined the CubeView class and we would like to show it within the -CubeViewUI. - -The CubeView class inherits the Fl_Gl_Window class, which -is created in the same way as an Fl_Box widget. Use -New->Other->Box to add a square box to the main window. -This will be no ordinary box, however. - -The Box properties window will appear. The key to letting CubeViewUI -display CubeView is to enter CubeView in the Class: text -entry box. This tells FLUID that it is not an Fl_Box, but a -similar widget with the same constructor. - -In the Extra Code: field enter \#include "CubeView.h" - -This \p \#include is important, as we have just included -CubeView as a member of CubeViewUI, so any public CubeView methods are -now available to CubeViewUI. - -\image html fluid3-cxx.png "CubeView methods" -\image latex fluid3-cxx.png "CubeView methods" width=10cm - -\par Defining the Callbacks - -Each of the widgets we defined before adding CubeView can have -callbacks that call CubeView methods. You can call an external -function or put a short amount of code in the Callback -field of the widget panel. For example, the callback for the -\p ypan slider is: - -\code -cube->pany(((Fl_Slider *)o)->value()); -cube->redraw(); -\endcode - -We call cube->redraw() after changing the value to update -the CubeView window. CubeView could easily be modified to do this, but -it is nice to keep this exposed. In the case where you may want to do -more than one view change only redrawing once saves a lot of time. - -There is no reason to wait until after you have added CubeView to -enter these callbacks. FLUID assumes you are smart enough not to refer -to members or functions that don't exist. - -\par Adding a Class Method - -You can add class methods within FLUID that have nothing to do with the -GUI. As an example add a show function so that CubeViewUI can actually -appear on the screen. - -Make sure the top level CubeViewUI is selected and select -New->Code->Function/Method. Just use the name -\p show(). We don't need a return value here, and since we will -not be adding any widgets to this method FLUID will assign it a return -type of \p void. - -\image html fluid4.png "CubeView constructor" -\image latex fluid4.png "CubeView constructor" width=10cm - -Once the new method has been added, highlight its name and select -New->Code->Code. Enter the method's code in the code window. - -\subsection fluid_addconst Adding Constructor Initialization Code - -If you need to add code to initialize a class, for example setting -initial values of the horizontal and vertical angles in the -CubeView, you can simply highlight the constructor and select -New->Code->Code. Add any required code. - -\subsection fluid_gencode Generating the Code - -Now that we have completely defined the CubeViewUI, we have to generate -the code. There is one last trick to ensure this all works. Open the -preferences dialog from Edit->Preferences. - -At the bottom of the preferences dialog box is the key: -"Include Header from Code". -Select that option and set your desired file -extensions and you are in business. You can include the CubeViewUI.h -(or whatever extension you prefer) as you would any other C++ class. - - - -\section fluid_references FLUID Reference - -The following sections describe each of the windows in FLUID. - -\subsection fluid_browser The Widget Browser - -The main window shows a menu bar and a scrolling browser of -all the defined widgets. The name of the .fl file being -edited is shown in the window title. - -The widgets are stored in a hierarchy. You can open and close a -level by clicking the "triangle" at the left of a widget. -The leftmost widgets are the \e parents, and all the widgets -listed below them are their \e children. Parents don't have to have -any children. - -The top level of the hierarchy is composed of \e functions and -\e classes. Each of these will produce a single C++ public function -or class in the output .cxx file. Calling the function or -instantiating the class will create all of the child widgets. - -The second level of the hierarchy contains the \e windows. -Each of these produces an instance of class Fl_Window. - -Below that are either \e widgets (subclasses of Fl_Widget) or -\e groups of widgets (including other groups). Plain groups are for -layout, navigation, and resize purposes. Tab groups provide the -well-known file-card tab interface. - -Widgets are shown in the browser by either their \e name (such -as "main_panel" in the example), or by their \e type -and \e label (such as "Button "the green""). - -You \e select widgets by clicking on their names, which highlights -them (you can also select widgets from any displayed window). You can -select many widgets by dragging the mouse across them, or by using -Shift+Click to toggle them on and off. To select no widgets, click in -the blank area under the last widget. Note that hidden children may -be selected even when there is no visual indication of this. - -You \e open widgets by double-clicking on them, or (to open several -widgets you have picked) by typing the F1 key. A control panel will appear -so you can change the widget(s). - -\subsection fluid_menu_items Menu Items - -The menu bar at the top is duplicated as a pop-up menu on any -displayed window. The shortcuts for all the menu items work in any -window. The menu items are: - -\par File/Open... (Ctrl+o) - -\par -Discards the current editing session and reads in a different -.fl file. You are asked for confirmation if you have -changed the current file. - -\par -FLUID can also read .fd files produced by the Forms -and XForms "fdesign" programs. It is best to -File/Merge them instead of opening them. FLUID does not -understand everything in a .fd file, and will print a -warning message on the controlling terminal for all data it does -not understand. You will probably need to edit the resulting -setup to fix these errors. Be careful not to save the file -without changing the name, as FLUID will write over the -.fd file with its own format, which fdesign cannot read! - -\par File/Insert... (Ctrl+i) - -\par -Inserts the contents of another .fl file, without -changing the name of the current .fl file. All the -functions (even if they have the same names as the current ones) -are added, and you will have to use cut/paste to put the widgets -where you want. - -\par File/Save (Ctrl+s) - -\par -Writes the current data to the .fl file. If the -file is unnamed then FLUID will ask for a filename. - -\par File/Save As... (Ctrl+Shift+S) - -\par -Asks for a new filename and saves the file. - -\par File/Save A Copy... - -\par -Save a copy of the .fl data to a different file. - -\par File/Revert... - -\par -Revert the .fl data to a previously saved state. - -\par File/New From Template... - -\par -Create a new user interface design from a previously saved template. -This can be useful for including a predefined enterprise copyright message -for projects, or for managing boilerplate code for repeating project code. - -\par File/Save As Template... - -\par -Save the current project as a starting point for future projects. - -\par File/Print... (Ctrl-P) - -\par -Generate a printout containing all currently open windows within your project. - -\par File/Write Code (Ctrl+Shift+C) - -\par -"Compiles" the data into a .cxx and .h -file. These are exactly the same as the files you get when you run -FLUID with the \c -c switch. - -\par -The output file names are the same as the .fl file, with -the leading directory and trailing ".fl" stripped, and -".h" or ".cxx" appended. - -\par File/Write Strings (Ctrl+Shift+W) - -\par -Writes a message file for all of the text labels defined in -the current file. - -\par -The output file name is the same as the .fl file, -with the leading directory and trailing ".fl" -stripped, and ".txt", ".po", or ".msg" appended depending on the -\ref fluid_i18n "Internationalization Mode". - -\par File/Quit (Ctrl+q) - -\par -Exits FLUID. You are asked for confirmation if you have -changed the current file. - -\par Edit/Undo (Ctrl+z) and Redo (Shift+Ctrl+z) - -\par -FLUID saves the project state for undo and redo operations after every -major change. - -\par Edit/Cut (Ctrl+x) - -\par -Deletes the selected widgets and all of their children. -These are saved to a "clipboard" file and can be -pasted back into any FLUID window. - -\par Edit/Copy (Ctrl+c) - -\par -Copies the selected widgets and all of their children to the -"clipboard" file. - -\par Edit/Paste (Ctrl+v) - -\par -Pastes the widgets from the clipboard file. - -\par -If the widget is a window, it is added to whatever function -is selected, or contained in the current selection. - -\par -If the widget is a normal widget, it is added to whatever -window or group is selected. If none is, it is added to the -window or group that is the parent of the current selection. - -\par -To avoid confusion, it is best to select exactly one widget -before doing a paste. - -\par -Cut/paste is the only way to change the parent of a -widget. - -\par Edit/Select All (Ctrl+a) - -\par -Selects all widgets in the same group as the current selection. - -\par -If they are all selected already then this selects all -widgets in that group's parent. Repeatedly typing Ctrl+a will -select larger and larger groups of widgets until everything is -selected. - -\par Edit/Properties... (F1 or double click) - -\par -Displays the current widget in the attributes panel. If the -widget is a window and it is not visible then the window is -shown instead. - -\par Edit/Sort - -\par -Sorts the selected widgets into left to right, top to bottom order. -You need to do this to make navigation keys in FLTK work correctly. -You may then fine-tune the sorting with "Earlier" and "Later". -This does not affect the positions of windows or functions. - -\par Edit/Earlier (F2) - -\par -Moves all of the selected widgets one earlier in order among -the children of their parent (if possible). This will affect -navigation order, and if the widgets overlap it will affect how -they draw, as the later widget is drawn on top of the earlier -one. You can also use this to reorder functions, classes, and -windows within functions. - -\par Edit/Later (F3) - -\par -Moves all of the selected widgets one later in order among -the children of their parent (if possible). - -\par Edit/Group (F7) - -\par -Creates a new Fl_Group and make all the currently -selected widgets children of it. - -\par Edit/Ungroup (F8) - -\par -Deletes the parent group if all the children of a group are -selected. - -\par Edit/Show or Hide Overlays (Ctrl+Shift+O) - -\par -Toggles the display of the red overlays off, without changing -the selection. This makes it easier to see box borders and how -the layout looks. The overlays will be forced back on if you -change the selection. - -\par Edit/Show or Hide Guides (Ctrl+Shift+G) - -\par -Guides can be used to arrange a widget layout easily and consistently. They -indicating preferred widget positions and sizes with user definable margins, -grids, and gap sizes. See the "Layout" tab in the "Settings" dialog. - -\par -This menu item enables and disable guides and the snapping action when dragging -widgets and their borders. - -\par Edit/Show or Hide Restricted (Ctrl+Shift+R) - -\par -It is recommended to ensure that user interface elements within FLTK do not -exceed the size of their container group or overlap with each other. -By activating this button, a hatch pattern is enabled, visually highlighting -areas where restricted or undefined behavior may occur. - -\par Edit/Show or Hide Widget Bin (Alt+B) - -\par -The widget bin provides quick access to all widget types supported by FLUID. -Layouts can be created by clicking on elements in the widget bin, or by dragging -them from the bin to their position within the layout. This button shows or -hides the widget bin. - -\par Edit/Show or Hide Source Code (Shift+Alt+S) - -\par -This button shows or hides the source code preview window. Any change to the -layout or code in the layout editores can be previewed and verified immediatly -in the Code View window. - -\par Edit/Settings... (Alt+p) - -\par -Displays the FLUID settings panel. The settings panel contains tabs for -general FLUID settings, project setting, layout preferences, custom shell -commands, and the internationalisation settings for GNU Gettext -and POSIX catgets. - -\par -Under the "Project" tab you control the extensions or names of the files -that are generated by FLUID. If you check the "Include Header from Code" -button the code file will include the header file automatically. - -\par -Under the "Locale" tab are the \ref fluid_i18n "internationalization" -options, described later in this chapter. - -\image html fluid-edit-gui-settings.png "FLUID General Settings Tab" -\image latex fluid-edit-gui-settings.png "FLUID General Settings Tab" width=10cm - -\image html fluid-edit-proj-settings.png "FLUID Project Settings Tab" -\image latex fluid-edit-proj-settings.png "FLUID Project Settings Tab" width=10cm - -\par New/Code/Function - -\par -Creates a new C function. You will be asked for a name for -the function. This name should be a legal C++ function -template, without the return type. You can pass arguments which -can be referred to by code you type into the individual widgets. - -\par -If the function contains any unnamed windows, it will be -declared as returning an Fl_Window pointer. The unnamed window -will be returned from it (more than one unnamed window is -useless). If the function contains only named windows, it will -be declared as returning nothing (\c void ). - -\par -It is possible to make the .cxx output be a -self-contained program that can be compiled and executed. This -is done by deleting the function name so -\p main(argc,argv) is used. The function will call -\p show() on all the windows it creates and then call -\p Fl::run(). This can also be used to test resize -behavior or other parts of the user interface. - -\par -You can change the function name by double-clicking on the -function. - -\par New/Window - -\par -Creates a new Fl_Window widget. The window is added -to the currently selected function, or to the function -containing the currently selected item. The window will appear, -sized to 100x100. You can resize it to whatever size you -require. - -\par -The widget panel will also appear and is described later in -this chapter. - -\par New/... - -\par -All other items on the New menu are subclasses of -Fl_Widget. Creating them will add them to the -currently selected group or window, or the group or window -containing the currently selected widget. The initial -dimensions and position are chosen by copying the current -widget, if possible. - -\par -When you create the widget you will get the widget's control -panel, which is described later in this chapter. - -\par Layout/Align/... - -\par -Align all selected widgets to the first widget in the selection. - -\par Layout/Space Evenly/... - -\par -Space all selected widgets evenly inside the selected space. -Widgets will be sorted from first to last. - -\par Layout/Make Same Size/... - -\par -Make all selected widgets the same size as the first selected widget. - -\par Layout/Center in Group/... - -\par -Center all selected widgets relative to their parent widget - -\par Layout/Grid and Size Settings... (Ctrl+g) - -\par -Displays the grid settings panel. - -\par -This panel controls dimensions that all widgets snap to when you move -and resize them, and for the "snap" which is how far a widget has to be -dragged from its original position to actually change. - -Layout preferences are defined using margins to parent groups and window, gaps -between widget, and /orr by overlaying a grid over a group or window. A layout -comes as a suite of three presets, one for the main application window, one -for dialog boxes, and one for toolboxes. - -FLUID comes with two include layout suites. `FLTK` was used to design FLUID and -other included apps, and `Grid` is a more ridgid grid layout. Users can add -more suites, import and export them, and include them into their .fl -project files. - -\image html fluid-layout-grid-and-size-settings.png "FLUID Layout/Grid Settings Window" -\image latex fluid-layout-grid-and-size-settings.png "FLUID Layout/Grid Settings Window" width=10cm - -\par Shell/Execute Command... (Alt+x) - -\par -Displays the shell command panel. The shell command -is commonly used to run a 'make' script to compile the FLTK output. - -\par Shell/Execute Again (Alt+g) - -\par -Run the shell command again. - -\par Help/Repid development with FLUID - -\par -Shows this chapter of the manual. - -\par Help/FLTK Programmers Manual - -\par -Shows the contents page of the manual - -\par Help/About FLUID - -\par -Pops up a panel showing the version of FLUID. - -\subsection fluid_widget_panel The Widget Panel - -When you double-click on a widget or a set of widgets you -will get the "widget attribute panel". - -When you change attributes using this panel, the changes are -reflected immediately in the window. It is useful to hit the -"Hide Overlays" button (or type Ctrl+Shift+O) to hide the -red overlay so you can see the widgets more accurately, -especially when setting the box type. - -If you have several widgets selected, they may have different -values for the fields. In this case the value for \e one of -the widgets is shown. But if you change this value, \e all -of the selected widgets are changed to the new value. - -Hitting "OK" makes the changes permanent. -Selecting a different widget also makes the changes permanent. -FLUID checks for simple syntax errors such as mismatched -parenthesis in any code before saving any text. - - - -\image html fluid_widget_gui.png "The FLUID widget GUI attributes" -\image latex fluid_widget_gui.png "The FLUID widget GUI attributes" width=10cm - -\section fluid_widget_attributes GUI Attributes - -\par Not all fields in the Widget attributes dialog will be visible -for all types of widgets. - -\par Label (text field) - -\par -String to print next to or inside the button. You can put -newlines into the string to make multiple lines. The easiest way -is by typing Ctrl+j. - -\par -\ref common_labels "Symbols" -can be added to the label using the at sign ("@"). - -\par Label (pull down menu) - -\par -How to draw the label. Normal, shadowed, engraved, and -embossed change the appearance of the text. - -\par Image - -\par -The active image for the widget. Click on the -\b Browse... button to pick an image file using the file -chooser. - -\par Inactive - -\par -The inactive image for the widget. Click on the -\b Browse... button to pick an image file using the file -chooser. - -\par Alignment (buttons) - -\par -Where to draw the label. The arrows put it on that side of the -widget, you can combine them to put it in the corner. The "box" -button puts the label inside the widget, rather than outside. - -\par -The \b clip button clips the label to the widget box, the -\b wrap button wraps any text in the label, and the -text image button puts the text over the image instead of under -the image. - -\par Position (text fields) - -\par -The position fields show the current position and size of the -widget box. Enter new values to move and/or resize a widget. - -\par -These fields understand basic math and variables. -Appending +10 to the X coordinate will move a widget 10 units -to the right without having to reenter the value. -Entering the formula w+3 in the Width field will widen all -selected Widgets by 3 units. -The formula py+i*20 in the Y field will order all selected -widgets vertically in their group by increments of 20 units. - -\par - - - - - - - -
NameValue
`i` zero based counter of selected widgets
`x`, `y`, `w`, `h` position and size of the current widget
`px`, `py`, `pw`, `ph` dimensions of the parent widget
`sx`, `sy`, `sw`, `sh` dimensions of the previous sibling
`cx`, `cy`, `cw`, `ch` bounding box of all children
- -\par Values (text fields) - -\par -The values and limits of the current widget. Depending on the -type of widget, some or all of these fields may be inactive. - -\par Shortcut - -\par -The shortcut key to activate the widget. Click on the -shortcut button and press any key sequence to set the shortcut. - -\par Attributes (buttons) - -\par -The \b Visible button controls whether the widget is -visible (on) or hidden (off) initially. Don't change this for -windows or for the immediate children of a Tabs group. - -\par -The \b Active button controls whether the widget is -activated (on) or deactivated (off) initially. Most widgets -appear greyed out when deactivated. - -\par -The \b Resizable button controls whether the window is -resizeable. In addition all the size changes of a window or -group will go "into" the resizable child. If you have -a large data display surrounded by buttons, you probably want -that data area to be resizable. You can get more complex -behavior by making invisible boxes the resizable widget, or by -using hierarchies of groups. Unfortunately the only way to test -it is to compile the program. Resizing the FLUID window is -\e not the same as what will happen in the user program. - -\par -The \b Hotspot button causes the parent window to be -positioned with that widget centered on the mouse. This -position is determined when the FLUID function is called, -so you should call it immediately before showing the window. If -you want the window to hide and then reappear at a new position, -you should have your program set the hotspot itself just before -\p show(). - -\par -The \b Border button turns the window manager border on -or off. On most window managers you will have to close the -window and reopen it to see the effect. - -\par X Class (text field) - -\par -The string typed into here is passed to the X window manager -as the class. This can change the icon or window decorations. -On most (all?) window managers you will have to close the window -and reopen it to see the effect. - -\image html fluid_widget_style.png "The FLUID widget Style attributes" -\image latex fluid_widget_style.png "The FLUID widget Style attributes" width=10cm - -\subsection fluid_style_attributes Style Attributes - -\par Label Font (pulldown menu) - -\par -Font to draw the label in. Ignored by symbols, bitmaps, and -pixmaps. Your program can change the actual font used by these -"slots" in case you want some font other than the 16 -provided. - -\par Label Size (pulldown menu) - -\par -Pixel size (height) for the font to draw the label in. -Ignored by symbols, bitmaps, and pixmaps. To see the result -without dismissing the panel, type the new number and then Tab. - -\par Label Color (button) - -\par -Color to draw the label. Ignored by pixmaps (bitmaps, -however, do use this color as the foreground color). - -\par Box (pulldown menu) - -\par -The boxtype to draw as a background for the widget. - -\par -Many widgets will work, and draw faster, with a -"frame" instead of a "box". A frame does -not draw the colored interior, leaving whatever was already -there visible. Be careful, as FLUID may draw this ok but the -real program may leave unwanted stuff inside the widget. - -\par -If a window is filled with child widgets, you can speed up -redrawing by changing the window's box type to -"NO_BOX". FLUID will display a checkerboard for any -areas that are not colored in by boxes. Note that this -checkerboard is not drawn by the resulting program. Instead -random garbage will be displayed. - -\par Down Box (pulldown menu) - -\par -The boxtype to draw when a button is pressed or for some -parts of other widgets like scrollbars and valuators. - -\par Color (button) - -\par -The color to draw the box with. - -\par Select Color (button) - -\par -Some widgets will use this color for certain parts. FLUID -does not always show the result of this: this is the color -buttons draw in when pushed down, and the color of input fields -when they have the focus. - -\par Text Font, Size, and Color - -\par -Some widgets display text, such as input fields, pull-down -menus, and browsers. - -\image html fluid_widget_cxx.png "The FLUID widget C++ attributes" -\image latex fluid_widget_cxx.png "The FLUID widget C++ attributes" width=10cm - -\subsection fluid_cpp_attributes C++ Attributes - -\par Class - -\par -This is how you use your own subclasses of -Fl_Widget. Whatever identifier you type in here will -be the class that is instantiated. - -\par -In addition, no \p \#include header file is put in the -.h file. You must provide a \p \#include line as -the first line of the "Extra Code" which declares your -subclass. - -\par -The class must be similar to the class you are spoofing. It -does not have to be a subclass. It is sometimes useful to -change this to another FLTK class. For windows you can select either -\p Single or \p Double in the drop-down box right to the "Class:" field -to get a normal window (Fl_Window) or a double-buffered window -(Fl_Double_Window), respectively. - -\par Type (upper-right pulldown menu) - -\par -Some classes have subtypes that modify their appearance or behavior. -You pick the subtype off of this menu. - -\par Name (text field) - -\par -Name of a variable to declare, and to store a pointer to this -widget into. This variable will be of type "*". If the name is -blank then no variable is created. - -\par -You can name several widgets with "name[0]", "name[1]", "name[2]", etc. -This will cause FLUID to declare an array of pointers. The array -is big enough that the highest number found can be stored. All widgets -in the array must be the same type. - -\par Public (button) - -\par -Controls whether the widget is publicly accessible. When -embedding widgets in a C++ class, this controls whether the -widget is \p public or \p private in the class. -Otherwise it controls whether the widget is declared -\p static or global (\p extern ). - -\par Extra Code (text fields) - -\par -These four fields let you type in literal lines of code to -dump into the .h or .cxx files. - -\par -If the text starts with a \# or the word -\p extern then FLUID thinks this is an "include" -line, and it is written to the .h file. If the same -include line occurs several times then only one copy is -written. - -\par -All other lines are "code" lines. The current -widget is pointed to by the local variable \p o. The -window being constructed is pointed to by the local variable -\p w. You can also access any arguments passed to the -function here, and any named widgets that are before this one. - -\par -FLUID will check for matching parenthesis, braces, and -quotes, but does not do much other error checking. Be careful -here, as it may be hard to figure out what widget is producing -an error in the compiler. If you need more than four lines you -probably should call a function in your own .cxx -code. - -\par Callback (text field) - -\par -This can either be the name of a function, or a small snippet -of code. If you enter anything other than letters, numbers, and the -underscore then FLUID treats it as code. - -\par -A name refers to a function in your own code. It must be -declared as void name(*,void*). - -\par -A code snippet is inserted into a static function in the -.cxx output file. The function prototype is -void name(class *o, void *v) -so that you can refer to the widget as \p o and the \p user_data() -as \p v. FLUID will check for matching parenthesis, braces, -and quotes, but does not do much other error checking. Be -careful here, as it may be hard to figure out what widget is -producing an error in the compiler. - -\par -If the callback is blank then no callback is set. - -\par User Data (text field) - -\par -This is a value for the \p user_data() of the widget. -If blank the default value of zero is used. This can be any -piece of C code that can be cast to a \p void pointer. - -\par Type (text field) - -\par -The \p void* in the callback function prototypes is -replaced with this. You may want to use \p long for old -XForms code. Be warned that anything other than \p void* -is not guaranteed to work! However on most architectures other -pointer types are ok, and \p long is usually ok, too. - -\par When (pulldown menu) - -\par -When to do the callback. This can be \b Never, -\b Changed, \b Release, or \b Enter Key. The value of -Enter Key is only useful for text input fields. - -\par -There are other rare but useful values for the -\p when() field that are not in the menu. You should use -the extra code fields to put these values in. - -\par No Change (button) - -\par -The No Change button means the callback is done on the -matching event even if the data is not changed. - -\section fluid_selecting_moving Selecting and Moving Widgets - -Double-clicking a window name in the browser will display it, -if not displayed yet. From this display you can select widgets, -sets of widgets, and move or resize them. To close a window -either double-click it or type \c ESC. - -To select a widget, click it. To select several widgets drag -a rectangle around them. Holding down shift will toggle the -selection of the widgets instead. - -You cannot pick hidden widgets. You also cannot choose some -widgets if they are completely overlapped by later widgets. Use -the browser to select these widgets. - -The selected widgets are shown with a red "overlay" -line around them. You can move the widgets by dragging this -box. Or you can resize them by dragging the outer edges and -corners. Hold down the Alt key while dragging the mouse to -defeat the snap-to-grid effect for fine positioning. - -If there is a tab box displayed you can change which child is -visible by clicking on the file tabs. The child you pick is -selected. - -The arrow, tab, and shift+tab keys "navigate" the -selection. Left, right, tab, or shift+tab move to the next or -previous widgets in the hierarchy. Hit the right arrow enough -and you will select every widget in the window. Up/down widgets -move to the previous/next widgets that overlap horizontally. If -the navigation does not seem to work you probably need to -"Sort" the widgets. This is important if you have -input fields, as FLTK uses the same rules when using arrow keys -to move between input fields. - -To "open" a widget, double click it. To open -several widgets select them and then type F1 or pick -"Edit/Open" off the pop-up menu. - -Type Ctrl+o to temporarily toggle the overlay off without -changing the selection, so you can see the widget borders. - -You can resize the window by using the window manager border -controls. FLTK will attempt to round the window size to the -nearest multiple of the grid size and makes it big enough to -contain all the widgets (it does this using illegal X methods, -so it is possible it will barf with some window managers!). -Notice that the actual window in your program may not be -resizable, and if it is, the effect on child widgets may be -different. - -The panel for the window (which you get by double-clicking -it) is almost identical to the panel for any other Fl_Widget. -There are three extra items: - -\section fluid_images Image Labels - -The \e contents of the image files in the \b Image -and \b Inactive text fields are written to the .cxx -file. If many widgets share the same image then only one copy is -written. Since the image data is embedded in the generated -source code, you need only distribute the C++ code and not the -image files themselves. - -However, the \e filenames are stored in the .fl -file so you will need the image files as well to read the -.fl file. Filenames are relative to the location of the -.fl file and not necessarily the current directory. We -recommend you either put the images in the same directory as the -.fl file, or use absolute path names. - -\par Notes for All Image Types - -\par -FLUID runs using the default visual of your X server. This -may be 8 bits, which will give you dithered images. You may get -better results in your actual program by adding the code -"Fl::visual(FL_RGB)" to your code right before the -first window is displayed. - -\par -All widgets with the same image on them share the same code -and source X pixmap. Thus once you have put an image on a -widget, it is nearly free to put the same image on many other -widgets. - -\par -If you edit an image at the same time you are using it in FLUID, -the only way to convince FLUID to read the image file again is to -remove the image from all widgets that are using it or re-load the -.fl file. - -\par -Don't rely on how FLTK crops images that are outside the -widget, as this may change in future versions! The cropping of -inside labels will probably be unchanged. - -\par -To more accurately place images, make a new "box" -widget and put the image in that as the label. - -\par XBM (X Bitmap) Files - -\par -FLUID reads X bitmap files which use C source code to define -a bitmap. Sometimes they are stored with the ".h" or -".bm" extension rather than the standard -".xbm" extension. - -\par -FLUID writes code to construct an Fl_Bitmap image and use it -to label the widget. The '1' bits in the bitmap are drawn using -the label color of the widget. You can change this color in the -FLUID widget attributes panel. The '0' bits are transparent. - -\par -The program "bitmap" on the X distribution does an -adequate job of editing bitmaps. - -\par XPM (X Pixmap) Files - -\par -FLUID reads X pixmap files as used by the \p libxpm -library. These files use C source code to define a pixmap. The -filenames usually have the ".xpm" extension. - -\par -FLUID writes code to construct an Fl_Pixmap image and use it -to label the widget. The label color of the widget is ignored, -even for 2-color images that could be a bitmap. XPM files can -mark a single color as being transparent, and FLTK uses this -information to generate a transparency mask for the image. - -\par -We have not found any good editors for small iconic pictures. -For pixmaps we have used -XPaint -and the KDE icon editor. - -\par BMP Files - -\par -FLUID reads Windows BMP image files which are often used in -Windows applications for icons. FLUID converts BMP files into -(modified) XPM format and uses an Fl_BMP_Image image to label the -widget. Transparency is handled the same as for XPM files. All -image data is uncompressed when written to the source file, so -the code may be much bigger than the .bmp file. - -\par GIF Files - -\par -FLUID reads GIF image files which are often used in HTML -documents to make icons. FLUID converts GIF files into -(modified) XPM format and uses an Fl_GIF_Image image to label the -widget. Transparency is handled the same as for XPM files. All -image data is uncompressed when written to the source file, so -the code may be much bigger than the .gif file. Only -the first image of an animated GIF file is used. - -\par JPEG Files - -\par -If FLTK is compiled with JPEG support, FLUID can read JPEG -image files which are often used for digital photos. FLUID uses -an Fl_JPEG_Image image to label the widget, and writes -uncompressed RGB or grayscale data to the source file. - -\par PNG (Portable Network Graphics) Files - -\par -If FLTK is compiled with PNG support, FLUID can read PNG -image files which are often used in HTML documents. FLUID uses a -Fl_PNG_Image image to label the widget, and writes uncompressed -RGB or grayscale data to the source file. PNG images can provide -a full alpha channel for partial transparency, and FLTK supports -this as best as possible on each platform. - -\section fluid_templates FLUID Templates - -\par -Fluid can store a number of project templates. Project templates -are great for storing often used boilerplate code for fast access. -A common use would be projects with readily prepared copyright messages. - -\par -A sample template for FLTK projects is included with Fluid. - -\par -Choose "File > New From Template..." to create a new project -based on a template file. In the template dialog, select one of -the existing templates. All occurrences of the word -"@INSTANCE@" in the template are replaced with the text in -the "Instance" field. To create the new project click "New". - -\par -To add your current project as a new template, choose -"File > Save As Template...", fill in a name, and click "Save". - -\par -To delete a template, open the template dialog using -"New from Template" or "Save As Template", then select any -existing template, and click "Delete Template". - -\section fluid_i18n Internationalization with FLUID - -FLUID supports internationalization (I18N for short) of label -strings and tooltips used by widgets. The GNU gettext option also -supports deferred translation of statically initialised menu item -labels. The preferences window (Ctrl+p) provides access -to the I18N options. - -\subsection fluid_i18n_methods I18N Methods - -FLUID supports three methods of I18N: none, GNU -gettext, and POSIX catgets. The "none" method is the -default and just passes the label strings as-is to the widget -constructors. - -The "GNU gettext" method uses GNU gettext (or a similar -text-based I18N library) to retrieve a localized string before -calling the widget constructor. - -The "POSIX catgets" method uses the POSIX catgets function to -retrieve a numbered message from a message catalog before -calling the widget constructor. - -\subsection fluid_gettext_i18n Using GNU gettext for I18N - -FLUID's code support for GNU gettext is limited to calling a -function or macro to retrieve the localized label; you still -need to call \p setlocale() and \p textdomain() or -\p bindtextdomain() to select the appropriate language and -message file. - -To use GNU gettext for I18N, open the preferences window and -choose "GNU gettext" from the \b Use: chooser. Four new input -fields will then appear to control the include file and -function/macro names to use when retrieving localized label -strings in dynamic allocation and static initialisation. - - \image html fluid-gettext.png "Internationalization using GNU gettext" - \image latex fluid-gettext.png "Internationalization using GNU gettext" width=10cm - -The \b \#include -field controls the header file to include for -I18N; by default this is \b , the -standard I18N file for GNU gettext. - -If the \b Conditional: field contains a macro name, i18n will only be compiled -into the product if this macro is defined. The build system should define the -macro only if all required headers and libraries are available. If the macro -is not defined, no headers are included and `gettext` passes text through -untranslated. - -The \b Function: field controls the function (or macro) that -will retrieve the localized message; by default the -\p gettext function will be called. - -The **Static Function:** field names a macro that will mark static text -fields for extraction with the `xgettext` tool. The default macro name is -\p gettext_noop and will be defined as `#define gettext_noop(text) text` -right after the `#include` statement. Fluid will do its best to call -`gettext` on static texts later, after the textdomain was set by the user. - -\see [GNU gettext special cases](https://www.gnu.org/software/gettext/manual/html_node/Special-cases.html) - -\subsection fluid_catgets_i18n Using POSIX catgets for I18N - -FLUID's code support for POSIX catgets allows you to use a -global message file for all interfaces or a file specific to -each .fl file; you still need to call -\p setlocale() to select the appropriate language. - -To use POSIX catgets for I18N, open the preferences window -and choose "POSIX catgets" from the \b Use: chooser. Three new -input fields will then appear to control the include file, -catalog file, and set number for retrieving the localized label -strings. - - \image html fluid-catgets.png "Internationalization using POSIX catgets" - \image latex fluid-catgets.png "Internationalization using POSIX catgets" width=10cm - -The \b \#include -field controls the header file to include for -I18N; by default this is \b , the -standard I18N file for POSIX catgets. - -The \b File: field controls the name of the catalog file -variable to use when retrieving localized messages; by default -the file field is empty which forces a local (static) catalog -file to be used for all of the windows defined in your -.fl file. - -The \b Set: field controls the set number in the catalog file. -The default set is 1 and rarely needs to be changed. - -\section fluid_limitations Known Limitations - -Declaration Blocks can be used to temporarily block out already -designed code using \#if 0 and \#endif -type construction. This will effectively avoid compilation of -blocks of code. However, static code and data generated by this -segment (menu items, images, include statements, etc.) will still -be generated and likely cause compile-time warnings. - -\section fluid_hotkeys Keyboard Shortcuts - -On Apple computers, use the Apple Command key instead of Ctrl. - - - - - - - - - - - - - - - - - - - widget bin - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Key ComboFunction
`F1` widget properties dialog
`F2` move widget earlier in tree
`F3` move widget later in tree
`F7` group widgets
`F8` ungroup widgets
`Delete` delete selected widgets
`Ctrl-1..9` load project from history
`Alt-1` label text tiny
`Alt-2` lLabel text small
`Alt-3` label text normal
`Alt-4` label text medium
`Alt-5` label text large
`Alt-6` label text huge
`Ctrl-A` select all
`Shift-Ctrl-A` select none
`Alt-B`
`Ctrl-C` copy widgets
`Shift-Ctrl-C` generate C code
`Ctrl-G` grid setting dialog
`Alt-G` execute again
`Shift-Alt-G` FLTK settings dialog
`Ctrl-I` insert design into project
`Ctrl-N` new design
`Shift-Ctrl-N` new design from template
`Ctrl-O` open design file
`Shift-Ctrl-O` toggle overlays
`Ctrl-P` print all windows
`Alt-P` project settings
`Shift-Alt-P` Fluid settings dialog
`Ctrl-Q` quit Fluid
`Ctrl-S` save design
`Shift-Ctrl-S` save design with new name
`Shift-Alt-S` source view window
`Ctrl-U` duplicate widgets
`Ctrl-V` paste widgets
`Shift-Ctrl-W` write text strings
`Ctrl-X` cut selected Widgets
`Alt-X` show 'execute command' dialog
`Ctrl-Z` undo
`Shift-Ctrl-Z` redo
Key ComboFunction in interactive Window
`LMB` select one widget
`Shift-LMB` extend widget selection
`Shift-LMB-Drag` window only: resize proportional
`Tab` select next
`Shift-Tab` select previous
`Arrow` move by one unit
`Shift-Arrow` resize by one unit
`Ctrl-Arrow` move by grid units
`Shift-Ctrl-Arrow` resize by grid units
- -\section fluid_licenses Licenses - -FLUID uses graphical images based on the Zendesk Garden Stroke icon set: -https://github.com/zendeskgarden. -Garden Stroke is licensed under the Apache License, Version 2.0: -https://www.apache.org/licenses/LICENSE-2.0.html. - -\htmlonly -
- - - - - - -
- - [Prev] - Using OpenGL - - - [Index] - - - FLTK Runtime Options - [Next] - -
-\endhtmlonly - -*/ diff --git a/documentation/src/fluid1.png b/documentation/src/fluid1.png deleted file mode 100644 index dbded1c3a..000000000 Binary files a/documentation/src/fluid1.png and /dev/null differ diff --git a/documentation/src/fluid2.png b/documentation/src/fluid2.png deleted file mode 100644 index 7c8faca2a..000000000 Binary files a/documentation/src/fluid2.png and /dev/null differ diff --git a/documentation/src/fluid3-cxx.png b/documentation/src/fluid3-cxx.png deleted file mode 100644 index 57ed92d95..000000000 Binary files a/documentation/src/fluid3-cxx.png and /dev/null differ diff --git a/documentation/src/fluid3-gui.png b/documentation/src/fluid3-gui.png deleted file mode 100644 index 48d564c8a..000000000 Binary files a/documentation/src/fluid3-gui.png and /dev/null differ diff --git a/documentation/src/fluid3-style.png b/documentation/src/fluid3-style.png deleted file mode 100644 index b7d02a2ab..000000000 Binary files a/documentation/src/fluid3-style.png and /dev/null differ diff --git a/documentation/src/fluid4.png b/documentation/src/fluid4.png deleted file mode 100644 index 60cec7458..000000000 Binary files a/documentation/src/fluid4.png and /dev/null differ diff --git a/documentation/src/fluid_widget_cxx.png b/documentation/src/fluid_widget_cxx.png deleted file mode 100644 index c5261fb56..000000000 Binary files a/documentation/src/fluid_widget_cxx.png and /dev/null differ diff --git a/documentation/src/fluid_widget_gui.png b/documentation/src/fluid_widget_gui.png deleted file mode 100644 index df26e7316..000000000 Binary files a/documentation/src/fluid_widget_gui.png and /dev/null differ diff --git a/documentation/src/fluid_widget_style.png b/documentation/src/fluid_widget_style.png deleted file mode 100644 index fd44a0fd0..000000000 Binary files a/documentation/src/fluid_widget_style.png and /dev/null differ diff --git a/documentation/src/index.dox b/documentation/src/index.dox index 48494d229..e82bccfd6 100644 --- a/documentation/src/index.dox +++ b/documentation/src/index.dox @@ -67,11 +67,6 @@ \subpage opengl - \subpage fluid - - \ref fluid_widget_attributes - - \ref fluid_selecting_moving - - \ref fluid_images - \subpage fltk-options \subpage advanced diff --git a/documentation/src/intro.dox b/documentation/src/intro.dox index 7e441b502..48eee0dc8 100644 --- a/documentation/src/intro.dox +++ b/documentation/src/intro.dox @@ -142,6 +142,17 @@ the toolkit, which was already in use by several people, Bill came up with "FLTK", including a bogus excuse that it stands for "The Fast Light Toolkit". +\section intro_fluid FLUID + +FLTK comes bundled with FLUID. FLUID, short for Fast Light User Interface +Designer, is a graphical editor capable of generating C++ source code and +header files ready for compilation. These files ultimately create the graphical +user interface for an application. + +The FLUID User Handbook is available at https://www.fltk.org/documentation.php . +It can also be compiled from the FLTK source repository using the `fluid_docs` +target in the CMake build environment. + \section intro_cmake Building and Installing FLTK with CMake Starting with version 1.4, the recommended FLTK building system diff --git a/documentation/src/opengl.dox b/documentation/src/opengl.dox index 6ab4dc2f7..14f33a625 100644 --- a/documentation/src/opengl.dox +++ b/documentation/src/opengl.dox @@ -164,9 +164,7 @@ loading functions by doing: Your main program can now create one of your windows by doing new MyWindow(...). -You can also use your new window class in -\ref fluid "FLUID" -by: +You can also use your new window class in FLUID by: -# Putting your class definition in a \p MyWindow.H file. -# Creating a Fl_Box widget in FLUID. @@ -670,8 +668,8 @@ Link with libGLEW.so (with X11 or Wayland), libglew32.a (with MinGW) or glew32.l [Index]
- - Programming with FLUID + + FLTK Runtime Options [Next]
+ + + + +
+ \image html fluid-128.png + \image latex fluid-128.png "" width=3cm +
+ FLUID 1.4.0 User Manual + + By F. Costantini, D. Gibson, M. Melcher, + A. Schlosser, B. Spitzak and M. Sweet. + + Copyright © 1998 - 2024 by Bill Spitzak and others. +
+ + + + + +
+ This software and manual are provided under the terms of the GNU + Library General Public License. Permission is granted to reproduce + this manual or any portion for any purpose, provided this copyright + and permission notice are preserved. +
+ + + + + + +
+ + \subpage page_introduction + - \ref introduction_workflow + + \subpage page_commandline + - \ref commandline_options + - \ref commandline_passive + - \ref commandline_windows + + \subpage page_interactive + + \subpage page_main_window + - \ref main_titlebar + - \ref main_menubar + - \ref main_widget_browser + - \ref main_menu_items + + \subpage page_widgetbin_panel + + \subpage page_edit_window + - \ref edit_selection + - \ref edit_layout + - \ref edit_snap + - \ref edit_resize + + \subpage page_widget_panel + - \ref widget_panel_gui + - \ref widget_panel_style + - \ref widget_panel_cpp + - \ref widget_panel_grid + - \ref widget_panel_gridc + + + + \subpage page_functional_nodes + - \ref functional_function + - \ref functional_code + - \ref functional_codeblock + - \ref functional_decl + - \ref functional_declblock + - \ref functional_class + - \ref functional_widgetclass + - \ref functional_comment + - \ref functional_data + + \subpage page_codeview_panel + - \ref codeview_find + - \ref codeview_settings + + \subpage page_setting_dialog + - \ref setting_general + - \ref setting_project + - \ref setting_layout + - \ref setting_shell + - \ref setting_i18n + - \ref setting_user + + \subpage page_tutorial + - \ref fluid_hello_world_tutorial + - \ref fluid_1of7guis_tutorial + - \ref fluid_cubeview_tutorial + - \ref fluid_cubeview_ui + - \ref fluid_addconst + - \ref fluid_gencode + + \subpage page_appendices + - \ref appendix_keyboard_shortcuts + - \ref appendix_fileformat + - \ref appendix_licenses + +
+ + \endcond + +*/ diff --git a/fluid/documentation/src/main_titlebar.png b/fluid/documentation/src/main_titlebar.png new file mode 100644 index 000000000..128ecddef Binary files /dev/null and b/fluid/documentation/src/main_titlebar.png differ diff --git a/fluid/documentation/src/page_appendices.dox b/fluid/documentation/src/page_appendices.dox new file mode 100644 index 000000000..4b352ce71 --- /dev/null +++ b/fluid/documentation/src/page_appendices.dox @@ -0,0 +1,92 @@ +/** + + \page page_appendices Appendices + + \tableofcontents + + +\section appendix_keyboard_shortcuts Keyboard Shortcuts + +On Apple computers, use the Apple Command key instead of Ctrl. + +| Key Combo | Function | +| :-------: | :------- | +| `F1` | open widget dialog | +| `F2` | move widget earlier in tree | +| `F3` | move widget later in tree | +| `F7` | move widgets into group | +| `F8` | ungroup widgets | +| `Delete` | delete selected widgets | +| `Ctrl-1..9` | load project from history | +| `Ctrl-A` | select all | +| `Shift-Ctrl-A` | select none | +| `Alt-B` | show or hide Widget Bin | +| `Ctrl-C` | copy widgets | +| `Alt-C` | show or hide Code View window | +| `Shift-Ctrl-C` | generate C++ code files | +| `Ctrl-G` | grid setting dialog | +| `Ctrl-I` | merge project file into current project | +| `Ctrl-N` | start a new project, close the current project | +| `Shift-Ctrl-N` | new project from template | +| `Ctrl-O` | open project file | +| `Shift-Ctrl-O` | toggle overlays | +| `Ctrl-P` | print all visible project windows | +| `Alt-P` | open FLUID settings dialog | +| `Ctrl-Q` | quit FLUID | +| `Ctrl-S` | save project | +| `Shift-Ctrl-S` | save project with new name | +| `Ctrl-U` | duplicate selected widgets | +| `Ctrl-V` | paste last copied widgets | +| `Shift-Ctrl-W` | write i18n translation file | +| `Ctrl-X` | cut selected widgets | +| `Alt-X` | show shell command settings | +| `Ctrl-Z` | undo | +| `Shift-Ctrl-Z` | redo | + + + + +| Action | Function in Layout Editor | +| :----: | :------------------------ | +| `left mouse button (LMB)` | select one widget | +| `LMB-drag` | select multiple widgets with selection box | +| `Shift-LMB` | extend widget selection | +| `Shift-LMB-Drag` | toggle selection in selection box | +| `Shift-LMB-Drag` | resize window proportionally | +| `Tab` | select next widget | +| `Shift-Tab` | select previous widget | +| `Arrow` | move selected widgets by one unit | +| `Shift-Arrow` | resize by one unit | +| `Ctrl-Arrow` | move by grid units | +| `Shift-Ctrl-Arrow` | resize by grid units | + + + + +\section appendix_fileformat .fl File Format + +FLUID edits and saves its state in `.fl` project files. These files are text, +and you can (with care) edit them in a text editor, perhaps to get some special +effects. The `.fl` file format is described in detail in the file +`fluid/README_fl.txt` which is part of the FLTK source code repository. + + + +\section appendix_licenses External Licenses + +FLUID uses graphical images based on the Zendesk Garden Stroke icon set: + +[https://github.com/zendeskgarden](https://github.com/zendeskgarden) +Garden Stroke is licensed under the +[Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.html). + +FLUID includes templates based on 7GUIs: + +[7GUIs](https://7guis.github.io/7guis/) was created as a spin-off +of the master’s thesis Comparison of Object-Oriented and Functional +Programming for GUI Development by Eugen Kiss at the Human-Computer +Interaction group of the Leibniz Universität Hannover in 2014. + +With kind permission by Prof. Dr. Michael Rohs. + + */ diff --git a/fluid/documentation/src/page_codeview_panel.dox b/fluid/documentation/src/page_codeview_panel.dox new file mode 100644 index 000000000..2fac1a286 --- /dev/null +++ b/fluid/documentation/src/page_codeview_panel.dox @@ -0,0 +1,76 @@ +/** + + \page page_codeview_panel Code View Panel + + \tableofcontents + + # The Code View Panel # + + \image html codeview_panel.png "Code View Panel" + \image latex codeview_panel.png "Code View Panel" width=9cm + + The Code View panel shows all code files that can be generated by FLUID. + + The Code View window can be activated via the main + menu: *Edit* > *Show Source Code* . FLUID will remember the state and + dimensions of the Code View panel. + + If the Auto-Refresh option is selected, the code views will be updated + automatically while editing the project. + + Code View has four tabs. The first tab shows the source code. Inlined data + is omitted in the code view for brevity. + + The second tab shows the content of the header file. The size of inline data + is not calculated and shown as `-1`. + + The third tab shows the list of labels and tooltips as they would be written + to a translation file, using the selected project internationalization method. + + The fourth tab previews the contents of the `.fl` project file. + + + \section codeview_find Code View Find + + \image html cv_find_row.png + \image latex cv_find_row.png "Find in Code" width=9cm + + This group of buttons makes it easy to find any text in the Source, Header, or + Project file. Press *Reveal* to select the widget that generated the indicated + line of code. + + __Find__: enter any text you may want to find in the current tab + + __aA__: press this button to activate case sensitive search + + __<<__, __>>__: find the previous or next occurrence + + __Reveal__: clicking this button reveals the widget that generated the + selected code in the widget browser + + + \section codeview_settings Code View Settings + + \image html cv_settings_row.png + \image latex cv_settings_row.png "Code View Settings" width=9cm + + __Refresh__: preview the code in the selected tab as it would be generated + for the project in its current state + + __Auto-Refresh__: Automatically refresh the code view when the project changes. + The Auto Refresh is designed to use relatively little resources, even when + continuously updating the selected code tab. + The Code View window can usually stay open and auto refresh during the entire + design process, even for relatively complex GUIs. + + __Auto-Position__: highlight and reposition to the source code generated by + the currently selected widget whenever the selection changes + + __code...__: choose the type of code that is highlighted. In source + files, *static* code is generated by Menu Items, *code* refers to widget + creation code, *code1* is the part before possible children, *code2* is + code generated after children. In header files, *static* highlights + `#include` statements generated by a widget, *code* refers to + the widget declaration. + +*/ diff --git a/fluid/documentation/src/page_commandline.dox b/fluid/documentation/src/page_commandline.dox new file mode 100644 index 000000000..b89c5f3d4 --- /dev/null +++ b/fluid/documentation/src/page_commandline.dox @@ -0,0 +1,124 @@ +/** + + \page page_commandline Command Line + + \tableofcontents + + FLUID can be used in interactive and in command line mode. If launched with + `-c`, followed by a project filename, FLUID will convert the project file + into C++ source files without ever opening a window (or opening an X11 server + connection under Linux/X11). This makes FLUID a great command line tool + for build processes with complex project files that reference + external resources. For example, an image referenced by a `.fl` file can be + modified and recompiled into the application binary without the need to reload + it in an interactive FLUID session. + + + \section commandline_options Command Line Options + + To launch FLUID in interactive mode from the command line, you can give it an + optional name of a project file. If no name is given, it will launch with an + empty project, or with the last open project, if so selected in the + application setting dialog. + + The ampersand `&` is optional on Linux machines and lets FLUID run in its + own new process, giving the shell back to the caller. + + ``` + fluid filename.fl & + ``` + +If the file does not exist you will get an error pop-up, but if you dismiss it +you will be editing a blank file of that name. + +FLUID understands all of the standard FLTK switches before the filename: + +``` +-display host:n.n +-geometry WxH+X+Y +-title windowtitle +-name classname +-iconic +-fg color +-bg color +-bg2 color +-scheme schemename +``` + + + \section commandline_passive Compile Tool Options + +FLUID can also be called as a command-line only tool to create +the `.cxx` and `.h` file from a `.fl` file directly. To do this type: + +``` +fluid -c filename.fl +``` + +This is the same as the menu __File > Write Code...__ . +It will read the `filename.fl` file and write +`filename.cxx` and `filename.h`. Any leading +directory on `filename.fl` will be stripped, so they are +always written to the current directory. If there are any errors +reading or writing the files, FLUID will print the error and +exit with a non-zero code. You can use the following lines in a +Makefile to automate the creation of the source and header +files: + +``` +my_panels.h my_panels.cxx: my_panels.fl + fluid -c my_panels.fl +``` + +Most versions of "make" support rules that cause `.fl` files to be compiled: + +``` +.SUFFIXES: .fl .cxx .h +.fl.h .fl.cxx: + fluid -c $< +``` + +Check `README.CMake.txt` for examples on how to integrate FLUID into the +`CMake` build process. + +If you use + +\code +fluid -cs filename.fl +\endcode + +FLUID will also write the "strings" for internationalization into the file +'filename.txt', 'filename.po', or 'filename.msg', depending on the chosen type +of i18n (menu: 'File/Write Strings...'). + +Finally there is another option which is useful for program developers +who have many `.fl` files and want to upgrade them to the current FLUID +version. FLUID will read the `filename.fl` file, save it, and exit +immediately. This writes the file with current syntax and options and +the current FLTK version in the header of the file. Use + +``` +fluid -u filename.fl +``` + +to 'upgrade' `filename.fl` . You may combine this with `-c` or `-cs`. + +\note All these commands overwrite existing files w/o warning. You should +particularly take care when running `fluid -u` since this overwrites the +original `.fl` project file. + + + \section commandline_windows Windows Specifics + + FLTK uses Linux-style forward slashes to separate path segments in file names. + When running on Windows, FLUID will understand Microsoft drive names and + backward slashes as path separators and convert them internally into + forward slashes. + + Under Windows, binaries can only be defined either as command line tools, or + as interactive apps. FLTK generates two almost identical binaries under + Windows. `fluid.exe` is meant to be used in interactive mode, and + `fluid-cmd.exe` is generated for the command line. Both tools do exactly the + same thing, except `fluid-cmd.exe` can use stdio to output error messages. + +*/ diff --git a/fluid/documentation/src/page_edit_window.dox b/fluid/documentation/src/page_edit_window.dox new file mode 100644 index 000000000..7cbbf5de5 --- /dev/null +++ b/fluid/documentation/src/page_edit_window.dox @@ -0,0 +1,179 @@ +/** + + \page page_edit_window Layout Editor Window + + \tableofcontents + + \image html edit_window.png "Layout Editor Window" + \image latex edit_window.png "Layout Editor Window" width=7cm + + The Layout Editor window is used to interactively add groups and widgets, and + resize and align them. The editor window already looks very much like the + final product that will be built by the FLUID generated C++ source code. + + To create a user interface, first add a function to the project tree by either + clicking the Function icon in the widget bin, or by selecting __New* > Code > + Function/Method__ from the main menu. + + Now just drag the Window icon from the widget bin onto the desktop. FLUID + will generate code that instantiates this window when the function is called. + The return value of the function is a pointer to that window, unless changed + in the Function Panel. Widgets can be added to the window by dragging them from + the widget bin. If a widget is dropped on a group, it will automatically + become a child of that group. + + + \section edit_selection Selecting and Moving Widgets + + To move or resize a widget, it must be selected first by clicking on it. + Multiple widgets can be selected by holding down the Shift key when clicking + on them, or by dragging a selection box around widgets. Widgets can also be + selected in the widget browser the main window. Shift-click will select a + range of widgets, Ctrl-click will add widgets to the selection. + + \image html edit_select_multiple.png + \image latex edit_select_multiple.png "Select Multiple Widgets" width=5cm + + Menu items are selected by clicking on the menu button and selecting it from + the popup menu. Multiple menu items can only be selected in the widget browser + in the main application window. + + Once selected, widgets can be moved by clicking and dragging the center + of the selection box. The outer edges allow resizing in one direction, and + dragging the corners resizes widgets horizontally and vertically. + + Widgets can also be repositioned with the arrow keys. Without a shift key, + the selection moves by a single pixel. With the Meta key held down, they + move by the amount indicated in the *Gap* field in the *Widget* section of + the *Layout* setting panel. + + Holding down the Shift key resizes a selected widget by moving the bottom + right corner of the widget. Holding Shift and Meta while pressing arrow keys + resizes by the amount in the *Widget* *Gap* layout setting. + + Children of groups that reposition their contained widgets may behave + differently. Pressing the arrow keys on children of `Fl_Grid` will move + the widget from grid cell to grid cell instead. Resizing a child of `Fl_Flex` + will also mark the child size as `fixed`. + + The tab and shift+tab keys "navigate" the selection. Tab or shift+tab move to + the next or previous widgets in the hierarchy. If the navigation does not seem + to work you probably need to "Sort" the widgets. This is important if you have + input fields, as FLTK uses the same rules when using tab keys + to move between input fields. + + + \section edit_layout Layout Helpers + + \image html edit_overlap.png + \image latex edit_overlap.png "Overlapping Widgets" width=5cm + + In FLTK, the behavior of overlapping children of a group is undefined. If + enabled in the settings, FLUID will show overlapping widgets in a group + with a green hash pattern. + + \image html edit_outside.png + \image latex edit_outside.png "Out Of Bounds" width=5cm + + The behavior of widgets that reach outside the bounds of their parent group + is also undefined. They may be visible, but confuse the user when they don't + react to mouse clicks or don't redraw as expected. Outside widgets are marked + with a red hash pattern. + + Note that `Fl_Tile` requires that all children exactly fill the area of the + tile group to function properly. The hash patterns are great helpers to align + children correctly. + + + \section edit_snap Layout Alignment + + FLUID layouts are a handful of rules that help creating a clean and consistent + user interface. When repositioning widgets, the mouse pointer snaps to the + closest position based on those rules. A guide line is drawn for the rule that was + applied. Guides and snaps can be disabled with `Ctrl-Shift-G` or via the + *Edit* > *Hide Guides* menu. + + \image html edit_snap_group.png + \image latex edit_snap_group.png "Snap To Group" width=5cm + + If a horizontal or vertical outline snaps to the group, the + border of that group will highlight. If the outline snaps to the margin + of the parent window or group, an additional arrow is drawn. + + Children of `Fl_Tabs` use the top and bottom margin from the *Tabs* + section. If all children use this rule, the margin height will also be the + height of all tabs. + + \image html edit_snap_sibling.png + \image latex edit_snap_sibling.png "Snap To Sibling" width=5cm + + The selection can also snap to the outline of other widgets in the same group, + or to the outline plus the Widget Gap. The outline that triggers the snap + action is highlighted. + + Note that only the first snap guide found is drawn for horizontal and vertical + movement. Multiple rules may apply, but are not highlighted. + + \image html edit_snap_size.png + \image latex edit_snap_size.png "Snap To Size" width=7cm + + Widget size rules define a minimum size and an increment value that may + be applied multiple times to the size. For example, with a minimum width of 25 + and an increment of 10, the widget will snap horizontally to 25, 35, 45, + 55, etc. . + + \image html edit_snap_grid.png + \image latex edit_snap_grid.png "Snap To Grid" width=5cm + + The grid rule is the easiest to explain. All corners of a selection snap to + a fixed grid. If the selected widgets are children of a window, they will snap + to the window grid. If they are in a group, they snap to the group grid. + + + \section edit_resize Live Resize + + \image html edit_select_group.png + \image latex edit_select_group.png "Selected Group" width=9cm + + The Resizable system within FLTK is smart, but not always obvious. When + constructing a sophisticated GUI, it is helpful to organize widgets into + multiple levels of nested groups. Sometimes, incorporating an invisible + resizable box can improve the behavior of a group. FLUID offers a Live Resize + feature, allowing designers to experiment with resizing at each level within + the hierarchy independently. + + To test the resizing behavior of a group, begin by selecting it: + + \image html edit_live_resize.png + \image latex edit_live_resize.png "Live Resize" width=7cm + + Click on *Live Resize* in the widget panel. FLUID will generate a new window + with all the resizing attributes inherited from the original design. This + enables the designer to thoroughly test the behavior and limitations, + making adjustments until they are satisfied. This streamlined process makes + it significantly easier to address resizing behavior at a higher level, + particularly once the lower levels are behaving as intended. + + In the example above, the radio buttons are not fixed to the left side of + the group and the text snippet "of the bed" does not stay aligned + to "right side". To fix this, a thin hidden box could be added to the right + edge of the group that holds the radio button which is then marked `resizable`. + + + \section edit_limits Limitations + + Almost all FLTK widgets can be edited with FLUID. Notable exceptions include + + - FLUID does not support an `Fl_Window` inside another `Fl_Window` + - widgets inside `Fl_Scroll` can not be created in the hidden areas of the + scrollable rectangle. It is recommended to organize the children in + a separate Widget Class that is derived from `Fl_Scroll` and then inserted + as a single custom widget. + - children of `Fl_Pack` are not automatically reorganized to fit the packing + group. Again, a Widget Class is recommended here. + - if children of `Fl_Grid` are again some kind of group, their internal layout + may not follow changes in the grid widgets. It's best to complete the grid + first, then add children to the grid cells, size them correctly, and + then finally lay out the grid cell children. + +*/ diff --git a/fluid/documentation/src/page_functional_nodes.dox b/fluid/documentation/src/page_functional_nodes.dox new file mode 100644 index 000000000..4407f0e38 --- /dev/null +++ b/fluid/documentation/src/page_functional_nodes.dox @@ -0,0 +1,450 @@ +/** + + \page page_functional_nodes Functional Node Panels + + \tableofcontents + + + + \section functional_function Function and Method Panel + + ![](flFunction.png) Functions and Methods + + Fluid can generate C functions, C++ functions, and methods in classes. + Functions can contain widgets to build windows and dialogs. *Code* nodes can + be used to add more source code to a function. + + ### Parents ### + + To generate a function, the function node must be created at the top level or + inside a declaration block. If added inside a class node, this node generates + a method inside that class. + + ### Children ### + + Function nodes can contain code nodes and windows that in turn contain widgets. + If the function node has no children, only a forward declaration will be + created in the header, but no source code will be generated. + + \image html function_panel.png "Function/Method Properties" + \image latex function_panel.png "Function/Method Properties" width=7cm + + ### Declaring a Function ### + + A function node at the top level or inside a declaration block generates a C + or C++ function. + + The *Name* field contains the function name and all arguments. + If the *Name* field is left empty, Fluid will generate a typical 'main()' function. + ``` + // .cxx + int main(int argc, char **argv) { + // code generated by children + w->show(argc, argv); // <-- code generated if function has a child widget + Fl::run(); + } + ``` + + If a function node has a name but no children, a forward declaration is + generated in the header, but the implementation in the source file is omitted. + This is used to reference functions in other modules. + ``` + // .h + void make_window(); + ``` + + If the function contains one or more Code nodes, the implementation code will + be generated. The default return type is `void`. Text in the *Return Type* field + overrides the default type. + ``` + // .cxx + void make_window() { + // code generated by children + } + ``` + + If the function contains one or more windows, a pointer to the first window + will be returned. The default return type will match the window class. + ``` + // .h + Fl_Window* make_window(); + ``` + + ``` + // .cxx + Fl_Window* make_window() { + Fl_Window* w; + // code generated by children: + // w = new Fl_Window(...) + return w; + } + ``` + + #### Options for Functions #### + + Choosing *static* in the pulldown menu will generate the function `static` in + the source file. No forward declaration will be generated in the header file. + ``` + // .cxx + static Fl_Window* make_window() { ... } + ``` + + Choosing *global* will generate a forward declaration of the function in the + header file and no `static` attribute in the source file. + ``` + // .h + void make_window(); + // .cxx + Fl_Window* make_window() { ... } + ``` + + Additionally, + if the *C* option is checked, the function will be declared as a plain C + function in the header file. + ``` + // .h + extern "C" { void my_plain_c_function(); } + // .cxx + void my_plain_c_function() { ... } + ``` + + The *local* option will generate a function in the source file with no `static` + attribute. No forward declaration will be generated in the header file. + ``` + // .cxx + Fl_Window* make_window() { ... } + ``` + + ### Declaring a Method ### + + A function node inside a class node generates a C++ method. If a method node has + no children, the declaration is generated in the header, but no implementation + in the source file. + ``` + // .h + class UserInterface { + public: + void make_window(); + }; + ``` + + If the method contains one or more Code nodes, an implementation will also be + generated. + + ``` + // .cxx + void UserInterface::make_window() { + printf("Hello, World!\n"); + } + ``` + + If the method contains at least one widget, a pointer to the topmost widget + will be returned and the return type will be generated accordingly. + ``` + // .h + class UserInterface { + public: + Fl_Double_Window* make_window(); + }; + ``` + + ``` + // .cxx + Fl_Double_Window* UserInterface::make_window() { + Fl_Double_Window* w; + // code generated by children + return w; + } + ``` + + #### Options for Methods #### + + Class access can be defined with the pulldown menu. It provides a choice of + `private`, `protected`, and `public`. + + Fluid recognizes the keyword `static` or `virtual` at the beginning of the + *return type* and will generate the declaration including the keyword, but will + omit it in the implementation. The return type defaults still apply if there + is no text after the keyword. + + #### Further Options #### + + Users can define a comment text in the *comment* field. The first line of the + comment will be shown in the widget browser. The comment text will be generated + in the source file before the function. + ``` + // .cxx + // + // My multilen comment will be here... . + // Fluid may actually use C style comment markers. + // + Fl_Window* make_window() { + ``` + + FLUID recognizes default values in the argument list and generates them in the + declaration, but omits them in the implementation. + + A short function body can be appended in the *Name* field. With no child, this + creates an inlined function in the header file. + + + + \section functional_code C Source Code + + ![](flCode.png) Code + + Code nodes hold arbitrary C++ code that is copied verbatim into the + source code file. They are commonly used inside Function nodes. + + ### Parents ### + + Code nodes can be added inside Functions, Code Blocks, and Widget Classes. + + \image html code_panel.png "Code Properties" + \image latex code_panel.png "Code Properties" width=9cm + + The Code Properties panel features a syntax-highlighting C++ code editor. + Some basic bracket and braces match checking is done when closing the dialog. + + When inside a Function or Code Block, the C++ code is inserted directly. + Inside a Widget Class, the code will be added to the constructor of the + widget class. + + + + \section functional_codeblock Code Block + + ![](flCodeBlock.png) Code Block + + Code Blocks are used when a single function generates different GUI elements + conditionally. + + ### Parents ### + + Code Blocks are used inside functions and methods. + + ### Children ### + + Code Blocks can contain widgets, code, or more code blocks. + + \image html codeblock_panel.png "Code Block Properties" + \image latex codeblock_panel.png "Code Block Properties" width=7cm + + The two fields expect the code before and after the `{ ... }` statements. The + second field can be empty. + + Two consecutive Code Blocks can be used to generate `else`/`else if` + statements by leaving the second field of the first node empty. + + + + \section functional_decl Declaration + + ![](flDeclaration.png) Declaration + + ### Parents ### + + Declarations can be added at the top level or inside classes and widget classes. + + \image html decl_panel.png "Declaration Properties" + \image latex decl_panel.png "Declaration Properties" width=7cm + + Declaration nodes are quite flexible and can be a simple variable declaration + such as `int i;`. But include statements are also allowed, as are type + declarations, and comments. FLUID does its best to understand user intention, + but the generated code should be verified by the user. + + Declarations nodes at the top level can selectively generate code in the header + and /or in the source file. If a declaration is inside a class, the user can + select if the class member is *private*, *protected*, or *public* instead. + + + + \section functional_declblock Declaration Block + + ![](flDeclarationBlock.png) Declaration Block + + Declaration Blocks are a way to selectively compile child nodes via + preprocessor commands, typically `#ifdef TEST` and `#endif`. + + ### Parents ### + + Declaration Blocks can be created at the top level or inside classes. + + ### Children ### + + Declaration Blocks can contain classes, functions, methods, declarations, and + comments. + + \image html declblock_panel.png "Declaration Block Properties" + \image latex declblock_panel.png "Declaration Block Properties" width=7cm + + Users can select if the block is generated in the source file only, or in the + header file as well. The two input fields are used to enter the line of code + before and after the child nodes. Two consecutive Declaration Blocks can be + used to generate `#else`/`#elif` style code by leaving the second field of + the first node empty. + + \note Declaration Blocks are not smart, and child nodes may still generate + unexpected code outside the scope of this block. This may change in future + versions of FLUID. + + + + \section functional_class Classes + +![](flClass.png) Class + + FLUID can generate code to implement C++ classes. Classes can be used to keep + dialogs and groups of UI elements organized. See Widget Class nodes as an + alternative to implement compound widgets. + + ### Parents ### + + Class nodes can be created at top level or inside a Class or Widget + Class node. + + ### Children ### + + Class nodes can contain Functions, Declarations, Widgets, Data, and + other classes. + + \image html class_panel.png "Class Properties" + \image latex class_panel.png "Class Properties" width=7cm + + The *Name:* and *Subclass of:* fields should be set to standard C++ class + names. + + Function nodes inside classes are implemented as methods. Constructors and + destructors are recognized and implemented as such. Inlined data is declared + as a static class member. + + Note that methods without a code or widget node are only declared in the + header file, but no code is generated for them in the source file. + + + + \section functional_widgetclass Widget Class + + ![](flWidgetClass.png) Widget Class + + The Widget Class node creates a new widget type by deriving a class from another + widget class. These are often compound widgets derived from `Fl_Group`. A less + automated but more flexible way to implement compound widgets is the Class node. + + ### Parents ### + + Widget Class nodes can be created at top level or inside a Class or Widget + Class node. + + ### Children ### + + Widget Class nodes can contain Functions, Declarations, Widgets, Data, and + other classes. + + ### Properties ### + + Widget Class nodes use the Widget panel to edit their properties. The super + class can be set in the *C++* tab in the *Class* field. If that field is empty, + FLUID derives from `Fl_Group`. + + The Widget Class always creates a constructor with the common widget parameters: + ``` + MyWidget::MyWidget(int X, int Y, int W, int H, const char *L) + : Fl_Group(X, Y, W, H, L) { ... } + ``` + + If the super class name contains the text `Window`, two more constructors + and a common initializer method are created: + ``` + MyWidget::MyWidget(int W, int H, const char *L) : + Fl_Window(0, 0, W, H, L) { ... } + + MyWidget::MyWidget() : + Fl_Window(0, 0, 480, 320, 0) { ... } + + void MyWidget::_MyWidget() { ... } + ``` + + Code and Widget nodes are then added to the constructor. Function nodes are + added as methods to the class. Declarations are added as class members. + Data nodes generate static class members. + + It may be useful to design compound widgets with a variable size. The Widget + Panel provides a choice menu in the *GUI* tab's *Position* row under + *Children*. The options *resize* and *reposition* generate code to fix up + the coordinates of the widget after instantiation. + + Note that methods without a code or widget node are only declared in the + header file, but no code is generated for them in the source file. + + + + \section functional_comment Comments + + ![](flComment.png) Comment + + This node adds a comment block to the generated source code. + + ### Parents ### + + Comment nodes can be added inside Functions, Code Blocks, and Widget Classes. + If a Comment node is the top node in a tree, it will appear in the source + files even before the `// generated by FLUID ...` line. + + \image html comment_panel.png "Comment Properties" + \image latex comment_panel.png "Comment Properties" width=9cm + + Comment blocks are generated by adding `// ` to the start of each line unless + the first line of a comment starts with `/``*`. In that case, FLUID assumes + a correct block comment and will copy the text verbatim. + + Comments can be generated in the header file, the source file, or both. + + FLUID keeps a small database of predefined comments. Users can add reoccurring + comment blocks, license information for example, to this database via the + pulldown menu. + + Comments can also be imported from an external file. + + + + \section functional_data Inlined Data + + ![](flData.png) Inlined Data + + The Data node makes it easy to inline data from an external file into the + source code. + + ### Parents ### + + Data nodes can be added at the top level or inside Widget Classes, Classes, + and Declaration Blocks. + + \image html data_panel.png "Data Properties" + \image latex data_panel.png "Data Properties" width=7cm + + At top level, or inside a Declaration Block, Data can be declared *in source + file only*, *static in source file*, or *in source and extern in header*. + + If Data is inside a Class node, it is always declared `static`. The user can + select *private*, *protected*, or *public*. + + Data in binary mode will be stored in an `unsigned char` array. The data size + can be queried with `sizeof()`. In Text mode, it will be stored as `const + char*` and terminated with a `NUL` character. + + In compressed mode, data will be compressed with zlib `compress()` and stored + in an `unsigned char` array. A second variable, holding the original data size, + is declared `int` by appending `_size` to the variable name. + + ``` + // .cxx + int myInlineData_size = 12034; + unsigned char myInlineData[380] = { 65, 128, ... }; + ``` + + The Variable Name should be a regular C++ name. The Filename field expects + the path and name of a file, relative to the location of the .fl file. + + */ diff --git a/fluid/documentation/src/page_interactive.dox b/fluid/documentation/src/page_interactive.dox new file mode 100644 index 000000000..58f46b130 --- /dev/null +++ b/fluid/documentation/src/page_interactive.dox @@ -0,0 +1,57 @@ +/** + + \page page_interactive Interactive Mode + + \tableofcontents + + + + In interactive mode, FLUID allows users to construct and modify their GUI + design by organizing widgets hierarchically through drag-and-drop actions. + The project windows provide a live preview of the final UI layout. + Most widget attributes can be adjusted in detail using the + \ref page_widget_panel. + + Users can also incorporate C++ coding elements such as functions, code blocks, + and classes. FLUID supports the integration of external sources, for + example images, text, or binary data, by embedding them directly into the + generated source code. + + \image html fluid_gui_overview_800.png + \image latex fluid_gui_overview_800.png "FLUID Overview" + + A typical FLUID session manages the widget hierarchy in the main application + window on the left. The project file name is shown in the title bar. In the + example above, we edit the FLTK _Preferences_ example file + `test/preferences.fl`. + + \see \ref page_main_window + + The layout editor window left of center, titled + "My Preferences" shows the GUI design as it will be generated by the C++ + source file. The widgets "shower", "shave", and "brush teeth" are shown + in their selected state and can now be resized or moved by grabbing any of + the red boxes around the selection frame. + + \see \ref page_edit_window + + To the right, we have the "Widget Properties" panel. We can use this to + edit many more parameters of the selected widget. If multiple widgets are + selected, changes are applied to all of them where appropriate. + + \see \ref page_widget_panel + + The Widget Bin at the top is an optional tool bar (__Edit > Show Widget Bin__, + Alt-B). It gives quick access to all widget and code types. Widgets can + be added by clicking onto the tool, or by dragging them out of the tool box + into the layout editor. + + \see \ref page_widgetbin_panel + + The optional panel on the right shows a live source code preview. This is + very helpful for verifying how changes in the GUI will be reflected in the + generated C++ code (__Edit > Show Code View__, Alt-C). + + \see \ref page_codeview_panel + +*/ diff --git a/fluid/documentation/src/page_introduction.dox b/fluid/documentation/src/page_introduction.dox new file mode 100644 index 000000000..890dc3718 --- /dev/null +++ b/fluid/documentation/src/page_introduction.dox @@ -0,0 +1,69 @@ +/** + + \page page_introduction Introduction + + \tableofcontents + + + + \image latex fluid-128.png "FLUID" width=3cm + + FLUID, short for Fast Light User Interface Designer, is a graphical editor + capable of generating C++ source code and header files ready for compilation. + These files ultimately create an FLTK based graphical user interface + for an application. + + The FLTK programming manual is available at https://www.fltk.org/documentation.php . + + This manual provides instructions on launching FLUID as a command line tool + and integrating `.fl` project files into the application build process. + FLTK utilizes _CMake_, but other build systems and IDEs capable of running + external tools can also build applications based on FLUID. + + The majority of the manual focuses on using FLUID as an interactive GUI + design tool. It covers an overview of windows, menu items, and dialog boxes, + detailing how to create visually appealing and consistent user experiences + through drag and drop functionality, a "what you see is what you get" editor, + and alignment tools. The \ref page_setting_dialog will detail the process of initiating + a new project, creating an alignment template, and incorporating + internationalization. + + Several tutorials will explain how to generate small apps in FLUID alone, + and how to create more complex user interfaces, followed by some advanced + subjects like creating integrated reusable widget classes. + + The appendices contain additional technical information for reference. + + + + \section introduction_workflow Workflow + + FLUID stores user interface designs within `.fl` project files. These files + are transformed into a binary application through a multi-step process. + Initially, FLUID converts `.fl` files into C++ source and header files. + Subsequently, these files are compiled into object files, which are then + linked with other object files to form an executable binary. + FLUID-generated header files give access to UI elements from other C++ modules + within the project. FLUID can also generate forward declarations to + variables and callback functions that are defined and implemented in other + C++ modules. + + \image html fluid_flow_chart_800.png "FLUID Workflow" + \image latex fluid_flow_chart.png "FLUID Workflow" + + Small applications can be fully designed and developed with FLUID alone. + Users have the option to include shell scripts in FLUID projects, enabling + them to directly call compilers and linkers to produce the binaries. + + For medium-sized projects, a build system such as _CMake_ or an IDE + with integrated build setup is recommended. FLUID in interactive mode + can pre-generate C++ code files for direct compilation by the IDE. + + In larger projects, FLUID projects frequently reference external resources + such as graphics, binary data, and internationalized text. + In such scenarios, it is very useful to distribute the `.fl` project files + instead of prebuilt source files. FLUID in command-line mode can then be + called as an external tool, dynamically generating C++ source code from all + external resources at build time. + + */ diff --git a/fluid/documentation/src/page_main_window.dox b/fluid/documentation/src/page_main_window.dox new file mode 100644 index 000000000..005ce01ec --- /dev/null +++ b/fluid/documentation/src/page_main_window.dox @@ -0,0 +1,371 @@ +/** + + \page page_main_window Main Application Window + + \tableofcontents + + \image html main_window.png "Main Application Window" + \image latex main_window.png "Main Application Window" width=5cm + + A FLUID project is a hierarchy of nodes. Each node holds information to + generate C++ source code which in turn generates the user interface that + is created in the layout editor windows. Projects usually define one or more + functions. These functions can generate one or more + FLTK windows and all the widgets that go inside those windows. + + The FLUID Main Window is split into three parts. The title bar shows the + status of the source and project files. The menu bar provides a wealth of + menu items for all major actions in FLUID. The biggest part of the + app window is the widget browser, a tree structure that lists every code + node and widget in the project. + + + \section main_titlebar Title Bar + + \image html main_titlebar.png + \image latex main_titlebar.png "Title Bar" width=5cm + + The title bar shows the status of the project file, _function_panel.fl_ in this + case, followed by an asterisk if the project was changed after it was saved. + If the asterisk shows, FLUID will ask the user to save changes before closing + the project, loading another project, or starting a new one. Pressing `Ctrl-S` + will save the project and make the asterisk disappear. + + The _.cxx_ in the title bar reflects the status of header and source files + in relation to the project. A trailing asterisk indicates that the project and code + files differ. Pressing `Ctrl-Shift-C` to write the code files will make this + asterisk go away. + + \note FLUID currently supports only one open project at a time. + + + \section main_menubar Application Menu Bar + + \image html main_menubar.png + \image latex main_menubar.png "Main Menu" width=5cm + + The menu bar is the true control center of FLUID. All actions start here. + + The *File* menu offers the common file operation for FLUID projects. Projects + can be loaded, merged, and saved. *Print* will print a snapshot of all open + project windows. + The *New From Template* item opens a dialog that provides access to a small + number of sample projects. More projects can be added using *Save as Template*. + + Use *Write Code* to write the header and source code files, and *Write Strings* + to write the translation file if one of the internationalization options + is active. + + The *Edit* menu is mainly used to manipulate widgets within the widget tree. + The bottom entries toggle various dialogs and pop up the settings panel. + + The *New* menu holds a list of all widgets that can be used in FLUID. They + are grouped by functionality, very similarly to the widget bin. New widgets are + added inside or right after the selected widget. If the parent widget is not + compatible, FLUID tries to find another location for the widget. If that also + fails, FLUID will pop up a dialog, describing the required parent type. + + The *Layout* menu is used to adjust the position and size of widgets in + relation to each other. + + The *Shell* menu gives quick access to user definable shell scripts. Note that + scripts can be stored inside `.fl` project files. + + \see \ref main_menu_items + + + \section main_widget_browser Widget Tree View + + \image html main_browser.png + \image latex main_browser.png "Widget Browser" width=5cm + + Widgets are stored in a hierarchy. You can open and close a level by clicking + the "triangle" at the left of a widget. The leftmost widgets are the + \e parents, and all the widgets listed below them are their \e children. + Parents don't have to have any children. + + The top level of the hierarchy is composed of \e functions and + \e classes. Each of these will produce a single C++ public function + or class in the output .cxx file. Calling the function or + instantiating the class will create all of the child widgets. + + The second level of the hierarchy contains the \e windows. + Each of these produces an instance of class Fl_Window. + + Below that are either \e widgets (subclasses of Fl_Widget) or + \e groups of widgets (including other groups). Plain groups are for + layout, navigation, and resize purposes. Tab groups provide the + well-known file-card tab interface. + + Widgets are shown in the browser by either their \e name (such + as "Button emergency_btn" in the example), or by their \e type + and \e label (such as "Double_Window "My Main Window""). + + You \e select widgets by clicking on their names, which highlights + them (you can also select widgets from any displayed window). You can + select many widgets by dragging the mouse across them, or by using + Shift+Click to toggle them on and off. To select no widgets, click in + the blank area under the last widget. Note that hidden children may + be selected even when there is no visual indication of this. + + You \e open widgets by double-clicking on them, or (to open several + widgets you have picked) by typing the F1 key. A control panel will appear + so you can change the widget(s). + + Nodes are moved within their group using + `F2` and `F3`. They can be grouped and ungrouped with `F7` and `F8`, and + relocated by selecting them and using cut, copy, and paste. + + Every line in the browser has the same basic format. The level of indentation + reflects the depth of a node within the tree. + + The triangle appears only in front of nodes that can have children. If it is + white, the group has no children. If it is black, there is at least one child. + If the triangle points to the right, the children are hidden in the tree view. + Click the triangle to reveal all children. + + The icon to the right is a small representation of the base type of the node. + Widgets are gray, windows have a blue title bar, and functional nodes are + green. If the widget is static or private, a padlock icon will appear in the + bottom right corner of the type icon. + + The content of text fields depends on the node type. If a comment is set, it + appears in green over the text. Widgets combine their type (bold black) and + label text (red), or their C++ name in black (not bold). + + All colors and font styles can be customized in the User tab of the + Settings panel. + + + \section main_menu_items The Main Menu + +The "New" menu of the main menu bar is duplicated as a pop-up menu on any +layout editor window. The shortcuts for all the menu items work in any +window. The menu items are: + +__File > New (Ctrl+n)__: Close the current project and start a new, empty project. + +__File > Open... (Ctrl+o)__: Discard the current editing session and read in a +different `.fl` project file. You are asked for confirmation if you have +changed the current file. + +FLUID can also read `.fd` files produced by the Forms and XForms "fdesign" +programs. It is best to _File > Merge_ them instead of opening them. FLUID does +not understand everything in a `.fd` file, and will print a warning message on +the controlling terminal for all data it does not understand. You will probably +need to edit the resulting setup to fix these errors. Be careful not to save +the file without changing the name, as FLUID will write over the `.fd` file +with its own format, which fdesign cannot read! + +__File > Insert... (Ctrl+i)__: Insert the contents of another `.fl` file +without changing the name of the current `.fl` file. All the functions (even if +they have the same names as the current ones) are added, and you will have to +use cut/paste to put the widgets where you want. + +__File > Save (Ctrl+s)__: Write the current data to the `.fl` file. If the +file is unnamed then FLUID will ask for a filename. + +__File > Save As... (Ctrl+Shift+S)__: Ask for a new filename and +save the file. + +__File > Save A Copy...__: Save a copy of the `.fl` data to a different file. + +__File > Revert...__: Revert the `.fl` data to the previously saved state. + +__File > New From Template...__: Create a new user interface design from a +previously saved template. This can be useful for including a predefined +enterprise copyright message for projects, or for managing boilerplate code +for repeating project code. + +__File > Save As Template...__: Save the current project as a starting point +for future projects. + +__File > Print... (Ctrl-P)__: Generate a printout containing all currently +open windows within your project. + +__File > Write Code (Ctrl+Shift+C)__: Write the GUI layout as a `.cxx` and +`.h` file. These are exactly the same as the files you get when you run +FLUID with the `-c` switch. + +The output file names are the same as the `.fl` file, with the leading directory +and trailing ".fl" stripped, and ".h" or ".cxx" appended. + +__File > Write Strings (Ctrl+Shift+W)__: Write a message file for all of the +text labels and tooltips defined in the current file. + +The output file name is the same as the `.fl` file, with the leading directory +and trailing ".fl" stripped, and ".txt", ".po", or ".msg" appended depending on +the \ref setting_i18n "Internationalization Mode". + +__File > Quit (Ctrl+q)__: Exit FLUID. You are asked for confirmation if you +have changed the current file. + +__Edit > Undo (Ctrl+z)__ and __Redo (Shift+Ctrl+z)__: FLUID saves the project +state for undo and redo operations after every major change. + +__Edit > Cut (Ctrl+x)__: Delete the selected widgets and all of their children. +These are saved to a "clipboard" file and can be pasted back into any +FLUID window. + +__Edit > Copy (Ctrl+c)__: Copy the selected widgets and all of their children +to the "clipboard" file. + +__Edit > Paste (Ctrl+v)__: Paste the widgets from the clipboard file. + +If the widget is a window, it is added to whatever function +is selected, or contained in the current selection. + +If the widget is a normal widget, it is added to whatever +window or group is selected. If none is, it is added to the +window or group that is the parent of the current selection. + +To avoid confusion, it is best to select exactly one widget +before doing a paste. + +Cut/paste is the only way to change the parent of a +widget. + +__Edit > Duplicate (Ctrl-u)__: Duplicate all currently selected widgets and +insert the duplicates after the last selected widget. + +__Edit > Delete__: Delete all selected widgets. + +__Edit > Select All (Ctrl+a)__: Select all widgets in the same group as the +current selection. + +If they are all selected already then this selects all +widgets in that group's parent. Repeatedly typing `Ctrl+a` will +select larger and larger groups of widgets until everything is +selected. + +__Edit > Properties... (F1 or double click)__: Display the current widget in +the widgets panel. If the widget is a window and it is not visible then the +window is shown instead. + +__Edit > Sort__: Sort the selected widgets into left to right, top to bottom +order. You need to do this to make navigation keys in FLTK work correctly. +You may then fine-tune the sorting with "Earlier" and "Later". This does not +affect the positions of windows or functions. + +__Edit > Earlier (F2)__: Move all of the selected widgets one earlier in order +among the children of their parent (if possible). This will affect navigation +order, and if the widgets overlap it will affect how they draw, as the later +widget is drawn on top of the earlier one. You can also use this to reorder +functions, classes, and windows within functions. + +__Edit > Later (F3)__: Move all of the selected widgets one later in order +among the children of their parent (if possible). + +__Edit > Group (F7)__: Create a new Fl_Group and make all the currently +selected widgets children of it. + +__Edit > Ungroup (F8)__: Delete the parent group if all the children of a +group are selected. + +__Edit > Show or Hide Overlays (Ctrl+Shift+O)__: Toggle the display of the +red overlays off, without changing the selection. This makes it easier to see +box borders and how the layout looks. The overlays will be forced back on if +you change the selection. + +__Edit > Show or Hide Guides (Ctrl+Shift+G)__: Guides can be used to arrange a +widget layout easily and consistently. They indicate preferred widget +positions and sizes with user definable margins, grids, and gap sizes. See +the "Layout" tab in the "Settings" dialog, \ref setting_layout. + +This menu item enables and disables guides and the snapping action when dragging +widgets and their borders. + +__Edit > Show or Hide Restricted (Ctrl+Shift+R)__: The behavior of overlapping +widgets in FLTK is undefined. By activating this button, a hatch pattern is +shown, highlighting areas where restricted or undefined behavior may occur. + +__Edit > Show or Hide Widget Bin (Alt+B)__: The widget bin provides quick +access to all widget types supported by FLUID. Layouts can be created by +clicking on elements in the widget bin, or by dragging them from the bin to +their position within the layout. This button shows or hides the widget bin. + +__Edit > Show or Hide Code View (Alt+C)__: Shows or hide +the source code preview window. Any changes to the layout or code in the layout +editor can be previewed and verified immediately in the Code View window. + +__Edit > Settings... (Alt+p)__: Open the application and project settings +dialog: \ref page_setting_dialog + +__New > Code > Function__: Create a new C function. You will be asked for a +name for the function. This name should be a legal C++ function +template, without the return type. You can pass arguments which +can be referred to by code you type into the individual widgets. + +If the function contains any unnamed windows, it will be +declared as returning an Fl_Window pointer. The unnamed window +will be returned from it (more than one unnamed window is +useless). If the function contains only named windows, it will +be declared as returning nothing (\c void ). + +It is possible to make the .cxx output be a +self-contained program that can be compiled and executed. This +is done by deleting the function name so +\p main(argc,argv) is used. The function will call +\p show() on all the windows it creates and then call +\p Fl::run(). This can also be used to test resize +behavior or other parts of the user interface. + +You can change the function name by double-clicking on the +function. + +\see \ref functional_function + +__New > Group > Window__: Create a new Fl_Window widget. The window is added +to the currently selected function, or to the function containing the currently +selected item. The window will appear, sized to 480x320. You can resize it to +whatever size you require. + +The widget panel will also appear and is described later in +this chapter. + +__New > ...__: All other items on the New menu are subclasses of +`Fl_Widget`. Creating them will add them to the +currently selected group or window, or the group or window +containing the currently selected widget. The initial +dimensions and position are chosen by copying the current +widget, if possible. + +When you create the widget you will get the widget's control +panel, which is described later in this chapter. + +__Layout > Align > ...__: Align all selected widgets to the first widget in +the selection. + +__Layout > Space Evenly > ...__: Space all selected widgets evenly inside the +selected space. Widgets will be sorted from first to last. + +__Layout > Make Same Size > ...__: Make all selected widgets the same size as +the first selected widget. + +__Layout > Center in Group > ...__: Center all selected widgets relative to +their parent widget + +__Layout > Grid and Size Settings... (Ctrl+g)__: Display the grid settings +panel. See \ref setting_layout . + +This panel controls dimensions that all widgets snap to when you move +and resize them, and for the "snap" which is how far a widget has to be +dragged from its original position to actually change. + +Layout preferences are defined using margins to parent groups and windows, gaps +between widget, and/or by overlaying a grid over a group or window. A layout +comes as a suite of three presets, one for the main application window, one +for dialog boxes, and one for toolboxes. + +FLUID comes with two included layout suites. `FLTK` was used to design FLUID and +other included apps, and `Grid` is a more rigid grid layout. Users can add +more suites, import and export them, and include them into their `.fl` +project files. + +__Shell > Customize... (Alt+x)__: Displays the shell command settings panel. +Shell commands are commonly used to run a 'make' script to compile the FLUID +output. See \ref setting_shell . + +__Help > About FLUID__: Pops up a panel showing the version of FLUID. + +*/ diff --git a/fluid/documentation/src/page_setting_dialog.dox b/fluid/documentation/src/page_setting_dialog.dox new file mode 100644 index 000000000..78b7282ee --- /dev/null +++ b/fluid/documentation/src/page_setting_dialog.dox @@ -0,0 +1,338 @@ +/** + + \page page_setting_dialog Settings Dialog + + \tableofcontents + + + \image latex w_settings.png "Settings Dialog" width=7cm + + The *Settings* dialog combines application preferences + and project settings in a compact set of six tabs. + + The *General* tab contains a collection of application wide settings. They are + stored as user preferences. + + The *Project* tab holds settings for the current project. They are saved with + the `.fl` file. + + The *Layout* tab manages databases of preferred widget alignment. These + preferences can be saved per user, or as part of the project, or exported for + use in other projects. + + The *Shell* tab manages a database of quick access shell commands and scripts. + Shell commands can be saved as a user preference and also as part of the + `.fl` project file. + + The *Locale* tab sets the method of internationalizing texts in the project, + commonly used for labels and tooltips. + + The *User* tab manages customization of fonts and colors in the widget browser. + These settings are stored as user preferences. + +
+ + + \section setting_general Application Settings + + + \image latex w_settings_general_tab.png "General Settings Tab" width=7cm + + __Scheme__: + + Select one of the graphics schemes built into FLTK. It's helpful + to verify the look of various schemes for an application design. + + __Options__: + + Various options to make life as a developer more convenient. + + __Recent Files__: + + FLUID keeps track of recently opened files. + + __External Editor__: + + Users that don't like the built-in FLUID code editor can enter a shell command + here that opens the content of Code nodes in an external editor. FLUID does + its best to pick up on changed content or when the editor is closed. + + __Overlays__: + + The *Position Guides* are little red arrows that indicate if snap points are + found. See the *Layout* tab for details. *Restricted Areas* are areas where + widgets from within the same group overlap. They are visible in the project + window as a diagonally hashed pattern. *Ghosted Group Outlines* show faint + frames around groups that would otherwise be invisible in the project window. + +
+ + + \section setting_project Project Settings + + + \image latex w_settings_project_tab.png "Project Settings Tab" width=7cm + + __Header File__, __Code File__: + + These fields are used to build the file path and name of the generated header + and source file. If one field is empty the value defaults to `.h` and `.cxx` + respectively. If a name starts with a `.`, FLUID assumes that the rest of the + text is a file extension. The code file name is then generated by replacing + the extension of the `.fl` project file name. + + \todo Document the exact way the source and header file paths are calculated + for interactive FLUID, and for FLUID launched from the command line. + + __Include Header from Code__: + + If checked, the statement to include the header file is automatically + generated in one of the first lines of the source file. + + __Menu shortcuts use FL_COMMAND__: + + Setting this option will replace FL_CTRL and FL_META as a modifier for + shortcuts with the platform aware modifiers FL_COMMAND and FL_CONTROL, making + shortcuts more portable between macOS and Windows/Linux. + + __allow Unicode__: + + If unchecked, Unicode characters in strings are escaped. If checked, the Unicode + character is stored in the source code in UTF-8 encoding. + + __avoid early include__: + + FLUID by default includes `` early in the header file. If this option + is checked, users can include other files before including the FL header. The + user must then include `` later using a Declaration node. + +
+ + + \section setting_layout Layout Preferences + + + \image latex w_settings_layout_tab.png "Layout Settings Tab" width=7cm + + Layouts are a collection of hints that help when interactively positioning and + resizing widgets in the project window. Layouts come in a set of three for + the application window, for dialog boxes, and for toolboxes. + + __Layout__: + + The layout pulldown menu lets users choose from a list of existing layouts. + The plus button creates a new set of layouts based on the currently selected + layout. + The pulldown menu has items to rename, load, and save layouts. It can also + change the location where the layout is stored. The FLUID beaker is for + layouts that are predefined in FLUID, the portrait icon stores as user + preference, the document + icon stores the layout in the `.fl` file, and the disk icon lets users store + layout in external files. + + __Window Margin and Grid__: + + Snap widget position to that margin in relation to the window. The grid + snaps widgets to fixed intervals. + + __Group Margin and Grid__: + + Snap widget position to that margin in relation to the group. The grid + snaps widgets to fixed intervals relative to the top left of the group. + + __Tabs Margin__: + + Snap the tab inside `Fl_Tabs` to the tab border and the offset given in + Margins. + + __Widget Minimum, Increment, and Gap__: + + _Minimum_ sets the minimal width of a widget. _Increment_ is the size multiplier + added to the _Minimum_ value. _Gap_ is the preferred distance to other widgets + in the same group. + + __Label Font__, __Text Font__: + + The preferred label and text font and size for new widgets. + +
+ + + \section setting_shell Shell Commands + + + \image latex w_settings_shell_tab.png "Shell Settings Tab" width=7cm + + __Shell Command List__: + + A list of all currently available shell commands. The portrait symbol in front + of the name indicates that the script is stored in the user preferences. The + document symbol saves them within the `.fl` project file. + + `[+]` adds a fresh new script to the list, `[++]` duplicates the currently + selected script. `[DEL]` deletes it, and `[v]` offers import and export + functionality. The `[T]` button shows the terminal window, and finally the + `[Run]` button runs the selected shell script. + + Selecting a shell script will fill in the bottom half of the dialog. + + __Name__: + + This is the name of the script as it appears in the Shell Command List. + + __Menu Label__: + + Shell scripts that match the *Condition* flag are also available for quick + access in the *Shell* menu in the main window and via shortcut key + combinations. This is the text that is used for the menu entry. + + __Shortcut__: + + Assign a keyboard shortcut to this shell script for even faster access. FLUID + does not check if a shortcut is already used elsewhere. Try to avoid + collisions, especially when the script is part of a project file. + + __Store__: + + Choose where to store the settings of this shell script, either in the user + preferences or as part of the `.fl` project file. + + __Condition__: + + Shell scripts can be quite different for different platforms hosting FLUID. + This choice limits scripts to specific platforms. Multiple scripts can have + the same shortcut if they have different conditions. + + __Shell Script__: + + This is a text field for the shell script. The `[v]` pulldown menu has a list + of variables that are replaced with the corresponding value before running + the script. The zoom button gives access to a much larger shell script editor. + + The options below are a list of actions that can be executed before running + the script. + +
+ + + \section setting_i18n Internationalization + + The *Locale* tab can be used to configure optional internationalization. + FLUID supports GNU `gettext` and POSIX `catgets`. + + FLUID supports internationalization (I18N for short) of label + strings and tooltips used by widgets. The GNU gettext option also + supports deferred translation of statically initialized menu item + labels. The setting panel (`Alt+p`) provides access + to the I18N options. + + \image html w_settings_i18n_gnu.png + \image latex w_settings_i18n_gnu.png "I18N With GNU gettext" width=7cm + + FLUID supports three methods of I18N: none, GNU + gettext, and POSIX catgets. The "none" method is the + default and just passes the label strings as-is to the widget + constructors. + + The "GNU gettext" method uses GNU gettext (or a similar + text-based I18N library) to retrieve a localized string before + calling the widget constructor. + + The GNU gettext option adds some preprocessor code to the source file: + ``` + #include + #ifndef gettext_noop + # define gettext_noop(text) text + #endif + ``` + and the gettext call around strings in the source code: + ``` + new Fl_Button(50, 50, 54, 40, "Button"); + // -> + new Fl_Button(50, 50, 54, 40, gettext("Button")); + ``` + + FLUID's code support for GNU gettext is limited to calling a + function or macro to retrieve the localized label; you still + need to call \p setlocale() and \p textdomain() or + \p bindtextdomain() to select the appropriate language and + message file. + + __Include__: controls the header file to include for +I18N; by default this is \b , the +standard I18N file for GNU gettext. + + __Conditional__: If this field contains a macro name, i18n will only be + compiled into the product if this macro is defined. The build system should + define the macro only if all required headers and libraries are available. If + the macro is not defined, no headers are included and `gettext` passes text + through untranslated. + + __Function__: controls the function (or macro) that will retrieve the localized + message; by default the \p gettext function will be called. + + __Static Function__: names a macro that will mark static text fields for + extraction with the `xgettext` tool. The default macro name is + \p gettext_noop and will be defined as `#define gettext_noop(text) text` + right after the `#include` statement. FLUID will call `gettext` on static + texts later, after the textdomain was set by the user. + + \see [GNU gettext special cases](https://www.gnu.org/software/gettext/manual/html_node/Special-cases.html) + + \image html w_settings_i18n_psx.png + \image latex w_settings_i18n_psx.png "I18N With POSIX catgets" width=7cm + + The "POSIX catgets" method uses the POSIX catgets function to + retrieve a numbered message from a message catalog before + calling the widget constructor. + + FLUID's code support for POSIX catgets allows you to use a + global message file for all interfaces or a file specific to + each .fl file; you still need to call + \p setlocale() to select the appropriate language. + + This option adds some preprocessor code to the source file: + ``` + #include + // Initialize I18N stuff now for menus... + #include + static char *_locale = setlocale(LC_MESSAGES, ""); + static nl_catd _catalog = catopen("", 0); + ``` + and the catgets call around strings in the source code: + ``` + new Fl_Button(50, 50, 54, 40, "Button"); + // -> + new Fl_Button(50, 50, 54, 40, catgets(_catalog,1,6,"Button")); + ``` + + __Include__: controls the header file to include for + I18N; by default this is \b , the + standard I18N file for POSIX catgets. + + __Conditional__: include the header file only if this preprocessor macro is + defined. + + __Catalog__: controls the name of the catalog file +variable to use when retrieving localized messages; by default +the file field is empty which forces a local (static) catalog +file to be used for all of the windows defined in your +.fl file. + + __Set__: controls the set number in the catalog file. +The default set is 1 and rarely needs to be changed. + + + \section setting_user User Interface Preferences + + + \image latex w_settings_user_tab.png "User Settings Tab" width=7cm + + This tab lets users change the font and color of text in the widget browser. + The settings are stored in the user preferences. + + All changes are directly visible in the widget browser. + +
+ + */ diff --git a/fluid/documentation/src/page_tutorial.dox b/fluid/documentation/src/page_tutorial.dox new file mode 100644 index 000000000..3f0d48cae --- /dev/null +++ b/fluid/documentation/src/page_tutorial.dox @@ -0,0 +1,534 @@ +/** + + \page page_tutorial Tutorials + + \tableofcontents + + + + \section fluid_hello_world_tutorial Hello, World! + + The first FLUID tutorial explains the FLUID basics. It creates a single + `main()` function that opens an application window with a static text box + inside. + + After launching FLUID we want to make sure that two very useful tool windows + are open. + The "Widget Bin" gives quick access to all available widgets and functional + types. It can be opened via the main menu: __Edit > Show Widget Bin__, or + using the shortcut __Alt-B__. + + The second very helpful tool box is the "Code View". The Code View gives + a preview of the code as it will be generated by FLUID. All changes in the + layout or in attributes are reflected immediately in the Code View. + Choose __Edit > Show Code View__ or press __Alt-C__ to get this + toolbox. Make sure that _Auto-Refresh_ and _Auto-Position_ are active in + the Code View. + + Let's start Hello World from scratch. If there is already a previous project + loaded, select __File > New__ or __Ctrl-N__. + + Before we can create a window, we need a "C" function that can be called + when we run the program. Select __New > Code > Function/Method...__ or click on + the + \image{inline} html flFunction.png "Function/Method" + \image{inline} latex flFunction.png + image in the widget bin. + + A function is added as a first line to the widget tree in the main window, + and a "Function/Method Properties" dialog box will pop up. For our Hello World + program, delete all text in the top "Name(args)" text field. If this field + is left empty, FLUID will generate a `main(argc, argv)` function for us. + + \image html fluid4.png "Function/Method Properties Dialog" + \image latex fluid4.png "Function/Method Properties Dialog" width=7cm + + Click OK to apply the changes you made in the Function Properties dialog. + You can get this dialog back at any time by selecting the function in the + main window and pressing __F1__, or by double-clicking it. + + Note that the function will not show up in the Code View yet. FLUID will + not generate code for functions that don't have any content, and only create + a forward declaration in the header file, assuming that the function will + be implemented inside another module. + + Keep the `main` function selected and add an `Fl_Window` to the function by + selecting __New > Group > Window...__, by clicking the + \image{inline} html flWindow.png "Group/Window" + \image{inline} latex flWindow.png + image in the Widget Bin, or by dragging the Group/Window image from the + Widget Bin onto the desktop. + + A new application window will open up on the desktop. The thin red outline + around the window indicates that it is selected. Dragging the red line will + resize the window. Take a look at the Code View: the main function + is now generated, including code to instantiate our `Fl_Window`. + + To edit all the attributes of our window, make sure it is selected and press + __F1__, or double-click the entry in the main FLUID window, or double-click + the window itself. The "Widget Properties" dialog box will pop up. Enter + some text in the "Label:" text box and see how the label is updated immediately + in the window itself, in the widget list, and in the Code View. + + Adding a static text to our window is just as easy. Put an `Fl_Box` into our + window by selecting __New > Other > Box__, or by clicking on the + \image{inline} html flBox.png "Other/Box" + \image{inline} latex flBox.png + image in the Widget Bin, or by dragging the Other/Box image from the + Widget Bin into our newly created window. + + Most importantly, enter the text "Hello, World!" in the "Label:" field + of the Box Widget Properties panel to achieve the goal of this tutorial. Now + is also a great time to experiment with label styles, label fonts, sizes, + colors, etc. . + + Finally, we should save our project as an `.fl` project file somewhere. Once + the project is saved, select __File > Write Code__ or press __Shift-Ctrl-C__ + to write our source code and header file to the same directory. + + Compile the program using a Makefile, CMake file, or fltk-config as described + in the FLTK manual and the `README.txt` files in the FLTK source tree. + + + + \section fluid_1of7guis_tutorial 7GUIs, Task 1 + + In the first "Hello World" tutorial, we built an entire application in FLUID. + It's a boring application though that does nothing except quitting when the + close button in the window border is clicked. + + \image html 1of7GUIs.png "Task 1 of 7GUIs" + \image latex 1of7GUIs.png "Task 1 of 7GUIs" width=5cm + + The second tutorial will introduce callbacks by implementing task 1, "Counter", + of 7GUIs. 7GUIs has been created as a spin-off of my master’s thesis + Comparison of Object-Oriented and Functional Programming for GUI Development + at the Human-Computer Interaction group of the Leibniz Universität Hannover + in 2014. 7GUIs defines seven tasks that represent typical challenges in GUI + programming. https://eugenkiss.github.io/7guis/ . + + Task 1 requires "Understanding the basic ideas of a language/toolkit. The + task is to build a frame containing a label or read-only textfield T and a + button B. Initially, the value in T is “0” and each click of B increases the + value in T by one." + + Our knowledge from tutorial 1 is enough to generate the `main()` function, and + add an `Fl_Window`, an `Fl_Output`, and an `Fl_Button`. To make life easy, + FLUID comes with a built-in template for this tutorial. Just select + __File > New from Template...__ and double-click "1of7GUIs" in the Template + Panel. + + We will need to reference the output widget in our callback, so let's assign a + pointer to the widget to a global variable and give that variable a name. + Open the Widget Properties dialog by double-clicking the output widget. + Change to the "C++" tab, and enter "`counter_widget`" in the "Name:" field. + + The "Count" button is the active element in our application. To tell the + app what to do when the user clicks the button, we create a callback function + for that button. Open the widget properties dialog for the button. + In the "C++" tab, we find the input field "Callback:". + + The callback is called exactly once every time the user clicks the button. Our + strategy here is to read the current value from the `counter_widget`, + increment it by 1, and write it back to `counter_widget`. + The FLTK documentation tells us that we can use `Fl_Output::ivalue()` to get + text in `Fl_Output` as an integer, and we can write it back by calling + `Fl_Output::value(int)`. When the value is changed, FLTK will automatically + redraw the output widget for us. So here is the callback code: + + ``` + int i = counter_widget->ivalue(); + i++; + counter_widget->value(i); + ``` + + That's it. This is a complete interactive desktop application. Compile, link, + run, and test it to see how it works. + + + +\section fluid_cubeview_tutorial Cube View + +This tutorial will show you how to generate a complete user interface +class with FLUID that is used for the CubeView program provided with FLTK. + +\image html cubeview.png "CubeView demo" +\image latex cubeview.png "CubeView demo" width=7cm + +The window is of class CubeViewUI, and is completely generated by FLUID, +including class member functions. The central display of the cube is a +separate subclass of Fl_Gl_Window called CubeView. CubeViewUI manages +CubeView using callbacks from the various sliders and rollers to +manipulate the viewing angle and zoom of CubeView. + +At the completion of this tutorial you will (hopefully) understand how to: + +-# Use FLUID to create a complete user interface class, including + constructor and any member functions necessary. +-# Use FLUID to set callback member functions of custom widget classes. +-# Subclass an Fl_Gl_Window to suit your purposes. + +\subsection fluid_cubeview The CubeView Class + +The CubeView class is a subclass of Fl_Gl_Window. It has methods for +setting the zoom, the \e x and \e y pan, and the rotation angle +about the \e x and \e y axes. + +You can safely skip this section as long as you realize that CubeView +is a sublass of Fl_Gl_Window and will respond to calls from +CubeViewUI, generated by FLUID. + +\par The CubeView Class Definition + +Here is the CubeView class definition, as given by its header file +"test/CubeView.h": +
+ + +\code +#include +#include +#include + +class CubeView : public Fl_Gl_Window { + +public: + CubeView(int x, int y, int w, int h, const char *l = 0); + + // This value determines the scaling factor used to draw the cube. + double size; + + /* Set the rotation about the vertical (y) axis. + * + * This function is called by the horizontal roller in + * CubeViewUI and the initialize button in CubeViewUI. + */ + void v_angle(double angle) { vAng = angle; } + + // Return the rotation about the vertical (y) axis. + double v_angle() const { return vAng; } + + /* Set the rotation about the horizontal (x) axis. + * + * This function is called by the vertical roller in + * CubeViewUI and the initialize button in CubeViewUI. + */ + + void h_angle(double angle) { hAng = angle; } + + // The rotation about the horizontal (x) axis. + double h_angle() const { return hAng; } + + /* Sets the x shift of the cube view camera. + * + * This function is called by the slider in CubeViewUI + * and the initialize button in CubeViewUI. + */ + void panx(double x) { xshift = x; } + + /* Sets the y shift of the cube view camera. + * + * This function is called by the slider in CubeViewUI + * and the initialize button in CubeViewUI. + */ + void pany(double y) { yshift = y; } + + /* The widget class draw() override. + * + * The draw() function initializes Gl for another round of + * drawing, then calls specialized functions for drawing each + * of the entities displayed in the cube view. + */ + void draw(); + +private: + /* Draw the cube boundaries. + * + * Draw the faces of the cube using the boxv[] vertices, + * using GL_LINE_LOOP for the faces. + */ + void drawCube(); + + double vAng, hAng; + double xshift, yshift; + + float boxv0[3]; float boxv1[3]; + float boxv2[3]; float boxv3[3]; + float boxv4[3]; float boxv5[3]; + float boxv6[3]; float boxv7[3]; +}; +\endcode + +\par The CubeView Class Implementation + +Here is the CubeView implementation. It is very similar to the +"CubeView" demo included with FLTK. +
+ + +\code +#include "CubeView.h" +#include + +CubeView::CubeView(int x, int y, int w, int h, const char *l) + : Fl_Gl_Window(x, y, w, h, l) +{ + Fl::use_high_res_GL(1); + vAng = 0.0; + hAng = 0.0; + size = 10.0; + xshift = 0.0; + yshift = 0.0; + + /* The cube definition. These are the vertices of a unit cube + * centered on the origin.*/ + + boxv0[0] = -0.5; boxv0[1] = -0.5; boxv0[2] = -0.5; + boxv1[0] = 0.5; boxv1[1] = -0.5; boxv1[2] = -0.5; + boxv2[0] = 0.5; boxv2[1] = 0.5; boxv2[2] = -0.5; + boxv3[0] = -0.5; boxv3[1] = 0.5; boxv3[2] = -0.5; + boxv4[0] = -0.5; boxv4[1] = -0.5; boxv4[2] = 0.5; + boxv5[0] = 0.5; boxv5[1] = -0.5; boxv5[2] = 0.5; + boxv6[0] = 0.5; boxv6[1] = 0.5; boxv6[2] = 0.5; + boxv7[0] = -0.5; boxv7[1] = 0.5; boxv7[2] = 0.5; +} + +void CubeView::drawCube() { +/* Draw a colored cube */ +#define ALPHA 0.5 + glShadeModel(GL_FLAT); + + glBegin(GL_QUADS); + glColor4f(0.0, 0.0, 1.0, ALPHA); + glVertex3fv(boxv0); + glVertex3fv(boxv1); + glVertex3fv(boxv2); + glVertex3fv(boxv3); + + glColor4f(1.0, 1.0, 0.0, ALPHA); + glVertex3fv(boxv0); + glVertex3fv(boxv4); + glVertex3fv(boxv5); + glVertex3fv(boxv1); + + glColor4f(0.0, 1.0, 1.0, ALPHA); + glVertex3fv(boxv2); + glVertex3fv(boxv6); + glVertex3fv(boxv7); + glVertex3fv(boxv3); + + glColor4f(1.0, 0.0, 0.0, ALPHA); + glVertex3fv(boxv4); + glVertex3fv(boxv5); + glVertex3fv(boxv6); + glVertex3fv(boxv7); + + glColor4f(1.0, 0.0, 1.0, ALPHA); + glVertex3fv(boxv0); + glVertex3fv(boxv3); + glVertex3fv(boxv7); + glVertex3fv(boxv4); + + glColor4f(0.0, 1.0, 0.0, ALPHA); + glVertex3fv(boxv1); + glVertex3fv(boxv5); + glVertex3fv(boxv6); + glVertex3fv(boxv2); + glEnd(); + + glColor3f(1.0, 1.0, 1.0); + glBegin(GL_LINES); + glVertex3fv(boxv0); + glVertex3fv(boxv1); + + glVertex3fv(boxv1); + glVertex3fv(boxv2); + + glVertex3fv(boxv2); + glVertex3fv(boxv3); + + glVertex3fv(boxv3); + glVertex3fv(boxv0); + + glVertex3fv(boxv4); + glVertex3fv(boxv5); + + glVertex3fv(boxv5); + glVertex3fv(boxv6); + + glVertex3fv(boxv6); + glVertex3fv(boxv7); + + glVertex3fv(boxv7); + glVertex3fv(boxv4); + + glVertex3fv(boxv0); + glVertex3fv(boxv4); + + glVertex3fv(boxv1); + glVertex3fv(boxv5); + + glVertex3fv(boxv2); + glVertex3fv(boxv6); + + glVertex3fv(boxv3); + glVertex3fv(boxv7); + glEnd(); +} // drawCube + +void CubeView::draw() { + if (!valid()) { + glLoadIdentity(); + glViewport(0, 0, pixel_w(), pixel_h()); + glOrtho(-10, 10, -10, 10, -20050, 10000); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + + glTranslatef((GLfloat)xshift, (GLfloat)yshift, 0); + glRotatef((GLfloat)hAng, 0, 1, 0); + glRotatef((GLfloat)vAng, 1, 0, 0); + glScalef(float(size), float(size), float(size)); + + drawCube(); + + glPopMatrix(); +} +\endcode + +\subsection fluid_cubeview_ui The CubeViewUI Class + +We will completely construct a window to display and control the +CubeView defined in the previous section using FLUID. + +\par Defining the CubeViewUI Class + +Once you have started FLUID, the first step in defining a class is to +create a new class within FLUID using the New->Code->Class +menu item. Name the class "CubeViewUI" and leave the subclass blank. +We do not need any inheritance for this window. You should see the +new class declaration in the FLUID browser window. + +\image html fluid1.png "FLUID file for CubeView" +\image latex fluid1.png "FLUID file for CubeView" width=7cm + +\par Adding the Class Constructor + +Click on the CubeViewUI class in the FLUID window and add a new method +by selecting New->Code->Function/Method. The name of the +function will also be CubeViewUI. FLUID will understand that this will +be the constructor for the class and will generate the appropriate +code. Make sure you declare the constructor public. + +Then add a window to the CubeViewUI class. Highlight the name of +the constructor in the FLUID browser window and click on +New->Group->Window. In a similar manner add the +following to the CubeViewUI constructor: + +\li A horizontal roller named \p hrot +\li A vertical roller named \p vrot +\li A horizontal slider named \p xpan +\li A vertical slider named \p ypan +\li A horizontal value slider named \p zoom + +None of these additions need be public. And they shouldn't be +unless you plan to expose them as part of the interface for +CubeViewUI. + +When you are finished you should have something like this: + +\image html fluid2.png "FLUID window containing CubeView demo" +\image latex fluid2.png "FLUID window containing CubeView demo" width=7cm + +We will talk about the \p show() method that is highlighted +shortly. + +\par Adding the CubeView Widget + +What we have is nice, but does little to show our cube. We have already +defined the CubeView class and we would like to show it within the +CubeViewUI. + +The CubeView class inherits the Fl_Gl_Window class, which +is created in the same way as an Fl_Box widget. Use +New->Other->Box to add a square box to the main window. +This will be no ordinary box, however. + +The Box properties window will appear. The key to letting CubeViewUI +display CubeView is to enter CubeView in the Class: text +entry box. This tells FLUID that it is not an Fl_Box, but a +similar widget with the same constructor. + +In the Extra Code: field enter \#include "CubeView.h" + +This \p \#include is important, as we have just included +CubeView as a member of CubeViewUI, so any public CubeView methods are +now available to CubeViewUI. + +\image html fluid3-cxx.png "CubeView methods" +\image latex fluid3-cxx.png "CubeView methods" width=7cm + +\par Defining the Callbacks + +Each of the widgets we defined before adding CubeView can have +callbacks that call CubeView methods. You can call an external +function or put a short amount of code in the Callback +field of the widget panel. For example, the callback for the +\p ypan slider is: + +\code +cube->pany(((Fl_Slider *)o)->value()); +cube->redraw(); +\endcode + +We call cube->redraw() after changing the value to update +the CubeView window. CubeView could easily be modified to do this, but +it is nice to keep this exposed. In the case where you may want to do +more than one view change only redrawing once saves a lot of time. + +There is no reason to wait until after you have added CubeView to +enter these callbacks. FLUID assumes you are smart enough not to refer +to members or functions that don't exist. + +\par Adding a Class Method + +You can add class methods within FLUID that have nothing to do with the +GUI. As an example add a show function so that CubeViewUI can actually +appear on the screen. + +Make sure the top level CubeViewUI is selected and select +New->Code->Function/Method. Just use the name +\p show(). We don't need a return value here, and since we will +not be adding any widgets to this method FLUID will assign it a return +type of \p void. + +\image html fluid4.png "CubeView constructor" +\image latex fluid4.png "CubeView constructor" width=7cm + +Once the new method has been added, highlight its name and select +New->Code->Code. Enter the method's code in the code window. + +\subsection fluid_addconst Adding Constructor Initialization Code + +If you need to add code to initialize a class, for example setting +initial values of the horizontal and vertical angles in the +CubeView, you can simply highlight the constructor and select +New->Code->Code. Add any required code. + +\subsection fluid_gencode Generating the Code + +Now that we have completely defined the CubeViewUI, we have to generate +the code. There is one last trick to ensure this all works. Open the +preferences dialog from Edit->Preferences. + +At the bottom of the preferences dialog box is the key: +"Include Header from Code". +Select that option and set your desired file +extensions and you are in business. You can include the CubeViewUI.h +(or whatever extension you prefer) as you would any other C++ class. + +*/ diff --git a/fluid/documentation/src/page_widget_panel.dox b/fluid/documentation/src/page_widget_panel.dox new file mode 100644 index 000000000..158f4663b --- /dev/null +++ b/fluid/documentation/src/page_widget_panel.dox @@ -0,0 +1,429 @@ +/** + + \page page_widget_panel Widget Properties Panel + + \tableofcontents + + # The Widget Properties Panel # + + \image html widget_panel.png "Widget Properties" + \image latex widget_panel.png "Widget Properties" width=9cm + + This panel is used to edit the properties of the currently selected widgets. + It can be opened by double-clicking on a widget or by pressing `F1`. + + When you change attributes using this panel, the changes are + reflected immediately in the window. It is useful to hit the + "Hide Overlays" button (or type Ctrl+Shift+O) to hide the + red overlay so you can see the widgets more accurately, + especially when setting the box type. + + One or more widgets can be selected at the same time, and most attribute + changes will be applied to the entire selection. + Depending on the selected widget types, some properties may + be grayed out or may not be visible. + + All changes in the widget panel are immediately applied to all selected + widgets and their effect can be seen in the project window. It can be very + useful to keep the *Code View* window open at all times. All code changes + appear instantly for all generated files if *Auto-Refresh* is active. + + FLUID generates only code for properties that differ from their default + setting. If a widget class is derived from another class, FLUID can't know + the defaults and will generate code for all attributes instead. + + \image html wLiveMode.png + \image latex wLiveMode.png "" width=9cm + + Correctly resizing a window can be a complex task. It is easier to check + resizing behavior on a more local level first. + To use *Live Resize*, select any group or window in your project. FLUID creates + a resizable clone of that part of your design to try out resizing behavior + of that group only. + + The widget panel itself is resizable to make more room for entering code + and long texts. + + + \section widget_panel_gui The GUI Tab + + \image html wp_gui_tab.png + \image latex wp_gui_tab.png "" width=9cm + + The widget panel has three standard tabs that apply to all widgets. Some widget + types, `Fl_Grid` and children of `Fl_Grid`, will create additional + tabs with more options. + + The GUI tab controls basic GUI settings, including label text and widget size. + + \image html wp_gui_label.png + \image latex wp_gui_label.png "" width=7cm + + The *Label* field can be any Unicode string and is stored as a static text. + If internationalization is enabled, the corresponding modifiers are + added. Labels can span multiple lines by pressing `Ctrl-J` to insert a newline + (NL) character. + + The `@` character adds a symbol to the label. See *Labels and Label Types* + in the FLTK documentation. + + The pulldown menu offers some additional rendering styles for the label. + + \image html wp_gui_image.png + \image latex wp_gui_image.png "" width=7cm + + Add an image to the widget label here. The second row takes an optional image + for rendering a deactivated widget. + + The image path must be relative to the location of the `.fl` file and not + necessarily the current directory. It is helpful to keep images in the same + directory as the `.fl` file. + + The image data is inlined into the source code. If many widgets share the same + image then only one copy is written. Since the image data is embedded in the + generated source code, you need only distribute the C++ code and not the + image files themselves. The `.fl` project files however store only the image + file name, so you will need the image files as well to read a project file. + + FLUID can read XBM bitmap files, XPM pixmaps with a transparency channel, and + all other types supported by the FLTK image extension. FLUID stores images + as bitmaps or RGB data by default. If *compressed* is selected in the image + properties field, the image is stored in its original format, and + the FLTK-images library must be linked to decompress the image at runtime. + + Images are stored at their original resolution. The image properties dialog + provides *Scale* settings to scale the image before rendering to screen. + To make full use of high-dpi screen support, images should be stored at double + resolution and then scaled to FLTK coordinates. This gives FLTK the chance to + fall back to the full size image for high-dpi screens. + + \image html wp_gui_alignment.png + \image latex wp_gui_alignment.png "" width=7cm + + Control alignment of the label in relation to the widget position and size as + well as the relation between the image and the label. The box on the right + toggles between inside and outside label alignment. + + \image html wp_gui_size.png + \image latex wp_gui_size.png "" width=7cm + + Control the size and position of a widget here. The input fields react to + vertical scroll wheel input for interactive positioning. + + All fields understand basic math. They are evaluated after the formula is + entered and the result is stored in the respective properties. Formulas can + also contain a number of variables. The *x* input can handle the variables + `x` for its own position, `px` for the parent position, `sx` for the previous + sibling, `cx` for the leftmost x position of all children, and `i`, which is a + counter through all selected widgets. + + The formula `x+10` in the *x* field moves all selected widgets 10 pixels to + the right. `100+25*i` in the *y* field arranges all widgets vertically + starting at 100 with 25 pixels distance. + +| Name | Value | +| ---- | ----- | +| `i` | zero based counter of selected widgets | +| `x`, `y`, `w`, `h` | position and size of the current widget | +| `px`, `py`, `pw`, `ph` | dimensions of the parent widget | +| `sx`, `sy`, `sw`, `sh` | dimensions of the previous sibling | +| `cx`, `cy`, `cw`, `ch` | bounding box of all children | + + \image html wp_gui_values.png + \image latex wp_gui_values.png "" width=7cm + + Activate for widgets that can take numerical values, these input fields take + floating point numbers. They generate lines like `o->minimum(2);` only if the + corresponding value differs from the default value for this property. + + \image html wp_gui_flexp.png + \image latex wp_gui_flexp.png "" width=7cm + + This row is only visible for children of `Fl_Flex` widgets. It sets the + width or height of a widget in a horizontal or vertical Flex widget. If *fixed* + is unchecked, this value is instead calculated by the Flex. + + \image html wp_gui_margins.png + \image latex wp_gui_margins.png "" width=7cm + + This row is only visible for `Fl_Flex` widgets. It sets the various margins + and the gap value for this widget. + + \image html wp_gui_sizerange.png + \image latex wp_gui_sizerange.png "" width=7cm + + This row is only visible for top level windows. The fields set the minimum + and maximum size range for windows. Use the *set* button to copy the current + size. Set width and height to `0` to disable that aspect of the size range. + + \image html wp_gui_shortcut.png + \image latex wp_gui_shortcut.png "" width=7cm + + This option is only visible for buttons and other widgets that can react to a + shortcut key combination. FLUID does not check if a shortcut was already used + elsewhere. + + If *shortcut use FL_COMMAND* is set in the project settings, modifiers are + created in a more compatible way across platforms. + + \image html wp_gui_xclass.png + \image latex wp_gui_xclass.png "" width=7cm + + This row is only visible for top level windows. Note that selecting *modal* + and *non modal* together is undefined. + + The string typed into the *X Class* field is passed to the X window manager + as the class. This can change the icon or window decorations. On most window + managers you will have to close the window and reopen it at runtime to + see the effect. + + \image html wp_gui_attributes.png + \image latex wp_gui_attributes.png "" width=7cm + + Some additional attributes for all widget types. + + The *Visible* button controls whether the widget is + visible (on) or hidden (off) initially. Don't change this for + windows or for the immediate children of a Tabs group. + + The *Active* button controls whether the widget is + activated (on) or deactivated (off) initially. Most widgets + appear grayed out when deactivated. + + The *Resizable* button controls whether the window or widget is + resizable. In addition all the size changes of a window or + group will go "into" the resizable child. If you have + a large data display surrounded by buttons, you probably want + that data area to be resizable. You can get more complex + behavior by making invisible boxes the resizable widget, or by + using hierarchies of groups. Resizing of a window or group can be tested + using the *live resize* button. + + The *Hotspot* button causes the parent window to be + positioned with that widget centered on the mouse. This + position is determined when the FLUID function is called, + so you should call it immediately before showing the window. If + you want the window to hide and then reappear at a new position, + you should have your program set the hotspot itself just before + `show()`. + + \image html wp_gui_tooltip.png + \image latex wp_gui_tooltip.png "" width=7cm + + The *Tooltip* field can be any Unicode string and is stored as a static text. + If internationalization is enabled, the corresponding modifiers are + added. + + + \section widget_panel_style The Style Tab + + \image html wp_style_tab.png + \image latex wp_style_tab.png "Style Tab" width=9cm + + The Style tab is used to edit font styles and sizes, and the color of elements + of the widget. + + \image html wp_style_label.png + \image latex wp_style_label.png "" width=7cm + + \image html wp_style_text.png + \image latex wp_style_text.png "" width=7cm + + The font pulldown menu provides a list of standard fonts. To enter the index + of a user loaded font, an *extra code* field must be used. The *label color* + and *text color* fields opens a color palette selector. The arrow pulldown + contains a list of the most commonly used colors. Again, user specific colors + can be defined using the *extra code* field. + + The *Text Font* row is only available for widgets that contain an additional + text area. + + \image html wp_style_box.png + \image latex wp_style_box.png "" width=7cm + + Select the up and down box for the given widget. The first six entries in the + box and frame style list are influenced by the FLTK Scheme setting. Other + box styles will always look the same, independently of the selected scheme. + + Many widgets will work, and draw faster, with a + "frame" instead of a "box". A frame does + not draw the colored interior, leaving whatever was already + there visible. Be careful, as FLUID may draw this ok but the + real program may leave unwanted stuff inside the widget. + + If a window is filled with child widgets, you can speed up + redrawing by changing the window's box type to + "NO_BOX". FLUID will display a checkerboard for any + areas that are not colored in by boxes. Note that this + checkerboard is not drawn by the resulting program. Instead + random garbage will be displayed. + + The *Down Box* row is only available for widgets that can be pressed down + by the user. + + Some widgets will use the *Select Color* for certain parts. FLUID + does not always show the result of this: this is the color + buttons draw in when pushed down, and the color of input fields + when they have the focus. + + + \section widget_panel_cpp The C++ Tab + + \image html wp_cpp_tab.png + \image latex wp_cpp_tab.png "C++ Tab" width=9cm + + The C++ tab has various input fields for adding C++ code at various places + in the source and header file. + + \image html wp_cpp_class.png + \image latex wp_cpp_class.png "" width=7cm + + If the class property is set, FLUID assumes that the user wants to instantiate + a widget that is derived from the selected widget. For a derived widget, the + default values of attribute can not be known. FLUID will generate code to + explicitly set every known attribute of the super class. + + FLUID generates "include" statements for known classes. Custom classes should + provide a \p \#include line as one of the "Extra Code" lines of the widget. + + If the selected widget is a Widget Class node, the Class property will instead + set the super class of the widget. + + The pulldown menu on the right side contains additional subtypes for some + widget types. `Fl_Button` widgets, for instance, can be further refined to + be an `Fl_Toggle_Button` or an `Fl_Radio_Button`. + + \image html wp_cpp_name.png + \image latex wp_cpp_name.png "" width=7cm + + The name field can be any valid C++ variable name. If the widget is inside + a class, the pulldown menu lets the user select between *private*, *protected*, + and *public*. If not in the group, the variable can be *global* or *static* + within the source file. + + Widgets created by FLUID are either "named", "complex named" or + "unnamed". A named widget has a legal C++ variable identifier as its + name (i.e. only alphanumeric and underscore). In this case FLUID + defines a global variable or class member that will point at the widget + after the function defining it is called. A complex named object has + punctuation such as '.' or '->' or any other symbols + in its name. In this case FLUID does not attempt to declare it. This can be + used to get the widgets into structures. An unnamed widget has a blank + name and no pointer is stored. + + You can name several widgets with "name[0]", "name[1]", "name[2]", etc.. + This will cause FLUID to declare an array of pointers. The array + is big enough that the highest number found can be stored. All widgets + in the array must be the same type. + + \image html v_input.png + \image latex v_input.png "" width=7cm + + These four input fields can be used to add arbitrary code to different parts + of the header and source file. A line can be divided into multiple lines + of code by inserting a `Ctrl-J`. + + All Extra Code fields are interpreted individually. If a field contains a `#` + character, or the words `extern`, `typedef`, or `using`, FLUID assumes that + the code is a declaration and writes it to the header file, and only if it + does not duplicate previously written code. This is great for creating a + `#include "MyWidgetType.H"` include statement in the header. + + If the code is not recognized as a declaration, it will instead be put after + the code that instantiates the widget and all its children. For menu items, + the code is added after the container `Fl_Menu_` is created, but before the + menu array is added to the container. + + FLUID will check for matching parentheses, braces, and + quotes, but does not do much other error checking. Be careful + here, as it may be hard to figure out what widget is producing + an error in the compiler. If you need more than four lines you + probably should call a function in your own `.cxx` + code. + + \image html wComment.png + \image latex wComment.png "" width=7cm + + Comments are added to the source code before the widget constructor by adding + `// ` in front of every line of the comment. The first few characters of a + comment are also visible in the widget browser in the main window. + + \image html wp_cpp_callback.png + \image latex wp_cpp_callback.png "" width=7cm + + The callback field can be interpreted in two ways. If the callback text is only + a single word, FLUID assumes that this is the name of an external callback + function and declares it in the header as + `extern void my_button_action(Fl_Button*, void*);`. + + Otherwise, FLUID assumes that the text is the body of a C++ callback function + and instead creates a local static callback function. The name of the callback + function is generated by FLUID and guaranteed to be unique within the file. + ``` + static void cb_input(Fl_Input *o, void *v) { + ... // my text from the Callback field here + } + ``` + You can refer to the widget as \p o and the \p user_data() + as \p v. FLUID will check for matching parentheses, braces, + and quotes, but does not do much other error checking. + + If the callback is blank then no callback is set. + + The *User Data* field can contain any valid C++ code and is copied as the + callback argument. If blank the default value of zero is used. + *Type* is currently limited to a pointer (a type name ending in `*`) or `long`. + + The *When* pulldown gives access to the `Fl_When` flags, including some + commonly used combinations. + + + \section widget_panel_grid The Grid Tab + + \image html wp_grid_tab.png + \image latex wp_grid_tab.png "Grid Tab" width=9cm + + This tab is only available if the selected widget is an `Fl_Grid`. When editing + a Grid widget, no other widgets should be selected. + + The *Grid Layout* fields adjust the number of rows and columns in the grid. + + The *Margins* fields describe the size of the margins around all children of + the grid. + + The *Gaps* fields set the gaps between individual children in the grid. + + The *Row* and *Column* groups can be used to set the size of individual rows + and columns within the grid. + + + \section widget_panel_gridc The Grid Child Tab + + \image html wp_gridc_tab.png + \image latex wp_gridc_tab.png "Grid Child Tab" width=9cm + + This tab is only available if the selected widget is a child of an `Fl_Grid`. + When editing a child of a Grid widget, no other widgets should be selected. + + Use the *Location* group to move a child around within the grid. Note that + every cell in a grid can only manage one single widget. When moving widgets + over occupied cells, they become "transient". Just continue and move them into + an available cell. If a layout is saved with a transient widget, all grid + attributes for that widget are lost, and it will remain unassigned in the + project file and in the source code. + + The *Align* fields provide a way to align a widget within its cell. + + The *Min. Size* fields define a minimum width and height for the widget + in the cell. + + The *Span* fields change the number of cells that a widget can span in x and y. + + \note Most attributes in this tab will also change the size of the widget. If + the child of the Grid is itself a group, the children of that group do not + follow changes in position or size. It is recommended to either lay out the + grid contents first and leave it unchanged, or to use widgets generated with + Widget Class that automatically adjust themselves to the size constraints + of the grid. + +*/ diff --git a/fluid/documentation/src/page_widgetbin_panel.dox b/fluid/documentation/src/page_widgetbin_panel.dox new file mode 100644 index 000000000..c9da9f9c9 --- /dev/null +++ b/fluid/documentation/src/page_widgetbin_panel.dox @@ -0,0 +1,34 @@ +/** + + \page page_widgetbin_panel Widget Bin Panel + + \tableofcontents + + # The Widget Bin Panel # + + \image html widgetbin_panel.png "Widget Bin" + \image latex widgetbin_panel.png "Widget Bin" width=9cm + + The Widget Bin can be activated via the main + menu: *Edit* > *Show Widget Bin* . FLUID will remember its + state and dimensions. + + The Widget Bin is a great way to quickly create a GUI project. Clicking + an icon in the bin will create the corresponding code or widget node inside + or right after the selected widget. If the parent widget is not supported + for this widget type, FLUID tries to find a better position. If that fails, + a dialog box will pop up, explaining what type of parent node is required. + + The Window and Widget Class icons can be dragged onto the desktop, + creating a new window or widget at the drop position. + + \image html widgetbin_action.png + \image latex widgetbin_action.png + + All other widget types can be dragged from the bin into a window, or a group + inside a window. When dropped, they will be positioned close to the drop point + and inserted into the widget tree as the last child of the chosen group. + The order of widgets within their group can be changed with + the `F2` and `F3` keys. + +*/ diff --git a/fluid/documentation/src/widgetbin_action.png b/fluid/documentation/src/widgetbin_action.png new file mode 100644 index 000000000..26463b6e9 Binary files /dev/null and b/fluid/documentation/src/widgetbin_action.png differ diff --git a/fluid/factory.cxx b/fluid/factory.cxx index 46183bb8a..a4072967f 100644 --- a/fluid/factory.cxx +++ b/fluid/factory.cxx @@ -1208,7 +1208,7 @@ static Fl_Type *known_types[] = { add_new_widget_from_user(Fl_Type*, int) add_new_widget_from_user(const char*, int) */ -Fl_Type *add_new_widget_from_user(Fl_Type *inPrototype, Strategy strategy) { +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); @@ -1314,7 +1314,8 @@ Fl_Type *add_new_widget_from_user(Fl_Type *inPrototype, Strategy strategy) { // make the new widget visible select_only(t); set_modflag(1); - t->open(); + if (and_open) + t->open(); } else { undo_current --; undo_last --; @@ -1332,10 +1333,10 @@ Fl_Type *add_new_widget_from_user(Fl_Type *inPrototype, Strategy strategy) { add_new_widget_from_user(Fl_Type*, int) add_new_widget_from_user(const char*, int) */ -Fl_Type *add_new_widget_from_user(const char *inName, Strategy strategy) { +Fl_Type *add_new_widget_from_user(const char *inName, Strategy strategy, bool and_open) { Fl_Type *prototype = typename_to_prototype(inName); if (prototype) - return add_new_widget_from_user(prototype, strategy); + return add_new_widget_from_user(prototype, strategy, and_open); else return NULL; } diff --git a/fluid/factory.h b/fluid/factory.h index 7bd09eb05..7f3ca6dfa 100644 --- a/fluid/factory.h +++ b/fluid/factory.h @@ -27,8 +27,8 @@ void fill_in_New_Menu(); Fl_Type *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); -Fl_Type *add_new_widget_from_user(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); #endif // _FLUID_FACTORY_H diff --git a/fluid/file.cxx b/fluid/file.cxx index a054a34cb..e71f4b9a6 100644 --- a/fluid/file.cxx +++ b/fluid/file.cxx @@ -27,7 +27,7 @@ #include "Fl_Widget_Type.h" #include "Fl_Grid_Type.h" #include "Fl_Window_Type.h" -#include "alignment_panel.h" +#include "settings_panel.h" #include "widget_browser.h" #include "shell_command.h" #include "code.h" @@ -75,9 +75,9 @@ int read_file(const char *filename, int merge, Strategy strategy) { is used to implement copy and paste. \return 0 if the operation failed, 1 if it succeeded */ -int write_file(const char *filename, int selected_only, bool to_sourceview) { +int write_file(const char *filename, int selected_only, bool to_codeview) { Fd_Project_Writer out; - return out.write_project(filename, selected_only, to_sourceview); + return out.write_project(filename, selected_only, to_codeview); } /** @@ -780,7 +780,7 @@ void Fd_Project_Reader::read_fdesign() { Fd_Project_Writer::Fd_Project_Writer() : fout(NULL), needspace(0), - write_sourceview_(false) + write_codeview_(false) { } @@ -824,11 +824,11 @@ int Fd_Project_Writer::close_write() { \param[in] filename create this file, and if it exists, overwrite it \param[in] selected_only write only the selected nodes in the widget_tree. This is used to implement copy and paste. - \param[in] sv if set, this file will be used by SourceView + \param[in] sv if set, this file will be used by codeview \return 0 if the operation failed, 1 if it succeeded */ int Fd_Project_Writer::write_project(const char *filename, int selected_only, bool sv) { - write_sourceview_ = sv; + write_codeview_ = sv; undo_suspend(); if (!open_write(filename)) { undo_resume(); diff --git a/fluid/file.h b/fluid/file.h index b2e3739a3..71ee543a4 100644 --- a/fluid/file.h +++ b/fluid/file.h @@ -26,7 +26,7 @@ class Fl_Type; extern int fdesign_flip; int read_file(const char *, int merge, Strategy strategy=kAddAsLastChild); -int write_file(const char *, int selected_only = 0, bool to_sourceview = false); +int write_file(const char *, int selected_only = 0, bool to_codeview = false); class Fd_Project_Reader { @@ -73,22 +73,22 @@ protected: FILE *fout; /// If set, one space is written before text unless the format starts with a newline character int needspace; - /// Set if this file will be used in the SourceView dialog - bool write_sourceview_; + /// Set if this file will be used in the codeview dialog + bool write_codeview_; public: Fd_Project_Writer(); ~Fd_Project_Writer(); int open_write(const char *s); int close_write(); - int write_project(const char *filename, int selected_only, bool sourceview); + int write_project(const char *filename, int selected_only, bool codeview); void write_word(const char *); void write_string(const char *,...) __fl_attr((__format__ (__printf__, 2, 3))); void write_indent(int n); void write_open(); void write_close(int n); FILE *file() const { return fout; } - bool write_sourceview() const { return write_sourceview_; } + bool write_codeview() const { return write_codeview_; } }; #endif // _FLUID_FILE_H diff --git a/fluid/fluid.cxx b/fluid/fluid.cxx index 7878124f8..fcc859ad2 100644 --- a/fluid/fluid.cxx +++ b/fluid/fluid.cxx @@ -29,11 +29,12 @@ #include "code.h" #include "mergeback.h" -#include "alignment_panel.h" +#include "settings_panel.h" #include "function_panel.h" -#include "sourceview_panel.h" +#include "codeview_panel.h" #include "template_panel.h" #include "about_panel.h" +#include "autodoc.h" #include #ifdef __APPLE__ @@ -132,8 +133,8 @@ Fl_Menu_Item *history_item = NULL; /// Menuitem to show or hide the widget bin, label will change if bin is visible. Fl_Menu_Item *widgetbin_item = NULL; -/// Menuitem to show or hide the source view, label will change if view is visible. -Fl_Menu_Item *sourceview_item = NULL; +/// Menuitem to show or hide the code view, label will change if view is visible. +Fl_Menu_Item *codeview_item = NULL; /// Menuitem to show or hide the editing overlay, label will change if overlay visibility changes. Fl_Menu_Item *overlay_item = NULL; @@ -184,6 +185,9 @@ Fl_String g_header_filename_arg; /// current directory path at application launch Fl_String g_launch_path; +/// if set, generate images for automatic documentation in this directory +Fl_String g_autodoc_path; + /// path to store temporary files during app run /// \see tmpdir_create_called Fl_String tmpdir_path; @@ -796,15 +800,15 @@ void exit_cb(Fl_Widget *,void *) { save_position(widgetbin_panel,"widgetbin_pos"); delete widgetbin_panel; } - if (sourceview_panel) { - Fl_Preferences svp(fluid_prefs, "sourceview"); - svp.set("autorefresh", sv_autorefresh->value()); - svp.set("autoposition", sv_autoposition->value()); - svp.set("tab", sv_tab->find(sv_tab->value())); - svp.set("code_choice", sv_code_choice); - save_position(sourceview_panel,"sourceview_pos"); - delete sourceview_panel; - sourceview_panel = 0; + if (codeview_panel) { + Fl_Preferences svp(fluid_prefs, "codeview"); + svp.set("autorefresh", cv_autorefresh->value()); + svp.set("autoposition", cv_autoposition->value()); + svp.set("tab", cv_tab->find(cv_tab->value())); + svp.set("code_choice", cv_code_choice); + save_position(codeview_panel,"codeview_pos"); + delete codeview_panel; + codeview_panel = 0; } if (shell_run_window) { save_position(shell_run_window,"shell_run_Window_pos"); @@ -838,10 +842,10 @@ void exit_cb(Fl_Widget *,void *) { to save the old project first. \param[in] user_must_confirm if set, a confimation dialog is presented to the - user before resetting the project. + user before resetting the project. Default is `true`. \return false if the operation was canceled */ -bool new_project(bool user_must_confirm = true) { +bool new_project(bool user_must_confirm) { // verify user intention if ((user_must_confirm) && (confirm_project_clear() == false)) return false; @@ -1696,7 +1700,7 @@ Fl_Menu_Item Main_Menu[] = { {"Hide Guides",FL_COMMAND+FL_SHIFT+'g',toggle_guides}, {"Hide Restricted",FL_COMMAND+FL_SHIFT+'r',toggle_restricted}, {"Show Widget &Bin...",FL_ALT+'b',toggle_widgetbin_cb}, - {"Show Source Code...",FL_ALT+FL_SHIFT+'s', (Fl_Callback*)toggle_sourceview_cb, 0, FL_MENU_DIVIDER}, + {"Show Code View",FL_ALT+'c', (Fl_Callback*)toggle_codeview_cb, 0, FL_MENU_DIVIDER}, {"Settings...",FL_ALT+'p',show_settings_cb}, {0}, {"&New", 0, 0, (void *)New_Menu, FL_SUBMENU_POINTER}, @@ -1813,7 +1817,11 @@ void init_scheme() { scheme_name = const_cast(scheme_choice->text(scheme_index)); fluid_prefs.set("scheme_name", scheme_name); } - Fl::scheme(scheme_name); + // Set the new scheme only if it was not overridden by the -scheme + // command line option + if (Fl::scheme() == NULL) { + Fl::scheme(scheme_name); + } free(scheme_name); } @@ -1839,15 +1847,15 @@ void toggle_widgetbin_cb(Fl_Widget *, void *) { /** Show or hide the code preview window. */ -void toggle_sourceview_cb(Fl_Double_Window *, void *) { - sourceview_toggle_visibility(); +void toggle_codeview_cb(Fl_Double_Window *, void *) { + codeview_toggle_visibility(); } /** Show or hide the code preview window, button callback. */ -void toggle_sourceview_b_cb(Fl_Button*, void *) { - sourceview_toggle_visibility(); +void toggle_codeview_b_cb(Fl_Button*, void *) { + codeview_toggle_visibility(); } /** @@ -1877,7 +1885,7 @@ void make_main_window() { save_item = (Fl_Menu_Item*)main_menubar->find_item(save_cb); history_item = (Fl_Menu_Item*)main_menubar->find_item(menu_file_open_history_cb); widgetbin_item = (Fl_Menu_Item*)main_menubar->find_item(toggle_widgetbin_cb); - sourceview_item = (Fl_Menu_Item*)main_menubar->find_item((Fl_Callback*)toggle_sourceview_cb); + codeview_item = (Fl_Menu_Item*)main_menubar->find_item((Fl_Callback*)toggle_codeview_cb); overlay_item = (Fl_Menu_Item*)main_menubar->find_item((Fl_Callback*)toggle_overlays); guides_item = (Fl_Menu_Item*)main_menubar->find_item((Fl_Callback*)toggle_guides); restricted_item = (Fl_Menu_Item*)main_menubar->find_item((Fl_Callback*)toggle_restricted); @@ -2049,9 +2057,9 @@ void set_modflag(int mf, int mfc) { if (!old_title || strcmp(old_title, new_title)) main_window->copy_label(new_title); } - // if the UI was modified in any way, update the Source View panel - if (sourceview_panel && sourceview_panel->visible() && sv_autorefresh->value()) - sourceview_defer_update(); + // if the UI was modified in any way, update the Code View panel + if (codeview_panel && codeview_panel->visible() && cv_autorefresh->value()) + codeview_defer_update(); } // ---- Main program entry point @@ -2091,6 +2099,12 @@ static int arg(int argc, char** argv, int& i) { batch_mode++; i += 2; return 2; } +#ifndef NDEBUG + if ((i+1 < argc) && (strcmp(argv[i], "--autodoc") == 0)) { + g_autodoc_path = argv[i+1]; + i += 2; return 2; + } +#endif if (argv[i][1] == 'h' && !argv[i][2]) { if ( (i+1 < argc) && (argv[i+1][0] != '-') ) { g_header_filename_arg = argv[i+1]; @@ -2179,7 +2193,9 @@ int main(int argc,char **argv) { return 1; } - const char *c = argv[i]; + const char *c = NULL; + if (g_autodoc_path.empty()) + c = argv[i]; fl_register_images(); @@ -2202,8 +2218,8 @@ int main(int argc,char **argv) { g_layout_list.read(fluid_prefs, FD_STORE_USER); main_window->show(argc,argv); toggle_widgetbin_cb(0,0); - toggle_sourceview_cb(0,0); - if (!c && openlast_button->value() && absolute_history[0][0]) { + toggle_codeview_cb(0,0); + if (!c && openlast_button->value() && absolute_history[0][0] && g_autodoc_path.empty()) { // Open previous file when no file specified... open_project_file(absolute_history[0]); } @@ -2257,6 +2273,14 @@ int main(int argc,char **argv) { // Set (but do not start) timer callback for external editor updates ExternalCodeEditor::set_update_timer_callback(external_editor_timer); +#ifndef NDEBUG + // check if the user wants FLUID to generate image for the user documentation + if (!g_autodoc_path.empty()) { + run_autodoc(g_autodoc_path); + return 0; + } +#endif + #ifdef _WIN32 Fl::run(); #else diff --git a/fluid/fluid.h b/fluid/fluid.h index b71baaeb7..95f4dc4dd 100644 --- a/fluid/fluid.h +++ b/fluid/fluid.h @@ -78,7 +78,7 @@ extern void update_history(const char *); extern Fl_Menu_Item *save_item; extern Fl_Menu_Item *history_item; extern Fl_Menu_Item *widgetbin_item; -extern Fl_Menu_Item *sourceview_item; +extern Fl_Menu_Item *codeview_item; extern Fl_Menu_Item *overlay_item; extern Fl_Button *overlay_button; extern Fl_Menu_Item *guides_item; @@ -98,6 +98,8 @@ extern Fl_String g_code_filename_arg; extern Fl_String g_header_filename_arg; extern Fl_String g_launch_path; +extern Fl_String g_autodoc_path; + // ---- project class declaration /** @@ -176,6 +178,7 @@ extern Fluid_Project g_project; // ---- public functions +extern bool new_project(bool user_must_confirm = true); extern void enter_project_dir(); extern void leave_project_dir(); extern void set_filename(const char *c); diff --git a/fluid/makedepend b/fluid/makedepend index f3a4d99f5..cdef22f26 100644 --- a/fluid/makedepend +++ b/fluid/makedepend @@ -26,89 +26,89 @@ about_panel.o: ../FL/Fl_Window.H about_panel.o: ../FL/platform_types.h about_panel.o: ../src/flstring.h about_panel.o: about_panel.h -alignment_panel.o: ../config.h -alignment_panel.o: ../FL/Enumerations.H -alignment_panel.o: ../FL/filename.H -alignment_panel.o: ../FL/Fl.H -alignment_panel.o: ../FL/fl_ask.H -alignment_panel.o: ../FL/fl_attr.h -alignment_panel.o: ../FL/Fl_Bitmap.H -alignment_panel.o: ../FL/Fl_Box.H -alignment_panel.o: ../FL/Fl_Browser.H -alignment_panel.o: ../FL/Fl_Browser_.H -alignment_panel.o: ../FL/Fl_Button.H -alignment_panel.o: ../FL/Fl_Cairo.H -alignment_panel.o: ../FL/fl_casts.H -alignment_panel.o: ../FL/Fl_Check_Button.H -alignment_panel.o: ../FL/Fl_Choice.H -alignment_panel.o: ../FL/fl_config.h -alignment_panel.o: ../FL/Fl_Device.H -alignment_panel.o: ../FL/Fl_Double_Window.H -alignment_panel.o: ../FL/fl_draw.H -alignment_panel.o: ../FL/Fl_Export.H -alignment_panel.o: ../FL/Fl_File_Browser.H -alignment_panel.o: ../FL/Fl_File_Chooser.H -alignment_panel.o: ../FL/Fl_File_Icon.H -alignment_panel.o: ../FL/Fl_File_Input.H -alignment_panel.o: ../FL/Fl_Flex.H -alignment_panel.o: ../FL/Fl_Graphics_Driver.H -alignment_panel.o: ../FL/Fl_Group.H -alignment_panel.o: ../FL/Fl_Image.H -alignment_panel.o: ../FL/Fl_Input.H -alignment_panel.o: ../FL/Fl_Input_.H -alignment_panel.o: ../FL/Fl_Int_Input.H -alignment_panel.o: ../FL/Fl_Light_Button.H -alignment_panel.o: ../FL/Fl_Menu_.H -alignment_panel.o: ../FL/Fl_Menu_Button.H -alignment_panel.o: ../FL/Fl_Menu_Item.H -alignment_panel.o: ../FL/Fl_Multi_Label.H -alignment_panel.o: ../FL/Fl_Native_File_Chooser.H -alignment_panel.o: ../FL/Fl_Pack.H -alignment_panel.o: ../FL/Fl_Pixmap.H -alignment_panel.o: ../FL/Fl_Plugin.H -alignment_panel.o: ../FL/Fl_PNG_Image.H -alignment_panel.o: ../FL/Fl_Preferences.H -alignment_panel.o: ../FL/Fl_Rect.H -alignment_panel.o: ../FL/Fl_Repeat_Button.H -alignment_panel.o: ../FL/Fl_Return_Button.H -alignment_panel.o: ../FL/Fl_RGB_Image.H -alignment_panel.o: ../FL/Fl_Scheme.H -alignment_panel.o: ../FL/Fl_Scheme_Choice.H -alignment_panel.o: ../FL/Fl_Scrollbar.H -alignment_panel.o: ../FL/Fl_Shortcut_Button.H -alignment_panel.o: ../FL/fl_show_colormap.H -alignment_panel.o: ../FL/Fl_Slider.H -alignment_panel.o: ../FL/Fl_Spinner.H -alignment_panel.o: ../FL/fl_string_functions.h -alignment_panel.o: ../FL/Fl_Tabs.H -alignment_panel.o: ../FL/Fl_Terminal.H -alignment_panel.o: ../FL/Fl_Text_Buffer.H -alignment_panel.o: ../FL/Fl_Text_Display.H -alignment_panel.o: ../FL/Fl_Text_Editor.H -alignment_panel.o: ../FL/Fl_Tile.H -alignment_panel.o: ../FL/Fl_Tooltip.H -alignment_panel.o: ../FL/fl_types.h -alignment_panel.o: ../FL/fl_utf8.h -alignment_panel.o: ../FL/Fl_Valuator.H -alignment_panel.o: ../FL/Fl_Value_Input.H -alignment_panel.o: ../FL/Fl_Widget.H -alignment_panel.o: ../FL/Fl_Window.H -alignment_panel.o: ../FL/Fl_Wizard.H -alignment_panel.o: ../FL/platform_types.h -alignment_panel.o: ../src/flstring.h -alignment_panel.o: ../src/Fl_String.H -alignment_panel.o: alignment_panel.h -alignment_panel.o: code.h -alignment_panel.o: Fd_Snap_Action.h -alignment_panel.o: fluid.h -alignment_panel.o: fluid_filename.h -alignment_panel.o: Fl_Group_Type.h -alignment_panel.o: Fl_Type.h -alignment_panel.o: Fl_Widget_Type.h -alignment_panel.o: Fl_Window_Type.h -alignment_panel.o: shell_command.h -alignment_panel.o: undo.h -alignment_panel.o: widget_browser.h +settings_panel.o: ../config.h +settings_panel.o: ../FL/Enumerations.H +settings_panel.o: ../FL/filename.H +settings_panel.o: ../FL/Fl.H +settings_panel.o: ../FL/fl_ask.H +settings_panel.o: ../FL/fl_attr.h +settings_panel.o: ../FL/Fl_Bitmap.H +settings_panel.o: ../FL/Fl_Box.H +settings_panel.o: ../FL/Fl_Browser.H +settings_panel.o: ../FL/Fl_Browser_.H +settings_panel.o: ../FL/Fl_Button.H +settings_panel.o: ../FL/Fl_Cairo.H +settings_panel.o: ../FL/fl_casts.H +settings_panel.o: ../FL/Fl_Check_Button.H +settings_panel.o: ../FL/Fl_Choice.H +settings_panel.o: ../FL/fl_config.h +settings_panel.o: ../FL/Fl_Device.H +settings_panel.o: ../FL/Fl_Double_Window.H +settings_panel.o: ../FL/fl_draw.H +settings_panel.o: ../FL/Fl_Export.H +settings_panel.o: ../FL/Fl_File_Browser.H +settings_panel.o: ../FL/Fl_File_Chooser.H +settings_panel.o: ../FL/Fl_File_Icon.H +settings_panel.o: ../FL/Fl_File_Input.H +settings_panel.o: ../FL/Fl_Flex.H +settings_panel.o: ../FL/Fl_Graphics_Driver.H +settings_panel.o: ../FL/Fl_Group.H +settings_panel.o: ../FL/Fl_Image.H +settings_panel.o: ../FL/Fl_Input.H +settings_panel.o: ../FL/Fl_Input_.H +settings_panel.o: ../FL/Fl_Int_Input.H +settings_panel.o: ../FL/Fl_Light_Button.H +settings_panel.o: ../FL/Fl_Menu_.H +settings_panel.o: ../FL/Fl_Menu_Button.H +settings_panel.o: ../FL/Fl_Menu_Item.H +settings_panel.o: ../FL/Fl_Multi_Label.H +settings_panel.o: ../FL/Fl_Native_File_Chooser.H +settings_panel.o: ../FL/Fl_Pack.H +settings_panel.o: ../FL/Fl_Pixmap.H +settings_panel.o: ../FL/Fl_Plugin.H +settings_panel.o: ../FL/Fl_PNG_Image.H +settings_panel.o: ../FL/Fl_Preferences.H +settings_panel.o: ../FL/Fl_Rect.H +settings_panel.o: ../FL/Fl_Repeat_Button.H +settings_panel.o: ../FL/Fl_Return_Button.H +settings_panel.o: ../FL/Fl_RGB_Image.H +settings_panel.o: ../FL/Fl_Scheme.H +settings_panel.o: ../FL/Fl_Scheme_Choice.H +settings_panel.o: ../FL/Fl_Scrollbar.H +settings_panel.o: ../FL/Fl_Shortcut_Button.H +settings_panel.o: ../FL/fl_show_colormap.H +settings_panel.o: ../FL/Fl_Slider.H +settings_panel.o: ../FL/Fl_Spinner.H +settings_panel.o: ../FL/fl_string_functions.h +settings_panel.o: ../FL/Fl_Tabs.H +settings_panel.o: ../FL/Fl_Terminal.H +settings_panel.o: ../FL/Fl_Text_Buffer.H +settings_panel.o: ../FL/Fl_Text_Display.H +settings_panel.o: ../FL/Fl_Text_Editor.H +settings_panel.o: ../FL/Fl_Tile.H +settings_panel.o: ../FL/Fl_Tooltip.H +settings_panel.o: ../FL/fl_types.h +settings_panel.o: ../FL/fl_utf8.h +settings_panel.o: ../FL/Fl_Valuator.H +settings_panel.o: ../FL/Fl_Value_Input.H +settings_panel.o: ../FL/Fl_Widget.H +settings_panel.o: ../FL/Fl_Window.H +settings_panel.o: ../FL/Fl_Wizard.H +settings_panel.o: ../FL/platform_types.h +settings_panel.o: ../src/flstring.h +settings_panel.o: ../src/Fl_String.H +settings_panel.o: settings_panel.h +settings_panel.o: code.h +settings_panel.o: Fd_Snap_Action.h +settings_panel.o: fluid.h +settings_panel.o: fluid_filename.h +settings_panel.o: Fl_Group_Type.h +settings_panel.o: Fl_Type.h +settings_panel.o: Fl_Widget_Type.h +settings_panel.o: Fl_Window_Type.h +settings_panel.o: shell_command.h +settings_panel.o: undo.h +settings_panel.o: widget_browser.h align_widget.o: ../FL/Enumerations.H align_widget.o: ../FL/filename.H align_widget.o: ../FL/Fl.H @@ -476,7 +476,7 @@ Fd_Snap_Action.o: ../FL/Fl_Window.H Fd_Snap_Action.o: ../FL/Fl_Wizard.H Fd_Snap_Action.o: ../FL/platform_types.h Fd_Snap_Action.o: ../src/Fl_String.H -Fd_Snap_Action.o: alignment_panel.h +Fd_Snap_Action.o: settings_panel.h Fd_Snap_Action.o: code.h Fd_Snap_Action.o: Fd_Snap_Action.h Fd_Snap_Action.o: file.h @@ -561,7 +561,7 @@ file.o: ../FL/Fl_Wizard.H file.o: ../FL/platform_types.h file.o: ../src/flstring.h file.o: ../src/Fl_String.H -file.o: alignment_panel.h +file.o: settings_panel.h file.o: code.h file.o: ExternalCodeEditor_UNIX.h file.o: factory.h @@ -658,7 +658,7 @@ fluid.o: ../FL/platform_types.h fluid.o: ../src/flstring.h fluid.o: ../src/Fl_String.H fluid.o: about_panel.h -fluid.o: alignment_panel.h +fluid.o: settings_panel.h fluid.o: code.h fluid.o: CodeEditor.h fluid.o: ExternalCodeEditor_UNIX.h @@ -677,7 +677,7 @@ fluid.o: function_panel.h fluid.o: mergeback.h fluid.o: pixmaps.h fluid.o: shell_command.h -fluid.o: sourceview_panel.h +fluid.o: codeview_panel.h fluid.o: StyleParse.h fluid.o: template_panel.h fluid.o: undo.h @@ -1195,7 +1195,7 @@ Fl_Widget_Type.o: ../FL/Fl_Wizard.H Fl_Widget_Type.o: ../FL/platform_types.h Fl_Widget_Type.o: ../src/flstring.h Fl_Widget_Type.o: ../src/Fl_String.H -Fl_Widget_Type.o: alignment_panel.h +Fl_Widget_Type.o: settings_panel.h Fl_Widget_Type.o: code.h Fl_Widget_Type.o: CodeEditor.h Fl_Widget_Type.o: custom_widgets.h @@ -1296,7 +1296,7 @@ Fl_Window_Type.o: ../FL/platform_types.h Fl_Window_Type.o: ../FL/x11.H Fl_Window_Type.o: ../src/flstring.h Fl_Window_Type.o: ../src/Fl_String.H -Fl_Window_Type.o: alignment_panel.h +Fl_Window_Type.o: settings_panel.h Fl_Window_Type.o: code.h Fl_Window_Type.o: CodeEditor.h Fl_Window_Type.o: custom_widgets.h @@ -1525,7 +1525,7 @@ shell_command.o: ../FL/Fl_Window.H shell_command.o: ../FL/Fl_Wizard.H shell_command.o: ../FL/platform_types.h shell_command.o: ../src/Fl_String.H -shell_command.o: alignment_panel.h +shell_command.o: settings_panel.h shell_command.o: code.h shell_command.o: Fd_Snap_Action.h shell_command.o: file.h @@ -1537,59 +1537,58 @@ shell_command.o: Fl_Widget_Type.h shell_command.o: Fl_Window_Type.h shell_command.o: shell_command.h shell_command.o: widget_browser.h -sourceview_panel.o: ../config.h -sourceview_panel.o: ../FL/Enumerations.H -sourceview_panel.o: ../FL/filename.H -sourceview_panel.o: ../FL/Fl.H -sourceview_panel.o: ../FL/fl_attr.h -sourceview_panel.o: ../FL/Fl_Bitmap.H -sourceview_panel.o: ../FL/Fl_Box.H -sourceview_panel.o: ../FL/Fl_Button.H -sourceview_panel.o: ../FL/Fl_Cairo.H -sourceview_panel.o: ../FL/fl_casts.H -sourceview_panel.o: ../FL/Fl_Choice.H -sourceview_panel.o: ../FL/fl_config.h -sourceview_panel.o: ../FL/Fl_Device.H -sourceview_panel.o: ../FL/Fl_Double_Window.H -sourceview_panel.o: ../FL/fl_draw.H -sourceview_panel.o: ../FL/Fl_Export.H -sourceview_panel.o: ../FL/Fl_Graphics_Driver.H -sourceview_panel.o: ../FL/Fl_Group.H -sourceview_panel.o: ../FL/Fl_Image.H -sourceview_panel.o: ../FL/Fl_Input.H -sourceview_panel.o: ../FL/Fl_Input_.H -sourceview_panel.o: ../FL/Fl_Light_Button.H -sourceview_panel.o: ../FL/Fl_Menu_.H -sourceview_panel.o: ../FL/Fl_Menu_Item.H -sourceview_panel.o: ../FL/Fl_Multi_Label.H -sourceview_panel.o: ../FL/Fl_Pixmap.H -sourceview_panel.o: ../FL/Fl_Plugin.H -sourceview_panel.o: ../FL/Fl_Preferences.H -sourceview_panel.o: ../FL/Fl_Rect.H -sourceview_panel.o: ../FL/Fl_RGB_Image.H -sourceview_panel.o: ../FL/Fl_Scrollbar.H -sourceview_panel.o: ../FL/Fl_Slider.H -sourceview_panel.o: ../FL/fl_string_functions.h -sourceview_panel.o: ../FL/Fl_Tabs.H -sourceview_panel.o: ../FL/Fl_Text_Buffer.H -sourceview_panel.o: ../FL/Fl_Text_Display.H -sourceview_panel.o: ../FL/Fl_Text_Editor.H -sourceview_panel.o: ../FL/fl_types.h -sourceview_panel.o: ../FL/fl_utf8.h -sourceview_panel.o: ../FL/Fl_Valuator.H -sourceview_panel.o: ../FL/Fl_Widget.H -sourceview_panel.o: ../FL/Fl_Window.H -sourceview_panel.o: ../FL/platform_types.h -sourceview_panel.o: ../src/flstring.h -sourceview_panel.o: ../src/Fl_String.H -sourceview_panel.o: code.h -sourceview_panel.o: CodeEditor.h -sourceview_panel.o: file.h -sourceview_panel.o: fluid.h -sourceview_panel.o: fluid_filename.h -sourceview_panel.o: Fl_Type.h -sourceview_panel.o: sourceview_panel.h -sourceview_panel.o: StyleParse.h +codeview_panel.o: ../config.h +codeview_panel.o: ../FL/Enumerations.H +codeview_panel.o: ../FL/filename.H +codeview_panel.o: ../FL/Fl.H +codeview_panel.o: ../FL/fl_attr.h +codeview_panel.o: ../FL/Fl_Bitmap.H +codeview_panel.o: ../FL/Fl_Box.H +codeview_panel.o: ../FL/Fl_Button.H +codeview_panel.o: ../FL/Fl_Cairo.H +codeview_panel.o: ../FL/fl_casts.H +codeview_panel.o: ../FL/Fl_Choice.H +codeview_panel.o: ../FL/fl_config.h +codeview_panel.o: ../FL/Fl_Device.H +codeview_panel.o: ../FL/Fl_Double_Window.H +codeview_panel.o: ../FL/fl_draw.H +codeview_panel.o: ../FL/Fl_Export.H +codeview_panel.o: ../FL/Fl_Graphics_Driver.H +codeview_panel.o: ../FL/Fl_Group.H +codeview_panel.o: ../FL/Fl_Image.H +codeview_panel.o: ../FL/Fl_Input.H +codeview_panel.o: ../FL/Fl_Input_.H +codeview_panel.o: ../FL/Fl_Light_Button.H +codeview_panel.o: ../FL/Fl_Menu_.H +codeview_panel.o: ../FL/Fl_Menu_Item.H +codeview_panel.o: ../FL/Fl_Multi_Label.H +codeview_panel.o: ../FL/Fl_Pixmap.H +codeview_panel.o: ../FL/Fl_Plugin.H +codeview_panel.o: ../FL/Fl_Preferences.H +codeview_panel.o: ../FL/Fl_Rect.H +codeview_panel.o: ../FL/Fl_RGB_Image.H +codeview_panel.o: ../FL/Fl_Scrollbar.H +codeview_panel.o: ../FL/Fl_Slider.H +codeview_panel.o: ../FL/Fl_Tabs.H +codeview_panel.o: ../FL/Fl_Text_Buffer.H +codeview_panel.o: ../FL/Fl_Text_Display.H +codeview_panel.o: ../FL/Fl_Text_Editor.H +codeview_panel.o: ../FL/fl_types.h +codeview_panel.o: ../FL/fl_utf8.h +codeview_panel.o: ../FL/Fl_Valuator.H +codeview_panel.o: ../FL/Fl_Widget.H +codeview_panel.o: ../FL/Fl_Window.H +codeview_panel.o: ../FL/platform_types.h +codeview_panel.o: ../src/flstring.h +codeview_panel.o: ../src/Fl_String.H +codeview_panel.o: code.h +codeview_panel.o: CodeEditor.h +codeview_panel.o: file.h +codeview_panel.o: fluid.h +codeview_panel.o: fluid_filename.h +codeview_panel.o: Fl_Type.h +codeview_panel.o: codeview_panel.h +codeview_panel.o: StyleParse.h StyleParse.o: StyleParse.h template_panel.o: ../config.h template_panel.o: ../FL/Enumerations.H diff --git a/fluid/alignment_panel.cxx b/fluid/settings_panel.cxx similarity index 99% rename from fluid/alignment_panel.cxx rename to fluid/settings_panel.cxx index 1ad8cfdfe..8a403bbff 100644 --- a/fluid/alignment_panel.cxx +++ b/fluid/settings_panel.cxx @@ -16,7 +16,7 @@ // generated by Fast Light User Interface Designer (fluid) version 1.0400 -#include "alignment_panel.h" +#include "settings_panel.h" #include "undo.h" #include #include @@ -123,6 +123,8 @@ static void cb_w_settings_tabs(Fl_Tabs* o, void* v) { propagate_load(o, v); } +Fl_Group *w_settings_general_tab=(Fl_Group *)0; + #include static const unsigned char idata_general_64[] = @@ -2419,6 +2421,8 @@ static Fl_Image *image_user_circle_64() { return image; } +Fl_Choice *w_settings_user_commenttext=(Fl_Choice *)0; + static void cb_Close(Fl_Button*, void*) { if (g_shell_config) g_shell_config->write(fluid_prefs, FD_STORE_USER); @@ -2434,10 +2438,10 @@ Fl_Double_Window* make_settings_window() { w_settings_tabs->labelsize(11); w_settings_tabs->labelcolor(FL_WHITE); w_settings_tabs->callback((Fl_Callback*)cb_w_settings_tabs); - { Fl_Group* o = new Fl_Group(10, 60, 320, 480, "General"); - o->image( image_general_64() ); - o->image()->scale(36, 24, 0, 1); - o->labelsize(11); + { w_settings_general_tab = new Fl_Group(10, 60, 320, 480, "General"); + w_settings_general_tab->image( image_general_64() ); + w_settings_general_tab->image()->scale(36, 24, 0, 1); + w_settings_general_tab->labelsize(11); { Fl_Group* o = new Fl_Group(120, 78, 130, 25); o->callback((Fl_Callback*)cb_); { scheme_choice = new Fl_Scheme_Choice(120, 78, 120, 25, "Scheme: "); @@ -2577,9 +2581,9 @@ th a dim outline in the editing window only"); o->hide(); Fl_Group::current()->resizable(o); } // Fl_Box* o - o->end(); - Fl_Group::current()->resizable(o); - } // Fl_Group* o + w_settings_general_tab->end(); + Fl_Group::current()->resizable(w_settings_general_tab); + } // Fl_Group* w_settings_general_tab { w_settings_project_tab = new Fl_Group(10, 60, 320, 480, "Project"); w_settings_project_tab->image( image_document_64() ); w_settings_project_tab->image()->scale(36, 24, 0, 1); @@ -2734,7 +2738,7 @@ itional data in code and project files."); o->labelsize(11); o->align(Fl_Align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE)); } // Fl_Box* o - { Fl_Box* o = new Fl_Box(25, 167, 60, 20, "Margin:"); + { Fl_Box* o = new Fl_Box(25, 167, 60, 20, "Margins:"); o->labelsize(11); o->align(Fl_Align(FL_ALIGN_RIGHT|FL_ALIGN_INSIDE)); } // Fl_Box* o @@ -2795,7 +2799,7 @@ itional data in code and project files."); o->labelsize(11); o->align(Fl_Align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE)); } // Fl_Box* o - { Fl_Box* o = new Fl_Box(25, 261, 60, 20, "Margin:"); + { Fl_Box* o = new Fl_Box(25, 261, 60, 20, "Margins:"); o->labelsize(11); o->align(Fl_Align(FL_ALIGN_RIGHT|FL_ALIGN_INSIDE)); } // Fl_Box* o @@ -2856,7 +2860,7 @@ itional data in code and project files."); o->labelsize(11); o->align(Fl_Align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE)); } // Fl_Box* o - { Fl_Box* o = new Fl_Box(25, 355, 60, 20, "Margin:"); + { Fl_Box* o = new Fl_Box(25, 355, 60, 20, "Margins:"); o->labelsize(11); o->align(Fl_Align(FL_ALIGN_RIGHT|FL_ALIGN_INSIDE)); } // Fl_Box* o @@ -3295,7 +3299,7 @@ le FLTK_GETTEXT_FOUND"); i18n_pos_conditional_input->textsize(11); i18n_pos_conditional_input->callback((Fl_Callback*)cb_i18n_pos_conditional_input); } // Fl_Input* i18n_pos_conditional_input - { i18n_pos_file_input = new Fl_Input(100, 153, 220, 20, "File:"); + { i18n_pos_file_input = new Fl_Input(100, 153, 220, 20, "Catalog:"); i18n_pos_file_input->tooltip("The name of the message catalog."); i18n_pos_file_input->box(FL_THIN_DOWN_BOX); i18n_pos_file_input->labelsize(11); @@ -3451,16 +3455,16 @@ le FLTK_GETTEXT_FOUND"); } // Fl_Group* o { Fl_Group* o = new Fl_Group(100, 237, 220, 20); o->callback((Fl_Callback*)propagate_load); - { Fl_Choice* o = new Fl_Choice(100, 237, 151, 20, "Comments:"); - o->box(FL_THIN_UP_BOX); - o->down_box(FL_BORDER_BOX); - o->labelfont(1); - o->labelsize(11); - o->textsize(11); - o->callback((Fl_Callback*)cb_Comments, (void*)(&Widget_Browser::comment_font)); - Fl_Group::current()->resizable(o); + { Fl_Choice* o = w_settings_user_commenttext = new Fl_Choice(100, 237, 151, 20, "Comments:"); + w_settings_user_commenttext->box(FL_THIN_UP_BOX); + w_settings_user_commenttext->down_box(FL_BORDER_BOX); + w_settings_user_commenttext->labelfont(1); + w_settings_user_commenttext->labelsize(11); + w_settings_user_commenttext->textsize(11); + w_settings_user_commenttext->callback((Fl_Callback*)cb_Comments, (void*)(&Widget_Browser::comment_font)); + Fl_Group::current()->resizable(w_settings_user_commenttext); o->menu(fontmenu); - } // Fl_Choice* o + } // Fl_Choice* w_settings_user_commenttext { Fl_Button* o = new Fl_Button(251, 237, 51, 20); o->labelsize(11); o->callback((Fl_Callback*)cb_Color_Chip, (void*)(&Widget_Browser::comment_color)); diff --git a/fluid/alignment_panel.fl b/fluid/settings_panel.fl similarity index 99% rename from fluid/alignment_panel.fl rename to fluid/settings_panel.fl index 8c14d9811..ed5a2d7c3 100644 --- a/fluid/alignment_panel.fl +++ b/fluid/settings_panel.fl @@ -82,7 +82,7 @@ decl {\#include } {public local decl {\#include } {private global } -decl {\#include } {private global +decl {\#include } {selected private global } decl {\#include } {private global @@ -195,8 +195,8 @@ Function {make_settings_window()} {open callback {propagate_load(o, v);} open xywh {10 10 320 530} selection_color 12 labelsize 11 labelcolor 255 resizable } { - Fl_Group {} { - label General open selected + Fl_Group w_settings_general_tab { + label General open scale_image {36 24} image {icons/general_64.png} compress_image 1 xywh {10 60 320 480} labelsize 11 resizable } { Fl_Group {} { @@ -622,7 +622,7 @@ g_layout_list.update_dialogs();} xywh {85 132 235 20} labelfont 1 labelsize 11 align 20 } Fl_Box {} { - label {Margin:} + label {Margins:} xywh {25 167 60 20} labelsize 11 align 24 } Fl_Value_Input {} { @@ -688,7 +688,7 @@ g_layout_list.update_dialogs();} xywh {85 226 235 20} labelfont 1 labelsize 11 align 20 } Fl_Box {} { - label {Margin:} + label {Margins:} xywh {25 261 60 20} labelsize 11 align 24 } Fl_Value_Input {} { @@ -754,7 +754,7 @@ g_layout_list.update_dialogs();} xywh {85 320 235 20} labelfont 1 labelsize 11 align 20 } Fl_Box {} { - label {Margin:} + label {Margins:} xywh {25 355 60 20} labelsize 11 align 24 } Fl_Value_Input {} { @@ -1623,7 +1623,7 @@ if (v == LOAD) { tooltip {only include the header file if this preprocessor macro is defined, for example FLTK_GETTEXT_FOUND} xywh {100 128 220 20} box THIN_DOWN_BOX labelsize 11 textfont 4 textsize 11 } Fl_Input i18n_pos_file_input { - label {File:} + label {Catalog:} callback {if (v == LOAD) { o->value(g_project.i18n_pos_file.c_str()); } else { @@ -1796,7 +1796,7 @@ if (v == LOAD) { callback propagate_load open xywh {100 237 220 20} } { - Fl_Choice {} { + Fl_Choice w_settings_user_commenttext { label {Comments:} user_data {&Widget_Browser::comment_font} callback cb_Comments open diff --git a/fluid/alignment_panel.h b/fluid/settings_panel.h similarity index 97% rename from fluid/alignment_panel.h rename to fluid/settings_panel.h index 0f10e9494..faf4686a1 100644 --- a/fluid/alignment_panel.h +++ b/fluid/settings_panel.h @@ -16,8 +16,8 @@ // generated by Fast Light User Interface Designer (fluid) version 1.0400 -#ifndef alignment_panel_h -#define alignment_panel_h +#ifndef settings_panel_h +#define settings_panel_h #include #include "fluid.h" #include "widget_browser.h" @@ -51,6 +51,7 @@ Fl_Double_Window* make_script_panel(); extern Fl_Double_Window *settings_window; #include extern Fl_Tabs *w_settings_tabs; +extern Fl_Group *w_settings_general_tab; extern void scheme_cb(Fl_Scheme_Choice*, void*); extern Fl_Scheme_Choice *scheme_choice; #include @@ -120,6 +121,7 @@ extern Fl_Int_Input *i18n_pos_set_input; extern Fl_Group *w_settings_user_tab; extern Fl_Menu_Item fontmenu[]; extern Fl_Menu_Item colormenu[]; +extern Fl_Choice *w_settings_user_commenttext; Fl_Double_Window* make_settings_window(); extern Fl_Menu_Item menu_layout_choice[]; extern Fl_Menu_Item menu_w_layout_menu[]; diff --git a/fluid/shell_command.cxx b/fluid/shell_command.cxx index 525f58141..b1dd6d16c 100644 --- a/fluid/shell_command.cxx +++ b/fluid/shell_command.cxx @@ -93,7 +93,7 @@ #include "fluid.h" #include "file.h" -#include "alignment_panel.h" +#include "settings_panel.h" #include #include diff --git a/fluid/sourceview_panel.cxx b/fluid/sourceview_panel.cxx deleted file mode 100644 index 0b7c52306..000000000 --- a/fluid/sourceview_panel.cxx +++ /dev/null @@ -1,542 +0,0 @@ -// -// Code dialogs 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 -// - -// generated by Fast Light User Interface Designer (fluid) version 1.0400 - -#include "sourceview_panel.h" -#include "fluid.h" -#include "file.h" -#include "../src/flstring.h" -#include -#include -static char *sv_source_filename = NULL; -static char *sv_header_filename = NULL; -static char *sv_design_filename = NULL; -int sv_code_choice; -extern void select_only(Fl_Type *o); -extern void reveal_in_browser(Fl_Type *t); - -/** - Update the header and source code highlighting depending on the - currently selected object - - The Source View system offers an immediate preview of the code - files that will be generated by FLUID. It also marks the code - generated for the last selected item in the header and the source - file. -*/ -void update_sourceview_position() { - if (!sourceview_panel || !sourceview_panel->visible()) - return; - if (sv_autoposition->value()==0) - return; - if (sourceview_panel && sourceview_panel->visible() && Fl_Type::current) { - int pos0 = 0, pos1 = 0; - if (sv_source->visible_r()) { - switch (sv_code_choice) { - case 0: // prolog: not yet (include statements) - pos0 = Fl_Type::current->code1_start; - pos1 = Fl_Type::current->code2_end; - break; - case 1: // static: callbacks, menu declarations - pos0 = Fl_Type::current->code_static_start; - pos1 = Fl_Type::current->code_static_end; - break; - case 2: // code: entire implementation block including children - pos0 = Fl_Type::current->code1_start; - pos1 = Fl_Type::current->code2_end; - break; - case 3: // code1: all implementation code before the children - pos0 = Fl_Type::current->code1_start; - pos1 = Fl_Type::current->code1_end; - break; - case 4: // code1: all implementation code before the children - pos0 = Fl_Type::current->code2_start; - pos1 = Fl_Type::current->code2_end; - break; - } - if (pos0>=0) { - if (pos1buffer()->line_end(pos0); - sv_source->buffer()->highlight(pos0, pos1); - int line = sv_source->buffer()->count_lines(0, pos0); - sv_source->scroll(line, 0); - } - } - if (sv_header->visible_r()) { - switch (sv_code_choice) { - case 0: // prolog: not yet (include statements) - case 1: // static: callbacks, menu declarations - pos0 = Fl_Type::current->header_static_start; - pos1 = Fl_Type::current->header_static_end; - break; - case 2: // code: entire implementation block including children - pos0 = Fl_Type::current->header1_start; - pos1 = Fl_Type::current->header2_end; - break; - case 3: // code1: all implementation code before the children - pos0 = Fl_Type::current->header1_start; - pos1 = Fl_Type::current->header1_end; - break; - case 4: // code1: all implementation code before the children - pos0 = Fl_Type::current->header2_start; - pos1 = Fl_Type::current->header2_end; - break; - } - if (pos0>=0) { - if (pos1buffer()->line_end(pos0); - sv_header->buffer()->highlight(pos0, pos1); - int line = sv_header->buffer()->count_lines(0, pos0); - sv_header->scroll(line, 0); - } - } - if (sv_project->visible_r()) { - switch (sv_code_choice) { - case 0: // prolog: not yet (include statements) - case 1: // static: callbacks, menu declarations - case 2: // code: entire implementation block including children - pos0 = Fl_Type::current->proj1_start; - pos1 = Fl_Type::current->proj2_end; - break; - case 3: // code1: all implementation code before the children - pos0 = Fl_Type::current->proj1_start; - pos1 = Fl_Type::current->proj1_end; - break; - case 4: // code1: all implementation code before the children - pos0 = Fl_Type::current->proj2_start; - pos1 = Fl_Type::current->proj2_end; - break; - } - if (pos0>=0) { - if (pos1buffer()->line_end(pos0); - sv_project->buffer()->highlight(pos0, pos1); - int line = sv_project->buffer()->count_lines(0, pos0); - sv_project->scroll(line, 0); - } - } - } -} - -/** - Callback to update the sourceview position. -*/ -void update_sourceview_position_cb(class Fl_Tabs*, void*) { - // make sure that the selected tab shows the current view - update_sourceview_cb(0,0); - // highlight the selected widget in the selected tab - update_sourceview_position(); -} - -/** - Generate a header, source, strings, or design file in a temporary directory - and load those into the Code Viewer widgets. -*/ -void update_sourceview_cb(class Fl_Button*, void*) { - if (!sourceview_panel || !sourceview_panel->visible()) - return; - - if (!sv_source_filename) { - sv_source_filename = (char*)malloc(FL_PATH_MAX); - fl_strlcpy(sv_source_filename, get_tmpdir().c_str(), FL_PATH_MAX); - fl_strlcat(sv_source_filename, "source_view_tmp.cxx", FL_PATH_MAX); - } - if (!sv_header_filename) { - sv_header_filename = (char*)malloc(FL_PATH_MAX); - fl_strlcpy(sv_header_filename, get_tmpdir().c_str(), FL_PATH_MAX); - fl_strlcat(sv_header_filename, "source_view_tmp.h", FL_PATH_MAX); - } - if (!sv_design_filename) { - sv_design_filename = (char*)malloc(FL_PATH_MAX); - fl_strlcpy(sv_design_filename, get_tmpdir().c_str(), FL_PATH_MAX); - fl_strlcat(sv_design_filename, "source_view_tmp.fl", FL_PATH_MAX); - } - - if (sv_project->visible_r()) { - write_file(sv_design_filename, false, true); - int top = sv_project->top_line(); - sv_project->buffer()->loadfile(sv_design_filename); - sv_project->scroll(top, 0); - } else if (sv_strings->visible_r()) { - static const char *exts[] = { ".txt", ".po", ".msg" }; - char fn[FL_PATH_MAX+1]; - fl_strlcpy(fn, get_tmpdir().c_str(), FL_PATH_MAX); - fl_strlcat(fn, "strings", FL_PATH_MAX); - fl_filename_setext(fn, FL_PATH_MAX, exts[g_project.i18n_type]); - write_strings(fn); - int top = sv_strings->top_line(); - sv_strings->buffer()->loadfile(fn); - sv_strings->scroll(top, 0); - } else if (sv_source->visible_r() || sv_header->visible_r()) { - Fl_String code_file_name_bak = g_project.code_file_name; - g_project.code_file_name = sv_source_filename; - Fl_String header_file_name_bak = g_project.header_file_name; - g_project.header_file_name = sv_header_filename; - - // generate the code and load the files - Fd_Code_Writer f; - // generate files - if (f.write_code(sv_source_filename, sv_header_filename, true)) - { - // load file into source editor - int pos = sv_source->top_line(); - sv_source->buffer()->loadfile(sv_source_filename); - sv_source->scroll(pos, 0); - // load file into header editor - pos = sv_header->top_line(); - sv_header->buffer()->loadfile(sv_header_filename); - sv_header->scroll(pos, 0); - // update the source code highlighting - update_sourceview_position(); - } - - g_project.code_file_name = code_file_name_bak; - g_project.header_file_name = header_file_name_bak; - } -} - -/** - This is called by the timer itself -*/ -void update_sourceview_timer(void*) { - update_sourceview_cb(0,0); -} - -void sourceview_defer_update() { - // we will only update earliest 0.5 seconds after the last change, and only - // if no other change was made, so dragging a widget will not generate any - // CPU load - Fl::remove_timeout(update_sourceview_timer, 0); - Fl::add_timeout(0.5, update_sourceview_timer, 0); -} - -/** - Show or hide the source code preview. - The state is stored in the app preferences. -*/ -void sourceview_toggle_visibility() { - if (!sourceview_panel) { - make_sourceview(); - sourceview_panel->callback((Fl_Callback*)toggle_sourceview_cb); - Fl_Preferences svp(fluid_prefs, "sourceview"); - int autorefresh; - svp.get("autorefresh", autorefresh, 1); - sv_autorefresh->value(autorefresh); - int autoposition; - svp.get("autoposition", autoposition, 1); - sv_autoposition->value(autoposition); - int tab; - svp.get("tab", tab, 0); - if (tab>=0 && tabchildren()) sv_tab->value(sv_tab->child(tab)); - svp.get("code_choice", sv_code_choice, 2); - sv_code_choice_w->value(sv_code_choice_w->find_item_with_argument(sv_code_choice)); - if (!position_window(sourceview_panel,"sourceview_pos", 0, 320, 120, 550, 500)) return; - } - - if (sourceview_panel->visible()) { - sourceview_panel->hide(); - sourceview_item->label("Show Source Code..."); - } else { - sourceview_panel->show(); - sourceview_item->label("Hide Source Code..."); - update_sourceview_cb(0,0); - } -} - -Fl_Double_Window *sourceview_panel=(Fl_Double_Window *)0; - -Fl_Tabs *sv_tab=(Fl_Tabs *)0; - -CodeViewer *sv_source=(CodeViewer *)0; - -CodeViewer *sv_header=(CodeViewer *)0; - -TextViewer *sv_strings=(TextViewer *)0; - -TextViewer *sv_project=(TextViewer *)0; - -Fl_Button *sv_find_text_case=(Fl_Button *)0; - -Fl_Input *sv_find_text=(Fl_Input *)0; - -static void cb_sv_find_text(Fl_Input* o, void*) { - Fl_Text_Display *e = NULL; - if (sv_source->visible_r()) { - e = sv_source; - } else if (sv_header->visible_r()) { - e = sv_header; - } else if (sv_project->visible_r()) { - e = sv_project; - } - if (e) { - Fl_Text_Buffer *b = e->buffer(); - int pos = e->insert_position(); - int found = b->search_forward(pos, o->value(), &pos, sv_find_text_case->value()); - if (found) { - b->select(pos, pos + (int)strlen(o->value())); - e->insert_position(pos); - e->show_insert_position(); - } - } -} - -static void cb_(Fl_Button*, void*) { - Fl_Text_Display *e = NULL; - if (sv_source->visible_r()) { - e = sv_source; - } else if (sv_header->visible_r()) { - e = sv_header; - } else if (sv_project->visible_r()) { - e = sv_project; - } - if (e) { - const char *needle = sv_find_text->value(); - Fl_Text_Buffer *b = e->buffer(); - int pos = e->insert_position()-1; - if (pos < 0) pos = b->length()-1; - int found = b->search_backward(pos, needle, &pos, sv_find_text_case->value()); - if (!found) - found = b->search_backward(b->length()-1, needle, &pos, sv_find_text_case->value()); - if (found) { - b->select(pos, pos + (int)strlen(needle)); - e->insert_position(pos); - e->show_insert_position(); - } - } -} - -static void cb_1(Fl_Button*, void*) { - Fl_Text_Display *e = NULL; - if (sv_source->visible_r()) { - e = sv_source; - } else if (sv_header->visible_r()) { - e = sv_header; - } else if (sv_project->visible_r()) { - e = sv_project; - } - if (e) { - const char *needle = sv_find_text->value(); - Fl_Text_Buffer *b = e->buffer(); - int pos = e->insert_position() + 1; - if (pos+1 >= b->length()) pos = 0; - int found = b->search_forward(pos, needle, &pos, sv_find_text_case->value()); - if (!found && (pos > 0)) - found = b->search_forward(0, needle, &pos, sv_find_text_case->value()); - if (found) { - b->select(pos, pos + (int)strlen(needle)); - e->insert_position(pos); - e->show_insert_position(); - } - } -} - -static void cb_Reveal(Fl_Button*, void*) { - if (sourceview_panel && sourceview_panel->visible()) { - Fl_Type *node = NULL; - if (sv_source->visible_r()) - node = Fl_Type::find_in_text(0, sv_source->insert_position()); - else if (sv_header->visible_r()) - node = Fl_Type::find_in_text(1, sv_header->insert_position()); - else if (sv_project->visible_r()) - node = Fl_Type::find_in_text(2, sv_project->insert_position()); - if (node) { - select_only(node); - reveal_in_browser(node); - if (Fl::event_clicks()==1) // double click - node->open(); - } - } -} - -Fl_Light_Button *sv_autorefresh=(Fl_Light_Button *)0; - -Fl_Light_Button *sv_autoposition=(Fl_Light_Button *)0; - -Fl_Choice *sv_code_choice_w=(Fl_Choice *)0; - -static void cb_sv_code_choice_w(Fl_Choice* o, void*) { - sv_code_choice = (int)o->mvalue()->argument(); - update_sourceview_position(); -} - -Fl_Menu_Item menu_sv_code_choice_w[] = { - {"prolog", 0, 0, (void*)(0), 16, (uchar)FL_NORMAL_LABEL, 0, 11, 0}, - {"static", 0, 0, (void*)(1), 0, (uchar)FL_NORMAL_LABEL, 0, 11, 0}, - {"code", 0, 0, (void*)(2), 0, (uchar)FL_NORMAL_LABEL, 0, 11, 0}, - {"code 1", 0, 0, (void*)(3), 0, (uchar)FL_NORMAL_LABEL, 0, 11, 0}, - {"code 2", 0, 0, (void*)(4), 0, (uchar)FL_NORMAL_LABEL, 0, 11, 0}, - {0,0,0,0,0,0,0,0,0} -}; - -Fl_Double_Window* make_sourceview() { - { sourceview_panel = new Fl_Double_Window(520, 515, "Code View"); - sourceview_panel->callback((Fl_Callback*)toggle_sourceview_cb); - sourceview_panel->align(Fl_Align(FL_ALIGN_CLIP|FL_ALIGN_INSIDE)); - { sv_tab = new Fl_Tabs(10, 10, 500, 440); - sv_tab->selection_color((Fl_Color)4); - sv_tab->labelcolor(FL_BACKGROUND2_COLOR); - sv_tab->callback((Fl_Callback*)update_sourceview_position_cb); - { Fl_Group* o = new Fl_Group(10, 35, 500, 415, "Source"); - o->labelsize(13); - { CodeViewer* o = sv_source = new CodeViewer(10, 40, 500, 410); - sv_source->box(FL_DOWN_FRAME); - sv_source->color(FL_BACKGROUND2_COLOR); - sv_source->selection_color(FL_SELECTION_COLOR); - sv_source->labeltype(FL_NORMAL_LABEL); - sv_source->labelfont(0); - sv_source->labelsize(14); - sv_source->labelcolor(FL_FOREGROUND_COLOR); - sv_source->textfont(4); - sv_source->textsize(11); - sv_source->align(Fl_Align(FL_ALIGN_TOP)); - sv_source->when(FL_WHEN_RELEASE); - Fl_Group::current()->resizable(sv_source); - o->linenumber_width(60); - o->linenumber_size(o->Fl_Text_Display::textsize()); - } // CodeViewer* sv_source - o->end(); - Fl_Group::current()->resizable(o); - } // Fl_Group* o - { Fl_Group* o = new Fl_Group(10, 35, 500, 415, "Header"); - o->labelsize(13); - o->hide(); - { CodeViewer* o = sv_header = new CodeViewer(10, 40, 500, 410); - sv_header->box(FL_DOWN_FRAME); - sv_header->color(FL_BACKGROUND2_COLOR); - sv_header->selection_color(FL_SELECTION_COLOR); - sv_header->labeltype(FL_NORMAL_LABEL); - sv_header->labelfont(0); - sv_header->labelsize(14); - sv_header->labelcolor(FL_FOREGROUND_COLOR); - sv_header->textfont(4); - sv_header->textsize(11); - sv_header->align(Fl_Align(FL_ALIGN_TOP)); - sv_header->when(FL_WHEN_RELEASE); - Fl_Group::current()->resizable(sv_header); - o->linenumber_width(60); - o->linenumber_size(o->Fl_Text_Display::textsize()); - } // CodeViewer* sv_header - o->end(); - } // Fl_Group* o - { Fl_Group* o = new Fl_Group(10, 35, 500, 415, "Strings"); - o->labelsize(13); - o->hide(); - { TextViewer* o = sv_strings = new TextViewer(10, 40, 500, 410); - sv_strings->box(FL_DOWN_FRAME); - sv_strings->color(FL_BACKGROUND2_COLOR); - sv_strings->selection_color(FL_SELECTION_COLOR); - sv_strings->labeltype(FL_NORMAL_LABEL); - sv_strings->labelfont(0); - sv_strings->labelsize(14); - sv_strings->labelcolor(FL_FOREGROUND_COLOR); - sv_strings->textfont(4); - sv_strings->textsize(11); - sv_strings->align(Fl_Align(FL_ALIGN_TOP)); - sv_strings->when(FL_WHEN_RELEASE); - Fl_Group::current()->resizable(sv_strings); - o->linenumber_width(60); - o->linenumber_size(o->Fl_Text_Display::textsize()); - } // TextViewer* sv_strings - o->end(); - } // Fl_Group* o - { Fl_Group* o = new Fl_Group(10, 35, 500, 415, "Project"); - o->labelsize(13); - o->hide(); - { TextViewer* o = sv_project = new TextViewer(10, 40, 500, 410); - sv_project->box(FL_DOWN_FRAME); - sv_project->color(FL_BACKGROUND2_COLOR); - sv_project->selection_color(FL_SELECTION_COLOR); - sv_project->labeltype(FL_NORMAL_LABEL); - sv_project->labelfont(0); - sv_project->labelsize(14); - sv_project->labelcolor(FL_FOREGROUND_COLOR); - sv_project->textfont(4); - sv_project->textsize(11); - sv_project->align(Fl_Align(FL_ALIGN_TOP)); - sv_project->when(FL_WHEN_RELEASE); - Fl_Group::current()->resizable(sv_project); - o->linenumber_width(60); - o->linenumber_size(o->Fl_Text_Display::textsize()); - } // TextViewer* sv_project - o->end(); - } // Fl_Group* o - sv_tab->end(); - Fl_Group::current()->resizable(sv_tab); - } // Fl_Tabs* sv_tab - { Fl_Group* o = new Fl_Group(10, 460, 500, 20); - { sv_find_text_case = new Fl_Button(244, 460, 25, 20, "aA"); - sv_find_text_case->type(1); - sv_find_text_case->labelsize(11); - } // Fl_Button* sv_find_text_case - { sv_find_text = new Fl_Input(40, 460, 200, 20, "Find:"); - sv_find_text->labelsize(11); - sv_find_text->textsize(11); - sv_find_text->callback((Fl_Callback*)cb_sv_find_text); - sv_find_text->when(FL_WHEN_RELEASE | FL_WHEN_ENTER_KEY_CHANGED); - } // Fl_Input* sv_find_text - { Fl_Button* o = new Fl_Button(273, 460, 25, 20, "<<"); - o->labelsize(11); - o->callback((Fl_Callback*)cb_); - } // Fl_Button* o - { Fl_Button* o = new Fl_Button(298, 460, 25, 20, ">>"); - o->labelsize(11); - o->callback((Fl_Callback*)cb_1); - } // Fl_Button* o - { Fl_Button* o = new Fl_Button(327, 460, 61, 20, "Reveal"); - o->labelsize(11); - o->callback((Fl_Callback*)cb_Reveal); - } // Fl_Button* o - { Fl_Box* o = new Fl_Box(490, 460, 20, 20); - Fl_Group::current()->resizable(o); - } // Fl_Box* o - o->end(); - } // Fl_Group* o - { Fl_Group* o = new Fl_Group(10, 485, 500, 20); - { Fl_Button* o = new Fl_Button(10, 485, 61, 20, "Refresh"); - o->labelsize(11); - o->callback((Fl_Callback*)update_sourceview_cb); - } // Fl_Button* o - { Fl_Light_Button* o = sv_autorefresh = new Fl_Light_Button(77, 485, 91, 20, "Auto-Refresh"); - sv_autorefresh->labelsize(11); - o->callback((Fl_Callback*)update_sourceview_cb); - } // Fl_Light_Button* sv_autorefresh - { sv_autoposition = new Fl_Light_Button(172, 485, 89, 20, "Auto-Position"); - sv_autoposition->labelsize(11); - } // Fl_Light_Button* sv_autoposition - { sv_code_choice_w = new Fl_Choice(265, 485, 70, 20); - sv_code_choice_w->down_box(FL_BORDER_BOX); - sv_code_choice_w->labelsize(11); - sv_code_choice_w->textsize(11); - sv_code_choice_w->callback((Fl_Callback*)cb_sv_code_choice_w); - sv_code_choice_w->menu(menu_sv_code_choice_w); - } // Fl_Choice* sv_code_choice_w - { Fl_Box* o = new Fl_Box(375, 485, 80, 20); - Fl_Group::current()->resizable(o); - } // Fl_Box* o - { Fl_Button* o = new Fl_Button(460, 485, 50, 20, "Close"); - o->labelsize(11); - o->callback((Fl_Callback*)toggle_sourceview_b_cb); - } // Fl_Button* o - o->end(); - } // Fl_Group* o - sourceview_panel->size_range(384, 120); - sourceview_panel->end(); - } // Fl_Double_Window* sourceview_panel - return sourceview_panel; -} - -// diff --git a/fluid/sourceview_panel.h b/fluid/sourceview_panel.h deleted file mode 100644 index 281aa41ff..000000000 --- a/fluid/sourceview_panel.h +++ /dev/null @@ -1,55 +0,0 @@ -// -// Code dialogs 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 -// - -// generated by Fast Light User Interface Designer (fluid) version 1.0400 - -#ifndef sourceview_panel_h -#define sourceview_panel_h -#include -extern int sv_code_choice; -void update_sourceview_position(); -void update_sourceview_position_cb(class Fl_Tabs*, void*); -void update_sourceview_cb(class Fl_Button*, void*); -void update_sourceview_timer(void*); -void sourceview_defer_update(); -void sourceview_toggle_visibility(); -#include -extern void toggle_sourceview_cb(Fl_Double_Window*, void*); -extern Fl_Double_Window *sourceview_panel; -#include -extern Fl_Tabs *sv_tab; -#include -#include "CodeEditor.h" -extern CodeViewer *sv_source; -extern CodeViewer *sv_header; -extern TextViewer *sv_strings; -extern TextViewer *sv_project; -#include -extern Fl_Button *sv_find_text_case; -#include -extern Fl_Input *sv_find_text; -#include -#include -extern Fl_Light_Button *sv_autorefresh; -extern Fl_Light_Button *sv_autoposition; -#include -extern Fl_Choice *sv_code_choice_w; -extern void toggle_sourceview_b_cb(Fl_Button*, void*); -Fl_Double_Window* make_sourceview(); -extern Fl_Menu_Item menu_sv_code_choice_w[]; -#endif - -// diff --git a/fluid/widget_panel.cxx b/fluid/widget_panel.cxx index 46cd29548..cb08f132f 100644 --- a/fluid/widget_panel.cxx +++ b/fluid/widget_panel.cxx @@ -413,6 +413,10 @@ static void cb_widget_tabs(Fl_Tabs* o, void* v) { propagate_load((Fl_Group *)o,v); } +Fl_Group *wp_gui_tab=(Fl_Group *)0; + +Fl_Input *wp_gui_label=(Fl_Input *)0; + Fl_Input *widget_image_input=(Fl_Input *)0; static void cb_(Fl_Button*, void* v) { @@ -423,6 +427,8 @@ static void cb_(Fl_Button*, void* v) { Fl_Input *widget_deimage_input=(Fl_Input *)0; +Fl_Group *wp_gui_alignment=(Fl_Group *)0; + Fl_Menu_Item menu_[] = { {" Image Alignment ", 0, 0, (void*)((fl_intptr_t)0xFFFFFFFF), 1, (uchar)FL_NORMAL_LABEL, 2, 10, 0}, {"image over text", 0, 0, (void*)((fl_intptr_t)FL_ALIGN_IMAGE_OVER_TEXT), 0, (uchar)FL_NORMAL_LABEL, 0, 9, 0}, @@ -467,18 +473,50 @@ Fl_Menu_Item menu_Children[] = { {0,0,0,0,0,0,0,0,0} }; +Fl_Group *wp_gui_flexp=(Fl_Group *)0; + Fl_Value_Input *widget_flex_size=(Fl_Value_Input *)0; Fl_Check_Button *widget_flex_fixed=(Fl_Check_Button *)0; +Fl_Group *wp_gui_values=(Fl_Group *)0; + +Fl_Group *wp_gui_margins=(Fl_Group *)0; + +Fl_Group *wp_gui_sizerange=(Fl_Group *)0; + +Fl_Shortcut_Button *wp_gui_shortcut=(Fl_Shortcut_Button *)0; + +Fl_Group *wp_gui_xclass=(Fl_Group *)0; + +Fl_Group *wp_gui_attributes=(Fl_Group *)0; + +Fl_Input *wp_gui_tooltip=(Fl_Input *)0; + +Fl_Group *wp_style_tab=(Fl_Group *)0; + +Fl_Group *wp_style_label=(Fl_Group *)0; + Fl_Button *w_labelcolor=(Fl_Button *)0; +Fl_Group *wp_style_box=(Fl_Group *)0; + Fl_Button *w_color=(Fl_Button *)0; +Fl_Group *wp_style_downbox=(Fl_Group *)0; + Fl_Button *w_selectcolor=(Fl_Button *)0; +Fl_Group *wp_style_text=(Fl_Group *)0; + Fl_Button *w_textcolor=(Fl_Button *)0; +Fl_Group *wp_cpp_tab=(Fl_Group *)0; + +Fl_Group *wp_cpp_class=(Fl_Group *)0; + +Fl_Group *wp_cpp_name=(Fl_Group *)0; + Fl_Menu_Item menu_2[] = { {"private", 0, 0, (void*)(0), 0, (uchar)FL_NORMAL_LABEL, 0, 11, 0}, {"public", 0, 0, (void*)(1), 0, (uchar)FL_NORMAL_LABEL, 0, 11, 0}, @@ -503,6 +541,8 @@ Fl_Text_Editor *wComment=(Fl_Text_Editor *)0; CodeEditor *wCallback=(CodeEditor *)0; +Fl_Group *wp_cpp_callback=(Fl_Group *)0; + Fl_Menu_Item menu_4[] = { {"void*", 0, 0, 0, 0, (uchar)FL_NORMAL_LABEL, 4, 11, 0}, {"long", 0, 0, 0, 0, (uchar)FL_NORMAL_LABEL, 4, 11, 0}, @@ -537,6 +577,8 @@ static void cb_widget_grid_transient(Fl_Box* o, void* v) { Fl_Box *widget_grid_unlinked=(Fl_Box *)0; +Fl_Group *wp_gridc_align=(Fl_Group *)0; + Fl_Menu_Item menu_Horizontal[] = { {"GRID_LEFT", 0, 0, (void*)(FL_GRID_LEFT), 0, (uchar)FL_NORMAL_LABEL, 0, 11, 0}, {"GRID_CENTER", 0, 0, (void*)(FL_GRID_CENTER), 0, (uchar)FL_NORMAL_LABEL, 0, 11, 0}, @@ -553,6 +595,8 @@ Fl_Menu_Item menu_Vertical[] = { {0,0,0,0,0,0,0,0,0} }; +Fl_Group *wp_gridc_size=(Fl_Group *)0; + Fluid_Coord_Input *widget_grid_rowspan_input=(Fluid_Coord_Input *)0; Fluid_Coord_Input *widget_grid_colspan_input=(Fluid_Coord_Input *)0; @@ -643,6 +687,8 @@ static void cb_5(Fl_Button*, void* v) { } } +Fl_Group *wp_grid_margin=(Fl_Group *)0; + static void cb_Left(Fl_Value_Input* o, void* v) { Fl_Grid *grid = Fl_Grid_Type::selected(); if (!grid) return; @@ -719,6 +765,8 @@ static void cb_Bottom(Fl_Value_Input* o, void* v) { } } +Fl_Group *wp_grid_gaps=(Fl_Group *)0; + static void cb_Row(Fl_Value_Input* o, void* v) { Fl_Grid *grid = Fl_Grid_Type::selected(); if (!grid) return; @@ -963,24 +1011,24 @@ Fl_Double_Window* make_widget_panel() { widget_tabs->labelcolor(FL_BACKGROUND2_COLOR); widget_tabs->callback((Fl_Callback*)cb_widget_tabs); widget_tabs->when(FL_WHEN_NEVER); - { Fl_Group* o = new Fl_Group(10, 30, 400, 330, "GUI"); - o->labelsize(11); - o->callback((Fl_Callback*)propagate_load); - o->when(FL_WHEN_NEVER); + { wp_gui_tab = new Fl_Group(10, 30, 400, 330, "GUI"); + wp_gui_tab->labelsize(11); + wp_gui_tab->callback((Fl_Callback*)propagate_load); + wp_gui_tab->when(FL_WHEN_NEVER); { Fl_Group* o = new Fl_Group(95, 40, 309, 20, "Label:"); o->labelfont(1); o->labelsize(11); o->callback((Fl_Callback*)propagate_load); o->align(Fl_Align(FL_ALIGN_LEFT)); - { Fl_Input* o = new Fl_Input(95, 40, 190, 20); - o->tooltip("The label text for the widget.\nUse Ctrl-J for newlines."); - o->labelfont(1); - o->labelsize(11); - o->textsize(11); - o->callback((Fl_Callback*)label_cb); - o->when(FL_WHEN_RELEASE | FL_WHEN_ENTER_KEY_CHANGED); - Fl_Group::current()->resizable(o); - } // Fl_Input* o + { wp_gui_label = new Fl_Input(95, 40, 190, 20); + wp_gui_label->tooltip("The label text for the widget.\nUse Ctrl-J for newlines."); + wp_gui_label->labelfont(1); + wp_gui_label->labelsize(11); + wp_gui_label->textsize(11); + wp_gui_label->callback((Fl_Callback*)label_cb); + wp_gui_label->when(FL_WHEN_RELEASE | FL_WHEN_ENTER_KEY_CHANGED); + Fl_Group::current()->resizable(wp_gui_label); + } // Fl_Input* wp_gui_label { Fl_Choice* o = new Fl_Choice(285, 40, 119, 20); o->tooltip("The label style for the widget."); o->box(FL_THIN_UP_BOX); @@ -1038,11 +1086,11 @@ Fl_Double_Window* make_widget_panel() { } // Fl_Button* o o->end(); } // Fl_Group* o - { Fl_Group* o = new Fl_Group(95, 115, 310, 20, "Alignment:"); - o->labelfont(1); - o->labelsize(11); - o->callback((Fl_Callback*)propagate_load); - o->align(Fl_Align(FL_ALIGN_LEFT)); + { wp_gui_alignment = new Fl_Group(95, 115, 310, 20, "Alignment:"); + wp_gui_alignment->labelfont(1); + wp_gui_alignment->labelsize(11); + wp_gui_alignment->callback((Fl_Callback*)propagate_load); + wp_gui_alignment->align(Fl_Align(FL_ALIGN_LEFT)); { Fl_Button* o = new Fl_Button(95, 115, 30, 20, "Clip"); o->tooltip("Clip the label to the inside of the widget."); o->type(1); @@ -1120,8 +1168,8 @@ Fl_Double_Window* make_widget_panel() { o->labelsize(11); Fl_Group::current()->resizable(o); } // Fl_Box* o - o->end(); - } // Fl_Group* o + wp_gui_alignment->end(); + } // Fl_Group* wp_gui_alignment { Fl_Group* o = new Fl_Group(95, 150, 314, 20, "Position:"); o->labelfont(1); o->labelsize(11); @@ -1205,12 +1253,12 @@ sized to fit the container."); o->end(); } // Fl_Group* o { // This group is only visible if the parent is an Fl_Flex widget - Fl_Group* o = new Fl_Group(95, 150, 314, 20, "Flex Parent:"); - o->labelfont(1); - o->labelsize(11); - o->callback((Fl_Callback*)flex_size_group_cb); - o->align(Fl_Align(FL_ALIGN_LEFT)); - o->hide(); + wp_gui_flexp = new Fl_Group(95, 150, 314, 20, "Flex Parent:"); + wp_gui_flexp->labelfont(1); + wp_gui_flexp->labelsize(11); + wp_gui_flexp->callback((Fl_Callback*)flex_size_group_cb); + wp_gui_flexp->align(Fl_Align(FL_ALIGN_LEFT)); + wp_gui_flexp->hide(); { widget_flex_size = new Fl_Value_Input(95, 150, 55, 20, "Size:"); widget_flex_size->tooltip("Fixed Width or Height for a horizontal or vertical Fl_Flex Parent."); widget_flex_size->labelsize(11); @@ -1227,13 +1275,13 @@ sized to fit the container."); { Fl_Box* o = new Fl_Box(398, 150, 1, 20); Fl_Group::current()->resizable(o); } // Fl_Box* o - o->end(); - } // Fl_Group* o - { Fl_Group* o = new Fl_Group(95, 185, 300, 20, "Values:"); - o->labelfont(1); - o->labelsize(11); - o->callback((Fl_Callback*)values_group_cb); - o->align(Fl_Align(FL_ALIGN_LEFT)); + wp_gui_flexp->end(); + } // Fl_Group* wp_gui_flexp + { wp_gui_values = new Fl_Group(95, 185, 300, 20, "Values:"); + wp_gui_values->labelfont(1); + wp_gui_values->labelsize(11); + wp_gui_values->callback((Fl_Callback*)values_group_cb); + wp_gui_values->align(Fl_Align(FL_ALIGN_LEFT)); { Fl_Value_Input* o = new Fl_Value_Input(95, 185, 55, 20, "Size:"); o->tooltip("The size of the slider."); o->labelsize(11); @@ -1273,15 +1321,15 @@ sized to fit the container."); { Fl_Box* o = new Fl_Box(395, 185, 0, 20); Fl_Group::current()->resizable(o); } // Fl_Box* o - o->end(); - } // Fl_Group* o + wp_gui_values->end(); + } // Fl_Group* wp_gui_values { // This group is only visible for Fl_Flex widgets - Fl_Group* o = new Fl_Group(95, 185, 300, 20, "Margins:"); - o->labelfont(1); - o->labelsize(11); - o->callback((Fl_Callback*)flex_margin_group_cb); - o->align(Fl_Align(FL_ALIGN_LEFT)); - o->hide(); + wp_gui_margins = new Fl_Group(95, 185, 300, 20, "Margins:"); + wp_gui_margins->labelfont(1); + wp_gui_margins->labelsize(11); + wp_gui_margins->callback((Fl_Callback*)flex_margin_group_cb); + wp_gui_margins->align(Fl_Align(FL_ALIGN_LEFT)); + wp_gui_margins->hide(); { Fl_Value_Input* o = new Fl_Value_Input(95, 185, 55, 20, "Left:"); o->tooltip("Left margin in group."); o->labelsize(11); @@ -1320,14 +1368,14 @@ sized to fit the container."); { Fl_Box* o = new Fl_Box(395, 185, 0, 20); Fl_Group::current()->resizable(o); } // Fl_Box* o - o->end(); - } // Fl_Group* o - { Fl_Group* o = new Fl_Group(95, 185, 300, 20, "Size Range:"); - o->labelfont(1); - o->labelsize(11); - o->callback((Fl_Callback*)size_range_group_cb); - o->align(Fl_Align(FL_ALIGN_LEFT)); - o->hide(); + wp_gui_margins->end(); + } // Fl_Group* wp_gui_margins + { wp_gui_sizerange = new Fl_Group(95, 185, 300, 20, "Size Range:"); + wp_gui_sizerange->labelfont(1); + wp_gui_sizerange->labelsize(11); + wp_gui_sizerange->callback((Fl_Callback*)size_range_group_cb); + wp_gui_sizerange->align(Fl_Align(FL_ALIGN_LEFT)); + wp_gui_sizerange->hide(); { Fl_Value_Input* o = new Fl_Value_Input(95, 185, 55, 20, "Minimum Size:"); o->tooltip("The size of the slider."); o->labelsize(11); @@ -1375,34 +1423,34 @@ sized to fit the container."); { Fl_Box* o = new Fl_Box(395, 185, 0, 20); Fl_Group::current()->resizable(o); } // Fl_Box* o - o->end(); - } // Fl_Group* o + wp_gui_sizerange->end(); + } // Fl_Group* wp_gui_sizerange { Fl_Group* o = new Fl_Group(95, 210, 310, 20, "Shortcut:"); o->labelfont(1); o->labelsize(11); o->callback((Fl_Callback*)propagate_load); o->align(Fl_Align(FL_ALIGN_LEFT)); { // This is a special button that grabs keystrokes directly - Fl_Shortcut_Button* o = new Fl_Shortcut_Button(95, 210, 310, 20); - o->tooltip("The shortcut key for the widget.\nUse \'Backspace\' key to clear."); - o->box(FL_DOWN_BOX); - o->color(FL_BACKGROUND2_COLOR); - o->selection_color((Fl_Color)12); - o->labeltype(FL_NORMAL_LABEL); - o->labelfont(0); - o->labelsize(11); - o->labelcolor(FL_FOREGROUND_COLOR); - o->callback((Fl_Callback*)shortcut_in_cb); - o->align(Fl_Align(FL_ALIGN_CENTER)); - o->when(FL_WHEN_CHANGED); - } // Fl_Shortcut_Button* o + wp_gui_shortcut = new Fl_Shortcut_Button(95, 210, 310, 20); + wp_gui_shortcut->tooltip("The shortcut key for the widget.\nUse \'Backspace\' key to clear."); + wp_gui_shortcut->box(FL_DOWN_BOX); + wp_gui_shortcut->color(FL_BACKGROUND2_COLOR); + wp_gui_shortcut->selection_color((Fl_Color)12); + wp_gui_shortcut->labeltype(FL_NORMAL_LABEL); + wp_gui_shortcut->labelfont(0); + wp_gui_shortcut->labelsize(11); + wp_gui_shortcut->labelcolor(FL_FOREGROUND_COLOR); + wp_gui_shortcut->callback((Fl_Callback*)shortcut_in_cb); + wp_gui_shortcut->align(Fl_Align(FL_ALIGN_CENTER)); + wp_gui_shortcut->when(FL_WHEN_CHANGED); + } // Fl_Shortcut_Button* wp_gui_shortcut o->end(); } // Fl_Group* o - { Fl_Group* o = new Fl_Group(95, 235, 300, 20, "X Class:"); - o->labelfont(1); - o->labelsize(11); - o->callback((Fl_Callback*)propagate_load); - o->align(Fl_Align(FL_ALIGN_LEFT)); + { wp_gui_xclass = new Fl_Group(95, 235, 300, 20, "X Class:"); + wp_gui_xclass->labelfont(1); + wp_gui_xclass->labelsize(11); + wp_gui_xclass->callback((Fl_Callback*)propagate_load); + wp_gui_xclass->align(Fl_Align(FL_ALIGN_LEFT)); { Fl_Input* o = new Fl_Input(95, 235, 95, 20, ":"); o->tooltip("The X resource class."); o->labelfont(1); @@ -1430,13 +1478,13 @@ sized to fit the container."); o->callback((Fl_Callback*)non_modal_cb); o->align(Fl_Align(132|FL_ALIGN_INSIDE)); } // Fl_Light_Button* o - o->end(); - } // Fl_Group* o - { Fl_Group* o = new Fl_Group(95, 260, 305, 20, "Attributes:"); - o->labelfont(1); - o->labelsize(11); - o->callback((Fl_Callback*)propagate_load); - o->align(Fl_Align(FL_ALIGN_LEFT)); + wp_gui_xclass->end(); + } // Fl_Group* wp_gui_xclass + { wp_gui_attributes = new Fl_Group(95, 260, 305, 20, "Attributes:"); + wp_gui_attributes->labelfont(1); + wp_gui_attributes->labelsize(11); + wp_gui_attributes->callback((Fl_Callback*)propagate_load); + wp_gui_attributes->align(Fl_Align(FL_ALIGN_LEFT)); { Fl_Light_Button* o = new Fl_Light_Button(95, 260, 60, 20, "Visible"); o->tooltip("Show the widget."); o->selection_color((Fl_Color)1); @@ -1467,32 +1515,32 @@ sized to fit the container."); o->labelsize(11); Fl_Group::current()->resizable(o); } // Fl_Box* o - o->end(); - } // Fl_Group* o - { Fl_Input* o = new Fl_Input(95, 285, 310, 20, "Tooltip:"); - o->tooltip("The tooltip text for the widget.\nUse Ctrl-J for newlines."); - o->labelfont(1); - o->labelsize(11); - o->textsize(11); - o->callback((Fl_Callback*)tooltip_cb); - } // Fl_Input* o + wp_gui_attributes->end(); + } // Fl_Group* wp_gui_attributes + { wp_gui_tooltip = new Fl_Input(95, 285, 310, 20, "Tooltip:"); + wp_gui_tooltip->tooltip("The tooltip text for the widget.\nUse Ctrl-J for newlines."); + wp_gui_tooltip->labelfont(1); + wp_gui_tooltip->labelsize(11); + wp_gui_tooltip->textsize(11); + wp_gui_tooltip->callback((Fl_Callback*)tooltip_cb); + } // Fl_Input* wp_gui_tooltip { Fl_Box* o = new Fl_Box(95, 305, 300, 5); o->hide(); Fl_Group::current()->resizable(o); } // Fl_Box* o - o->end(); - Fl_Group::current()->resizable(o); - } // Fl_Group* o - { Fl_Group* o = new Fl_Group(10, 30, 400, 330, "Style"); - o->labelsize(11); - o->callback((Fl_Callback*)propagate_load); - o->when(FL_WHEN_NEVER); - o->hide(); - { Fl_Group* o = new Fl_Group(95, 40, 309, 20, "Label Font:"); - o->labelfont(1); - o->labelsize(11); - o->callback((Fl_Callback*)propagate_load); - o->align(Fl_Align(FL_ALIGN_LEFT)); + wp_gui_tab->end(); + Fl_Group::current()->resizable(wp_gui_tab); + } // Fl_Group* wp_gui_tab + { wp_style_tab = new Fl_Group(10, 30, 400, 330, "Style"); + wp_style_tab->labelsize(11); + wp_style_tab->callback((Fl_Callback*)propagate_load); + wp_style_tab->when(FL_WHEN_NEVER); + wp_style_tab->hide(); + { wp_style_label = new Fl_Group(95, 40, 309, 20, "Label Font:"); + wp_style_label->labelfont(1); + wp_style_label->labelsize(11); + wp_style_label->callback((Fl_Callback*)propagate_load); + wp_style_label->align(Fl_Align(FL_ALIGN_LEFT)); { Fl_Choice* o = new Fl_Choice(95, 40, 152, 20); o->tooltip("The style of the label text."); o->box(FL_THIN_UP_BOX); @@ -1522,13 +1570,13 @@ sized to fit the container."); o->callback((Fl_Callback*)labelcolor_menu_cb); o->menu(colormenu); } // Fl_Menu_Button* o - o->end(); - } // Fl_Group* o - { Fl_Group* o = new Fl_Group(95, 65, 309, 20, "Box:"); - o->labelfont(1); - o->labelsize(11); - o->callback((Fl_Callback*)propagate_load); - o->align(Fl_Align(FL_ALIGN_LEFT)); + wp_style_label->end(); + } // Fl_Group* wp_style_label + { wp_style_box = new Fl_Group(95, 65, 309, 20, "Box:"); + wp_style_box->labelfont(1); + wp_style_box->labelsize(11); + wp_style_box->callback((Fl_Callback*)propagate_load); + wp_style_box->align(Fl_Align(FL_ALIGN_LEFT)); { Fl_Choice* o = new Fl_Choice(95, 65, 201, 20); o->tooltip("The \"up\" box of the widget."); o->box(FL_THIN_UP_BOX); @@ -1549,20 +1597,19 @@ sized to fit the container."); o->callback((Fl_Callback*)color_menu_cb); o->menu(colormenu); } // Fl_Menu_Button* o - o->end(); - } // Fl_Group* o - { Fl_Group* o = new Fl_Group(95, 90, 309, 20, "Down Box:"); - o->labelfont(1); - o->labelsize(11); - o->callback((Fl_Callback*)propagate_load); - o->align(Fl_Align(FL_ALIGN_LEFT)); + wp_style_box->end(); + } // Fl_Group* wp_style_box + { wp_style_downbox = new Fl_Group(95, 90, 309, 20, "Down Box:"); + wp_style_downbox->labelfont(1); + wp_style_downbox->labelsize(11); + wp_style_downbox->callback((Fl_Callback*)propagate_load); + wp_style_downbox->align(Fl_Align(FL_ALIGN_LEFT)); { Fl_Choice* o = new Fl_Choice(95, 90, 201, 20); o->tooltip("The \"down\" box of the widget."); o->box(FL_THIN_UP_BOX); o->down_box(FL_BORDER_BOX); o->labelfont(1); o->labelsize(11); - o->labelcolor(FL_DARK2); o->textsize(11); o->callback((Fl_Callback*)down_box_cb); Fl_Group::current()->resizable(o); @@ -1577,13 +1624,13 @@ sized to fit the container."); o->callback((Fl_Callback*)color2_menu_cb); o->menu(colormenu); } // Fl_Menu_Button* o - o->end(); - } // Fl_Group* o - { Fl_Group* o = new Fl_Group(95, 115, 309, 20, "Text Font:"); - o->labelfont(1); - o->labelsize(11); - o->callback((Fl_Callback*)propagate_load); - o->align(Fl_Align(FL_ALIGN_LEFT)); + wp_style_downbox->end(); + } // Fl_Group* wp_style_downbox + { wp_style_text = new Fl_Group(95, 115, 309, 20, "Text Font:"); + wp_style_text->labelfont(1); + wp_style_text->labelsize(11); + wp_style_text->callback((Fl_Callback*)propagate_load); + wp_style_text->align(Fl_Align(FL_ALIGN_LEFT)); { Fl_Choice* o = new Fl_Choice(95, 115, 152, 20); o->tooltip("The value text style."); o->box(FL_DOWN_BOX); @@ -1613,8 +1660,8 @@ sized to fit the container."); o->callback((Fl_Callback*)textcolor_menu_cb); o->menu(colormenu); } // Fl_Menu_Button* o - o->end(); - } // Fl_Group* o + wp_style_text->end(); + } // Fl_Group* wp_style_text { Fl_Box* o = new Fl_Box(95, 165, 300, 40); o->labelsize(11); Fl_Group::current()->resizable(o); @@ -1625,18 +1672,18 @@ sized to fit the container."); o->labelsize(11); o->callback((Fl_Callback*)compact_cb); } // Fl_Light_Button* o - o->end(); - } // Fl_Group* o - { Fl_Group* o = new Fl_Group(10, 30, 400, 330, "C++"); - o->labelsize(11); - o->callback((Fl_Callback*)propagate_load); - o->when(FL_WHEN_NEVER); - o->hide(); - { Fl_Group* o = new Fl_Group(95, 40, 310, 20, "Class:"); - o->labelfont(1); - o->labelsize(11); - o->callback((Fl_Callback*)propagate_load); - o->align(Fl_Align(FL_ALIGN_LEFT)); + wp_style_tab->end(); + } // Fl_Group* wp_style_tab + { wp_cpp_tab = new Fl_Group(10, 30, 400, 330, "C++"); + wp_cpp_tab->labelsize(11); + wp_cpp_tab->callback((Fl_Callback*)propagate_load); + wp_cpp_tab->when(FL_WHEN_NEVER); + wp_cpp_tab->hide(); + { wp_cpp_class = new Fl_Group(95, 40, 310, 20, "Class:"); + wp_cpp_class->labelfont(1); + wp_cpp_class->labelsize(11); + wp_cpp_class->callback((Fl_Callback*)propagate_load); + wp_cpp_class->align(Fl_Align(FL_ALIGN_LEFT)); { Fl_Input* o = new Fl_Input(95, 40, 172, 20); o->tooltip("The widget subclass."); o->labelfont(1); @@ -1654,13 +1701,13 @@ sized to fit the container."); o->textsize(11); o->callback((Fl_Callback*)subtype_cb); } // Fl_Choice* o - o->end(); - } // Fl_Group* o - { Fl_Group* o = new Fl_Group(95, 65, 310, 20, "Name:"); - o->labelfont(1); - o->labelsize(11); - o->callback((Fl_Callback*)propagate_load); - o->align(Fl_Align(FL_ALIGN_LEFT)); + wp_cpp_class->end(); + } // Fl_Group* wp_cpp_class + { wp_cpp_name = new Fl_Group(95, 65, 310, 20, "Name:"); + wp_cpp_name->labelfont(1); + wp_cpp_name->labelsize(11); + wp_cpp_name->callback((Fl_Callback*)propagate_load); + wp_cpp_name->align(Fl_Align(FL_ALIGN_LEFT)); { Fl_Input* o = new Fl_Input(95, 65, 235, 20); o->tooltip("The name of the widget."); o->labelfont(1); @@ -1688,8 +1735,8 @@ sized to fit the container."); o->hide(); o->menu(menu_3); } // Fl_Choice* o - o->end(); - } // Fl_Group* o + wp_cpp_name->end(); + } // Fl_Group* wp_cpp_name { v_input[0] = new Fl_Input(95, 90, 310, 20, "Extra Code:"); v_input[0]->tooltip("Extra initialization code for the widget."); v_input[0]->labelfont(1); @@ -1764,11 +1811,11 @@ access the Widget pointer and \'v\' to access the user value."); o->end(); Fl_Group::current()->resizable(o); } // Fl_Tile* o - { Fl_Group* o = new Fl_Group(95, 310, 310, 20, "User Data:"); - o->labelfont(1); - o->labelsize(11); - o->callback((Fl_Callback*)propagate_load); - o->align(Fl_Align(FL_ALIGN_LEFT)); + { wp_cpp_callback = new Fl_Group(95, 310, 310, 20, "User Data:"); + wp_cpp_callback->labelfont(1); + wp_cpp_callback->labelsize(11); + wp_cpp_callback->callback((Fl_Callback*)propagate_load); + wp_cpp_callback->align(Fl_Align(FL_ALIGN_LEFT)); { Fl_Input* o = new Fl_Input(95, 310, 158, 20); o->tooltip("The user data to pass into the callback code."); o->labelfont(1); @@ -1789,8 +1836,8 @@ access the Widget pointer and \'v\' to access the user value."); o->when(FL_WHEN_CHANGED); o->menu(whenmenu); } // Fl_Menu_Button* o - o->end(); - } // Fl_Group* o + wp_cpp_callback->end(); + } // Fl_Group* wp_cpp_callback { Fl_Group* o = new Fl_Group(95, 332, 310, 26, "Type:"); o->labelfont(1); o->labelsize(11); @@ -1814,8 +1861,8 @@ access the Widget pointer and \'v\' to access the user value."); } // Fl_Box* w_when_box o->end(); } // Fl_Group* o - o->end(); - } // Fl_Group* o + wp_cpp_tab->end(); + } // Fl_Group* wp_cpp_tab { widget_tab_grid_child = new Fl_Group(10, 30, 400, 330, "Grid Child"); widget_tab_grid_child->labelsize(11); widget_tab_grid_child->callback((Fl_Callback*)propagate_load); @@ -1898,11 +1945,11 @@ access the Widget pointer and \'v\' to access the user value."); } // Fl_Box* widget_grid_unlinked o->end(); } // Fl_Group* o - { Fl_Group* o = new Fl_Group(95, 100, 315, 20, "Align:"); - o->labelfont(1); - o->labelsize(11); - o->callback((Fl_Callback*)propagate_load); - o->align(Fl_Align(FL_ALIGN_LEFT)); + { wp_gridc_align = new Fl_Group(95, 100, 315, 20, "Align:"); + wp_gridc_align->labelfont(1); + wp_gridc_align->labelsize(11); + wp_gridc_align->callback((Fl_Callback*)propagate_load); + wp_gridc_align->align(Fl_Align(FL_ALIGN_LEFT)); { Fl_Choice* o = new Fl_Choice(95, 100, 115, 20, "Horizontal"); o->down_box(FL_BORDER_BOX); o->labelsize(11); @@ -1923,13 +1970,13 @@ access the Widget pointer and \'v\' to access the user value."); o->hide(); Fl_Group::current()->resizable(o); } // Fl_Box* o - o->end(); - } // Fl_Group* o - { Fl_Group* o = new Fl_Group(95, 135, 315, 20, "Min. Size:"); - o->labelfont(1); - o->labelsize(11); - o->callback((Fl_Callback*)propagate_load); - o->align(Fl_Align(FL_ALIGN_LEFT)); + wp_gridc_align->end(); + } // Fl_Group* wp_gridc_align + { wp_gridc_size = new Fl_Group(95, 135, 315, 20, "Min. Size:"); + wp_gridc_size->labelfont(1); + wp_gridc_size->labelsize(11); + wp_gridc_size->callback((Fl_Callback*)propagate_load); + wp_gridc_size->align(Fl_Align(FL_ALIGN_LEFT)); { Fluid_Coord_Input* o = new Fluid_Coord_Input(95, 135, 55, 20, "Width:"); o->box(FL_DOWN_BOX); o->color(FL_BACKGROUND2_COLOR); @@ -1960,8 +2007,8 @@ access the Widget pointer and \'v\' to access the user value."); o->hide(); Fl_Group::current()->resizable(o); } // Fl_Box* o - o->end(); - } // Fl_Group* o + wp_gridc_size->end(); + } // Fl_Group* wp_gridc_size { Fl_Group* o = new Fl_Group(95, 170, 315, 20, "Span:"); o->labelfont(1); o->labelsize(11); @@ -2108,11 +2155,11 @@ access the Widget pointer and \'v\' to access the user value."); } // Fl_Box* o o->end(); } // Fl_Group* o - { Fl_Group* o = new Fl_Group(95, 100, 315, 20, "Margin:"); - o->labelfont(1); - o->labelsize(11); - o->callback((Fl_Callback*)propagate_load); - o->align(Fl_Align(FL_ALIGN_LEFT)); + { wp_grid_margin = new Fl_Group(95, 100, 315, 20, "Margins:"); + wp_grid_margin->labelfont(1); + wp_grid_margin->labelsize(11); + wp_grid_margin->callback((Fl_Callback*)propagate_load); + wp_grid_margin->align(Fl_Align(FL_ALIGN_LEFT)); { Fl_Value_Input* o = new Fl_Value_Input(95, 100, 55, 20, "Left:"); o->tooltip("Left margin in group."); o->labelsize(11); @@ -2152,13 +2199,13 @@ access the Widget pointer and \'v\' to access the user value."); { Fl_Box* o = new Fl_Box(396, 100, 0, 20); Fl_Group::current()->resizable(o); } // Fl_Box* o - o->end(); - } // Fl_Group* o - { Fl_Group* o = new Fl_Group(95, 135, 315, 20, "Gaps:"); - o->labelfont(1); - o->labelsize(11); - o->callback((Fl_Callback*)propagate_load); - o->align(Fl_Align(FL_ALIGN_LEFT)); + wp_grid_margin->end(); + } // Fl_Group* wp_grid_margin + { wp_grid_gaps = new Fl_Group(95, 135, 315, 20, "Gaps:"); + wp_grid_gaps->labelfont(1); + wp_grid_gaps->labelsize(11); + wp_grid_gaps->callback((Fl_Callback*)propagate_load); + wp_grid_gaps->align(Fl_Align(FL_ALIGN_LEFT)); { Fl_Value_Input* o = new Fl_Value_Input(95, 135, 55, 20, "Row:"); o->tooltip("Gap between children."); o->labelsize(11); @@ -2180,8 +2227,8 @@ access the Widget pointer and \'v\' to access the user value."); { Fl_Box* o = new Fl_Box(396, 135, 0, 20); Fl_Group::current()->resizable(o); } // Fl_Box* o - o->end(); - } // Fl_Group* o + wp_grid_gaps->end(); + } // Fl_Group* wp_grid_gaps { Fl_Group* o = new Fl_Group(95, 175, 315, 20, "Row:"); o->labelfont(1); o->labelsize(11); diff --git a/fluid/widget_panel.fl b/fluid/widget_panel.fl index de9863c74..b6ee299b6 100644 --- a/fluid/widget_panel.fl +++ b/fluid/widget_panel.fl @@ -335,7 +335,7 @@ Function {make_widget_panel()} { } { Fl_Window {} { comment {Use a Double Window to avoid flickering.} open - xywh {160 297 420 400} type Double labelsize 11 align 80 resizable hotspot + xywh {430 217 420 400} type Double labelsize 11 align 80 resizable hotspot code0 {o->size_range(o->w(), o->h());} size_range {420 400 0 0} visible } { Fl_Tabs widget_tabs { @@ -343,9 +343,9 @@ Function {make_widget_panel()} { xywh {10 10 400 350} selection_color 12 labelsize 11 labelcolor 7 when 0 resizable code0 {o->show();} } { - Fl_Group {} { + Fl_Group wp_gui_tab { label GUI - callback propagate_load open + callback propagate_load open selected xywh {10 30 400 330} labelsize 11 when 0 resizable } { Fl_Group {} { @@ -353,7 +353,7 @@ Function {make_widget_panel()} { callback propagate_load open xywh {95 40 309 20} labelfont 1 labelsize 11 align 4 } { - Fl_Input {} { + Fl_Input wp_gui_label { callback label_cb tooltip {The label text for the widget. Use Ctrl-J for newlines.} xywh {95 40 190 20} labelfont 1 labelsize 11 when 15 textsize 11 resizable @@ -402,7 +402,7 @@ Use Ctrl-J for newlines.} xywh {95 40 190 20} labelfont 1 labelsize 11 when 15 t tooltip {Click to choose the inactive image.} xywh {295 90 89 20} labelsize 11 } } - Fl_Group {} { + Fl_Group wp_gui_alignment { label {Alignment:} callback propagate_load xywh {95 115 310 20} labelfont 1 labelsize 11 align 4 @@ -561,7 +561,7 @@ Use Ctrl-J for newlines.} xywh {95 40 190 20} labelfont 1 labelsize 11 when 15 t Fl_Button {} { label {@-3square} user_data {(fl_intptr_t)FL_ALIGN_INSIDE} - callback align_cb selected + callback align_cb tooltip {Show the label inside the widget.} xywh {384 115 20 20} type Toggle selection_color 8 labelsize 11 labelcolor 8 } Fl_Box {} { @@ -570,7 +570,7 @@ Use Ctrl-J for newlines.} xywh {95 40 190 20} labelfont 1 labelsize 11 when 15 t } Fl_Group {} { label {Position:} - callback position_group_cb + callback position_group_cb open xywh {95 150 314 20} labelfont 1 labelsize 11 align 4 } { Fl_Input widget_x_input { @@ -627,7 +627,7 @@ h, ph, sh, ch, and i} xywh {275 150 55 20} labelsize 11 align 5 textsize 11 xywh {399 150 1 20} hide resizable } } - Fl_Group {} { + Fl_Group wp_gui_flexp { label {Flex Parent:} callback flex_size_group_cb comment {This group is only visible if the parent is an Fl_Flex widget} @@ -647,7 +647,7 @@ h, ph, sh, ch, and i} xywh {275 150 55 20} labelsize 11 align 5 textsize 11 xywh {398 150 1 20} resizable } } - Fl_Group {} { + Fl_Group wp_gui_values { label {Values:} callback values_group_cb open xywh {95 185 300 20} labelfont 1 labelsize 11 align 4 @@ -681,7 +681,7 @@ h, ph, sh, ch, and i} xywh {275 150 55 20} labelsize 11 align 5 textsize 11 xywh {395 185 0 20} resizable } } - Fl_Group {} { + Fl_Group wp_gui_margins { label {Margins:} callback flex_margin_group_cb comment {This group is only visible for Fl_Flex widgets} @@ -716,7 +716,7 @@ h, ph, sh, ch, and i} xywh {275 150 55 20} labelsize 11 align 5 textsize 11 xywh {395 185 0 20} resizable } } - Fl_Group {} { + Fl_Group wp_gui_sizerange { label {Size Range:} callback size_range_group_cb open xywh {95 185 300 20} labelfont 1 labelsize 11 align 4 hide @@ -755,10 +755,10 @@ h, ph, sh, ch, and i} xywh {275 150 55 20} labelsize 11 align 5 textsize 11 } Fl_Group {} { label {Shortcut:} - callback propagate_load + callback propagate_load open xywh {95 210 310 20} labelfont 1 labelsize 11 align 4 } { - Fl_Button {} { + Fl_Button wp_gui_shortcut { callback shortcut_in_cb comment {This is a special button that grabs keystrokes directly} tooltip {The shortcut key for the widget. @@ -767,7 +767,7 @@ Use 'Backspace' key to clear.} xywh {95 210 310 20} box DOWN_BOX color 7 selecti class Fl_Shortcut_Button } } - Fl_Group {} { + Fl_Group wp_gui_xclass { label {X Class:} callback propagate_load xywh {95 235 300 20} labelfont 1 labelsize 11 align 4 @@ -793,7 +793,7 @@ Use 'Backspace' key to clear.} xywh {95 210 310 20} box DOWN_BOX color 7 selecti tooltip {Make the window non-modal.} xywh {320 235 75 20} selection_color 1 labelsize 11 align 148 } } - Fl_Group {} { + Fl_Group wp_gui_attributes { label {Attributes:} callback propagate_load xywh {95 260 305 20} labelfont 1 labelsize 11 align 4 @@ -822,7 +822,7 @@ Use 'Backspace' key to clear.} xywh {95 210 310 20} box DOWN_BOX color 7 selecti xywh {395 260 0 20} labelsize 11 resizable } } - Fl_Input {} { + Fl_Input wp_gui_tooltip { label {Tooltip:} callback tooltip_cb tooltip {The tooltip text for the widget. @@ -832,12 +832,12 @@ Use Ctrl-J for newlines.} xywh {95 285 310 20} labelfont 1 labelsize 11 textsize xywh {95 305 300 5} hide resizable } } - Fl_Group {} { + Fl_Group wp_style_tab { label Style callback propagate_load open xywh {10 30 400 330} labelsize 11 when 0 hide } { - Fl_Group {} { + Fl_Group wp_style_label { label {Label Font:} callback propagate_load open xywh {95 40 309 20} labelfont 1 labelsize 11 align 4 @@ -864,7 +864,7 @@ Use Ctrl-J for newlines.} xywh {95 285 310 20} labelfont 1 labelsize 11 textsize code1 {o->menu(colormenu);} } {} } - Fl_Group {} { + Fl_Group wp_style_box { label {Box:} callback propagate_load open xywh {95 65 309 20} labelfont 1 labelsize 11 align 4 @@ -887,14 +887,14 @@ Use Ctrl-J for newlines.} xywh {95 285 310 20} labelfont 1 labelsize 11 textsize code1 {o->menu(colormenu);} } {} } - Fl_Group {} { + Fl_Group wp_style_downbox { label {Down Box:} callback propagate_load open xywh {95 90 309 20} labelfont 1 labelsize 11 align 4 } { Fl_Choice {} { callback down_box_cb open - tooltip {The "down" box of the widget.} xywh {95 90 201 20} box THIN_UP_BOX down_box BORDER_BOX labelfont 1 labelsize 11 labelcolor 45 textsize 11 resizable + tooltip {The "down" box of the widget.} xywh {95 90 201 20} box THIN_UP_BOX down_box BORDER_BOX labelfont 1 labelsize 11 textsize 11 resizable code0 {extern Fl_Menu_Item boxmenu[];} code1 {o->menu(boxmenu);} } {} @@ -910,7 +910,7 @@ Use Ctrl-J for newlines.} xywh {95 285 310 20} labelfont 1 labelsize 11 textsize code1 {o->menu(colormenu);} } {} } - Fl_Group {} { + Fl_Group wp_style_text { label {Text Font:} callback propagate_load open xywh {95 115 309 20} labelfont 1 labelsize 11 align 4 @@ -946,12 +946,12 @@ Use Ctrl-J for newlines.} xywh {95 285 310 20} labelfont 1 labelsize 11 textsize tooltip {use compact box types for closely set buttons} xywh {95 140 90 20} selection_color 1 labelsize 11 } } - Fl_Group {} { + Fl_Group wp_cpp_tab { label {C++} - callback propagate_load + callback propagate_load open xywh {10 30 400 330} labelsize 11 when 0 hide } { - Fl_Group {} { + Fl_Group wp_cpp_class { label {Class:} callback propagate_load open xywh {95 40 310 20} labelfont 1 labelsize 11 align 4 @@ -966,9 +966,9 @@ Use Ctrl-J for newlines.} xywh {95 285 310 20} labelfont 1 labelsize 11 textsize tooltip {The widget subtype.} xywh {267 40 138 20} box THIN_UP_BOX down_box BORDER_BOX labelsize 11 textsize 11 } {} } - Fl_Group {} { + Fl_Group wp_cpp_name { label {Name:} - callback propagate_load open + callback propagate_load xywh {95 65 310 20} labelfont 1 labelsize 11 align 4 } { Fl_Input {} { @@ -1059,7 +1059,7 @@ wCallback->do_callback(wCallback, v);} open } } } - Fl_Group {} { + Fl_Group wp_cpp_callback { label {User Data:} callback propagate_load open xywh {95 310 310 20} labelfont 1 labelsize 11 align 4 @@ -1179,7 +1179,7 @@ wCallback->do_callback(wCallback, v);} open xywh {250 60 80 20} labelsize 11 labelcolor 1 hide } } - Fl_Group {} { + Fl_Group wp_gridc_align { label {Align:} callback propagate_load open xywh {95 100 315 20} labelfont 1 labelsize 11 align 4 @@ -1240,7 +1240,7 @@ wCallback->do_callback(wCallback, v);} open xywh {395 100 1 20} hide resizable } } - Fl_Group {} { + Fl_Group wp_gridc_size { label {Min. Size:} callback propagate_load open xywh {95 135 315 20} labelfont 1 labelsize 11 align 4 @@ -1432,8 +1432,8 @@ if (v == LOAD) { xywh {396 60 0 20} resizable } } - Fl_Group {} { - label {Margin:} + Fl_Group wp_grid_margin { + label {Margins:} callback propagate_load open xywh {95 100 315 20} labelfont 1 labelsize 11 align 4 } { @@ -1521,7 +1521,7 @@ if (v == LOAD) { xywh {396 100 0 20} resizable } } - Fl_Group {} { + Fl_Group wp_grid_gaps { label {Gaps:} callback propagate_load open xywh {95 135 315 20} labelfont 1 labelsize 11 align 4 diff --git a/fluid/widget_panel.h b/fluid/widget_panel.h index 013fa4abd..38a2599a9 100644 --- a/fluid/widget_panel.h +++ b/fluid/widget_panel.h @@ -45,8 +45,10 @@ Fl_Double_Window* make_image_panel(); void run_image_panel(); #include extern Fl_Tabs *widget_tabs; +extern Fl_Group *wp_gui_tab; #include extern void label_cb(Fl_Input*, void*); +extern Fl_Input *wp_gui_label; #include extern Fl_Menu_Item labeltypemenu[]; extern void labeltype_cb(Fl_Choice*, void*); @@ -56,6 +58,7 @@ extern void image_browse_cb(Fl_Button*, void*); extern void inactive_cb(Fl_Input*, void*); extern Fl_Input *widget_deimage_input; extern void inactive_browse_cb(Fl_Button*, void*); +extern Fl_Group *wp_gui_alignment; extern void align_cb(Fl_Button*, void*); extern void align_text_image_cb(Fl_Choice*, void*); extern void align_position_cb(Fl_Choice*, void*); @@ -70,24 +73,28 @@ extern void h_cb(Fluid_Coord_Input*, void*); extern Fluid_Coord_Input *widget_h_input; extern void wc_relative_cb(Fl_Choice*, void*); extern void flex_size_group_cb(Fl_Group*, void*); +extern Fl_Group *wp_gui_flexp; #include extern void flex_size_cb(Fl_Value_Input*, void*); extern Fl_Value_Input *widget_flex_size; extern void flex_fixed_cb(Fl_Check_Button*, void*); extern Fl_Check_Button *widget_flex_fixed; extern void values_group_cb(Fl_Group*, void*); +extern Fl_Group *wp_gui_values; extern void slider_size_cb(Fl_Value_Input*, void*); extern void min_cb(Fl_Value_Input*, void*); extern void max_cb(Fl_Value_Input*, void*); extern void step_cb(Fl_Value_Input*, void*); extern void value_cb(Fl_Value_Input*, void*); extern void flex_margin_group_cb(Fl_Group*, void*); +extern Fl_Group *wp_gui_margins; extern void flex_margin_left_cb(Fl_Value_Input*, void*); extern void flex_margin_top_cb(Fl_Value_Input*, void*); extern void flex_margin_right_cb(Fl_Value_Input*, void*); extern void flex_margin_bottom_cb(Fl_Value_Input*, void*); extern void flex_margin_gap_cb(Fl_Value_Input*, void*); extern void size_range_group_cb(Fl_Group*, void*); +extern Fl_Group *wp_gui_sizerange; extern void min_w_cb(Fl_Value_Input*, void*); extern void min_h_cb(Fl_Value_Input*, void*); extern void set_min_size_cb(Fl_Button*, void*); @@ -96,16 +103,22 @@ extern void max_h_cb(Fl_Value_Input*, void*); extern void set_max_size_cb(Fl_Button*, void*); #include extern void shortcut_in_cb(Fl_Shortcut_Button*, void*); +extern Fl_Shortcut_Button *wp_gui_shortcut; +extern Fl_Group *wp_gui_xclass; extern void xclass_cb(Fl_Input*, void*); #include extern void border_cb(Fl_Light_Button*, void*); extern void modal_cb(Fl_Light_Button*, void*); extern void non_modal_cb(Fl_Light_Button*, void*); +extern Fl_Group *wp_gui_attributes; extern void visible_cb(Fl_Light_Button*, void*); extern void active_cb(Fl_Light_Button*, void*); extern void resizable_cb(Fl_Light_Button*, void*); extern void hotspot_cb(Fl_Light_Button*, void*); extern void tooltip_cb(Fl_Input*, void*); +extern Fl_Input *wp_gui_tooltip; +extern Fl_Group *wp_style_tab; +extern Fl_Group *wp_style_label; extern Fl_Menu_Item fontmenu[]; extern void labelfont_cb(Fl_Choice*, void*); extern void labelsize_cb(Fl_Value_Input*, void*); @@ -114,23 +127,29 @@ extern Fl_Button *w_labelcolor; #include extern Fl_Menu_Item colormenu[]; extern void labelcolor_menu_cb(Fl_Menu_Button*, void*); +extern Fl_Group *wp_style_box; extern Fl_Menu_Item boxmenu[]; extern void box_cb(Fl_Choice*, void*); extern void color_cb(Fl_Button*, void*); extern Fl_Button *w_color; extern void color_menu_cb(Fl_Menu_Button*, void*); +extern Fl_Group *wp_style_downbox; extern void down_box_cb(Fl_Choice*, void*); extern void color2_cb(Fl_Button*, void*); extern Fl_Button *w_selectcolor; extern void color2_menu_cb(Fl_Menu_Button*, void*); +extern Fl_Group *wp_style_text; extern void textfont_cb(Fl_Choice*, void*); extern void textsize_cb(Fl_Value_Input*, void*); extern void textcolor_cb(Fl_Button*, void*); extern Fl_Button *w_textcolor; extern void textcolor_menu_cb(Fl_Menu_Button*, void*); extern void compact_cb(Fl_Light_Button*, void*); +extern Fl_Group *wp_cpp_tab; +extern Fl_Group *wp_cpp_class; extern void subclass_cb(Fl_Input*, void*); extern void subtype_cb(Fl_Choice*, void*); +extern Fl_Group *wp_cpp_name; extern void name_cb(Fl_Input*, void*); extern void name_public_member_cb(Fl_Choice*, void*); extern void name_public_cb(Fl_Choice*, void*); @@ -142,6 +161,7 @@ extern Fl_Text_Editor *wComment; #include "CodeEditor.h" extern void callback_cb(CodeEditor*, void*); extern CodeEditor *wCallback; +extern Fl_Group *wp_cpp_callback; extern void user_data_cb(Fl_Input*, void*); extern Fl_Menu_Item whenmenu[]; extern void when_cb(Fl_Menu_Button*, void*); @@ -159,8 +179,10 @@ extern void grid_dec_col_cb(Fl_Button*, void*); extern void grid_inc_col_cb(Fl_Button*, void*); extern Fl_Box *widget_grid_transient; extern Fl_Box *widget_grid_unlinked; +extern Fl_Group *wp_gridc_align; extern void grid_align_horizontal_cb(Fl_Choice*, void*); extern void grid_align_vertical_cb(Fl_Choice*, void*); +extern Fl_Group *wp_gridc_size; extern void grid_set_min_wdt_cb(Fluid_Coord_Input*, void*); extern void grid_set_min_hgt_cb(Fluid_Coord_Input*, void*); extern void grid_set_rowspan_cb(Fluid_Coord_Input*, void*); @@ -174,6 +196,8 @@ extern void grid_inc_colspan_cb(Fl_Button*, void*); extern Fl_Group *widget_tab_grid; extern Fluid_Coord_Input *widget_grid_rows; extern Fluid_Coord_Input *widget_grid_cols; +extern Fl_Group *wp_grid_margin; +extern Fl_Group *wp_grid_gaps; extern Fluid_Coord_Input *widget_grid_curr_row; extern Fl_Group *widget_grid_curr_row_attributes; extern Fluid_Coord_Input *widget_grid_curr_col; diff --git a/src/Fl_Input_Choice.cxx b/src/Fl_Input_Choice.cxx index fcb9f9c55..534e68f19 100644 --- a/src/Fl_Input_Choice.cxx +++ b/src/Fl_Input_Choice.cxx @@ -230,14 +230,21 @@ void Fl_Input_Choice::menu_cb(Fl_Widget*, void *data) { void Fl_Input_Choice::inp_cb(Fl_Widget*, void *data) { Fl_Input_Choice *o=(Fl_Input_Choice *)data; Fl_Widget_Tracker wp(o); - if (o->inp_->changed()) { - o->Fl_Widget::set_changed(); - if (o->when() & (FL_WHEN_CHANGED|FL_WHEN_RELEASE)) - o->do_callback(FL_REASON_CHANGED); + if ( ( (Fl::callback_reason()==FL_REASON_RELEASED) + || (Fl::callback_reason()==FL_REASON_LOST_FOCUS) ) + && (o->when() & FL_WHEN_RELEASE) ) + { + o->do_callback(FL_REASON_RELEASED); } else { - o->Fl_Widget::clear_changed(); - if (o->when() & FL_WHEN_NOT_CHANGED) - o->do_callback(FL_REASON_RESELECTED); + if (o->inp_->changed()) { + o->Fl_Widget::set_changed(); + if (o->when() & FL_WHEN_CHANGED) + o->do_callback(FL_REASON_CHANGED); + } else { + o->Fl_Widget::clear_changed(); + if (o->when() & FL_WHEN_NOT_CHANGED) + o->do_callback(FL_REASON_RESELECTED); + } } if (wp.deleted()) return; @@ -259,7 +266,7 @@ Fl_Input_Choice::Fl_Input_Choice (int X, int Y, int W, int H, const char *L) inp_ = new Fl_Input(inp_x(), inp_y(), inp_w(), inp_h()); inp_->callback(inp_cb, (void*)this); inp_->box(FL_FLAT_BOX); // cosmetic - inp_->when(FL_WHEN_CHANGED|FL_WHEN_NOT_CHANGED); + inp_->when(FL_WHEN_CHANGED|FL_WHEN_NOT_CHANGED|FL_WHEN_RELEASE); menu_ = new InputMenuButton(menu_x(), menu_y(), menu_w(), menu_h()); menu_->callback(menu_cb, (void*)this); end(); diff --git a/src/Fl_get_system_colors.cxx b/src/Fl_get_system_colors.cxx index e0a78fd86..ecc08a5e0 100644 --- a/src/Fl_get_system_colors.cxx +++ b/src/Fl_get_system_colors.cxx @@ -186,10 +186,11 @@ static Fl_Pixmap tile(tile_xpm); \param[in] s Scheme name of NULL - \returns Current scheme name or NULL - \retval NULL if the scheme has not been set or is the default scheme + \retval 0 if the scheme has not been set or is the default scheme + \retval 1 if a scheme other than "none"/"base" was set - \see Fl::is_scheme() + \see Fl::scheme() to get the name of the current scheme + \see Fl::is_scheme(const char*) to test if the specified scheme is set */ int Fl::scheme(const char *s) { if (!s) { @@ -197,12 +198,12 @@ int Fl::scheme(const char *s) { } if (s) { - if (!fl_ascii_strcasecmp(s, "none") || !fl_ascii_strcasecmp(s, "base") || !*s) s = 0; + if (!fl_ascii_strcasecmp(s, "none") || !fl_ascii_strcasecmp(s, "base") || !*s) s = NULL; else if (!fl_ascii_strcasecmp(s, "gtk+")) s = fl_strdup("gtk+"); else if (!fl_ascii_strcasecmp(s, "plastic")) s = fl_strdup("plastic"); else if (!fl_ascii_strcasecmp(s, "gleam")) s = fl_strdup("gleam"); else if (!fl_ascii_strcasecmp(s, "oxy")) s = fl_strdup("oxy"); - else s = 0; + else s = NULL; } if (scheme_) free((void*)scheme_); scheme_ = s; @@ -210,12 +211,13 @@ int Fl::scheme(const char *s) { // Save the new scheme in the FLTK_SCHEME env var so that child processes // inherit it... static char e[1024]; - strcpy(e,"FLTK_SCHEME="); - if (s) strlcat(e,s,sizeof(e)); + strcpy(e, "FLTK_SCHEME="); + if (s) strlcat(e, s, sizeof(e)); Fl::system_driver()->putenv(e); // Load the scheme... - return reload_scheme(); + reload_scheme(); + return (s != NULL); } /**