#include "component.hh" #include "creeper-qt/core/application.hh" #include "creeper-qt/layout/group.hh" #include "creeper-qt/layout/linear.hh" #include "creeper-qt/layout/mutual-exclusion-group.hh" #include "creeper-qt/utility/material-icon.hh" #include "creeper-qt/utility/theme/theme.hh" #include "creeper-qt/widget/buttons/icon-button.hh" #include "creeper-qt/widget/cards/filled-card.hh" #include "creeper-qt/widget/image.hh" using namespace creeper; namespace fc = filled_card::pro; namespace sg = select_group::pro; namespace ln = linear::pro; namespace im = image::pro; namespace ic = icon_button::pro; auto NavComponent(NavComponentState& state) noexcept -> raw_pointer { const auto AvatarComponent = new Image { im::FixedSize {60, 60}, im::Radius {-1}, im::ContentScale {ContentScale::CROP}, im::BorderWidth {3}, im::PainterResource { ":/images/images/logo.png", }, }; state.manager.append_handler(AvatarComponent, [AvatarComponent](const ThemeManager& manager) { const auto colorscheme = manager.color_scheme(); const auto colorborder = colorscheme.secondary_container; AvatarComponent->set_border_color(colorborder); }); const auto navigation_icons_config = std::tuple { ic::ThemeManager {state.manager}, ic::ColorStandard, ic::ShapeRound, ic::TypesToggleUnselected, ic::WidthDefault, ic::Font {material::regular::font_1}, ic::FixedSize {IconButton::kSmallContainerSize}, }; return new FilledCard { fc::ThemeManager {state.manager}, fc::Radius {0}, fc::Level {CardLevel::HIGHEST}, fc::Layout { ln::Spacing {10}, ln::Margin {15}, ln::Item { {0, Qt::AlignHCenter}, AvatarComponent, }, ln::SpacingItem {20}, ln::Item> { {0, Qt::AlignHCenter}, ln::Margin {0}, ln::SpacingItem {10}, sg::Compose { state.buttons_context | std::views::enumerate, [&](int index, const auto& context) { const auto& [name, icon] = context; const auto status = (index == 0) ? ic::TypesToggleSelected : ic::TypesToggleUnselected; return new IconButton { navigation_icons_config, status, ic::FontIcon(icon.data()), ic::Clickable {[=] { // state.switch_callback(index, name); state.stacked_callback(index); }}, }; }, Qt::AlignHCenter, }, sg::SignalInjection{&IconButton::clicked}, }, ln::SpacingItem {40}, ln::Stretch {255}, ln::Item { {0, Qt::AlignHCenter}, navigation_icons_config, ic::TypesDefault, ic::FontIcon {material::icon::kLogout}, ic::Clickable {&app::quit}, }, ln::Item { {0, Qt::AlignHCenter}, navigation_icons_config, ic::ColorFilled, ic::FontIcon {material::icon::k123}, MutableTransform{ [](auto& self, bool show_numbers) { self.set_types(show_numbers ? icon_button::internal::IconButton::Types::TOGGLE_SELECTED : icon_button::internal::IconButton::Types::TOGGLE_UNSELECTED); }, state.heatmap_show_numbers }, ic::Clickable{ [ctx = state.heatmap_show_numbers] { if (ctx) { ctx->set(!ctx->get()); } } }, }, ln::Item { {0, Qt::AlignHCenter}, navigation_icons_config, ic::ColorFilled, ic::FontIcon {material::icon::kDarkMode}, ic::Clickable{[&]{state.manager.toggle_color_mode();state.manager.apply_theme();}}, } } }; }