Gtkmm3: move a window inside a Gtk::ScrolledWindow by mouse event inside the window

I have a simple main window which contains a scrolled window and a canvas widget inside. If the size of the canvas is bigger than the scrolled window, the scroll bar appears and the canvas can be moved with the scrollbars. Works fine!

Now I want to move the window inside the scrolled window also by clicking with the mouse on the inside canvas and move the mouse cursor and the inside window should follow ( also the scrollbars should reflect the new shifted position).

Is there a predefined handler which simply can be enabled?

If it must be programmed manually, how can I modify the position of the inner window inside the scrolled window. I see tons of functions beginning from getting the scrollbar objects and then maybe modify something there or with the (v/h)adjustment things? But I did not find any example or documentation. The official docs are not very handy as they simply tell me what the name of a function describes already, but no further hints or examples. So all is more or less a black box.

As given in my start code, I am able to bind the button press/release and move events. So I have the coordinates the mouse cursor moves. I “only” need the point how to set the new position of the window inside the scrolled window.


#include <gtkmm.h>
#include <goocanvasmm.h>


int main(int argc, char *argv[])
{
    Gtk::Main kit(argc, argv);
    Goocanvas::init("Example", "0.1", argc, argv);

    Gtk::ScrolledWindow sw;
    Gtk::Window win;
    Gtk::VBox hbox;

    sw.set_size_request( 100,100); // set the outer scrollable window to that size

    Goocanvas::Canvas m_canvas; // we use a canvas widget to draw some boxes in it
    m_canvas.set_size_request(1000, 500); // physische Groesse des Canvas Widgets in Pixel
    m_canvas.set_bounds(0, 0, 4000, 2000); // logische Groesse!!! Auch der Ursprung der logischen Zeichenflaeche wird geaendert ( wenn gewuenscht )
    m_canvas.set_scale( 0.5 ); // Skalierung zwischen physischer und logischer Zeichenflaeche
    Glib::RefPtr<Goocanvas::Item> root = m_canvas.get_root_item();

    Glib::RefPtr<Goocanvas::Rect>  m_rect = Goocanvas::Rect::create(0, 0, 60, 60);
    m_rect->property_line_width() = 1.0;
    m_rect->property_stroke_color() = "black";
    m_rect->property_fill_color() = "blue";
    root->add_child( m_rect);

    Glib::RefPtr<Goocanvas::Rect>  m_rect2 = Goocanvas::Rect::create(4000-80, 2000-80, 60, 60);
    m_rect2->property_line_width() = 1.0;
    m_rect2->property_stroke_color() = "black";
    m_rect2->property_fill_color() = "red";
    root->add_child( m_rect2);


    sw.add(m_canvas);   // add the canvas to the scrolled window
    hbox.add(sw);       // we use a box and place the scrolled win inside
    win.add(hbox);      // and add the box to the main window

    win.show_all_children();

   // now bind the mouse click
    sw.signal_button_press_event().connect
        (
            []( GdkEventButton* event )
            {
                if ( event->button == 1 )
                {
                    std::cout << "Pressed " << event->x << ":" << event->y << std::endl;
                }

                return true;
            }
        );


    sw.signal_button_release_event().connect
        (
            []( GdkEventButton* event )
            {
                if ( event->button == 1 )
                {
                    std::cout << "Released " << event->x << ":" << event->y << std::endl;
                }

                return true;
            }
        );


    sw.signal_motion_notify_event().connect
        (
            []( GdkEventMotion* event )
            {
                std::cout << "Mouse moved " << event->x << ":" << event->y << std::endl;

                return true;
            }
        );

    Gtk::Main::run(win);
}

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.