16#include <glibmm/main.h>
17#include <gtkmm/grid.h>
18#include <gtkmm/label.h>
19#include <gtkmm/scrolledwindow.h>
20#include <gtkmm/separator.h>
21#include <gtkmm/window.h>
32class PopoverMenuGrid final
33 :
public CssNameClassInit
37 [[nodiscard]] PopoverMenuGrid()
38 :
Glib::ObjectBase{
"PopoverMenuGrid"}
42 add_css_class(
"menu");
43 set_orientation(Gtk::Orientation::VERTICAL);
48 :
Glib::ObjectBase{
"PopoverMenu"}
50 , _scrolled_window{*
Gtk::make_managed<
Gtk::ScrolledWindow>()}
51 , _grid {*
Gtk::make_managed<PopoverMenuGrid >()}
53 add_css_class(
"popover-menu");
54 add_css_class(
"menu");
56 set_position(position);
57 set_has_arrow(has_arrow);
64 signal_show().connect([
this]
79 int const left_attach,
int const right_attach,
80 int const top_attach,
int const bottom_attach)
84 auto const width = right_attach - left_attach;
85 auto const height = bottom_attach - top_attach;
94 _grid.attach_next_to(
item, Gtk::PositionType::BOTTOM);
102 _grid.attach_next_to(
item, Gtk::PositionType::TOP);
110 g_return_if_fail(it !=
_items.end());
118 auto const label = Gtk::make_managed<Gtk::Label>();
119 label->set_markup(markup);
120 auto const item = Gtk::make_managed<PopoverMenuItem>();
122 item->set_sensitive(
false);
128 append(*Gtk::make_managed<Gtk::Separator>(Gtk::Orientation::HORIZONTAL));
132 int const x_offset,
int const y_offset)
157 static constexpr int padding = 16;
158 auto &window =
dynamic_cast<Gtk::Window
const &
>(*get_root());
165 Gtk::Widget *fallback_match =
nullptr;
174 item->unset_state_flags(Gtk::StateFlags::FOCUSED | Gtk::StateFlags::PRELIGHT);
175 if (!search.empty()) {
177 if (
auto label =
dynamic_cast<Gtk::Label *
>(
mi)) {
178 auto text_data =
label->get_text();
180 if (!match && text_data.size() >= search.size()) {
181 if (text_data.substr(0, search.size()).lowercase() == search.lowercase()) {
186 if (!fallback_match && text_data.lowercase().find(search.lowercase()) != Glib::ustring::npos) {
187 fallback_match =
item;
195 if (!match && fallback_match) {
197 fallback_match->grab_focus();
200 if (search.empty()) {
203 auto searchstring = !pango_version_check(1, 50, 0) ?
204 "<span size=\"x-large\" line_height=\"0.7\">⌕</span><small> %1</small>" :
205 "<span size=\"large\">⌕</span><small> %1</small>";
206 _active_search->set_markup(Glib::ustring::compose(searchstring, search));
216 if (
item != except_active) {
217 item->unset_state_flags(Gtk::StateFlags::FOCUSED | Gtk::StateFlags::PRELIGHT);
virtual void hide(unsigned int key)
A class that can be inherited to set the CSS name of a Gtk::Widget subclass.
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.
static void popup_at(Gtk::Popover &popover, Gtk::Widget &widget, double const x_offset, double const y_offset, int width, int height)
std::vector< Gtk::Widget * > get_children(Gtk::Widget &widget)
Get a vector of the widgetʼs children, from get_first_child() through each get_next_sibling().