/* * Copyright (c) 2021 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "frameworks/bridge/common/dom/dom_calendar.h" #include "frameworks/bridge/common/utils/utils.h" namespace OHOS::Ace::Framework { namespace { constexpr uint32_t METHOD_GO_TO_ARGS_SIZE = 1; const char GO_TO_ARG_KEY_YEAR[] = "year"; const char GO_TO_ARG_KEY_MONTH[] = "month"; const char GO_TO_ARG_KEY_DAY[] = "day"; } // namespace DomCalendar::DomCalendar(NodeId nodeId, const std::string& nodeName) : DOMNode(nodeId, nodeName), calendarComponent_(AceType::MakeRefPtr(std::to_string(nodeId), nodeName)) { if (IsRightToLeft()) { calendarComponent_->SetTextDirection(TextDirection::RTL); } } bool DomCalendar::SetSpecializedAttr(const std::pair& attr) { static const LinearMapNode calendarAttrOperators[] = { { DOM_CALENDAR_DATA, [](const std::string& value, DomCalendar& calendar) { calendar.calendarComponent_->SetCalendarData(value); return true; } }, { DOM_CALENDAR_CARD_CALENDAR, [](const std::string& value, DomCalendar& calendar) { calendar.calendarComponent_->SetCardCalendar(StringToBool(value)); return true; } }, { DOM_CALENDAR_DATE, [](const std::string& value, DomCalendar& calendar) { CalendarDay day; auto isLegal = StringUtils::StringToCalendarDay(value, day); if (isLegal) { calendar.calendarComponent_->SetCalendarDate(day); return true; } return false; } }, { DOM_CALENDAR_DATE_ADAPTER, [](const std::string& value, DomCalendar& calendar) { return calendar.ParseDataAdapter(value); } }, { DOM_CALENDAR_DIRECTION, [](const std::string& value, DomCalendar& calendar) { if (value == "vertical") { calendar.calendarComponent_->SetAxis(Axis::VERTICAL); } else if (value == "horizontal") { calendar.calendarComponent_->SetAxis(Axis::HORIZONTAL); } else { LOGW("input do not match any direction"); } return true; } }, { DOM_CALENDAR_HOLIDAYS, [](const std::string& value, DomCalendar& calendar) { calendar.calendarComponent_->SetHolidays(value); return true; } }, { DOM_CALENDAR_OFF_DAYS, [](const std::string& value, DomCalendar& calendar) { calendar.calendarComponent_->SetOffDays(value); return true; } }, { DOM_CALENDAR_SHOW_HOLIDAY, [](const std::string& value, DomCalendar& calendar) { calendar.calendarComponent_->SetShowHoliday(StringToBool(value)); return true; } }, { DOM_CALENDAR_SHOW_LUNAR, [](const std::string& value, DomCalendar& calendar) { calendar.calendarComponent_->SetShowLunar(StringToBool(value)); return true; } }, { DOM_CALENDAR_START_DAY_OF_WEEK, [](const std::string& value, DomCalendar& calendar) { auto indexOfWeek = StringToInt(value); if (0 <= indexOfWeek && indexOfWeek < 7) { calendar.calendarComponent_->SetStartDayOfWeek(indexOfWeek); return true; } return false; } }, { DOM_CALENDAR_TYPE, [](const std::string& value, DomCalendar& calendar) { if (value == "normal") { calendar.calendarComponent_->SetCalendarType(CalendarType::NORMAL); } else if (value == "simple") { calendar.calendarComponent_->SetCalendarType(CalendarType::SIMPLE); } return true; } }, { DOM_CALENDAR_WORK_DAYS, [](const std::string& value, DomCalendar& calendar) { calendar.calendarComponent_->SetWorkDays(value); return true; } }, }; auto operatorIter = BinarySearchFindIndex(calendarAttrOperators, ArraySize(calendarAttrOperators), attr.first.c_str()); if (operatorIter != -1) { return calendarAttrOperators[operatorIter].value(attr.second, *this); } return false; } void DomCalendar::CallSpecializedMethod(const std::string& method, const std::string& args) { if (method == DOM_CALENDAR_METHOD_GO_TO) { HandleGoTo(args); } } bool DomCalendar::AddSpecializedEvent(int32_t pageId, const std::string& event) { if (event == DOM_CALENDAR_EVENT_SELECTED_CHANGE) { selectedChangeEvent_ = EventMarker(GetNodeIdForEvent(), event, pageId); calendarComponent_->SetSelectedChangeEvent(selectedChangeEvent_); return true; } else if (event == DOM_CALENDAR_EVENT_REQUEST_DATA) { requestDataEvent_ = EventMarker(GetNodeIdForEvent(), event, pageId); calendarComponent_->SetRequestDataEvent(requestDataEvent_); return true; } return false; } bool DomCalendar::ParseDataAdapter(const std::string& value) { std::unique_ptr dataAdapterValue = JsonUtil::ParseJsonString(value); if (!dataAdapterValue) { return false; } std::unique_ptr bundleNameValue = dataAdapterValue->GetValue("bundleName"); if (!bundleNameValue || !bundleNameValue->IsString()) { return false; } std::unique_ptr abilityNameValue = dataAdapterValue->GetValue("abilityName"); if (!abilityNameValue || !abilityNameValue->IsString()) { return false; } std::unique_ptr messageCodeValue = dataAdapterValue->GetValue("messageCode"); if (!messageCodeValue || !messageCodeValue->IsNumber()) { return false; } std::string bundleName = bundleNameValue->GetString(); std::string abilityName = abilityNameValue->GetString(); int32_t messageCode = messageCodeValue->GetInt(); CalendarDataAdapterAction dataAdapterAction { { .bundleName = bundleName, .abilityName = abilityName, .messageCode = messageCode } }; calendarComponent_->SetDataAdapterAction(dataAdapterAction); return true; } void DomCalendar::HandleGoTo(const std::string& args) { std::unique_ptr argsValue = JsonUtil::ParseJsonString(args); if (!argsValue || !argsValue->IsArray() || argsValue->GetArraySize() != METHOD_GO_TO_ARGS_SIZE) { return; } auto gotoArg = argsValue->GetArrayItem(0); if (!gotoArg || !gotoArg->Contains(GO_TO_ARG_KEY_YEAR) || !gotoArg->Contains(GO_TO_ARG_KEY_MONTH)) { return; } std::unique_ptr yearValue = gotoArg->GetValue(GO_TO_ARG_KEY_YEAR); if (!yearValue || !yearValue->IsNumber()) { return; } std::unique_ptr monthValue = gotoArg->GetValue(GO_TO_ARG_KEY_MONTH); if (!monthValue || !monthValue->IsNumber()) { return; } int32_t year = yearValue->GetInt(); int32_t month = monthValue->GetInt(); // default selected first day of month int32_t day = -1; std::unique_ptr dayValue = gotoArg->GetValue(GO_TO_ARG_KEY_DAY); if (dayValue && dayValue->IsNumber()) { day = dayValue->GetInt(); } calendarComponent_->GoTo(year, month, day); } bool DomCalendar::SetSpecializedStyle(const std::pair& style) { static const LinearMapNode calendarStyleOperators[] = { { "boundaryColumnOffset", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.boundaryColOffset = node.ParseDimension(value); } }, { "boundaryRowOffset", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.boundaryRowOffset = node.ParseDimension(value); } }, { "columnSpace", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.colSpace = node.ParseDimension(value); } }, { "dailyFiveRowSpace", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.dailyFiveRowSpace = node.ParseDimension(value); } }, { "dailySixRowSpace", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.dailySixRowSpace = node.ParseDimension(value); } }, { "dayColor", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.dayColor = node.ParseColor(value); } }, { "dayFontSize", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.dayFontSize = node.ParseDimension(value); } }, { "dayHeight", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.dayHeight = node.ParseDimension(value); } }, { "dayWidth", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.dayWidth = node.ParseDimension(value); } }, { "dayYAxisOffset", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.dayYAxisOffset = node.ParseDimension(value); } }, { "focusedAreaBackgroundColor", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.focusedAreaBackgroundColor = node.ParseColor(value); } }, { "focusedAreaRadius", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.focusedAreaRadius = node.ParseDimension(value); } }, { "focusedDayColor", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.focusedDayColor = node.ParseColor(value); } }, { "focusedLunarColor", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.focusedLunarColor = node.ParseColor(value); } }, { "gregorianCalendarHeight", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.gregorianCalendarHeight = node.ParseDimension(value); } }, { "lunarColor", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.lunarColor = node.ParseColor(value); } }, { "lunarDayFontSize", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.lunarDayFontSize = node.ParseDimension(value); } }, { "lunarDayYAxisOffset", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.lunarDayYAxisOffset = node.ParseDimension(value); } }, { "lunarHeight", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.lunarHeight = node.ParseDimension(value); } }, { "markLunarColor", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.markLunarColor = node.ParseColor(value); } }, { "nonCurrentMonthDayColor", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.nonCurrentMonthDayColor = node.ParseColor(value); } }, { "nonCurrentMonthLunarColor", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.nonCurrentMonthLunarColor = node.ParseColor(value); } }, { "nonCurrentMonthOffDayMarkColor", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.nonCurrentMonthOffDayMarkColor = node.ParseColor(value); } }, { "nonCurrentMonthWorkDayMarkColor", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.nonCurrentMonthWorkDayMarkColor = node.ParseColor(value); } }, { "offDayMarkColor", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.offDayMarkColor = node.ParseColor(value); } }, { "offDayMarkSize", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.offDayMarkSize = node.ParseDimension(value); } }, { "scheduleMarkerRadius", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.scheduleMarkerRadius = node.ParseDimension(value); } }, { "scheduleMarkerXAxisOffset", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.scheduleMarkerXAxisOffset = node.ParseDimension(value); } }, { "scheduleMarkerYAxisOffset", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.scheduleMarkerYAxisOffset = node.ParseDimension(value); } }, { "simpleOffTextColor", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.simpleOffTextColor = node.ParseColor(value); } }, { "simpleWorkTextColor", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.simpleWorkTextColor = node.ParseColor(value); } }, { "underscoreLength", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.underscoreLength = node.ParseDimension(value); } }, { "underscoreWidth", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.underscoreWidth = node.ParseDimension(value); } }, { "underscoreXAxisOffset", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.underscoreXAxisOffset = node.ParseDimension(value); } }, { "underscoreYAxisOffset", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.underscoreYAxisOffset = node.ParseDimension(value); } }, { "weekAndDayRowSpace", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.weekAndDayRowSpace = node.ParseDimension(value); } }, { "weekColor", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.weekColor = node.ParseColor(value); } }, { "weekFontSize", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.weekFontSize = node.ParseDimension(value); } }, { "weekHeight", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.weekHeight = node.ParseDimension(value); } }, { "weekWidth", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.weekWidth = node.ParseDimension(value); } }, { "weekendDayColor", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.weekendDayColor = node.ParseColor(value); } }, { "weekendLunarColor", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.weekendLunarColor = node.ParseColor(value); } }, { "workDayMarkColor", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.workDayMarkColor = node.ParseColor(value); } }, { "workDayMarkSize", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.workDayMarkSize = node.ParseDimension(value); } }, { "workStateHorizontalMovingDistance", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.workStateHorizontalMovingDistance = node.ParseDimension(value); } }, { "workStateOffset", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.workStateOffset = node.ParseDimension(value); } }, { "workStateVerticalMovingDistance", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.workStateVerticalMovingDistance = node.ParseDimension(value); } }, { "workStateWidth", [](const std::string& value, CalendarThemeStructure& theme, const DomCalendar& node) { theme.workStateWidth = node.ParseDimension(value); } }, }; auto context = GetPipelineContext().Upgrade(); if (!context) { return false; } auto theme = calendarComponent_->GetCalendarTheme(); if (!theme) { theme = GetTheme(); calendarComponent_->SetCalendarTheme(theme); } auto operatorIter = BinarySearchFindIndex(calendarStyleOperators, ArraySize(calendarStyleOperators), style.first.c_str()); if (operatorIter != -1) { auto& calendarTheme = context->IsJsCard() ? theme->GetCardCalendarTheme() : theme->GetCalendarTheme(); calendarStyleOperators[operatorIter].value(style.second, calendarTheme, *this); return true; } return false; } } // namespace OHOS::Ace::Framework