summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--adw/CMakeLists.txt2
-rw-r--r--adw/include/turns/adw/helpers/gobj_cast.hpp37
-rw-r--r--adw/include/turns/adw/helpers/properties.hpp35
-rw-r--r--adw/include/turns/adw/toast.hpp120
-rw-r--r--adw/include/turns/adw/toastoverlay.hpp64
-rw-r--r--adw/src/toast.cpp87
-rw-r--r--adw/src/toastoverlay.cpp85
-rw-r--r--adw/src/wrap_init.cpp16
-rw-r--r--ui/CMakeLists.txt2
-rw-r--r--ui/include/turns/ui/windows/tracker.hpp4
-rw-r--r--ui/src/windows/tracker.cpp8
11 files changed, 455 insertions, 5 deletions
diff --git a/adw/CMakeLists.txt b/adw/CMakeLists.txt
index 9ac563a..736aac6 100644
--- a/adw/CMakeLists.txt
+++ b/adw/CMakeLists.txt
@@ -1,5 +1,7 @@
add_library("adw"
"src/application.cpp"
+ "src/toast.cpp"
+ "src/toastoverlay.cpp"
"src/wrap_init.cpp"
)
diff --git a/adw/include/turns/adw/helpers/gobj_cast.hpp b/adw/include/turns/adw/helpers/gobj_cast.hpp
new file mode 100644
index 0000000..1ef9089
--- /dev/null
+++ b/adw/include/turns/adw/helpers/gobj_cast.hpp
@@ -0,0 +1,37 @@
+#ifndef TURNS_ADW_HELPERS_GOBJ_CAST_HPP
+#define TURNS_ADW_HELPERS_GOBJ_CAST_HPP
+
+#include <glibmm/object.h>
+
+#include <type_traits>
+
+namespace turns::adw::helpers
+{
+
+ template<typename Type, typename AdwType>
+ struct gobj_mixin
+ {
+ template<typename Self>
+ auto gobj(this Self && self) noexcept
+ {
+ using clean_type = std::remove_reference_t<Self>;
+ using gobj_type = std::conditional_t<std::is_const_v<clean_type>, std::add_const_t<Glib::Object>, Glib::Object>;
+ using cast_type = std::conditional_t<std::is_const_v<clean_type>, std::add_const_t<AdwType>, AdwType>;
+
+ return reinterpret_cast<cast_type *>(static_cast<gobj_type &&>(self).gobj());
+ }
+
+ template<typename Self>
+ auto gobj_copy(this Self && self) noexcept -> AdwType *
+ {
+ using clean_type = std::remove_reference_t<Self>;
+ using gobj_type = std::conditional_t<std::is_const_v<clean_type>, std::add_const_t<Glib::Object>, Glib::Object>;
+
+ static_cast<gobj_type &&>(self).reference();
+ return self.gobj();
+ }
+ };
+
+} // namespace turns::adw::helpers
+
+#endif \ No newline at end of file
diff --git a/adw/include/turns/adw/helpers/properties.hpp b/adw/include/turns/adw/helpers/properties.hpp
new file mode 100644
index 0000000..6cc602a
--- /dev/null
+++ b/adw/include/turns/adw/helpers/properties.hpp
@@ -0,0 +1,35 @@
+#ifndef TURNS_ADW_HELPERS_PROPERTIES_HPP
+#define TURNS_ADW_HELPERS_PROPERTIES_HPP
+
+#include <glibmm/propertyproxy.h>
+#include <glibmm/ustring.h>
+
+#include <type_traits>
+
+namespace turns::adw::helpers
+{
+
+ template<typename ProxiedType, typename ObjectType>
+ struct deduced_property_proxy
+ {
+ using type = Glib::PropertyProxy<ProxiedType>;
+ };
+
+ template<typename ProxiedType, typename ObjectType>
+ struct deduced_property_proxy<ProxiedType, ObjectType const>
+ {
+ using type = Glib::PropertyProxy_ReadOnly<ProxiedType>;
+ };
+
+ template<typename ProxiedType, typename ObjectType>
+ using deduced_property_proxy_t = typename deduced_property_proxy<ProxiedType, ObjectType>::type;
+
+ template<typename ProxiedType, typename ObjectType>
+ auto make_property_proxy(ObjectType && object, char const * property)
+ {
+ return deduced_property_proxy_t<ProxiedType, std::remove_reference_t<ObjectType>>{&object, property};
+ }
+
+} // namespace turns::adw::helpers
+
+#endif \ No newline at end of file
diff --git a/adw/include/turns/adw/toast.hpp b/adw/include/turns/adw/toast.hpp
new file mode 100644
index 0000000..21ccdef
--- /dev/null
+++ b/adw/include/turns/adw/toast.hpp
@@ -0,0 +1,120 @@
+#ifndef TURNS_ADW_TOAST_HPP
+#define TURNS_ADW_TOAST_HPP
+
+#include "turns/adw/helpers/gobj_cast.hpp"
+#include "turns/adw/helpers/properties.hpp"
+
+#include <glibmm/object.h>
+#include <glibmm/refptr.h>
+#include <glibmm/ustring.h>
+#include <glibmm/variant.h>
+
+#include <gtkmm/widget.h>
+
+using AdwToast = struct _AdwToast;
+
+namespace turns::adw
+{
+ struct Toast_Class;
+
+ struct Toast : Glib::Object,
+ helpers::gobj_mixin<Toast, AdwToast>
+ {
+ enum class Priority
+ {
+ NORMAL,
+ HIGH,
+ };
+
+ using helpers::gobj_mixin<Toast, AdwToast>::gobj;
+ using helpers::gobj_mixin<Toast, AdwToast>::gobj_copy;
+
+ Toast(Toast && other) noexcept = default;
+ auto operator=(Toast && other) noexcept -> Toast & = default;
+
+ Toast(Toast const & other) = delete;
+ auto operator=(Toast const & other) noexcept -> Toast & = delete;
+
+ explicit Toast(Glib::ustring const & title);
+
+ auto static get_type() -> GType;
+ auto static get_base_type() -> GType;
+
+ auto dismiss() -> void;
+
+ // clang-format off
+ template<typename Self> auto property_action_name(this Self && self);
+ template<typename Self> auto property_action_target(this Self && self);
+ template<typename Self> auto property_button_label(this Self && self);
+ template<typename Self> auto property_custom_title(this Self && self);
+ template<typename Self> auto property_priority(this Self && self);
+ template<typename Self> auto property_timeout(this Self && self);
+ template<typename Self> auto property_title(this Self && self);
+ template<typename Self> auto property_use_markup(this Self && self);
+ // clang-format on
+
+ protected:
+ explicit Toast(Glib::ConstructParams const & params);
+ explicit Toast(AdwToast * gobj);
+
+ private:
+ friend Toast_Class;
+ static Toast_Class s_class;
+ };
+
+ template<typename Self>
+ auto Toast::property_action_name(this Self && self)
+ {
+ return helpers::make_property_proxy<Glib::ustring>(self, "action-name");
+ }
+
+ template<typename Self>
+ auto Toast::property_action_target(this Self && self)
+ {
+ return helpers::make_property_proxy<Glib::VariantBase>(self, "action-target");
+ }
+
+ template<typename Self>
+ auto Toast::property_button_label(this Self && self)
+ {
+ return helpers::make_property_proxy<Glib::ustring>(self, "button-label");
+ }
+
+ template<typename Self>
+ auto Toast::property_custom_title(this Self && self)
+ {
+ return helpers::make_property_proxy<Gtk::Widget *>(self, "custom-title");
+ }
+
+ template<typename Self>
+ auto Toast::property_priority(this Self && self)
+ {
+ return helpers::make_property_proxy<Priority>(self, "priority");
+ }
+
+ template<typename Self>
+ auto Toast::property_timeout(this Self && self)
+ {
+ return helpers::make_property_proxy<unsigned>(self, "timeout");
+ }
+
+ template<typename Self>
+ auto Toast::property_title(this Self && self)
+ {
+ return helpers::make_property_proxy<Glib::ustring>(self, "title");
+ }
+
+ template<typename Self>
+ auto Toast::property_use_markup(this Self && self)
+ {
+ return helpers::make_property_proxy<bool>(self, "use-markup");
+ }
+
+} // namespace turns::adw
+
+namespace Glib
+{
+ auto wrap(AdwToast * object, bool copy = false) -> Glib::RefPtr<turns::adw::Toast>;
+} // namespace Glib
+
+#endif \ No newline at end of file
diff --git a/adw/include/turns/adw/toastoverlay.hpp b/adw/include/turns/adw/toastoverlay.hpp
new file mode 100644
index 0000000..bd5402f
--- /dev/null
+++ b/adw/include/turns/adw/toastoverlay.hpp
@@ -0,0 +1,64 @@
+#ifndef TURNS_ADW_TOASTOVERLAY_HPP
+#define TURNS_ADW_TOASTOVERLAY_HPP
+
+#include "turns/adw/helpers/gobj_cast.hpp"
+#include "turns/adw/helpers/properties.hpp"
+
+#include <glibmm/refptr.h>
+
+#include <gtkmm/widget.h>
+
+using AdwToastOverlay = struct _AdwToastOverlay;
+
+namespace turns::adw
+{
+ struct ToastOverlay_Class;
+
+ struct Toast;
+
+ struct ToastOverlay : Gtk::Widget,
+ helpers::gobj_mixin<ToastOverlay, AdwToastOverlay>
+ {
+ using helpers::gobj_mixin<ToastOverlay, AdwToastOverlay>::gobj;
+ using helpers::gobj_mixin<ToastOverlay, AdwToastOverlay>::gobj_copy;
+
+ ToastOverlay(ToastOverlay && other) noexcept = default;
+ auto operator=(ToastOverlay && other) noexcept -> ToastOverlay & = default;
+
+ ToastOverlay(ToastOverlay const & other) = delete;
+ auto operator=(ToastOverlay const & other) noexcept -> ToastOverlay & = delete;
+
+ explicit ToastOverlay();
+
+ auto static get_type() -> GType;
+ auto static get_base_type() -> GType;
+
+ auto add(Toast && toast) -> void;
+
+ // clang-format off
+ template<typename Self> auto property_child(this Self && self);
+ // clang-format on
+
+ protected:
+ explicit ToastOverlay(Glib::ConstructParams const & params);
+ explicit ToastOverlay(AdwToastOverlay * gobj);
+
+ private:
+ friend ToastOverlay_Class;
+ static ToastOverlay_Class s_class;
+ };
+
+ template<typename Self>
+ auto ToastOverlay::property_child(this Self && self)
+ {
+ return helpers::make_property_proxy<Gtk::Widget *>(self, "child");
+ }
+
+} // namespace turns::adw
+
+namespace Glib
+{
+ auto wrap(AdwToastOverlay * object, bool copy = false) -> Glib::RefPtr<turns::adw::ToastOverlay>;
+} // namespace Glib
+
+#endif \ No newline at end of file
diff --git a/adw/src/toast.cpp b/adw/src/toast.cpp
new file mode 100644
index 0000000..4f8d28a
--- /dev/null
+++ b/adw/src/toast.cpp
@@ -0,0 +1,87 @@
+#include "turns/adw/toast.hpp"
+
+#include <glibmm/class.h>
+#include <glibmm/object.h>
+#include <glibmm/objectbase.h>
+#include <glibmm/private/object_p.h>
+#include <glibmm/propertyproxy.h>
+#include <glibmm/refptr.h>
+#include <glibmm/ustring.h>
+#include <glibmm/utility.h>
+#include <glibmm/variant.h>
+
+#include <gtkmm/widget.h>
+
+#include <adwaita.h>
+#include <gio/gio.h>
+#include <glib-object.h>
+
+namespace turns::adw
+{
+ static_assert(static_cast<int>(Toast::Priority::NORMAL) == ADW_TOAST_PRIORITY_NORMAL);
+ static_assert(static_cast<int>(Toast::Priority::HIGH) == ADW_TOAST_PRIORITY_HIGH);
+
+ struct Toast_Class : Glib::Class
+ {
+ auto init() -> Glib::Class const &;
+ auto static class_init_function(void * gclass, void * data) -> void;
+ auto static wrap_new(GObject * object) -> Glib::ObjectBase *;
+ };
+
+ auto Toast_Class::init() -> Glib::Class const &
+ {
+ if (!gtype_)
+ {
+ gtype_ = adw_toast_get_type();
+ }
+ return *this;
+ }
+
+ auto Toast_Class::wrap_new(GObject * object) -> Glib::ObjectBase *
+ {
+ return new Toast(ADW_TOAST(object));
+ }
+
+ Toast_Class Toast::s_class{};
+
+ Toast::Toast(Glib::ustring const & title)
+ : Glib::ObjectBase{nullptr}
+ , Glib::Object{Glib::ConstructParams{s_class.init(), "title", Glib::c_str_or_nullptr(title), nullptr}}
+ {
+ }
+
+ auto Toast::get_type() -> GType
+ {
+ return s_class.init().get_type();
+ }
+
+ auto Toast::get_base_type() -> GType
+ {
+ return adw_toast_get_type();
+ }
+
+ auto Toast::dismiss() -> void
+ {
+ return adw_toast_dismiss(gobj());
+ }
+
+ Toast::Toast(Glib::ConstructParams const & params)
+ : Glib::Object{params}
+ {
+ }
+
+ Toast::Toast(AdwToast * gobj)
+ : Glib::ObjectBase{nullptr}
+ , Glib::Object((GObject *)gobj)
+ {
+ }
+
+} // namespace turns::adw
+
+namespace Glib
+{
+ auto wrap(AdwToast * object, bool copy) -> Glib::RefPtr<turns::adw::Toast>
+ {
+ return Glib::make_refptr_for_instance<turns::adw::Toast>(dynamic_cast<turns::adw::Toast *>(Glib::wrap_auto(G_OBJECT(object), copy)));
+ }
+} // namespace Glib \ No newline at end of file
diff --git a/adw/src/toastoverlay.cpp b/adw/src/toastoverlay.cpp
new file mode 100644
index 0000000..ca877a6
--- /dev/null
+++ b/adw/src/toastoverlay.cpp
@@ -0,0 +1,85 @@
+#include "turns/adw/toastoverlay.hpp"
+
+#include "turns/adw/toast.hpp"
+
+#include <glibmm/class.h>
+#include <glibmm/object.h>
+#include <glibmm/objectbase.h>
+#include <glibmm/propertyproxy.h>
+#include <glibmm/refptr.h>
+#include <glibmm/ustring.h>
+#include <glibmm/utility.h>
+#include <glibmm/variant.h>
+
+#include <gtkmm/widget.h>
+
+#include <adwaita.h>
+#include <gio/gio.h>
+#include <glib-object.h>
+
+namespace turns::adw
+{
+ struct ToastOverlay_Class : Glib::Class
+ {
+ auto init() -> Glib::Class const &;
+ auto static wrap_new(GObject * object) -> Glib::ObjectBase *;
+ };
+
+ auto ToastOverlay_Class::init() -> Glib::Class const &
+ {
+ if (!gtype_)
+ {
+ gtype_ = adw_toast_overlay_get_type();
+ }
+ return *this;
+ }
+
+ auto ToastOverlay_Class::wrap_new(GObject * object) -> Glib::ObjectBase *
+ {
+ return new ToastOverlay(ADW_TOAST_OVERLAY(object));
+ }
+
+ ToastOverlay_Class ToastOverlay::s_class{};
+
+ auto ToastOverlay::get_type() -> GType
+ {
+ return s_class.init().get_type();
+ }
+
+ auto ToastOverlay::get_base_type() -> GType
+ {
+ return adw_toast_overlay_get_type();
+ }
+
+ auto ToastOverlay::add(Toast && toast) -> void
+ {
+ adw_toast_overlay_add_toast(gobj(), toast.gobj_copy());
+ }
+
+ ToastOverlay::ToastOverlay(Glib::ConstructParams const & params)
+ : Gtk::Widget{params}
+ {
+ }
+
+ ToastOverlay::ToastOverlay(AdwToastOverlay * gobj)
+ : Glib::ObjectBase{nullptr}
+ , Gtk::Widget((GtkWidget *)gobj)
+ {
+ }
+
+ ToastOverlay::ToastOverlay()
+ : Glib::ObjectBase{nullptr}
+ , Gtk::Widget{Glib::ConstructParams{s_class.init()}}
+ {
+ }
+
+} // namespace turns::adw
+
+namespace Glib
+{
+ auto wrap(AdwToastOverlay * object, bool copy) -> Glib::RefPtr<turns::adw::ToastOverlay>
+ {
+ return Glib::make_refptr_for_instance<turns::adw::ToastOverlay>(
+ dynamic_cast<turns::adw::ToastOverlay *>(Glib::wrap_auto(G_OBJECT(object), copy)));
+ }
+} // namespace Glib \ No newline at end of file
diff --git a/adw/src/wrap_init.cpp b/adw/src/wrap_init.cpp
index 24bfad9..546f31e 100644
--- a/adw/src/wrap_init.cpp
+++ b/adw/src/wrap_init.cpp
@@ -1,6 +1,8 @@
#include "turns/adw/wrap_init.hpp"
#include "turns/adw/application.hpp"
+#include "turns/adw/toast.hpp"
+#include "turns/adw/toastoverlay.hpp"
#include <glibmm/wrap.h>
@@ -14,11 +16,25 @@ namespace turns::adw
auto static wrap_new(GObject * object) -> Glib::ObjectBase *;
};
+ struct Toast_Class
+ {
+ auto static wrap_new(GObject * object) -> Glib::ObjectBase *;
+ };
+
+ struct ToastOverlay_Class
+ {
+ auto static wrap_new(GObject * object) -> Glib::ObjectBase *;
+ };
+
auto wrap_init() -> void
{
adw_init();
Glib::wrap_register(adw_application_get_type(), &Application_Class::wrap_new);
g_type_ensure(Application::get_type());
+ Glib::wrap_register(adw_toast_get_type(), &Toast_Class::wrap_new);
+ g_type_ensure(Toast::get_type());
+ Glib::wrap_register(adw_toast_overlay_get_type(), &ToastOverlay_Class::wrap_new);
+ g_type_ensure(ToastOverlay::get_type());
}
} // namespace turns::adw \ No newline at end of file
diff --git a/ui/CMakeLists.txt b/ui/CMakeLists.txt
index b0f790d..b3a03c9 100644
--- a/ui/CMakeLists.txt
+++ b/ui/CMakeLists.txt
@@ -26,9 +26,9 @@ target_include_directories("ui" PUBLIC
)
target_link_libraries("ui" PUBLIC
+ "turns::adw"
"turns::core"
"turns::lang"
- "PkgConfig::adwaita"
"PkgConfig::gtkmm"
)
diff --git a/ui/include/turns/ui/windows/tracker.hpp b/ui/include/turns/ui/windows/tracker.hpp
index 4dd0c7a..7e5f799 100644
--- a/ui/include/turns/ui/windows/tracker.hpp
+++ b/ui/include/turns/ui/windows/tracker.hpp
@@ -1,6 +1,8 @@
#ifndef TURNS_UI_WINDOWS_TRACKER_HPP
#define TURNS_UI_WINDOWS_TRACKER_HPP
+#include "turns/adw/toast.hpp"
+#include "turns/adw/toastoverlay.hpp"
#include "turns/core/turn_order.hpp"
#include "turns/ui/widgets/turn_order_view.hpp"
@@ -58,7 +60,7 @@ namespace turns::ui::windows
Gtk::Revealer * m_controls;
Gtk::Widget * m_empty;
- Gtk::Widget * m_overlay;
+ adw::ToastOverlay * m_overlay;
Gtk::Stack * m_stack;
Gtk::Button * m_start;
Gtk::Widget * m_title;
diff --git a/ui/src/windows/tracker.cpp b/ui/src/windows/tracker.cpp
index 66e241b..0b581af 100644
--- a/ui/src/windows/tracker.cpp
+++ b/ui/src/windows/tracker.cpp
@@ -1,5 +1,7 @@
#include "turns/ui/windows/tracker.hpp"
+#include "turns/adw/toast.hpp"
+#include "turns/adw/toastoverlay.hpp"
#include "turns/core/turn_order.hpp"
#include "turns/lang/messages.hpp"
#include "turns/ui/widgets/turn_order_view.hpp"
@@ -29,6 +31,7 @@
#include <exception>
#include <format>
+#include <print>
#include <string>
namespace turns::ui::windows
@@ -38,7 +41,7 @@ namespace turns::ui::windows
: Gtk::ApplicationWindow{base}
, m_controls{builder->get_widget<Gtk::Revealer>("controls")}
, m_empty{builder->get_widget<Gtk::Widget>("empty")}
- , m_overlay{builder->get_widget<Gtk::Widget>("overlay")}
+ , m_overlay{builder->get_widget<adw::ToastOverlay>("overlay")}
, m_stack{builder->get_widget<Gtk::Stack>("stack")}
, m_start{builder->get_widget<Gtk::Button>("start")}
, m_title{builder->get_widget<Gtk::Widget>("title")}
@@ -170,8 +173,7 @@ namespace turns::ui::windows
auto tracker::show_toast(std::string const & message) -> void
{
- auto toast = adw_toast_new(message.c_str());
- adw_toast_overlay_add_toast(ADW_TOAST_OVERLAY(m_overlay->gobj()), toast);
+ m_overlay->add(adw::Toast{message});
}
auto tracker::update_subtitle() -> void