// STR # 3030 - resize behavior of widgets in an Fl_Tree
// https://www.fltk.home/str.php?L3030
// Date:    Jan 16, 2014
// Update:  Apr 07, 2026

#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Tree.H>
#include <FL/Fl_Light_Button.H>
#include <FL/Fl_Box.H>

#include <vector>

Fl_Window *win    = nullptr;
Fl_Tree   *tree   = nullptr;
const int BH      =   1;        // default button height (controlled by Fl_Tree ?)
const int BW      = 300;        // default button width

std::vector<Fl_Button *> buttons;

void resize_cb(Fl_Widget *w, void *v) {
  auto win = w->window();
  int n = 0;
  printf("Buttons before resize:\n");
  for (const auto b : buttons) {
    printf("Button[%d] = (%4d, %4d, %4d, %4d)\n", n++, b->x(), b->y(), b->w(), b->h());
  }
  win->size(400, 400);
  printf("Buttons after resize:\n");
  n = 0;
  for (const auto b : buttons) {
    printf("Button[%d] = (%4d, %4d, %4d, %4d)\n", n++, b->x(), b->y(), b->w(), b->h());
  }
  fflush(stdout);
  win->redraw();
}

void auto_cb(Fl_Widget *w, void *v) {
  auto btn = (Fl_Light_Button *)w;
#if FL_API_VERSION >= 10500
  int  val = btn->value();
  tree->auto_resize_children(val);
#else
  btn->value(1);
  int val = btn->value();
#endif
  printf("auto resize mode = %s\n", val ? "ON" : "off");
  int n = 0;
  for (const auto b : buttons) {
    b->resize(b->x(), b->y(), BW, BH);
    printf("Button[%d] reset to (%4d, %4d, %4d, %4d)\n", n++, b->x(), b->y(), b->w(), b->h());
  }
  fflush(stdout);
  win->redraw();
}

int main(int argc, char **argv) {
  win   = new Fl_Window(400, 400);
  tree  = new Fl_Tree(0, 0, 400, 300);
  tree->connectorstyle(FL_TREE_CONNECTOR_SOLID);
  tree->showroot(1);

  tree->add("/dir1/subdir1/subdir2/subdir3/node2");

  for (Fl_Tree_Item *itm = tree->first(); itm; itm = itm->next()) {
    tree->begin();
    Fl_Button *but = new Fl_Button(1, 1, BW, BH);
    buttons.push_back(but);
    but->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
    but->label("button");
    itm->widget(but);
    tree->end();
  }

  auto gr = new Fl_Group(0, 300, 400, 100); // prevent resizing of the following buttons

  auto ab = new Fl_Light_Button(20, 310, 360, 30, "auto resize children");
  ab->callback(auto_cb);
  ab->value(0);                             // 0 = *default* since 1.5, 1 = old 1.4 behavior

#if FL_API_VERSION >= 10500
  tree->auto_resize_children(ab->value());  // set tree behavior according to button
#else
  ab->label("auto resize children: ALWAYS ON in 1.4 or lower");
  ab->value(1);
#endif

  auto rb = new Fl_Button(0, 360, 400, 30, "restore window size");
  rb->color(FL_RED);
  rb->callback(resize_cb);

  gr->resizable(nullptr);
  gr->end();

  win->resizable(tree);
  win->end();
  win->size_range(200, 200);
  win->show(argc, argv);

  Fl::run();
}
