// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/blob/master/LICENSE.md #include "ApplicationMessages.hpp" #include "MessagesStyle.hpp" #include #include #include #include #include #include #include #include #include namespace gui { SMSInputWidget::SMSInputWidget(app::ApplicationCommon *application) : application(application) { setMinimumSize(style::window::default_body_width, style::messages::smsInput::min_h); setMargins(Margins( style::messages::smsInput::new_sms_left_margin, style::messages::smsInput::new_sms_vertical_spacer, 0, 0)); setEdges(gui::RectangleEdge::None); body = new HBox(this, 0, 0, 0, 0); body->setEdges(RectangleEdge::Bottom); body->setMaximumSize(style::window::default_body_width, style::messages::smsInput::max_input_h); deleteByList = false; inputText = new gui::Text(body, 0, 0, 0, 0, ExpandMode::Up); inputText->setMaximumSize(style::messages::smsInput::default_input_w, style::messages::smsInput::max_input_h); inputText->setMinimumSize(style::messages::smsInput::default_input_w, style::messages::smsInput::default_input_h); inputText->setTextLimitType(gui::TextLimitType::MaxSignsCount, msgConstants::maxConcatenatedLen); inputText->setFont(style::window::font::medium); inputText->setPadding(Padding(0, 0, 0, style::messages::smsInput::bottom_padding)); inputText->setPenFocusWidth(style::window::default_border_focus_w); inputText->setPenWidth(style::window::default_border_focus_w); inputText->setEdges(gui::RectangleEdge::None); replyImage = new Image(body, 0, 0, "messages_reply_32px_W_M"); replyImage->setAlignment(Alignment(gui::Alignment::Vertical::Bottom)); replyImage->setMargins(Margins(0, 0, 0, style::messages::smsInput::reply_bottom_margin)); replyImage->activeItem = false; inputCallback = [&]([[maybe_unused]] Item &item, const InputEvent &event) { return inputText->onInput(event); }; focusChangedCallback = [this]([[maybe_unused]] Item &item) { setFocusItem(focus ? body : nullptr); return true; }; inputText->setInputMode(new InputMode( {InputMode::Abc, InputMode::ABC, InputMode::abc, InputMode::digit}, [=](const UTF8 &Text) { application->getCurrentWindow()->navBarTemporaryMode(Text); }, [=]() { application->getCurrentWindow()->navBarRestoreFromTemporaryMode(); }, [=]() { application->getCurrentWindow()->selectSpecialCharacter(); }, [=](std::function restoreFunction) { application->getCurrentWindow()->startInputModeRestoreTimer(std::move(restoreFunction)); })); inputText->inputCallback = [this, application]([[maybe_unused]] Item &, const InputEvent &event) { if (event.isShortRelease(KeyCode::KEY_LF)) { auto app = dynamic_cast(application); assert(app != nullptr); return app->newMessageOptions(application->getCurrentWindow()->getName(), inputText); } return false; }; inputText->focusChangedCallback = [this, application]([[maybe_unused]] Item &) -> bool { assert(body != nullptr); assert(application != nullptr); const auto threadViewWindow = application->getWindow(gui::name::window::thread_view); if (inputText->focus) { inputText->setCursorStartPosition(CursorStartPosition::DocumentEnd); threadViewWindow->setNavBarText(utils::translate(utils::translate(style::strings::common::send)), nav_bar::Side::Center); } else { threadViewWindow->setNavBarText(utils::translate(style::strings::common::reply), nav_bar::Side::Center); } return true; }; dimensionChangedCallback = [&](gui::Item &, const BoundingBox &newDim) -> bool { if (newDim.w == style::listview::item_width_with_scroll - style::messages::smsInput::new_sms_left_margin) { inputText->setMinimumWidth(style::messages::smsInput::default_input_w); inputText->setMaximumWidth(style::messages::smsInput::default_input_w); } else { inputText->setMinimumWidth(style::messages::smsInput::default_input_w + style::listview::scroll::item_margin); inputText->setMaximumWidth(style::messages::smsInput::default_input_w + style::listview::scroll::item_margin); } body->setArea({0, 0, newDim.w, newDim.h}); return true; }; } void SMSInputWidget::handleDraftMessage() { const auto &text = inputText->getText(); text.empty() ? clearDraftMessage() : updateDraftMessage(text); } void SMSInputWidget::clearDraftMessage() { if (!draft.has_value()) { displayDraftMessage(); return; } auto app = dynamic_cast(application); assert(app != nullptr); if (const auto removed = app->removeDraft(draft.value()); removed) { draft = std::nullopt; displayDraftMessage(); } } void SMSInputWidget::displayDraftMessage() const { if (draft.has_value()) { inputText->setText(draft->body); } else { inputText->clear(); } } void SMSInputWidget::updateDraftMessage(const UTF8 &inputText) { auto app = dynamic_cast(application); assert(app != nullptr); assert(number != nullptr); if (draft.has_value()) { app->updateDraft(draft.value(), inputText); } else { app->createDraft(*number, inputText, [this](const SMSRecord &record) { draft = record; }); } } auto SMSInputWidget::handleRequestResize([[maybe_unused]] const Item *child, Length request_w, Length request_h) -> Size { request_h = std::clamp((Length)request_h, style::messages::smsInput::min_h, style::messages::smsInput::max_input_h); setMinimumHeight(request_h); if (parent != nullptr) { requestSize(request_w, request_h); } return Size(request_w, request_h); } } /* namespace gui */