Make widgets in Fl_Scroll resizable?

20 views
Skip to first unread message

Daniel Polski

unread,
Oct 8, 2017, 5:43:35 AM10/8/17
to fltkg...@googlegroups.com
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());
}

Greg Ercolano

unread,
Oct 8, 2017, 1:00:25 PM10/8/17
to fltkg...@googlegroups.com
On 10/08/17 02:43, Daniel Polski wrote:
> 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.

It kinda sounds like you want this:
http://seriss.com/people/erco/fltk/#ScrollableWidgetBrowser

That gets you a 'table' of data that only makes a vertical scrollbar
when content grows off the bottom, and data horizontally laid out
should simply stretch to fit, never scroll.

Usually when you set out to use an Fl_Scroll, it's to let the user
view contents that is larger than the area of the scroll, as it
makes scrollbars of appropriate size appear when the contents exceeds
the edge of the scroll widget either horizontally or vertically.
A way to "pan and scan" the contents.

This is why in the above example, resizing is handled in the code
(via the resize() method)

Reply all
Reply to author
Forward
0 new messages