17#include <gtkmm/dialog.h>
18#include <gtkmm/messagedialog.h>
19#include <gtkmm/aboutdialog.h>
20#include <gtkmm/label.h>
21#include <gtkmm/filechooser.h>
22#include <gtkmm/paned.h>
23#include <gtkmm/scrolledwindow.h>
24#include <gtkmm/window.h>
25#include <gtkmm/cssprovider.h>
26#include <gtkmm/stylecontext.h>
27#include <gdkmm/display.h>
30#include <gdkmm/monitor.h>
31#include <gdkmm/rectangle.h>
34#include <gdkmm/surface.h>
36#include <gtkmm/textbuffer.h>
37#include <gdkmm/pixbuf.h>
38#include <giomm/menu.h>
39#include <giomm/inputstream.h>
41#include <gdkmm/clipboard.h>
42#include <gdkmm/contentprovider.h>
43#include <gdkmm/contentformats.h>
45#include <gtkmm/clipboard.h>
46#include <gtkmm/selectiondata.h>
47#include <gtkmm/targetentry.h>
49#include <giomm/simpleactiongroup.h>
51#include <gtkmm/popovermenu.h>
53#include <gtkmm/menu.h>
54#include <gtkmm/menuitem.h>
57#include <gdkmm/texture.h>
60#include <gtkmm/gestureclick.h>
62#include <gtkmm/gesturemultipress.h>
64#include <gtkmm/widget.h>
65#include <gtkmm/textview.h>
69#include <gdkmm/enums.h>
71#include <gdkmm/types.h>
73#include <giomm/application.h>
74#include <pangomm/attributes.h>
75#include <pangomm/tabarray.h>
76#include <glibmm/main.h>
77#include <glibmm/ustring.h>
78#include <glibmm/value.h>
95 constexpr auto APP_NON_UNIQUE = Gio::Application::Flags::NON_UNIQUE;
116 constexpr auto ALIGN_END = Gtk::Align::END;
128 constexpr auto WRAP_NONE = Gtk::WrapMode::NONE;
134 constexpr auto RESPONSE_OK = Gtk::ResponseType::OK;
146 constexpr auto BUTTONS_OK = Gtk::ButtonsType::OK;
204 inline Gtk::TextBuffer::iterator
insert_image(
const Glib::RefPtr<Gtk::TextBuffer>& buffer,
205 const Gtk::TextBuffer::iterator& pos,
206 const Glib::RefPtr<Gdk::Pixbuf>& pixbuf)
209 return buffer->insert_paintable(pos, Gdk::Texture::create_for_pixbuf(pixbuf));
211 return buffer->insert_pixbuf(pos, pixbuf);
238 if(vertical) child.set_vexpand(
true);
239 else child.set_hexpand(
true);
243 child.set_margin_top(padding);
244 child.set_margin_bottom(padding);
247 child.set_margin_start(padding);
248 child.set_margin_end(padding);
254 box.pack_start(child,
255 expand==
Expand::yes ? Gtk::PACK_EXPAND_WIDGET : Gtk::PACK_SHRINK,
272 inline bool has_modifier(Gdk::ModifierType state, Gdk::ModifierType modifier)
274 return (state & modifier) == modifier;
283 constexpr auto SEQ_CLAIMED = Gtk::EventSequenceState::CLAIMED;
292 auto gesture = ClickGesture::create();
293 widget.add_controller(gesture);
296 return ClickGesture::create(widget);
315 namespace clipboard_detail {
321 inline void on_get(Gtk::SelectionData& selection_data, guint)
342 std::vector<Glib::RefPtr<Gdk::ContentProvider>> providers;
348 Glib::Value<Glib::ustring> value;
349 value.init(Glib::Value<Glib::ustring>::value_type());
351 providers.push_back(Gdk::ContentProvider::create(value));
353 widget.get_clipboard()->set_content(Gdk::ContentProvider::create(providers));
356 std::vector<Gtk::TargetEntry> targets;
359 targets.push_back(Gtk::TargetEntry(
"UTF8_STRING"));
360 targets.push_back(Gtk::TargetEntry(
"TEXT"));
362 Gtk::Clipboard::get(GDK_SELECTION_CLIPBOARD)->set(
377 const std::function<
void(
const std::string&)>& on_received)
380 auto clipboard = primary ? widget.get_primary_clipboard() : widget.get_clipboard();
383 clipboard->read_async(
385 [clipboard, on_received](
const Glib::RefPtr<Gio::AsyncResult>& result) {
387 Glib::ustring mime_type;
388 auto stream = clipboard->read_finish(result, mime_type);
394 while((n = stream->read(buffer,
sizeof(buffer))) > 0)
395 content.append(buffer, n);
396 on_received(content);
398 catch(
const Glib::Error&) { }
403 clipboard->read_text_async(
404 [clipboard, on_received](
const Glib::RefPtr<Gio::AsyncResult>& result) {
406 on_received(clipboard->read_text_finish(result));
408 catch(
const Glib::Error&) { }
412 auto clipboard = Gtk::Clipboard::get(primary ? GDK_SELECTION_PRIMARY : GDK_SELECTION_CLIPBOARD);
413 clipboard->request_targets(
414 [clipboard, on_received](
const std::vector<Glib::ustring>& targets) {
416 for(
const auto& t : targets) {
418 if(target.empty() && (t ==
"UTF8_STRING" || t ==
"TEXT" || t ==
"STRING"))
421 if(target.empty())
return;
423 clipboard->request_contents(target,
424 [on_received](
const Gtk::SelectionData& data) {
425 on_received(data.get_data_as_string());
459 void attach_to(Gtk::Widget& widget,
const Glib::ustring& action_prefix)
462 prefix = action_prefix;
463 model = Gio::Menu::create();
464 actions = Gio::SimpleActionGroup::create();
465 widget.insert_action_group(prefix, actions);
467 popover =
new Gtk::PopoverMenu(model);
468 popover->set_parent(widget);
469 popover->set_has_arrow(
false);
476 void add_item(
const Glib::ustring& label,
const sigc::slot<
void()>& callback)
479 const Glib::ustring name =
"item" + Glib::ustring::format(next_id++);
480 actions->add_action(name, callback);
481 model->append(label, prefix +
"." + name);
483 auto* item = Gtk::make_managed<Gtk::MenuItem>(label);
484 item->signal_activate().connect(callback);
494 popover->set_pointing_to(Gdk::Rectangle(
static_cast<int>(x),
static_cast<int>(y), 1, 1));
500 menu.popup_at_pointer(
nullptr);
506 Glib::ustring prefix;
507 Glib::RefPtr<Gio::Menu> model;
508 Glib::RefPtr<Gio::SimpleActionGroup> actions;
509 Gtk::PopoverMenu *popover =
nullptr;
519 template<
typename T,
typename U>
523 return std::dynamic_pointer_cast<T>(ptr);
525 return Glib::RefPtr<T>::cast_dynamic(ptr);
537 window.set_position(Gtk::WIN_POS_CENTER);
546 label.set_wrap(wrap);
548 label.set_line_wrap(wrap);
557 widget.set_margin_start(margin);
558 widget.set_margin_end(margin);
559 widget.set_margin_top(margin);
560 widget.set_margin_bottom(margin);
568 widget.size_allocate(allocation, -1);
570 widget.size_allocate(allocation);
588 double src_x,
double src_y,
589 double& dest_x,
double& dest_y)
592 return src.translate_coordinates(dest, src_x, src_y, dest_x, dest_y);
595 if(!src.translate_coordinates(dest,
static_cast<int>(src_x),
static_cast<int>(src_y), dx, dy))
622 auto loop = Glib::MainLoop::create(
false);
624 about.set_hide_on_close(
true);
625 auto conn_hide = about.signal_hide().connect(
627 if(loop->is_running())
631 about.set_modal(
true);
632 about.set_visible(
true);
635 conn_hide.disconnect();
636 about.set_visible(
false);
648 about.set_logo(Gdk::Texture::create_for_pixbuf(logo));
650 about.set_logo(logo);
667 return Glib::make_refptr_for_instance<T>(
object);
669 return Glib::RefPtr<T>(
object);
677 const std::string& data)
680 provider->load_from_data(data);
683 return provider->load_from_data(data);
695 for(
auto *child = box.get_first_child(); child; child = child->get_next_sibling())
699 return box.get_children().size();
709 box.reorder_child_at_start(child);
714 Gtk::Widget *sibling =
nullptr;
715 unsigned int seen = 0;
716 for(
auto *c = box.get_first_child(); c; c = c->get_next_sibling()) {
717 if(c == &child)
continue;
719 if(++seen == index)
break;
722 box.reorder_child_after(child, *sibling);
724 box.reorder_child(child, index);
743 paned.property_end_child() =
nullptr;
745 if(
auto *child = paned.get_child2())
746 paned.remove(*child);
756 widget.set_visible(
true);
770 chooser.set_do_overwrite_confirmation(
true);
780 Gtk::StyleContext::add_provider_for_display(Gdk::Display::get_default(), provider, priority);
782 Gtk::StyleContext::add_provider_for_screen(Gdk::Screen::get_default(), provider, priority);
791 auto display = Gdk::Display::get_default();
793 throw std::logic_error(
"cdb::monitor_geometry: cannot get default display.");
796 auto monitor = display->get_monitor_at_surface(window.get_surface());
798 auto monitor = display->get_monitor_at_window(window.get_window());
801 throw std::logic_error(
"cdb::monitor_geometry: cannot get monitor for window.");
803 Gdk::Rectangle geometry;
804 monitor->get_geometry(geometry);
816 window.set_type_hint(Gdk::WINDOW_TYPE_HINT_DIALOG);
823 inline void paned_set_start(Gtk::Paned& paned, Gtk::Widget& child,
bool resize,
bool shrink)
826 paned.set_start_child(child);
827 paned.set_resize_start_child(resize);
828 paned.set_shrink_start_child(shrink);
830 paned.pack1(child, resize, shrink);
834 inline void paned_set_end(Gtk::Paned& paned, Gtk::Widget& child,
bool resize,
bool shrink)
837 paned.set_end_child(child);
838 paned.set_resize_end_child(resize);
839 paned.set_shrink_end_child(shrink);
841 paned.pack2(child, resize, shrink);
853 widget.set_visible(
true);
863 template<
typename Container>
869 container.show_all_children();
878 template<
typename Parent>
879 inline void add_child(Parent& parent, Gtk::Widget& child)
882 if constexpr (std::is_base_of_v<Gtk::Box, Parent>)
883 parent.append(child);
885 parent.set_child(child);
904 int response =
static_cast<int>(Gtk::ResponseType::NONE);
905 auto loop = Glib::MainLoop::create(
false);
907 auto conn_response = dialog.signal_response().connect(
908 [&response, loop](
int id) {
909 if(loop->is_running()) {
918 auto conn_hide = dialog.signal_hide().connect(
920 if(loop->is_running())
924 dialog.set_modal(
true);
925 dialog.set_visible(
true);
928 conn_response.disconnect();
929 conn_hide.disconnect();
930 dialog.set_visible(
false);
954 auto obj = w.get_accessible();
967 Glib::Value<Glib::ustring> value;
968 value.init(Glib::Value<Glib::ustring>::value_type());
970 w.update_property(Gtk::Accessible::Property::LABEL, value);
972 auto obj = w.get_accessible();
Functions to handle the exchange properties of two or more symbols in a product.
Definition Adjform.cc:83
std::string & cadabra_payload()
Definition GtkCompat.hh:318
void on_get(Gtk::SelectionData &selection_data, guint)
Definition GtkCompat.hh:321
void on_clear()
Definition GtkCompat.hh:329
std::string & text_payload()
Definition GtkCompat.hh:317
Definition GtkCompat.hh:86
bool has_modifier(Gdk::ModifierType state, Gdk::ModifierType modifier)
Definition GtkCompat.hh:272
constexpr auto WRAP_NONE
Definition GtkCompat.hh:173
constexpr auto PANGO_TAB_LEFT
Definition GtkCompat.hh:197
constexpr auto SIZE_REQUEST_HEIGHT_FOR_WIDTH
Definition GtkCompat.hh:168
Gdk::Rectangle monitor_geometry(Gtk::Window &window)
The geometry of the monitor the window is on.
Definition GtkCompat.hh:789
void label_set_wrap(Gtk::Label &label, bool wrap=true)
Gtk::Label::set_line_wrap() is set_wrap() in GTK4.
Definition GtkCompat.hh:543
constexpr auto POLICY_ALWAYS
Definition GtkCompat.hh:164
bool css_load_from_data(const Glib::RefPtr< Gtk::CssProvider > &provider, const std::string &data)
Gtk::CssProvider::load_from_data() returns bool on gtkmm-3 but void on GTK4, where a parse failure is...
Definition GtkCompat.hh:676
void set_accessible_name(Gtk::Widget &w, const Glib::ustring &name)
Definition GtkCompat.hh:964
void show_all(Gtk::Widget &widget)
GTK4 removed show_all().
Definition GtkCompat.hh:850
constexpr auto APP_HANDLES_COMMAND_LINE
Definition GtkCompat.hh:102
void set_accessible_role(Gtk::Widget &w, AccessibleRole role)
Definition GtkCompat.hh:947
constexpr auto BUTTONS_YES_NO
Definition GtkCompat.hh:192
constexpr auto POLICY_NEVER
Definition GtkCompat.hh:166
AccessibleRole
Accessible roles we actually use.
Definition GtkCompat.hh:945
constexpr auto ORIENT_HORIZONTAL
Definition GtkCompat.hh:156
unsigned int box_child_count(Gtk::Box &box)
gtkmm-3's Gtk::Container API for inspecting and reordering children is gone in GTK4: there is no get_...
Definition GtkCompat.hh:691
void set_margin_all(Gtk::Widget &widget, int margin)
GTK4 has no single "margin" property, only the four sides.
Definition GtkCompat.hh:555
constexpr auto ALIGN_END
Definition GtkCompat.hh:161
void window_centre_on_parent(Gtk::Window &window)
Gtk::Window::set_position() is removed in GTK4, where placement is left to the compositor.
Definition GtkCompat.hh:532
constexpr auto COLORSPACE_RGB
Definition GtkCompat.hh:174
void paned_unset_end(Gtk::Paned &paned)
Definition GtkCompat.hh:740
void add_css_provider_for_default_display(const Glib::RefPtr< Gtk::CssProvider > &provider, guint priority)
Gdk::Screen is gone in GTK4; style providers attach to a Gdk::Display.
Definition GtkCompat.hh:776
void show_all_children(Container &container)
As above, but the gtkmm-3 form that shows the descendants without showing the widget itself.
Definition GtkCompat.hh:864
constexpr auto FILE_CHOOSER_ACTION_SAVE
Definition GtkCompat.hh:195
constexpr auto APP_HANDLES_OPEN
Unscoped gtkmm-3 enumerators became scoped enum classes in gtkmm-4, so the spellings differ even thou...
Definition GtkCompat.hh:101
void add_child(Parent &parent, Gtk::Widget &child)
Put child inside parent.
Definition GtkCompat.hh:879
constexpr auto MESSAGE_WARNING
Definition GtkCompat.hh:186
constexpr auto PANGO_UNDERLINE_ERROR
Definition GtkCompat.hh:198
Glib::RefPtr< ClickGesture > add_click_gesture(Gtk::Widget &widget)
Definition GtkCompat.hh:289
void paned_set_end(Gtk::Paned &paned, Gtk::Widget &child, bool resize, bool shrink)
Definition GtkCompat.hh:834
constexpr auto OPTION_TYPE_INT
Definition GtkCompat.hh:106
constexpr auto OPTION_TYPE_STRING
Definition GtkCompat.hh:107
constexpr auto TEXT_WINDOW_TEXT
Definition GtkCompat.hh:171
const char * CADABRA_CLIPBOARD_TARGET
Clipboard.
Definition GtkCompat.hh:313
void scrolled_window_unset_child(Gtk::ScrolledWindow &sw)
Detaching a child.
Definition GtkCompat.hh:731
constexpr auto RESPONSE_YES
Definition GtkCompat.hh:182
constexpr auto MESSAGE_QUESTION
Definition GtkCompat.hh:187
constexpr auto STATE_FLAG_SELECTED
Definition GtkCompat.hh:177
bool translate_widget_coords(Gtk::Widget &src, Gtk::Widget &dest, double src_x, double src_y, double &dest_x, double &dest_y)
Position of a point in src's coordinate space, expressed in dest's.
Definition GtkCompat.hh:587
constexpr auto RESPONSE_APPLY
Definition GtkCompat.hh:183
constexpr auto ALIGN_CENTER
Definition GtkCompat.hh:162
constexpr auto MODIFIER_SHIFT
Gdk::ModifierType became a scoped enum in GTK4, so both the enumerator spellings and the way a mask i...
Definition GtkCompat.hh:268
constexpr auto ALIGN_FILL
Definition GtkCompat.hh:159
void about_dialog_set_logo(Gtk::AboutDialog &about, const Glib::RefPtr< Gdk::Pixbuf > &logo)
GTK4's Gtk::AboutDialog::set_logo() takes a Gdk::Paintable rather than a Gdk::Pixbuf.
Definition GtkCompat.hh:645
Gtk::GestureMultiPress ClickGesture
Gtk::GestureMultiPress was renamed Gtk::GestureClick in GTK4, and the way a controller is attached to...
Definition GtkCompat.hh:285
void about_dialog_run(Gtk::AboutDialog &about)
Definition GtkCompat.hh:619
constexpr auto OPTION_TYPE_BOOL
Definition GtkCompat.hh:105
void set_dialog_type_hint(Gtk::Window &window)
Gtk::Window::set_type_hint() is removed in GTK4; the window manager is told what a dialog is via its ...
Definition GtkCompat.hh:811
Glib::RefPtr< T > refptr_for_instance(T *object)
Wrap a freshly-constructed Glib::Object subclass in a RefPtr.
Definition GtkCompat.hh:664
void widget_size_allocate(Gtk::Widget &widget, const Gtk::Allocation &allocation)
GTK4 added a baseline argument to Gtk::Widget::size_allocate().
Definition GtkCompat.hh:565
Glib::RefPtr< T > refptr_dynamic_cast(const Glib::RefPtr< U > &ptr)
glibmm-2.68 made Glib::RefPtr an alias for std::shared_ptr, which dropped the static RefPtr<T>::cast_...
Definition GtkCompat.hh:520
void box_append(Gtk::Box &box, Gtk::Widget &child, Expand expand=Expand::no, int padding=0)
Definition GtkCompat.hh:232
constexpr auto SIZE_REQUEST_WIDTH_FOR_HEIGHT
Definition GtkCompat.hh:169
int dialog_run(Gtk::Dialog &dialog)
Show the about box and block until the user dismisses it.
Definition GtkCompat.hh:901
constexpr auto RESPONSE_CLOSE
Definition GtkCompat.hh:181
void paned_set_start(Gtk::Paned &paned, Gtk::Widget &child, bool resize, bool shrink)
GTK4 replaced Gtk::Paned::pack1/pack2 with set_start_child/set_end_child plus separate resize/shrink ...
Definition GtkCompat.hh:823
constexpr auto POLICY_AUTOMATIC
Definition GtkCompat.hh:165
void show_now(Gtk::Widget &widget)
Gtk::Widget::show_now() is removed in GTK4; there is no way (nor need) to force a synchronous map.
Definition GtkCompat.hh:753
void file_chooser_confirm_overwrite(Gtk::FileChooser &chooser)
GTK4 removed Gtk::FileChooser::set_do_overwrite_confirmation(): a save dialog there always confirms a...
Definition GtkCompat.hh:765
constexpr auto SEQ_CLAIMED
Definition GtkCompat.hh:286
constexpr auto BUTTONS_OK
Definition GtkCompat.hh:191
constexpr auto ALIGN_START
Definition GtkCompat.hh:160
void clipboard_set(Gtk::Widget &widget, const std::string &text, const std::string &cadabra)
Put text on the clipboard, plus cadabra under the private target if it is non-empty.
Definition GtkCompat.hh:336
constexpr auto STATE_FLAG_NORMAL
Definition GtkCompat.hh:176
void clipboard_read(Gtk::Widget &widget, bool primary, const std::function< void(const std::string &)> &on_received)
Read the clipboard and hand the result to on_received.
Definition GtkCompat.hh:376
constexpr auto MESSAGE_ERROR
Definition GtkCompat.hh:188
constexpr auto MESSAGE_INFO
Definition GtkCompat.hh:185
constexpr auto RESPONSE_CANCEL
Definition GtkCompat.hh:180
constexpr auto WRAP_WORD_CHAR
Definition GtkCompat.hh:172
constexpr auto ORIENT_VERTICAL
Definition GtkCompat.hh:157
constexpr auto RESPONSE_OK
Definition GtkCompat.hh:179
constexpr auto BUTTONS_NONE
Definition GtkCompat.hh:190
Expand
GTK4 dissolved pack_start's three arguments into properties on the child: expand became set_h/vexpand...
Definition GtkCompat.hh:230
constexpr auto APP_NON_UNIQUE
Definition GtkCompat.hh:103
constexpr auto MODIFIER_CONTROL
Definition GtkCompat.hh:269
constexpr auto FILE_CHOOSER_ACTION_OPEN
Definition GtkCompat.hh:194
void box_reorder_child(Gtk::Box &box, Gtk::Widget &child, unsigned int index)
Move child to absolute position index among box's children.
Definition GtkCompat.hh:705
constexpr auto LICENSE_GPL_3_0
Definition GtkCompat.hh:196
Gtk::TextBuffer::iterator insert_image(const Glib::RefPtr< Gtk::TextBuffer > &buffer, const Gtk::TextBuffer::iterator &pos, const Glib::RefPtr< Gdk::Pixbuf > &pixbuf)
GTK4 replaced Gtk::TextBuffer::insert_pixbuf() with insert_paintable(); a Gdk::Pixbuf has to be wrapp...
Definition GtkCompat.hh:204