diff options
Diffstat (limited to 'fluid/tools/autodoc.cxx')
| -rw-r--r-- | fluid/tools/autodoc.cxx | 613 |
1 files changed, 613 insertions, 0 deletions
diff --git a/fluid/tools/autodoc.cxx b/fluid/tools/autodoc.cxx new file mode 100644 index 000000000..59f9a7b27 --- /dev/null +++ b/fluid/tools/autodoc.cxx @@ -0,0 +1,613 @@ +// +// Self-generate snapshots of user interface for FLUID documentation. +// +// Copyright 2024-2025 by Bill Spitzak and others. +// +// This library is free software. Distribution and use rights are outlined in +// the file "COPYING" which should have been included with this file. If this +// file is missing or damaged, see the license at: +// +// https://www.fltk.org/COPYING.php +// +// Please see the following page on how to report bugs and issues: +// +// https://www.fltk.org/bugs.php +// + +#ifndef NDEBUG + +#include "tools/autodoc.h" + +#include "app/fluid.h" +#include "nodes/factory.h" +#include "nodes/Fl_Widget_Type.h" +#include "nodes/Fl_Window_Type.h" +#include "panels/widget_panel.h" +#include "panels/function_panel.h" +#include "panels/settings_panel.h" +#include "panels/codeview_panel.h" +#include "widgets/widget_browser.h" + +#include <FL/Enumerations.H> +#include <FL/fl_draw.H> +#include <FL/Fl_Image_Surface.H> +#include <FL/Fl_PNG_Image.H> +#include <FL/Fl_Menu_Bar.H> + +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 = 0x01000000; + +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; i<img_h; i++) { + const uchar *src = (const uchar*)img->data()[0] + i * ld; + for (j=0; j<img_w; j++) { + *dst++ = *src++; + *dst++ = *src++; + *dst++ = *src++; + *dst++ = 255; + } + } + + // Delete the old image + delete img; + // Create the new image + img = new Fl_RGB_Image(data, img_w, img_h, 4); + img->alloc_array = 1; + return 0; +} + +/** + Blend the left 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_left(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.0f/static_cast<float>(max_x); + for (int i = 0; i < max_x; i++) { + uchar *rgba = (uchar*)img->data()[0] + i * img->d(); + uchar alpha = static_cast<uchar>(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.0f/static_cast<float>(max_y); + for (int i = 0; i < max_y; i++) { + uchar *rgba = (uchar*)img->data()[0] + i * ld; + uchar alpha = static_cast<uchar>(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.0f/static_cast<float>(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<uchar>(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.0f/static_cast<float>(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<uchar>(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); + int scaled_img_w = static_cast<int>(img->w()*scale); + int scaled_img_h = static_cast<int>(img->h()*scale); + Fl_RGB_Image *scaled_img = + static_cast<Fl_RGB_Image*>(img->copy(scaled_img_w, scaled_img_h)); + 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 std::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", Strategy::AS_LAST_CHILD, false); + Fl_Window_Type *t_win = (Fl_Window_Type*)add_new_widget_from_user("Fl_Window", Strategy::AS_LAST_CHILD, false); + t_win->label("My Main Window"); + Fl_Widget_Type *t_grp = (Fl_Widget_Type*)add_new_widget_from_user("Fl_Group", Strategy::AS_LAST_CHILD, false); + t_grp->public_ = 0; + Fl_Widget_Type *t_btn = (Fl_Widget_Type*)add_new_widget_from_user("Fl_Button", Strategy::AS_LAST_CHILD, 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", Strategy::AS_LAST_CHILD, false); + Fl_Type *t_inp = add_new_widget_from_user("Fl_Input", Strategy::AS_LAST_CHILD, false); + Fl_Type *t_flx = add_new_widget_from_user("Fl_Flex", Strategy::AS_LAST_CHILD, false); + Fl_Type *t_flxc = add_new_widget_from_user("Fl_Button", Strategy::AS_LAST_CHILD, false); + select_only(t_grp); + Fl_Type *t_grd = add_new_widget_from_user("Fl_Grid", Strategy::AS_LAST_CHILD, false); + Fl_Type *t_grdc = add_new_widget_from_user("Fl_Button", Strategy::AS_LAST_CHILD, 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) + Fl::wait(0.2); + Fl::flush(); + 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(); + codeview_panel->show(); + Fl::wait(0.2); + Fl::flush(); + update_codeview_cb(NULL, NULL); // must be visible on screen for this to work + cv_tab->value(cv_source_tab); + codeview_panel->redraw(); + Fl::flush(); + 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(); + declblock_before_input->value("#ifdef NDEBUG"); + declblock_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 |
