From 08a8362a39a7b71c087f165a1079b5439c52d35e Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 26 Jul 2024 20:16:33 +0200 Subject: turns: perform source cleanup --- ui/CMakeLists.txt | 2 + ui/include/turns/ui/init.hpp | 2 +- ui/include/turns/ui/widgets/fwd.hpp | 2 +- ui/include/turns/ui/widgets/participant_row.hpp | 7 +- ui/include/turns/ui/widgets/template_widget.hpp | 2 + ui/include/turns/ui/widgets/turn_order_view.hpp | 1 + ui/include/turns/ui/windows/fwd.hpp | 2 +- ui/include/turns/ui/windows/participant_editor.hpp | 4 +- ui/include/turns/ui/windows/tracker.hpp | 49 ++--- ui/src/init.cpp | 4 +- ui/src/widgets/participant_row.cpp | 22 +- ui/src/widgets/turn_order_view.cpp | 17 +- ui/src/windows/participant_editor.cpp | 18 +- ui/src/windows/tracker.cpp | 238 ++++----------------- ui/src/windows/tracker/actions.cpp | 123 +++++++++++ ui/src/windows/tracker/event_handlers.cpp | 100 +++++++++ ui/tests/gtk_test_init.cpp | 3 + ui/tests/widgets/participant_row.cpp | 6 +- ui/tests/windows/participant_editor.cpp | 5 +- ui/tests/windows/tracker.cpp | 4 +- 20 files changed, 363 insertions(+), 248 deletions(-) create mode 100644 ui/src/windows/tracker/actions.cpp create mode 100644 ui/src/windows/tracker/event_handlers.cpp (limited to 'ui') diff --git a/ui/CMakeLists.txt b/ui/CMakeLists.txt index fa4bc02..b0f790d 100644 --- a/ui/CMakeLists.txt +++ b/ui/CMakeLists.txt @@ -6,6 +6,8 @@ add_library("ui" "src/widgets/turn_order_view.cpp" "src/windows/participant_editor.cpp" "src/windows/tracker.cpp" + "src/windows/tracker/actions.cpp" + "src/windows/tracker/event_handlers.cpp" $ ) diff --git a/ui/include/turns/ui/init.hpp b/ui/include/turns/ui/init.hpp index a1b1184..b872063 100644 --- a/ui/include/turns/ui/init.hpp +++ b/ui/include/turns/ui/init.hpp @@ -6,6 +6,6 @@ namespace turns::ui auto register_types() -> void; -} // namespace turns::aop +} // namespace turns::ui #endif \ No newline at end of file diff --git a/ui/include/turns/ui/widgets/fwd.hpp b/ui/include/turns/ui/widgets/fwd.hpp index 4d2ddb7..353db58 100644 --- a/ui/include/turns/ui/widgets/fwd.hpp +++ b/ui/include/turns/ui/widgets/fwd.hpp @@ -5,6 +5,6 @@ namespace turns::ui::widgets { struct participant_row; struct turn_order_view; -} // namespace turns::ui::windows +} // namespace turns::ui::widgets #endif \ No newline at end of file diff --git a/ui/include/turns/ui/widgets/participant_row.hpp b/ui/include/turns/ui/widgets/participant_row.hpp index e7796d3..f33da34 100644 --- a/ui/include/turns/ui/widgets/participant_row.hpp +++ b/ui/include/turns/ui/widgets/participant_row.hpp @@ -1,10 +1,11 @@ #ifndef TURNS_UI_WIDGETS_PARTICIPANT_ROW_HPP #define TURNS_UI_WIDGETS_PARTICIPANT_ROW_HPP -#include "turns/ui/widgets/template_widget.hpp" #include "turns/core/fwd.hpp" +#include "turns/ui/widgets/template_widget.hpp" #include +#include #include #include @@ -28,8 +29,8 @@ namespace turns::ui::widgets participant_row(Glib::RefPtr participant); - auto property_delete_enabled() -> Glib::PropertyProxy; - auto property_edit_enabled() -> Glib::PropertyProxy; + auto delete_enabled() -> Glib::PropertyProxy; + auto edit_enabled() -> Glib::PropertyProxy; private: auto handle_delete() -> void; diff --git a/ui/include/turns/ui/widgets/template_widget.hpp b/ui/include/turns/ui/widgets/template_widget.hpp index b3e5195..c01fff2 100644 --- a/ui/include/turns/ui/widgets/template_widget.hpp +++ b/ui/include/turns/ui/widgets/template_widget.hpp @@ -6,6 +6,8 @@ #include +#include +#include #include #include diff --git a/ui/include/turns/ui/widgets/turn_order_view.hpp b/ui/include/turns/ui/widgets/turn_order_view.hpp index 6790563..a9a3654 100644 --- a/ui/include/turns/ui/widgets/turn_order_view.hpp +++ b/ui/include/turns/ui/widgets/turn_order_view.hpp @@ -2,6 +2,7 @@ #define TURNS_UI_WIDGETS_TURN_ORDER_VIEW_HPP #include "turns/core/fwd.hpp" +#include "turns/core/turn_order.hpp" #include "turns/ui/widgets/template_widget.hpp" #include diff --git a/ui/include/turns/ui/windows/fwd.hpp b/ui/include/turns/ui/windows/fwd.hpp index b0eb69e..f228d7b 100644 --- a/ui/include/turns/ui/windows/fwd.hpp +++ b/ui/include/turns/ui/windows/fwd.hpp @@ -5,6 +5,6 @@ namespace turns::ui::windows { struct participant_editor; struct tracker; -} // namespace turns::app::windows +} // namespace turns::ui::windows #endif \ No newline at end of file diff --git a/ui/include/turns/ui/windows/participant_editor.hpp b/ui/include/turns/ui/windows/participant_editor.hpp index 3ef8729..8618a0e 100644 --- a/ui/include/turns/ui/windows/participant_editor.hpp +++ b/ui/include/turns/ui/windows/participant_editor.hpp @@ -22,7 +22,7 @@ namespace turns::ui::windows struct participant_editor : Gtk::Widget { - using signal_finished_type = sigc::signal; + using signal_finished_type = sigc::signal; participant_editor(BaseObjectType * base, Glib::RefPtr const builder, Glib::RefPtr obj = {}); @@ -49,6 +49,6 @@ namespace turns::ui::windows signal_finished_type m_signal_finished{}; }; -} // namespace turns::app::windows +} // namespace turns::ui::windows #endif \ No newline at end of file diff --git a/ui/include/turns/ui/windows/tracker.hpp b/ui/include/turns/ui/windows/tracker.hpp index f520097..03260f1 100644 --- a/ui/include/turns/ui/windows/tracker.hpp +++ b/ui/include/turns/ui/windows/tracker.hpp @@ -4,6 +4,7 @@ #include "turns/core/turn_order.hpp" #include "turns/ui/widgets/turn_order_view.hpp" +#include #include #include #include @@ -19,11 +20,8 @@ #include #include -#include - -#include +#include #include -#include namespace turns::ui::windows { @@ -33,39 +31,42 @@ namespace turns::ui::windows tracker(BaseObjectType * base, Glib::RefPtr const builder); private: - auto do_save() -> void; - - auto handle_add_participant() -> void; - auto handle_delete_participant(Glib::VariantBase param) -> void; - auto handle_edit_participant(Glib::VariantBase param) -> void; - auto handle_open() -> void; - auto handle_open_done(Glib::RefPtr result) -> void; - auto handle_open_response(Glib::RefPtr result, Glib::RefPtr dialog) -> void; - auto handle_save(bool force_ask) -> void; - auto handle_save_done(Glib::RefPtr result) -> void; - auto handle_save_response(Glib::RefPtr result, Glib::RefPtr dialog) -> void; - auto handle_stop() -> void; - - + /** Setup */ auto setup_actions() -> void; - auto show_error_toast(std::exception const & e) -> void; + /** Actions */ + auto add_participant() -> void; + auto delete_participant(Glib::VariantBase param) -> void; + auto edit_participant(Glib::VariantBase param) -> void; + auto open() -> void; + auto save(bool force_ask) -> void; + auto stop() -> void; + + /** Event Handlers */ + auto on_open_response(Glib::RefPtr result, Glib::RefPtr dialog) -> void; + auto on_save_response(Glib::RefPtr result, Glib::RefPtr dialog) -> void; + auto on_load_content_done(Glib::RefPtr result) -> void; + auto on_replace_content_done(Glib::RefPtr result) -> void; + + /** Helpers */ + auto show_error(std::exception const & e) -> void; + auto show_toast(std::string const & message) -> void; + auto start_replace_content() -> void; auto update_subtitle() -> void; - AdwApplicationWindow * m_adw; Gtk::Revealer * m_controls; Gtk::Widget * m_empty; - AdwToastOverlay * m_overlay; + Gtk::Widget * m_overlay; Gtk::Stack * m_stack; Gtk::Button * m_start; - AdwWindowTitle * m_title; + Gtk::Widget * m_title; Glib::RefPtr m_turn_order; widgets::turn_order_view * m_turn_order_view; Glib::PropertyProxy m_subtitle; - std::string m_file_tag{}; Glib::RefPtr m_file{}; - std::string m_buffer{}; + std::string m_file_etag{}; + std::string m_file_buffer{}; }; } // namespace turns::ui::windows diff --git a/ui/src/init.cpp b/ui/src/init.cpp index e1b8cc3..8d48ced 100644 --- a/ui/src/init.cpp +++ b/ui/src/init.cpp @@ -1,4 +1,4 @@ -#include "turns/core/init.hpp" +#include "turns/ui/init.hpp" #include "turns/ui/widgets/participant_row.hpp" #include "turns/ui/widgets/turn_order_view.hpp" @@ -12,4 +12,4 @@ namespace turns::ui static_cast(widgets::turn_order_view{{}}); } -} // namespace turns::core \ No newline at end of file +} // namespace turns::ui \ No newline at end of file diff --git a/ui/src/widgets/participant_row.cpp b/ui/src/widgets/participant_row.cpp index 29e9100..305336e 100644 --- a/ui/src/widgets/participant_row.cpp +++ b/ui/src/widgets/participant_row.cpp @@ -3,14 +3,26 @@ #include "turns/core/disposition.hpp" #include "turns/core/participant.hpp" #include "turns/lang/messages.hpp" +#include "turns/ui/widgets/template_widget.hpp" + +#include #include #include +#include +#include +#include #include #include +#include +#include +#include +#include + #include #include +#include namespace turns::ui::widgets { @@ -64,10 +76,10 @@ namespace turns::ui::widgets [](auto active) { return active ? "face-sick-symbolic" : "face-smile-symbolic"; }); // clang-format off - Glib::Binding::bind_property(property_delete_enabled(), + Glib::Binding::bind_property(delete_enabled(), m_delete->property_sensitive(), Glib::Binding::Flags::SYNC_CREATE); - Glib::Binding::bind_property(property_edit_enabled(), + Glib::Binding::bind_property(edit_enabled(), m_edit->property_sensitive(), Glib::Binding::Flags::SYNC_CREATE); // clang-format on @@ -108,12 +120,12 @@ namespace turns::ui::widgets } } - auto participant_row::property_delete_enabled() -> Glib::PropertyProxy + auto participant_row::delete_enabled() -> Glib::PropertyProxy { return m_delete_enabled.get_proxy(); } - auto participant_row::property_edit_enabled() -> Glib::PropertyProxy + auto participant_row::edit_enabled() -> Glib::PropertyProxy { return m_edit_enabled.get_proxy(); } @@ -130,4 +142,4 @@ namespace turns::ui::widgets activate_action("win.edit", index); } -} // namespace turns::app::widgets \ No newline at end of file +} // namespace turns::ui::widgets \ No newline at end of file diff --git a/ui/src/widgets/turn_order_view.cpp b/ui/src/widgets/turn_order_view.cpp index 66042da..f3db3c4 100644 --- a/ui/src/widgets/turn_order_view.cpp +++ b/ui/src/widgets/turn_order_view.cpp @@ -1,12 +1,21 @@ #include "turns/ui/widgets/turn_order_view.hpp" #include "turns/core/participant.hpp" -#include "turns/core/turn_order.hpp" #include "turns/ui/widgets/participant_row.hpp" +#include "turns/ui/widgets/template_widget.hpp" #include #include +#include +#include +#include + +#include +#include +#include +#include +#include #include @@ -42,14 +51,14 @@ namespace turns::ui::widgets auto row = Gtk::make_managed(participant); Glib::Binding::bind_property(m_model->is_running(), - row->property_delete_enabled(), + row->delete_enabled(), Glib::Binding::Flags::SYNC_CREATE | Glib::Binding::Flags::INVERT_BOOLEAN); Glib::Binding::bind_property(m_model->is_running(), - row->property_edit_enabled(), + row->edit_enabled(), Glib::Binding::Flags::SYNC_CREATE | Glib::Binding::Flags::INVERT_BOOLEAN); return row; } -} // namespace turns::app::widgets \ No newline at end of file +} // namespace turns::ui::widgets \ No newline at end of file diff --git a/ui/src/windows/participant_editor.cpp b/ui/src/windows/participant_editor.cpp index 63c09c4..e41bc92 100644 --- a/ui/src/windows/participant_editor.cpp +++ b/ui/src/windows/participant_editor.cpp @@ -4,13 +4,29 @@ #include "turns/core/participant.hpp" #include "turns/lang/messages.hpp" +#include + #include +#include +#include +#include #include #include #include +#include +#include +#include +#include #include +#include + +#include +#include +#include +#include +#include #include namespace turns::ui::windows @@ -88,4 +104,4 @@ namespace turns::ui::windows item->set_child(*Gtk::make_managed()); } -} // namespace turns::app::windows \ No newline at end of file +} // namespace turns::ui::windows \ No newline at end of file diff --git a/ui/src/windows/tracker.cpp b/ui/src/windows/tracker.cpp index 6c248fe..e64eb18 100644 --- a/ui/src/windows/tracker.cpp +++ b/ui/src/windows/tracker.cpp @@ -1,68 +1,50 @@ #include "turns/ui/windows/tracker.hpp" -#include "turns/core/participant.hpp" #include "turns/core/turn_order.hpp" #include "turns/lang/messages.hpp" -#include "turns/ui/windows/participant_editor.hpp" +#include "turns/ui/widgets/turn_order_view.hpp" -#include +#include #include #include #include +#include +#include #include +#include +#include +#include #include #include +#include +#include +#include +#include #include #include +#include #include -#include -#include -#include +#include namespace turns::ui::windows { - namespace - { - auto editor_for(Glib::RefPtr participant) - { - auto builder = Gtk::Builder::create_from_resource("/windows/participant_editor.ui"); - return std::pair{builder, Gtk::Builder::get_widget_derived(builder, "participant_editor", participant)}; - } - - auto stop_dialog_callback(AdwAlertDialog * dialog, GAsyncResult * result, core::turn_order * order) - { - auto response = Glib::ustring{adw_alert_dialog_choose_finish(dialog, result)}; - if (response == "cancel") - { - return; - } - if (response == "clear") - { - order->clear(); - } - order->stop(); - } - - } // namespace - tracker::tracker(BaseObjectType * base, Glib::RefPtr const builder) : Gtk::ApplicationWindow{base} - , m_adw{ADW_APPLICATION_WINDOW(gobj())} , m_controls{builder->get_widget("controls")} - , m_empty(builder->get_widget("empty")) - , m_overlay{ADW_TOAST_OVERLAY(builder->get_widget("overlay")->gobj())} + , m_empty{builder->get_widget("empty")} + , m_overlay{builder->get_widget("overlay")} , m_stack{builder->get_widget("stack")} , m_start{builder->get_widget("start")} - , m_title(ADW_WINDOW_TITLE(builder->get_widget("title")->gobj())) + , m_title{builder->get_widget("title")} , m_turn_order{core::turn_order::create()} , m_turn_order_view{Gtk::make_managed(m_turn_order)} - , m_subtitle{Glib::wrap(GTK_WIDGET(m_title)), "subtitle"} + , m_subtitle{m_title, "subtitle"} { setup_actions(); @@ -84,168 +66,12 @@ namespace turns::ui::windows // clang-format on } - auto tracker::do_save() -> void - { - m_buffer = m_turn_order->serialize().dump(2); - m_file->replace_contents_async(sigc::mem_fun(*this, &tracker::handle_save_done), m_buffer, m_file_tag); - } - - auto tracker::handle_add_participant() -> void - { - auto [lifeline, dialog] = editor_for(nullptr); - dialog->present(this); - dialog->signal_finished().connect([this](auto n, auto p, auto d) { m_turn_order->add(n, p, d); }); - } - - auto tracker::handle_delete_participant(Glib::VariantBase param) -> void - { - auto index = Glib::VariantBase::cast_dynamic>(param); - m_turn_order->remove(index.get()); - } - - auto tracker::handle_edit_participant(Glib::VariantBase param) -> void - { - static_cast(param); - auto index = Glib::VariantBase::cast_dynamic>(param); - auto participant = m_turn_order->get_typed_object(index.get()); - auto [lifeline, dialog] = editor_for(participant); - dialog->present(this); - } - - auto tracker::handle_open() -> void - { - auto filters = Gio::ListStore::create(); - auto filter = Gtk::FileFilter::create(); - filter->set_name(_("Turns Files")); - filter->add_pattern("*.trns"); - filters->append(filter); - - auto dialog = Gtk::FileDialog::create(); - dialog->set_filters(filters); - dialog->open(sigc::bind(sigc::mem_fun(*this, &tracker::handle_open_response), dialog)); - } - - auto tracker::handle_open_done(Glib::RefPtr result) -> void - try - { - set_sensitive(); - char * data{}; - auto size = std::size_t{}; - if (!m_file->load_contents_finish(result, data, size, m_file_tag)) - { - m_file.reset(); - m_file_tag.clear(); - return; - } - auto deserialized = nlohmann::json::parse(std::string_view{data, size}); - m_turn_order->load(deserialized); - auto name = m_file->get_basename(); - auto message = std::vformat(_(lang::successfully_opened_format), std::make_format_args(name)); - auto toast = adw_toast_new(message.c_str()); - adw_toast_overlay_add_toast(m_overlay, toast); - set_title(std::format("{} - {}", _(lang::turns), name)); - } - catch (std::exception const & e) - { - show_error_toast(e); - } - - auto tracker::handle_open_response(Glib::RefPtr result, Glib::RefPtr dialog) -> void - try - { - m_file = dialog->open_finish(result); - m_file->load_contents_async(sigc::mem_fun(*this, &tracker::handle_open_done)); - set_sensitive(false); - } - catch (std::exception const & e) - { - set_sensitive(); - show_error_toast(e); - } - - auto tracker::handle_save(bool force_ask) -> void - { - if (m_file && !force_ask) - { - do_save(); - } - else - { - auto filters = Gio::ListStore::create(); - auto filter = Gtk::FileFilter::create(); - filter->set_name(_("Turns Files")); - filter->add_pattern("*.trns"); - filters->append(filter); - - auto dialog = Gtk::FileDialog::create(); - if (m_file) - { - dialog->set_initial_file(m_file); - } - else - { - dialog->set_initial_name(_(lang::new_turn_order_file_name)); - } - dialog->set_filters(filters); - dialog->save(*this, sigc::bind(sigc::mem_fun(*this, &tracker::handle_save_response), dialog)); - } - } - - auto tracker::handle_save_done(Glib::RefPtr result) -> void - try - { - set_sensitive(); - m_file->replace_contents_finish(result, m_file_tag); - auto name = m_file->get_basename(); - auto message = std::vformat(_(lang::successfully_saved_format), std::make_format_args(name)); - auto toast = adw_toast_new(message.c_str()); - adw_toast_overlay_add_toast(m_overlay, toast); - set_title(std::format("{} - {}", _(lang::turns), name)); - } - catch (Gio::Error const & e) - { - show_error_toast(e); - } - - auto tracker::handle_save_response(Glib::RefPtr result, Glib::RefPtr dialog) -> void - try - { - m_file = dialog->save_finish(result); - do_save(); - set_sensitive(false); - } - catch (Gtk::DialogError const & e) - { - if (e.code() == Gtk::DialogError::FAILED) - { - show_error_toast(e); - } - } - - auto tracker::handle_stop() -> void - { - auto dialog = ADW_ALERT_DIALOG(adw_alert_dialog_new(_(lang::stop_turn_order), _(lang::question_clear_turn_order))); - adw_alert_dialog_add_response(dialog, "stop", _(lang::stop)); - adw_alert_dialog_set_response_appearance(dialog, "stop", ADW_RESPONSE_SUGGESTED); - adw_alert_dialog_add_response(dialog, "clear", _(lang::stop_and_clear)); - adw_alert_dialog_set_response_appearance(dialog, "clear", ADW_RESPONSE_DESTRUCTIVE); - adw_alert_dialog_add_response(dialog, "cancel", _(lang::cancel)); - adw_alert_dialog_set_response_appearance(dialog, "cancel", ADW_RESPONSE_DEFAULT); - adw_alert_dialog_set_close_response(dialog, "cancel"); - adw_alert_dialog_set_default_response(dialog, "cancel"); - adw_alert_dialog_choose(dialog, - GTK_WIDGET(this->gobj()), - NULL, - reinterpret_cast(stop_dialog_callback), - m_turn_order.get()); - } - auto tracker::setup_actions() -> void { // win.add_participant // depends-on: turn_order:state == stopped { - auto action = add_action("add_participant", sigc::mem_fun(*this, &tracker::handle_add_participant)); + auto action = add_action("add_participant", sigc::mem_fun(*this, &tracker::add_participant)); Glib::Binding::bind_property(m_turn_order->is_running(), action->property_enabled(), @@ -295,7 +121,7 @@ namespace turns::ui::windows // win.stop // depends-on: turn_order:running == true { - auto action = add_action("stop", sigc::mem_fun(*this, &tracker::handle_stop)); + auto action = add_action("stop", sigc::mem_fun(*this, &tracker::stop)); Glib::Binding::bind_property(m_turn_order->is_running(), action->property_enabled(), Glib::Binding::Flags::SYNC_CREATE); } @@ -304,15 +130,15 @@ namespace turns::ui::windows // win.edit // win.open { - add_action_with_parameter("delete", Glib::VARIANT_TYPE_INT32, sigc::mem_fun(*this, &tracker::handle_delete_participant)); - add_action_with_parameter("edit", Glib::VARIANT_TYPE_INT32, sigc::mem_fun(*this, &tracker::handle_edit_participant)); - add_action("open", sigc::mem_fun(*this, &tracker::handle_open)); + add_action_with_parameter("delete", Glib::VARIANT_TYPE_INT32, sigc::mem_fun(*this, &tracker::delete_participant)); + add_action_with_parameter("edit", Glib::VARIANT_TYPE_INT32, sigc::mem_fun(*this, &tracker::edit_participant)); + add_action("open", sigc::mem_fun(*this, &tracker::open)); } // win.save // depends-on: turn_order:is_empty == false { - auto action = add_action("save", sigc::bind(sigc::mem_fun(*this, &tracker::handle_save), false)); + auto action = add_action("save", sigc::bind(sigc::mem_fun(*this, &tracker::save), false)); Glib::Binding::bind_property(m_turn_order->is_empty(), action->property_enabled(), @@ -322,7 +148,7 @@ namespace turns::ui::windows // win.save-as // depends-on: turn_order:is_empty == false { - auto action = add_action("save-as", sigc::bind(sigc::mem_fun(*this, &tracker::handle_save), true)); + auto action = add_action("save-as", sigc::bind(sigc::mem_fun(*this, &tracker::save), true)); Glib::Binding::bind_property(m_turn_order->is_empty(), action->property_enabled(), @@ -330,12 +156,22 @@ namespace turns::ui::windows } } - auto tracker::show_error_toast(std::exception const & e) -> void + auto tracker::start_replace_content() -> void + { + m_file_buffer = m_turn_order->serialize().dump(2); + m_file->replace_contents_async(sigc::mem_fun(*this, &tracker::on_replace_content_done), m_file_buffer, m_file_etag); + } + + auto tracker::show_error(std::exception const & e) -> void { auto error = e.what(); - auto message = std::vformat(_(lang::saving_failed_format), std::make_format_args(error)); + show_toast(std::vformat(_(lang::saving_failed_format), std::make_format_args(error))); + } + + auto tracker::show_toast(std::string const & message) -> void + { auto toast = adw_toast_new(message.c_str()); - adw_toast_overlay_add_toast(m_overlay, toast); + adw_toast_overlay_add_toast(ADW_TOAST_OVERLAY(m_overlay->gobj()), toast); } auto tracker::update_subtitle() -> void diff --git a/ui/src/windows/tracker/actions.cpp b/ui/src/windows/tracker/actions.cpp new file mode 100644 index 0000000..9da2e0c --- /dev/null +++ b/ui/src/windows/tracker/actions.cpp @@ -0,0 +1,123 @@ +#include "turns/core/participant.hpp" +#include "turns/core/turn_order.hpp" +#include "turns/lang/messages.hpp" +#include "turns/ui/windows/participant_editor.hpp" +#include "turns/ui/windows/tracker.hpp" + +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include + +#include + +namespace turns::ui::windows +{ + namespace + { + auto editor_for(Glib::RefPtr participant) + { + auto builder = Gtk::Builder::create_from_resource("/windows/participant_editor.ui"); + return std::pair{builder, Gtk::Builder::get_widget_derived(builder, "participant_editor", participant)}; + } + + auto stop_dialog_callback(AdwAlertDialog * dialog, GAsyncResult * result, core::turn_order * order) + { + auto response = Glib::ustring{adw_alert_dialog_choose_finish(dialog, result)}; + if (response == "cancel") + { + return; + } + if (response == "clear") + { + order->clear(); + } + order->stop(); + } + + auto file_filters() + { + auto filters = Gio::ListStore::create(); + auto filter = Gtk::FileFilter::create(); + filter->set_name(_("Turns Files")); + filter->add_pattern("*.trns"); + filters->append(filter); + return filters; + } + } // namespace + + auto tracker::add_participant() -> void + { + auto [lifeline, dialog] = editor_for(nullptr); + dialog->present(this); + dialog->signal_finished().connect([this](auto n, auto p, auto d) { m_turn_order->add(n, p, d); }); + } + + auto tracker::delete_participant(Glib::VariantBase param) -> void + { + auto index = Glib::VariantBase::cast_dynamic>(param); + m_turn_order->remove(index.get()); + } + + auto tracker::edit_participant(Glib::VariantBase param) -> void + { + static_cast(param); + auto index = Glib::VariantBase::cast_dynamic>(param); + auto participant = m_turn_order->get_typed_object(index.get()); + auto [lifeline, dialog] = editor_for(participant); + dialog->present(this); + } + + auto tracker::open() -> void + { + auto dialog = Gtk::FileDialog::create(); + dialog->set_filters(file_filters()); + dialog->open(sigc::bind(sigc::mem_fun(*this, &tracker::on_open_response), dialog)); + } + + auto tracker::save(bool force_ask) -> void + { + if (m_file && !force_ask) + { + start_replace_content(); + } + else + { + auto dialog = Gtk::FileDialog::create(); + m_file ? dialog->set_initial_file(m_file) : dialog->set_initial_name(_(lang::new_turn_order_file_name)); + dialog->set_filters(file_filters()); + dialog->save(*this, sigc::bind(sigc::mem_fun(*this, &tracker::on_save_response), dialog)); + } + } + + auto tracker::stop() -> void + { + auto dialog = ADW_ALERT_DIALOG(adw_alert_dialog_new(_(lang::stop_turn_order), _(lang::question_clear_turn_order))); + adw_alert_dialog_add_response(dialog, "stop", _(lang::stop)); + adw_alert_dialog_set_response_appearance(dialog, "stop", ADW_RESPONSE_SUGGESTED); + adw_alert_dialog_add_response(dialog, "clear", _(lang::stop_and_clear)); + adw_alert_dialog_set_response_appearance(dialog, "clear", ADW_RESPONSE_DESTRUCTIVE); + adw_alert_dialog_add_response(dialog, "cancel", _(lang::cancel)); + adw_alert_dialog_set_response_appearance(dialog, "cancel", ADW_RESPONSE_DEFAULT); + adw_alert_dialog_set_close_response(dialog, "cancel"); + adw_alert_dialog_set_default_response(dialog, "cancel"); + adw_alert_dialog_choose(dialog, + GTK_WIDGET(this->gobj()), + nullptr, + reinterpret_cast(stop_dialog_callback), + m_turn_order.get()); + } +} // namespace turns::ui::windows \ No newline at end of file diff --git a/ui/src/windows/tracker/event_handlers.cpp b/ui/src/windows/tracker/event_handlers.cpp new file mode 100644 index 0000000..3fc1c53 --- /dev/null +++ b/ui/src/windows/tracker/event_handlers.cpp @@ -0,0 +1,100 @@ +#include "turns/lang/messages.hpp" +#include "turns/ui/windows/tracker.hpp" + +#include + +#include +#include + +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include + +namespace turns::ui::windows +{ + + auto tracker::on_load_content_done(Glib::RefPtr result) -> void + { + set_sensitive(); + char * data{}; + auto size = std::size_t{}; + + try + { + if (!m_file->load_contents_finish(result, data, size, m_file_etag)) + { + m_file.reset(); + m_file_etag.clear(); + return; + } + + m_turn_order->load(nlohmann::json::parse(std::string_view{data, size})); + } + catch (std::exception const & e) + { + return show_error(e); + } + + auto name = m_file->get_basename(); + show_toast(std::vformat(_(lang::successfully_opened_format), std::make_format_args(name))); + set_title(std::format("{} - {}", _(lang::turns), name)); + } + + auto tracker::on_replace_content_done(Glib::RefPtr result) -> void + { + set_sensitive(); + + try + { + m_file->replace_contents_finish(result, m_file_etag); + } + catch (Gio::Error const & e) + { + return show_error(e); + } + + auto name = m_file->get_basename(); + show_toast(std::vformat(_(lang::successfully_saved_format), std::make_format_args(name))); + set_title(std::format("{} - {}", _(lang::turns), name)); + } + + auto tracker::on_open_response(Glib::RefPtr result, Glib::RefPtr dialog) -> void + { + try + { + m_file = dialog->open_finish(result); + } + catch (std::exception const & e) + { + return show_error(e); + } + + m_file->load_contents_async(sigc::mem_fun(*this, &tracker::on_load_content_done)); + set_sensitive(false); + } + + auto tracker::on_save_response(Glib::RefPtr result, Glib::RefPtr dialog) -> void + { + try + { + m_file = dialog->save_finish(result); + } + catch (std::exception const & e) + { + show_error(e); + } + + start_replace_content(); + set_sensitive(false); + } + +} // namespace turns::ui::windows \ No newline at end of file diff --git a/ui/tests/gtk_test_init.cpp b/ui/tests/gtk_test_init.cpp index 734de2f..4bf4303 100644 --- a/ui/tests/gtk_test_init.cpp +++ b/ui/tests/gtk_test_init.cpp @@ -9,6 +9,9 @@ #include #include +#include + +#include namespace turns::ui::tests { diff --git a/ui/tests/widgets/participant_row.cpp b/ui/tests/widgets/participant_row.cpp index d3440d0..a8e4166 100644 --- a/ui/tests/widgets/participant_row.cpp +++ b/ui/tests/widgets/participant_row.cpp @@ -5,6 +5,10 @@ #include +#include + +#include + namespace turns::ui::widgets::tests { @@ -21,4 +25,4 @@ namespace turns::ui::widgets::tests } } -} // namespace turns::app::widgets::tests \ No newline at end of file +} // namespace turns::ui::widgets::tests \ No newline at end of file diff --git a/ui/tests/windows/participant_editor.cpp b/ui/tests/windows/participant_editor.cpp index cd0a61c..2b3f5da 100644 --- a/ui/tests/windows/participant_editor.cpp +++ b/ui/tests/windows/participant_editor.cpp @@ -15,6 +15,9 @@ #include #include +#include + +#include namespace turns::ui::windows::tests { @@ -108,4 +111,4 @@ namespace turns::ui::windows::tests } } -} // namespace turns::app::windows::tests \ No newline at end of file +} // namespace turns::ui::windows::tests \ No newline at end of file diff --git a/ui/tests/windows/tracker.cpp b/ui/tests/windows/tracker.cpp index d61f868..dc81331 100644 --- a/ui/tests/windows/tracker.cpp +++ b/ui/tests/windows/tracker.cpp @@ -15,6 +15,8 @@ #include +#include + namespace turns::ui::windows::tests { @@ -72,4 +74,4 @@ namespace turns::ui::windows::tests } } -} // namespace turns::app::windows::tests \ No newline at end of file +} // namespace turns::ui::windows::tests \ No newline at end of file -- cgit v1.2.3