#include "turns/app/windows/tracker.hpp" #include "turns/app/widgets/participant_row.hpp" #include "turns/app/windows/participant_editor.hpp" #include "turns/lang/messages.hpp" #include #include #include #include #include namespace turns::app::windows { namespace { auto editor_for(Glib::RefPtr participant) { auto builder = Gtk::Builder::create_from_resource("/ch/arknet/Turns/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, domain::turn_order * order) { auto response = adw_alert_dialog_choose_finish(dialog, result); if (response == Glib::ustring{"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_stack{builder->get_widget("stack")} , m_start{builder->get_widget("start")} , m_title(ADW_WINDOW_TITLE(builder->get_widget("title")->gobj())) , m_turn_order{Gtk::make_managed()} , m_subtitle{Glib::wrap(GTK_WIDGET(m_title)), "subtitle"} { setup_actions(); m_stack->add(*m_turn_order); Glib::Binding::bind_property(m_turn_order->get_model()->property_empty(), m_stack->property_visible_child(), Glib::Binding::Flags::SYNC_CREATE, [this](auto empty) { return empty ? m_empty : m_turn_order; }); Glib::Binding::bind_property(m_turn_order->get_model()->property_running(), m_controls->property_reveal_child(), Glib::Binding::Flags::SYNC_CREATE); // clang-format off Glib::Binding::bind_property(m_turn_order->get_model()->property_empty(), m_subtitle, Glib::Binding::Flags::SYNC_CREATE, [](auto empty) { return empty ? _(lang::no_active_turn_order) : ""; }); // clang-format on } 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->get_model()->add(n, p, d); }); } auto tracker::handle_delete_participant(Glib::VariantBase param) -> void { auto index = Glib::VariantBase::cast_dynamic>(param); m_turn_order->get_model()->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_model()->get(index.get()); auto [lifeline, dialog] = editor_for(participant); dialog->present(this); } auto tracker::handle_stop() -> void { auto dialog = ADW_ALERT_DIALOG(adw_alert_dialog_new("Stop turn order", "Do you want to clear the turn order?")); adw_alert_dialog_add_response(dialog, "stop", "Stop"); adw_alert_dialog_set_response_appearance(dialog, "stop", ADW_RESPONSE_SUGGESTED); adw_alert_dialog_add_response(dialog, "clear", "Stop and clear"); adw_alert_dialog_set_response_appearance(dialog, "clear", ADW_RESPONSE_DESTRUCTIVE); adw_alert_dialog_set_close_response(dialog, "stop"); adw_alert_dialog_set_default_response(dialog, "stop"); adw_alert_dialog_choose(dialog, GTK_WIDGET(this->gobj()), NULL, reinterpret_cast(stop_dialog_callback), m_turn_order->get_model().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)); Glib::Binding::bind_property(m_turn_order->get_model()->property_running(), action->property_enabled(), Glib::Binding::Flags::SYNC_CREATE | Glib::Binding::Flags::INVERT_BOOLEAN); } // win.clear // depends-on: turn_order:empty == false { auto action = add_action("clear", sigc::mem_fun(*m_turn_order->get_model(), &domain::turn_order::clear)); Glib::Binding::bind_property(m_turn_order->get_model()->property_empty(), action->property_enabled(), Glib::Binding::Flags::SYNC_CREATE | Glib::Binding::Flags::INVERT_BOOLEAN); } // win.next // depends-on: turn_order:state == running { auto action = add_action("next", sigc::mem_fun(*m_turn_order->get_model(), &domain::turn_order::next)); Glib::Binding::bind_property(m_turn_order->get_model()->property_running(), action->property_enabled(), Glib::Binding::Flags::SYNC_CREATE); } // win.previous // depends-on: turn_order:has_previous == true { auto action = add_action("previous", sigc::mem_fun(*m_turn_order->get_model(), &domain::turn_order::previous)); Glib::Binding::bind_property(m_turn_order->get_model()->property_has_previous(), action->property_enabled(), Glib::Binding::Flags::SYNC_CREATE); } // win.start // depends-on: turn_order:empty == false { auto action = add_action("start", sigc::mem_fun(*m_turn_order->get_model(), &domain::turn_order::start)); Glib::Binding::bind_property(m_turn_order->get_model()->property_empty(), action->property_enabled(), Glib::Binding::Flags::SYNC_CREATE | Glib::Binding::Flags::INVERT_BOOLEAN); Glib::Binding::bind_property(m_turn_order->get_model()->property_running(), m_start->property_visible(), Glib::Binding::Flags::SYNC_CREATE | Glib::Binding::Flags::INVERT_BOOLEAN); } // win.stop // depends-on: turn_order:running == true { auto action = add_action("stop", sigc::mem_fun(*this, &tracker::handle_stop)); Glib::Binding::bind_property(m_turn_order->get_model()->property_running(), action->property_enabled(), Glib::Binding::Flags::SYNC_CREATE); } // win.delete // win.edit { 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)); } } } // namespace turns::app::windows