19#include <gtkmm/accelerator.h>
20#include <gtkmm/eventcontrollerkey.h>
21#include <gtkmm/gestureclick.h>
22#include <gdkmm/rectangle.h>
23#include <gtkmm/popover.h>
24#include <gtkmm/widget.h>
31static bool on_key_pressed(
unsigned const keyval,
unsigned , Gdk::ModifierType state,
34 if (keyval == GDK_KEY_Menu) {
35 return slot(std::nullopt);
38 state &= Gtk::Accelerator::get_default_mod_mask();
40 return slot(std::nullopt);
48 auto const event = click.get_current_event();
49 if (event->triggers_context_menu()) {
52 click.set_state(Gtk::EventSequenceState::CLAIMED);
59 auto key = Gtk::EventControllerKey::create();
61 widget.add_controller(
key);
63 auto click = Gtk::GestureClick::create();
65 click->set_propagation_phase(Gtk::PropagationPhase::CAPTURE);
66 click->signal_pressed().connect(sigc::bind(&
on_click_pressed, std::ref(*click), std::move(slot)));
67 widget.add_controller(click);
70static void popup_at(Gtk::Popover &popover, Gtk::Widget &widget,
71 double const x_offset,
double const y_offset,
74 popover.set_visible(
false);
76 auto const parent = popover.get_parent();
80 auto const allocation = widget.get_allocation();
81 if (!
width )
width = x_offset ? 1 : allocation.get_width ();
82 if (!
height)
height = y_offset ? 1 : allocation.get_height();
84 widget.translate_coordinates(*
parent, 0, 0, x, y);
87 auto const ix =
static_cast<int>(x + 0.5), iy =
static_cast<int>(y + 0.5);
93void popup_at(Gtk::Popover &popover, Gtk::Widget &widget,
94 double const x_offset,
double const y_offset)
96 popup_at(popover, widget, x_offset, y_offset, 0, 0);
99void popup_at(Gtk::Popover &popover, Gtk::Widget &widget,
100 std::optional<Geom::Point>
const &
offset)
104 popup_at(popover, widget, x_offset, y_offset);
109 auto const x_offset = widget.get_width () / 2;
110 auto const y_offset = widget.get_height() / 2;
111 popup_at(popover, widget, x_offset, y_offset);
114void popup_at(Gtk::Popover &popover, Gtk::Widget &widget, Gdk::Rectangle
const &rect)
116 popup_at(popover, widget, rect.get_x(), rect.get_y(), rect.get_width(), rect.get_height());
Cartesian point / 2D vector and related operations.
Utilities to more easily use Gtk::EventController & subclasses like Gesture.
static char const *const parent
bool has_flag(Gdk::ModifierType const state, Gdk::ModifierType const flags)
Helper to query if ModifierType state contains one or more of given flag(s).
static void on_click_pressed(int n_press, double x, double y, Gtk::GestureClick &click, PopupMenuSlot const &slot)
void popup_at_center(Gtk::Popover &popover, Gtk::Widget &widget)
As popup_at() but point to center of widget.
bool is_descendant_of(Gtk::Widget const &descendant, Gtk::Widget const &ancestor)
Returns if widget is a descendant of given ancestor, i.e.: itself, a child, or a childʼs child.
void on_popup_menu(Gtk::Widget &widget, PopupMenuSlot slot)
Connect slot to a widgetʼs key and button events that traditionally trigger a popup menu,...
sigc::slot< bool(PopupMenuOptionalClick)> PopupMenuSlot
Return whether a popup was activated.
static void popup_at(Gtk::Popover &popover, Gtk::Widget &widget, double const x_offset, double const y_offset, int width, int height)
static bool on_key_pressed(unsigned const keyval, unsigned, Gdk::ModifierType state, PopupMenuSlot const &slot)
static cairo_user_data_key_t key