mltm
mltm

Reputation: 403

How to listen to scroll events in GTKMM 4?

I have the following example, where I create a simple window with a scrollbar and a scroll event controller that connects the onScroll member function to handle the events:

#include <iostream>
#include <gtkmm.h>

class ScrollingWindow : public Gtk::Window {
    Gtk::Scrollbar scrollbar;
    Glib::RefPtr<Gtk::Adjustment> adjustment;
    Glib::RefPtr<Gtk::EventControllerScroll> eventControllerScroll;

public:

    ScrollingWindow() {
        set_default_size(600, 100);
        adjustment = Gtk::Adjustment::create(0, 0, 100, 1);
        eventControllerScroll = Gtk::EventControllerScroll::create();
        eventControllerScroll->signal_scroll().connect(sigc::mem_fun(*this, &ScrollingWindow::onScroll), true);
        scrollbar.set_adjustment(adjustment);
        scrollbar.add_controller(eventControllerScroll);

        set_child(scrollbar);
    }

    bool onScroll(double dx, double dy) {
        std::cout << "test" << std::endl;
        return true;
    }
};

int main(int argc, char **argv) {
    auto app = Gtk::Application::create("hu.azsn.animation");
    return app->make_window_and_run<ScrollingWindow>(argc, argv);
}

Unfortunately, I don't get any output in the terminal when I scroll the scrollbar. What do I miss?

Class reference that I checked: Gtk::EventControllerScroll::signal_scroll. It doesn't specify what the second bool argument should be, I tried both.

Upvotes: 0

Views: 83

Answers (2)

Peta-T
Peta-T

Reputation: 1

My trials examples like this work, but I am not expert. This code can replace "keyboard_event/simple" examplewindow.cc with mouse events. in https://gnome.pages.gitlab.gnome.org/gtkmm-documentation/chapter-keyboardevents.html

#include "examplewindow.h"
#include <iostream>

ExampleWindow::ExampleWindow()
{
  set_title("Keyboard: Alt, Shift, Ctrl, Meta, Mouse move, Mouse click, Mouse scroll Events");
  m_container.set_margin(10);
  set_child(m_container);

  // Radio buttons:
  m_first.set_label("First (Alt+a)");
  m_second.set_label("Second (Alt+b)");

  m_second.set_group(m_first);
  m_first.set_active();

  // Main Container:
  m_container.set_orientation(Gtk::Orientation::HORIZONTAL);
  m_container.append(m_first);
  m_container.append(m_second);

  //add_events (GDK_SCROLL_SMOOTH );

  // Events.
  auto controller = Gtk::EventControllerKey::create();
  controller->signal_key_pressed().connect(
    sigc::mem_fun(*this, &ExampleWindow::on_window_key_pressed), false);
  add_controller(controller);


  auto controller1 = Gtk::EventControllerMotion::create();
  controller1->signal_motion().connect(
    sigc::mem_fun(*this, &ExampleWindow::on_Mouse_Motion), false);
  add_controller(controller1);

  auto controller2 = Gtk::EventControllerKey::create();
  controller2->signal_modifiers().connect(
    sigc::mem_fun(*this, &ExampleWindow::on_Modifiers), false);
  add_controller(controller2);

    auto controller3 = Gtk::EventControllerScroll::create();
    controller3->set_flags(Gtk::EventControllerScroll::Flags::VERTICAL);
      controller3->set_propagation_phase(Gtk::PropagationPhase::CAPTURE);
    controller3->signal_scroll().connect(
    sigc::mem_fun(*this, &ExampleWindow::on_scroll), false);
  add_controller(controller3);

  auto mouse = Gtk::GestureClick::create();
  mouse->set_propagation_phase(Gtk::PropagationPhase::CAPTURE);
  mouse->set_button(GDK_BUTTON_PRIMARY);
  mouse->signal_pressed().connect(sigc::mem_fun(*this, &ExampleWindow::on_mb1pressed), false);
  add_controller(mouse);

  auto mouse1 = Gtk::GestureClick::create();
  mouse1->set_propagation_phase(Gtk::PropagationPhase::CAPTURE);
  mouse1->set_button(GDK_BUTTON_PRIMARY);
  mouse1->signal_released().connect(sigc::mem_fun(*this, &ExampleWindow::on_mb1released), false);
  add_controller(mouse1);

    auto mouse2 = Gtk::GestureClick::create();
  mouse2->set_propagation_phase(Gtk::PropagationPhase::CAPTURE);
  mouse2->set_button(GDK_BUTTON_MIDDLE);
  mouse2->signal_pressed().connect(sigc::mem_fun(*this, &ExampleWindow::on_mb2pressed), false);
  add_controller(mouse2);

  auto mouse3 = Gtk::GestureClick::create();
  mouse3->set_propagation_phase(Gtk::PropagationPhase::CAPTURE);
  mouse3->set_button(GDK_BUTTON_MIDDLE);
  mouse3->signal_released().connect(sigc::mem_fun(*this, &ExampleWindow::on_mb2released), false);
  add_controller(mouse3);

    auto mouse4 = Gtk::GestureClick::create();
  mouse4->set_propagation_phase(Gtk::PropagationPhase::CAPTURE);
  mouse4->set_button(GDK_BUTTON_SECONDARY);
  mouse4->signal_pressed().connect(sigc::mem_fun(*this, &ExampleWindow::on_mb3pressed), false);
  add_controller(mouse4);

  auto mouse5 = Gtk::GestureClick::create();
  mouse5->set_propagation_phase(Gtk::PropagationPhase::CAPTURE);
  mouse5->set_button(GDK_BUTTON_SECONDARY);
  mouse5->signal_released().connect(sigc::mem_fun(*this, &ExampleWindow::on_mb3released), false);
  add_controller(mouse5);
}

bool ExampleWindow::on_scroll(double dx, double dy)
{
    std::cout << "on_scroll: "  << dx << ", "<< dy << std::endl;
return true;
 }

bool ExampleWindow::on_Modifiers(Gdk::ModifierType state)
{
  if ((state & Gdk::ModifierType::SHIFT_MASK)  == Gdk::ModifierType::SHIFT_MASK)
  {
    std::cout << "_SHIFT" << std::endl;
        return true;
  }
  if ((state & Gdk::ModifierType::CONTROL_MASK)  == Gdk::ModifierType::CONTROL_MASK)
  {
    std::cout << "_CTRL" << std::endl;
        return true;
  }
  if ((state & Gdk::ModifierType::ALT_MASK)  == Gdk::ModifierType::ALT_MASK)
  {
    std::cout << "_ALT" << std::endl;
        return true;
  }
  if ((state & Gdk::ModifierType::META_MASK)  == Gdk::ModifierType::META_MASK)
  {
    std::cout << "_META" << std::endl;
        return true;
  }

return false;
}

void ExampleWindow::on_mb1pressed(int n_press, double x, double y)
{
std::cout << "on_mb1Pressed: " << n_press << ", " << x << ", "<< y << std::endl;

}

void ExampleWindow::on_mb1released(int n_press, double x, double y)
{
std::cout << "on_mb1Released: " << n_press << ", " << x << ", "<< y << std::endl;
}

void ExampleWindow::on_mb2pressed(int n_press, double x, double y)
{
std::cout << "on_mb2Pressed: " << n_press << ", " << x << ", "<< y << std::endl;
}

void ExampleWindow::on_mb2released(int n_press, double x, double y)
{
std::cout << "on_mb2Released: " << n_press << ", " << x << ", "<< y << std::endl;
}

void ExampleWindow::on_mb3pressed(int n_press, double x, double y)
{
std::cout << "on_mb3Pressed: " << n_press << ", " << x << ", "<< y << std::endl;
}

void ExampleWindow::on_mb3released(int n_press, double x, double y)
{
std::cout << "on_mb3Released: " << n_press << ", " << x << ", "<< y << std::endl;
}


void ExampleWindow::on_Mouse_Motion(double x, double y)
{
std::cout << "on_Mouse_Motion: "  << x << ", "<< y << std::endl;
}

bool ExampleWindow::on_window_key_pressed(guint keyval, guint, Gdk::ModifierType state)
{
  //Gdk::ModifierType::ALT_MASK -> the 'Alt' key(mask)
  //GDK_KEY_1 -> the '1' key
  //GDK_KEY_2 -> the '2' key

  //select the first radio button, when we press alt + 1
  if((keyval == GDK_KEY_a) &&
    (state & (Gdk::ModifierType::SHIFT_MASK | Gdk::ModifierType::CONTROL_MASK | Gdk::ModifierType::ALT_MASK)) == Gdk::ModifierType::ALT_MASK)
  {
    m_first.set_active();
    //returning true, cancels the propagation of the event
    return true;
  }
  else if((keyval == GDK_KEY_b) &&
    (state & (Gdk::ModifierType::SHIFT_MASK | Gdk::ModifierType::CONTROL_MASK | Gdk::ModifierType::ALT_MASK)) == Gdk::ModifierType::ALT_MASK)
  {
    //and the second radio button, when we press alt + 2
    m_second.set_active();
    return true;
  }
  else if(keyval == GDK_KEY_Escape)
  {
    //close the window, when the 'esc' key is pressed
    set_visible(false);
    return true;
  }


  //the event has not been handled
  return false;
}

ExampleWindow::~ExampleWindow()
{
}


Upvotes: 0

Mohit
Mohit

Reputation: 1

#include <iostream>
#include <gtkmm.h>

class ScrollingWindow : public Gtk::Window {
    Gtk::Scrollbar scrollbar;
    Glib::RefPtr<Gtk::Adjustment> adjustment;
    Glib::RefPtr<Gtk::EventControllerScroll> eventControllerScroll;

public:
    ScrollingWindow() {
        set_default_size(600, 100);
        adjustment = Gtk::Adjustment::create(0, 0, 100, 1);
        eventControllerScroll = Gtk::EventControllerScroll::create();
        
        // Connect the scroll signal to the handler function
        eventControllerScroll->signal_scroll().connect(sigc::mem_fun(*this, &ScrollingWindow::onScroll), false);

        scrollbar.set_adjustment(adjustment);
        
        // Add the controller to the window instead of the scrollbar
        add_controller(eventControllerScroll);

        set_child(scrollbar);
    }

    bool onScroll(double dx, double dy) {
        std::cout << "Scroll event detected. dx: " << dx << ", dy: " << dy << std::endl;
        return true;
    }
};

int main(int argc, char **argv) {
    auto app = Gtk::Application::create("hu.azsn.animation");
    return app->make_window_and_run<ScrollingWindow>(argc, argv);
}

Upvotes: 0

Related Questions