From 33d8a352eca90a530d560175f5406a5bde5e2861 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 28 Apr 2025 08:24:15 +0200 Subject: adw: add missing Dialog functions --- .vscode/settings.json | 1 + adw/include/adwaitamm/dialog.hpp | 65 +++++++- adw/include/adwaitamm/enums.hpp | 8 + adw/include/adwaitamm/private/dialog_p.hpp | 4 + adw/src/dialog.cpp | 237 +++++++++++++++++++++++++++-- adw/src/enums.cpp | 5 + adw/src/private/dialog_p.cpp | 58 +++++++ 7 files changed, 358 insertions(+), 20 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 8ffa765..1c7d479 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -11,6 +11,7 @@ "gboolean", "gclass", "gobj", + "gobject", "gtkmm", "gtype", "klass", diff --git a/adw/include/adwaitamm/dialog.hpp b/adw/include/adwaitamm/dialog.hpp index de6af0c..82e1cd1 100644 --- a/adw/include/adwaitamm/dialog.hpp +++ b/adw/include/adwaitamm/dialog.hpp @@ -8,10 +8,13 @@ #define LIBADWAITAMM_DIALOG_HPP #include "adwaitamm/breakpoint.hpp" +#include "adwaitamm/enums.hpp" #include "helpers/gobj_mixin.hpp" #include +#include #include +#include #include #include @@ -38,6 +41,7 @@ namespace Adwaita using helpers::gobj_mixin::gobj; using helpers::gobj_mixin::gobj_copy; +#pragma mark - Special Member Functions explicit Dialog(); Dialog(Dialog const & other) = delete; Dialog(Dialog && other) noexcept = default; @@ -45,25 +49,72 @@ namespace Adwaita auto operator=(Dialog const & other) noexcept -> Dialog & = delete; auto operator=(Dialog && other) noexcept -> Dialog & = default; +#pragma mark - GObject Support auto static get_type() -> GType; auto static get_base_type() -> GType; +#pragma mark - Functions auto add_breakpoint(Glib::RefPtr const & breakpoint) -> void; auto close() -> void; auto force_close() -> void; - auto get_can_close() const -> bool; - auto get_child() const -> Gtk::Widget *; - auto get_content_height() const -> int; - auto get_content_width() const -> int; - auto get_current_breakpoint() const -> Glib::RefPtr; - auto get_default_widget() const -> Gtk::Widget *; - auto get_focus() const -> Gtk::Widget *; auto present(Gtk::Widget * parent) -> void; + +#pragma mark - Getters + [[nodiscard]] auto get_can_close() const -> bool; + [[nodiscard]] auto get_child() const -> Gtk::Widget *; + [[nodiscard]] auto get_content_height() const -> int; + [[nodiscard]] auto get_content_width() const -> int; + [[nodiscard]] auto get_current_breakpoint() const -> Glib::RefPtr; + [[nodiscard]] auto get_default_widget() const -> Gtk::Widget *; + [[nodiscard]] auto get_focus() const -> Gtk::Widget *; + [[nodiscard]] auto get_follows_content_size() const -> bool; + [[nodiscard]] auto get_presentation_mode() const -> PresentationMode; + [[nodiscard]] auto get_title() const -> Glib::ustring; + +#pragma mark - Setters + auto set_can_close(bool value) -> void; + auto set_child(Gtk::Widget & value) -> void; + auto set_content_height(int value) -> void; + auto set_content_width(int value) -> void; + auto set_default_widget(Gtk::Widget & value) -> void; + auto set_focus(Gtk::Widget & value) -> void; + auto set_follows_content_size(bool value) -> void; + auto set_presentation_mode(PresentationMode value) -> void; auto set_title(Glib::ustring const & str) -> void; +#pragma mark - Properties + [[nodiscard]] auto property_can_close() -> Glib::PropertyProxy; + [[nodiscard]] auto property_can_close() const -> Glib::PropertyProxy_ReadOnly; + [[nodiscard]] auto property_child() -> Glib::PropertyProxy; + [[nodiscard]] auto property_child() const -> Glib::PropertyProxy_ReadOnly; + [[nodiscard]] auto property_content_height() -> Glib::PropertyProxy; + [[nodiscard]] auto property_content_height() const -> Glib::PropertyProxy_ReadOnly; + [[nodiscard]] auto property_content_width() -> Glib::PropertyProxy; + [[nodiscard]] auto property_content_width() const -> Glib::PropertyProxy_ReadOnly; + [[nodiscard]] auto property_current_breakpoint() const -> Glib::PropertyProxy_ReadOnly>; + [[nodiscard]] auto property_default_widget() -> Glib::PropertyProxy; + [[nodiscard]] auto property_default_widget() const -> Glib::PropertyProxy_ReadOnly; + [[nodiscard]] auto property_focus_widget() -> Glib::PropertyProxy; + [[nodiscard]] auto property_focus_widget() const -> Glib::PropertyProxy_ReadOnly; + [[nodiscard]] auto property_follows_content_size() -> Glib::PropertyProxy; + [[nodiscard]] auto property_follows_content_size() const -> Glib::PropertyProxy_ReadOnly; + [[nodiscard]] auto property_presentation_mode() -> Glib::PropertyProxy; + [[nodiscard]] auto property_presentation_mode() const -> Glib::PropertyProxy_ReadOnly; + [[nodiscard]] auto property_title() -> Glib::PropertyProxy; + [[nodiscard]] auto property_title() const -> Glib::PropertyProxy_ReadOnly; + +#pragma mark - Signals + [[nodiscard]] auto signal_close_attempt() -> Glib::SignalProxy; + [[nodiscard]] auto signal_closed() -> Glib::SignalProxy; + protected: friend Dialog_Class; +#pragma mark - Default Signal Handlers + auto virtual on_close_attempt() -> void; + auto virtual on_closed() -> void; + +#pragma mark - Internal Constructors explicit Dialog(Glib::ConstructParams const & params); explicit Dialog(BaseObjectType * gobj); }; diff --git a/adw/include/adwaitamm/enums.hpp b/adw/include/adwaitamm/enums.hpp index 8cae39d..0d09833 100644 --- a/adw/include/adwaitamm/enums.hpp +++ b/adw/include/adwaitamm/enums.hpp @@ -43,6 +43,13 @@ namespace Adwaita MaxHeight, }; + enum struct PresentationMode + { + Auto, + Floating, + BottomSheet, + }; + enum struct RatioType { MinAspectRatio, @@ -78,6 +85,7 @@ namespace Glib VALUE_SPECIALIZATION(AccentColor); VALUE_SPECIALIZATION(ColorScheme); VALUE_SPECIALIZATION(LengthType); + VALUE_SPECIALIZATION(PresentationMode); VALUE_SPECIALIZATION(RatioType); VALUE_SPECIALIZATION(ResponseAppearance); VALUE_SPECIALIZATION(ToastPriority); diff --git a/adw/include/adwaitamm/private/dialog_p.hpp b/adw/include/adwaitamm/private/dialog_p.hpp index a8be388..814a44e 100644 --- a/adw/include/adwaitamm/private/dialog_p.hpp +++ b/adw/include/adwaitamm/private/dialog_p.hpp @@ -29,6 +29,10 @@ namespace Adwaita auto init() -> Glib::Class const &; auto static class_init_function(void * gclass, void * data) -> void; auto static wrap_new(GObject * object) -> Glib::ObjectBase *; + + protected: + auto static close_attempt(BaseObjectType * self) -> void; + auto static closed(BaseObjectType * self) -> void; }; } // namespace Adwaita diff --git a/adw/src/dialog.cpp b/adw/src/dialog.cpp index c31fb8a..65da6a2 100644 --- a/adw/src/dialog.cpp +++ b/adw/src/dialog.cpp @@ -7,11 +7,14 @@ #include "adwaitamm/dialog.hpp" #include "adwaitamm/breakpoint.hpp" +#include "adwaitamm/enums.hpp" #include "adwaitamm/private/dialog_p.hpp" #include #include +#include #include +#include #include #include #include @@ -19,6 +22,7 @@ #include #include +#include #include namespace Adwaita @@ -27,6 +31,35 @@ namespace Adwaita namespace { auto constinit _class = Dialog_Class{}; + + namespace property_name + { + auto constexpr can_close = "can-close"; + auto constexpr child = "child"; + auto constexpr content_height = "content-height"; + auto constexpr content_width = "content-width"; + auto constexpr current_breakpoint = "current-breakpoint"; + auto constexpr default_widget = "default-widget"; + auto constexpr focus_widget = "focus-widget"; + auto constexpr follows_content_size = "follows_content_size"; + auto constexpr presentation_mode = "presentation_mode"; + auto constexpr title = "title"; + } // namespace property_name + + namespace signal_info + { + auto const close_attempt = Glib::SignalProxyInfo{ + "close-attempt", + reinterpret_cast(&Glib::SignalProxyNormal::slot0_void_callback), + reinterpret_cast(&Glib::SignalProxyNormal::slot0_void_callback), + }; + + auto const closed = Glib::SignalProxyInfo{ + "closed", + reinterpret_cast(&Glib::SignalProxyNormal::slot0_void_callback), + reinterpret_cast(&Glib::SignalProxyNormal::slot0_void_callback), + }; + } // namespace signal_info } // namespace auto Dialog::get_type() -> GType @@ -58,62 +91,240 @@ namespace Adwaita auto Dialog::add_breakpoint(Glib::RefPtr const & breakpoint) -> void { // Take a copy because the dialog will take ownership of the breakpoint. - adw_dialog_add_breakpoint(Glib::unwrap(this), Glib::unwrap_copy(breakpoint)); + adw_dialog_add_breakpoint(unwrap(this), Glib::unwrap_copy(breakpoint)); } auto Dialog::close() -> void { - adw_dialog_close(Glib::unwrap(this)); + adw_dialog_close(unwrap(this)); } auto Dialog::force_close() -> void { - adw_dialog_force_close(Glib::unwrap(this)); + adw_dialog_force_close(unwrap(this)); + } + + auto Dialog::present(Gtk::Widget * parent) -> void + { + adw_dialog_present(unwrap(this), Glib::unwrap(parent)); } auto Dialog::get_can_close() const -> bool { - return adw_dialog_get_can_close(const_cast(Glib::unwrap(this))); + return adw_dialog_get_can_close(const_cast(unwrap(this))); } auto Dialog::get_child() const -> Gtk::Widget * { - return Glib::wrap(adw_dialog_get_child(const_cast(Glib::unwrap(this))), true); + return Glib::wrap(adw_dialog_get_child(const_cast(unwrap(this))), true); } auto Dialog::get_content_height() const -> int { - return adw_dialog_get_content_height(const_cast(Glib::unwrap(this))); + return adw_dialog_get_content_height(const_cast(unwrap(this))); } auto Dialog::get_content_width() const -> int { - return adw_dialog_get_content_width(const_cast(Glib::unwrap(this))); + return adw_dialog_get_content_width(const_cast(unwrap(this))); } auto Dialog::get_current_breakpoint() const -> Glib::RefPtr { - return Glib::wrap(adw_dialog_get_current_breakpoint(const_cast(Glib::unwrap(this))), true); + return Glib::wrap(adw_dialog_get_current_breakpoint(const_cast(unwrap(this))), true); } auto Dialog::get_default_widget() const -> Gtk::Widget * { - return Glib::wrap(adw_dialog_get_default_widget(const_cast(Glib::unwrap(this)))); + return Glib::wrap(adw_dialog_get_default_widget(const_cast(unwrap(this)))); } auto Dialog::get_focus() const -> Gtk::Widget * { - return Glib::wrap(adw_dialog_get_focus(const_cast(Glib::unwrap(this)))); + return Glib::wrap(adw_dialog_get_focus(const_cast(unwrap(this)))); } - auto Dialog::present(Gtk::Widget * parent) -> void + auto Dialog::get_follows_content_size() const -> bool + { + return adw_dialog_get_follows_content_size(const_cast(unwrap(this))); + } + + auto Dialog::get_presentation_mode() const -> PresentationMode + { + return static_cast(adw_dialog_get_presentation_mode(const_cast(unwrap(this)))); + } + + auto Dialog::get_title() const -> Glib::ustring + { + return adw_dialog_get_title(const_cast(unwrap(this))); + } + + auto Dialog::set_can_close(bool value) -> void + { + return adw_dialog_set_can_close(unwrap(this), static_cast(value)); + } + + auto Dialog::set_child(Gtk::Widget & value) -> void + { + return adw_dialog_set_child(unwrap(this), unwrap(&value)); + } + + auto Dialog::set_content_height(int value) -> void + { + return adw_dialog_set_content_height(unwrap(this), value); + } + + auto Dialog::set_content_width(int value) -> void + { + return adw_dialog_set_content_width(unwrap(this), value); + } + + auto Dialog::set_default_widget(Gtk::Widget & value) -> void + { + return adw_dialog_set_default_widget(unwrap(this), unwrap(&value)); + } + + auto Dialog::set_focus(Gtk::Widget & value) -> void + { + return adw_dialog_set_focus(unwrap(this), unwrap(&value)); + } + + auto Dialog::set_follows_content_size(bool value) -> void + { + return adw_dialog_set_follows_content_size(unwrap(this), value); + } + + auto Dialog::set_presentation_mode(PresentationMode value) -> void { - adw_dialog_present(Glib::unwrap(this), Glib::unwrap(parent)); + return adw_dialog_set_presentation_mode(unwrap(this), static_cast(value)); } auto Dialog::set_title(Glib::ustring const & str) -> void { - adw_dialog_set_title(Glib::unwrap(this), Glib::c_str_or_nullptr(str)); + return adw_dialog_set_title(unwrap(this), Glib::c_str_or_nullptr(str)); + } + + auto Dialog::property_can_close() -> Glib::PropertyProxy + { + return {this, property_name::can_close}; + } + + auto Dialog::property_can_close() const -> Glib::PropertyProxy_ReadOnly + { + return {this, property_name::can_close}; + } + + auto Dialog::property_child() -> Glib::PropertyProxy + { + return {this, property_name::child}; + } + + auto Dialog::property_child() const -> Glib::PropertyProxy_ReadOnly + { + return {this, property_name::child}; + } + + auto Dialog::property_content_height() -> Glib::PropertyProxy + { + return {this, property_name::content_height}; + } + + auto Dialog::property_content_height() const -> Glib::PropertyProxy_ReadOnly + { + return {this, property_name::content_height}; + } + + auto Dialog::property_content_width() -> Glib::PropertyProxy + { + return {this, property_name::content_width}; + } + + auto Dialog::property_content_width() const -> Glib::PropertyProxy_ReadOnly + { + return {this, property_name::content_width}; + } + + auto Dialog::property_current_breakpoint() const -> Glib::PropertyProxy_ReadOnly> + { + return {this, property_name::current_breakpoint}; + } + + auto Dialog::property_default_widget() -> Glib::PropertyProxy + { + return {this, property_name::default_widget}; + } + + auto Dialog::property_default_widget() const -> Glib::PropertyProxy_ReadOnly + { + return {this, property_name::default_widget}; + } + + auto Dialog::property_focus_widget() -> Glib::PropertyProxy + { + return {this, property_name::focus_widget}; + } + + auto Dialog::property_focus_widget() const -> Glib::PropertyProxy_ReadOnly + { + return {this, property_name::focus_widget}; + } + + auto Dialog::property_follows_content_size() -> Glib::PropertyProxy + { + return {this, property_name::follows_content_size}; + } + + auto Dialog::property_follows_content_size() const -> Glib::PropertyProxy_ReadOnly + { + return {this, property_name::follows_content_size}; + } + + auto Dialog::property_presentation_mode() -> Glib::PropertyProxy + { + return {this, property_name::presentation_mode}; + } + + auto Dialog::property_presentation_mode() const -> Glib::PropertyProxy_ReadOnly + { + return {this, property_name::presentation_mode}; + } + + auto Dialog::property_title() -> Glib::PropertyProxy + { + return {this, property_name::title}; + } + + auto Dialog::property_title() const -> Glib::PropertyProxy_ReadOnly + { + return {this, property_name::title}; + } + + auto Dialog::signal_close_attempt() -> Glib::SignalProxy + { + return {this, &signal_info::close_attempt}; + } + + auto Dialog::signal_closed() -> Glib::SignalProxy + { + return {this, &signal_info::closed}; + } + + auto Dialog::on_close_attempt() -> void + { + auto base_class = static_cast(g_type_class_peek_parent(G_OBJECT_GET_CLASS(gobject_))); + if (base_class && base_class->close_attempt) + { + return (base_class->close_attempt)(unwrap(this)); + } + } + + auto Dialog::on_closed() -> void + { + auto base_class = static_cast(g_type_class_peek_parent(G_OBJECT_GET_CLASS(gobject_))); + if (base_class && base_class->closed) + { + return (base_class->closed)(unwrap(this)); + } } } // namespace Adwaita diff --git a/adw/src/enums.cpp b/adw/src/enums.cpp index bcc8290..b93ac3d 100644 --- a/adw/src/enums.cpp +++ b/adw/src/enums.cpp @@ -44,6 +44,10 @@ namespace Adwaita static_assert(matches); static_assert(matches); + static_assert(matches); + static_assert(matches); + static_assert(matches); + static_assert(matches); static_assert(matches); @@ -67,6 +71,7 @@ namespace Glib VALUE_SPECIALIZATION(AccentColor, accent_color) VALUE_SPECIALIZATION(ColorScheme, color_scheme) VALUE_SPECIALIZATION(LengthType, breakpoint_condition) + VALUE_SPECIALIZATION(PresentationMode, dialog_presentation_mode); VALUE_SPECIALIZATION(RatioType, breakpoint_condition) VALUE_SPECIALIZATION(ResponseAppearance, response_appearance) VALUE_SPECIALIZATION(ToastPriority, toast_priority) diff --git a/adw/src/private/dialog_p.cpp b/adw/src/private/dialog_p.cpp index e6ac6cd..7af615a 100644 --- a/adw/src/private/dialog_p.cpp +++ b/adw/src/private/dialog_p.cpp @@ -9,6 +9,7 @@ #include "adwaitamm/dialog.hpp" #include +#include #include #include @@ -16,9 +17,11 @@ #include #include +#include namespace Adwaita { + auto Dialog_Class::init() -> Glib::Class const & { if (!gtype_) @@ -34,10 +37,65 @@ namespace Adwaita { auto const klass = static_cast(gclass); CppClassParent::class_init_function(klass, data); + + klass->close_attempt = &close_attempt; + klass->closed = &closed; } auto Dialog_Class::wrap_new(GObject * object) -> Glib::ObjectBase * { return Gtk::manage(new Dialog(ADW_DIALOG(object))); } + + auto Dialog_Class::close_attempt(BaseObjectType * self) -> void + { + auto base_object = static_cast(Glib::ObjectBase::_get_current_wrapper(G_OBJECT(self))); + if (base_object && base_object->is_derived_()) + { + auto object = dynamic_cast(base_object); + if (object) + { + try + { + return object->on_close_attempt(); + } + catch (...) + { + Glib::exception_handlers_invoke(); + } + } + } + + auto base_class = static_cast(g_type_class_peek_parent(G_OBJECT_GET_CLASS(self))); + if (base_class && base_class->close_attempt) + { + return (base_class->close_attempt)(self); + } + } + + auto Dialog_Class::closed(BaseObjectType * self) -> void + { + auto base_object = static_cast(Glib::ObjectBase::_get_current_wrapper(G_OBJECT(self))); + if (base_object && base_object->is_derived_()) + { + auto object = dynamic_cast(base_object); + if (object) + { + try + { + return object->on_closed(); + } + catch (...) + { + Glib::exception_handlers_invoke(); + } + } + } + + auto base_class = static_cast(g_type_class_peek_parent(G_OBJECT_GET_CLASS(self))); + if (base_class && base_class->closed) + { + return (base_class->closed)(self); + } + } } // namespace Adwaita \ No newline at end of file -- cgit v1.2.3