// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #include "BluetoothAuthenticatePopup.hpp" #include #include namespace gui { namespace bluetooth::authenticate { inline constexpr auto option_box_top_margin = 40U; inline constexpr auto max_passkey_signs_count = 16U; inline constexpr auto min_passkey_signs_count = 4U; inline constexpr auto passkey_input_w = 300U; inline constexpr auto passkey_input_h = 60U; inline constexpr auto buttons_input_w = 150U; inline constexpr auto buttons_input_h = 75U; inline constexpr auto buttons_margin = 30U; enum ButtonsOptions { Pair, Cancel, }; } // namespace bluetooth::authenticate BluetoothAuthenticatePopup::BluetoothAuthenticatePopup(app::ApplicationCommon *app, const std::string &name) : AppWindow(app, name) { buildInterface(); } void BluetoothAuthenticatePopup::buildInterface() { AppWindow::buildInterface(); setTitle(utils::translate("bluetooth_popup")); navBar->setText(nav_bar::Side::Right, utils::translate(style::strings::common::back)); infoIcon = new gui::Icon(this, style::window::default_left_margin, style::window::default_vertical_pos, style::window::default_body_width, style::window::default_body_height, "bluetooth_128px_W_G", utils::translate("")); infoIcon->setAlignment(Alignment::Horizontal::Center); } void BluetoothAuthenticatePopup::onBeforeShow(ShowMode mode, SwitchData *data) { auto temp = dynamic_cast(data); authenticateParams = new BluetoothAuthenticateRequestParams( temp->getDevice(), temp->getAuthenticateType(), temp->getPairingCode()); if (authenticateParams == nullptr) { LOG_ERROR("No authenticate data received"); return; } switch (authenticateParams->getAuthenticateType()) { case ::bluetooth::AuthenticateType::Pin: case ::bluetooth::AuthenticateType::Passkey: createTextAuthenticateInput(); break; case ::bluetooth::AuthenticateType::PairCancel: createButtonsAuthenticateInput(); break; } } void BluetoothAuthenticatePopup::createTextAuthenticateInput() { inputText = new TextFixedSize(infoIcon, 0, 0, 0, 0); inputText->drawUnderline(false); inputText->setTextType(TextType::SingleLine); inputText->setTextEllipsisType(TextEllipsis::Both); inputText->setFont(style::window::font::largelight); inputText->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Top)); inputText->setEdges(RectangleEdge::Bottom); inputText->setInputMode(new InputMode({InputMode::digit})); inputText->setPenWidth(style::window::default_border_rect_no_focus); inputText->setMinimumSize(bluetooth::authenticate::passkey_input_w, bluetooth::authenticate::passkey_input_h); inputText->setMargins({0, bluetooth::authenticate::option_box_top_margin, 0, 0}); if (authenticateParams->getAuthenticateType() == ::bluetooth::AuthenticateType::Passkey) { infoIcon->text->setText(utils::translate("bluetooth_popup_passkey")); inputText->setTextLimitType(TextLimitType::MaxSignsCount, bluetooth::authenticate::max_passkey_signs_count); inputText->activatedCallback = [&](Item &) -> bool { auto passkey = inputText->getText(); if (passkey.length() >= bluetooth::authenticate::min_passkey_signs_count) { application->bus.sendUnicast(std::make_shared( passkey, authenticateParams->getDevice()), service::name::bluetooth); return true; } return false; }; } else if (authenticateParams->getAuthenticateType() == ::bluetooth::AuthenticateType::Pin) { infoIcon->text->setText(utils::translate("bluetooth_popup_pin")); inputText->setTextLimitType(TextLimitType::MaxSignsCount, bluetooth::authenticate::min_passkey_signs_count); inputText->activatedCallback = [&](Item &) -> bool { auto pin = inputText->getText(); if (pin.length() == bluetooth::authenticate::min_passkey_signs_count) { application->bus.sendUnicast(std::make_shared( pin, authenticateParams->getDevice()), service::name::bluetooth); return true; } return false; }; } infoIcon->resizeItems(); setFocusItem(inputText); } auto BluetoothAuthenticatePopup::onInput(const InputEvent &inputEvent) -> bool { auto ret = AppWindow::onInput(inputEvent); if (authenticateParams->getAuthenticateType() == ::bluetooth::AuthenticateType::Passkey || authenticateParams->getAuthenticateType() == ::bluetooth::AuthenticateType::Pin) { if (inputText->getText().length() >= bluetooth::authenticate::min_passkey_signs_count) { navBar->setText(nav_bar::Side::Center, utils::translate(style::strings::common::select)); } else { navBar->setActive(nav_bar::Side::Center, false); } } return ret; } void BluetoothAuthenticatePopup::createButtonsAuthenticateInput() { auto pairingCode = authenticateParams->getPairingCode(); if (pairingCode.has_value()) { infoIcon->text->setRichText(utils::translate("bluetooth_popup_pair_cancel_code"), {{"$DEVICE", std::string(authenticateParams->getDevice().name.data())}, {"$CODE", utils::to_string(pairingCode.value())}}); } else { infoIcon->text->setRichText(utils::translate("bluetooth_popup_pair_cancel_no_code"), {{"$DEVICE", std::string(authenticateParams->getDevice().name.data())}}); } navBar->setText(nav_bar::Side::Center, utils::translate(style::strings::common::select)); auto hBox = new HBox(infoIcon, 0, 0, 0, 0); hBox->setMinimumSize(style::window::default_body_width, bluetooth::authenticate::buttons_input_h); hBox->setAlignment(Alignment(gui::Alignment::Horizontal::Center)); hBox->setEdges(RectangleEdge::None); hBox->setMargins({0, bluetooth::authenticate::option_box_top_margin, 0, 0}); auto createButton = [&](gui::bluetooth::authenticate::ButtonsOptions optionName) { Label *option = new Label(hBox, 0, 0, 0, 0, ""); if (optionName == gui::bluetooth::authenticate::ButtonsOptions::Pair) { option->setText(utils::translate("bluetooth_popup_confirm")); option->activatedCallback = [&](Item &) -> bool { application->bus.sendUnicast(std::make_shared( true, authenticateParams->getDevice()), service::name::bluetooth); return true; }; } else if (optionName == gui::bluetooth::authenticate::ButtonsOptions::Cancel) { option->setText(utils::translate("bluetooth_popup_cancel")); option->setMargins({0, 0, gui::bluetooth::authenticate::buttons_margin, 0}); option->activatedCallback = [=](Item &) -> bool { application->bus.sendUnicast(std::make_shared( false, authenticateParams->getDevice()), service::name::bluetooth); application->returnToPreviousWindow(); return true; }; } option->setMinimumSize(bluetooth::authenticate::buttons_input_w, bluetooth::authenticate::buttons_input_h); option->setPenWidth(0); option->setPenFocusWidth(3); option->setEdges(RectangleEdge::Bottom | RectangleEdge::Top); option->setFont(style::window::font::big); option->setAlignment(Alignment(gui::Alignment::Horizontal::Center, gui::Alignment::Vertical::Center)); return option; }; createButton(bluetooth::authenticate::Cancel); createButton(bluetooth::authenticate::Pair); infoIcon->resizeItems(); setFocusItem(hBox); } } // namespace gui