Oh, I didn't notice the OP had included code as an attachment.
Another thing: if children in an Fl_Group are resized, it should
call
init_sizes() when done with the resizes to let the group know
the
children have been modified.
Also keep in mind Fl_Group::resize() will resize the children,
based on its own behavior, then you go in after that to make
changes to the children the way you want, then call
init_sizes();
before returning from your custom resize() override.
Here's a reduced version of the code so that it builds, and some
fixes applied. (I didn't look into any of the begin()/end()
stuff,
just changing the resize() calls around and adding init_sizes()
seemed to help)
___________________________________________________________________
#include <FL/Fl.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Group.H>
#include <FL/Fl_Output.H>
#include <FL/Fl_Text_Display.H>
#include <FL/Fl_Scroll.H>
#include <algorithm>
constexpr int window_w = 600;
constexpr int window_h = 400;
namespace savin::views
{
class ResizableBox : public Fl_Box
{
public:
ResizableBox(int x, int y, int w, int h, const char *l =
0)
: Fl_Box(x, y, w, h, l)
{
box(FL_BORDER_BOX);
color(FL_BLUE);
}
auto resize(int x, int y, int w, int h) -> void
override
{
int size = w < h ? w : h;
Fl_Box::resize(x, y, size, size);
}
};
class ChatList : public Fl_Scroll
{
public:
ChatList(int x, int y, int w, int h, const char *l = 0)
: Fl_Scroll(x, y, w, h, l)
{
box(FL_BORDER_BOX);
color(FL_RED);
type(Fl_Scroll::VERTICAL_ALWAYS);
}
auto handle(int event) -> int override{
return Fl_Scroll::handle(event);
}
auto resize(int x, int y, int w, int h) -> void
override
{
auto chatlist_max_width = Fl::w() * 0.15;
auto chatlist_width = std::min(float(parent()->w()
* 0.2), float(chatlist_max_width));
Fl_Scroll::resize(x, y, chatlist_width, h); // MOVED
for (int i = 0; i < children(); i++)
{
auto ch = child(i);
if(ch->type()!=6) continue;
ch->resize(1, ch->y(), chatlist_width - 30,
ch->h());
}
init_sizes(); // ADDED
redraw();
}
};
class ChatElement : public Fl_Group
{
public:
ChatElement(int x, int y, int w, int h, const char *l = 0)
: Fl_Group(x, y, w, h, l)
{
box(FL_BORDER_BOX);
color(FL_GREEN);
name = new Fl_Output(0, 0, 0, 0);
name->value("Savin");
name->box(FL_NO_BOX);
online_status = new Fl_Output(0, 0, 0, 0);
online_status->value("Online");
online_status->box(FL_NO_BOX);
avatar = new ResizableBox(0, 0, 0, 0);
last_message = new Fl_Text_Display(0, 0, 0, 0);
}
auto resize(int x, int y, int w, int h) -> void
override
{
float top_height = h * 0.25;
float avatar_max_height = h - top_height;
float avatar_size = std::min(float(avatar_max_height),
float(w * 0.3));
Fl_Group::resize(x, y, w, h); // MOVED
name->resize(x, y, w / 2, top_height);
online_status->resize(x + w / 2, y, y + w / 2,
top_height);
avatar->resize(x, y + top_height, avatar_size,
avatar_size);
last_message->resize(x + avatar_size, y +
top_height, w - avatar_size, h * 0.75);
init_sizes(); // ADDED
}
Fl_Output *name;
Fl_Output *online_status;
ResizableBox *avatar;
Fl_Text_Display *last_message;
};
}
auto main(int argc, char **argv) -> int
{
Fl_Window *window = new Fl_Double_Window(window_w, window_h,
"App");
auto temp = new savin::views::ChatList(0, 0, window_w / 7,
window_h);
int start = 0;
for (int i = 0; i < 10; i++)
{
auto element = new savin::views::ChatElement(0, start,
150, 70);
element->type(6);
temp->add(element);
start += 71;
}
temp->resizable(0);
window->size_range(600, 400);
window->resizable(temp);
window->end();
window->show(argc, argv);
window->resize(window->x(), window->y(), window_w+1,
window_h);
return Fl::run();
}