Hello,
I'm trying to create a "table" of custom widgets using an Fl_Scroll, but
I don't get resizing working as I want. I've created an example to
demonstrate what I'm trying to do. When you click the button you add
items with different amount of sub items to the scroll, and I would like
to be resized horizontally when the window is resized, so it looks
like after you've clicked the button again after resizing the window.
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Box.H>
#include <FL/names.h>
#include <FL/Fl_Scroll.H>
#include <FL/Fl_Button.H>
#include <sstream>
#include <iostream>
#include <vector>
class ItemGroup :public Fl_Group{
public:
ItemGroup(int x, int y, int w, int h, const char *l = 0) : Fl_Group(x,
y, w, h, l){
header = new Fl_Box(x, y, w-75, 20, "header");
header->box(FL_FLAT_BOX);
header->color(FL_GREEN);
header->align(FL_ALIGN_INSIDE | FL_ALIGN_CENTER);
Fl_Group* resizeDummy = new Fl_Group(x + w - 75, y, 75, 20);
Fl_Button* but = new Fl_Button(x+w-75, y, 75, 20, "a button");
resizeDummy->end();
end();
}
std::vector<int> my_items;
std::vector<Fl_Group*> my_sub_items;
Fl_Box* header;
void rearrange(){
for (int i = 0; i < my_sub_items.size(); i++){
remove(
my_sub_items.at(i));
Fl::delete_widget(
my_sub_items.at(i));
}
my_sub_items.clear();
int y_offset = header->y() + header->h();
begin();
for (int i = 0; i < my_items.size(); i++){
Fl_Group* anItem = new Fl_Group(this->x(), y_offset, this->w(), 20);
anItem->end();
std::stringstream ssLabel;
ssLabel << "item " << i;
anItem->copy_label(ssLabel.str().c_str());
anItem->box(FL_BORDER_BOX);
anItem->color(FL_LIGHT1);
anItem->align(FL_ALIGN_INSIDE | FL_ALIGN_CENTER);
y_offset += anItem->h();
my_sub_items.push_back(anItem);
}
Fl_Widget::resize(x(), y(), w(), y_offset - y());
init_sizes();
end();
}
void setItems(int items){
my_items.clear();
for (int i = 0; i < items; i++){
my_items.push_back(i);
}
rearrange();
}
};
class testWindow2 :public Fl_Window{
public:
testWindow2(int w, int h, const char *l = 0) : Fl_Window(w, h, l){
Fl_Group* resizeDummy = new Fl_Group(25, 25, 100, 25);
Fl_Button* aButton = new Fl_Button(25, 25, 100, 25, "Test");
aButton->callback(static_cb, this);
resizeDummy->resizable(0);
resizeDummy->end();
aScroll = new Fl_Scroll(25, 75, w - 50, h - 100);
aScroll->box(FL_FLAT_BOX);
aScroll->color(FL_RED);
aScroll->end();
resizable(aScroll);
end();
}
static void static_cb(Fl_Widget *w, void *data) {
testWindow2 *o = (testWindow2*)data;
o->cb(w);
}
private:
int counter = 0;
Fl_Scroll* aScroll;
std::vector<ItemGroup*> itemGroups;
void cb(Fl_Widget* data){
counter++;
for (int i = 0; i < itemGroups.size(); i++){
aScroll->remove(itemGroups.at(i));
Fl::delete_widget(itemGroups.at(i));
}
itemGroups.clear();
int y_offset = aScroll->y();
aScroll->begin();
for (int i = 0; i < counter; i++){
ItemGroup* temp = new ItemGroup(aScroll->x(), y_offset, aScroll->w(), 0);
temp->setItems(i);
y_offset = temp->y() + temp->h();
itemGroups.push_back(temp);
}
aScroll->end();
aScroll->redraw();
}
};
int main(int argc, char *argv[]) {
testWindow2 *aTest = new testWindow2(400, 400);
aTest->show();
return(Fl::run());
}