I have a large widget that I would like to fit into a small place and make it scrollable. For this, I have an example code as follows.
I have a Gtk::Window
with default size 100x100.
It has a Gtk::Box
that contains a Gtk::Viewport
and a Gtk::Scrollbar
.
The Gtk::Viewport
widget contains a "large" widget with size 100x200.
Unfortunately, the viewport size grows to 100x200.
How can I make the viewport stay 100x100 to allow the scrolling?
#include <gtkmm.h>
class LargeWidget : public Gtk::DrawingArea {
public:
LargeWidget(int width, int height) {
set_content_width(width);
set_content_height(height);
}
};
class Window : public Gtk::Window {
Gtk::Box box;
Gtk::Scrollbar scrollbar;
Glib::RefPtr<Gtk::Adjustment> h, v;
Gtk::Viewport viewport;
LargeWidget large_widget;
public:
Window() : h(Gtk::Adjustment::create(0, 0, 100)),
v(Gtk::Adjustment::create(0, 0, 200)),
viewport(h, v),
large_widget(100, 200) {
scrollbar.set_orientation(Gtk::Orientation::VERTICAL);
scrollbar.set_adjustment(viewport.get_vadjustment());
viewport.set_child(large_widget);
box.set_orientation(Gtk::Orientation::HORIZONTAL);
box.append(viewport);
box.append(scrollbar);
set_default_size(100, 100);
set_child(box);
}
};
int main(int argc, char **argv) {
auto app = Gtk::Application::create("hu.aszn.playground");
return app->make_window_and_run<Window>(argc, argv);
}
I tried:
viewport.size_allocate(Gtk::Allocation(0, 0, 100, 100), 0);
and
viewport.set_size_request(100, 100);
Thank you for your help.
set_size_request only sets the minimum size, not the maximum.
You need to override Gtk::Widget::get_request_mode_vfunc and return Gtk::SizeRequestMode::CONSTANT_SIZE
and override Gtk::Widget::measure_vfunc and set the size to 100 in either direction, or your widget will stretch to its child size, just subclass the viewport to do this, see Height For Width Geometry management and gtkmm Custom Widgets for more information.
class MyViewport : public Gtk::Viewport {
protected:
Gtk::SizeRequestMode get_request_mode_vfunc() const override
{
return Gtk::SizeRequestMode::CONSTANT_SIZE;
}
void measure_vfunc(Gtk::Orientation orientation, int for_size,
int& minimum, int& natural, int& minimum_baseline, int& natural_baseline) const override
{
// Don't use baseline alignment.
minimum_baseline = -1;
natural_baseline = -1;
minimum = 100;
natural = 100;
}
};