1a3e0fd82Sopenharmony_ci/* 2a3e0fd82Sopenharmony_ci * Copyright (c) 2020-2021 Huawei Device Co., Ltd. 3a3e0fd82Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4a3e0fd82Sopenharmony_ci * you may not use this file except in compliance with the License. 5a3e0fd82Sopenharmony_ci * You may obtain a copy of the License at 6a3e0fd82Sopenharmony_ci * 7a3e0fd82Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8a3e0fd82Sopenharmony_ci * 9a3e0fd82Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10a3e0fd82Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11a3e0fd82Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12a3e0fd82Sopenharmony_ci * See the License for the specific language governing permissions and 13a3e0fd82Sopenharmony_ci * limitations under the License. 14a3e0fd82Sopenharmony_ci */ 15a3e0fd82Sopenharmony_ci 16a3e0fd82Sopenharmony_ci#include "components/ui_toggle_button.h" 17a3e0fd82Sopenharmony_ci 18a3e0fd82Sopenharmony_ci#include "common/image.h" 19a3e0fd82Sopenharmony_ci#include "engines/gfx/gfx_engine_manager.h" 20a3e0fd82Sopenharmony_ci#include "imgdecode/cache_manager.h" 21a3e0fd82Sopenharmony_cinamespace { 22a3e0fd82Sopenharmony_ciconstexpr int16_t TOGGLE_BTN_WIDTH = 32; 23a3e0fd82Sopenharmony_ciconstexpr int16_t TOGGLE_BTN_CORNER_RADIUS = 11; 24a3e0fd82Sopenharmony_ciconstexpr int16_t TOGGLE_BTN_RADIUS_DIFF = 2; 25a3e0fd82Sopenharmony_ciconstexpr uint8_t TOGGLE_BTN_UNSELECTED_OPA = 97; 26a3e0fd82Sopenharmony_ci#if DEFAULT_ANIMATION 27a3e0fd82Sopenharmony_ciconstexpr int16_t DEFAULT_ANIMATOR_TIME = 150; 28a3e0fd82Sopenharmony_ciconstexpr float BEZIER_CONTROL_POINT_X_1 = 0.2; 29a3e0fd82Sopenharmony_ciconstexpr float BEZIER_CONTROL_POINT_X_2 = 0.2; 30a3e0fd82Sopenharmony_ci#endif 31a3e0fd82Sopenharmony_ci} // namespace 32a3e0fd82Sopenharmony_cinamespace OHOS { 33a3e0fd82Sopenharmony_ciUIToggleButton::UIToggleButton() 34a3e0fd82Sopenharmony_ci : corner_(TOGGLE_BTN_CORNER_RADIUS), 35a3e0fd82Sopenharmony_ci radius_(TOGGLE_BTN_CORNER_RADIUS - TOGGLE_BTN_RADIUS_DIFF), 36a3e0fd82Sopenharmony_ci rectWidth_(TOGGLE_BTN_WIDTH) 37a3e0fd82Sopenharmony_ci{ 38a3e0fd82Sopenharmony_ci backgroundOpacity_ = TOGGLE_BTN_UNSELECTED_OPA; 39a3e0fd82Sopenharmony_ci image_[UNSELECTED].SetSrc(""); 40a3e0fd82Sopenharmony_ci image_[SELECTED].SetSrc(""); 41a3e0fd82Sopenharmony_ci#if DEFAULT_ANIMATION 42a3e0fd82Sopenharmony_ci checkBoxAnimator_.SetTime(DEFAULT_ANIMATOR_TIME); 43a3e0fd82Sopenharmony_ci#endif 44a3e0fd82Sopenharmony_ci Resize(width_, height_); 45a3e0fd82Sopenharmony_ci} 46a3e0fd82Sopenharmony_ci 47a3e0fd82Sopenharmony_civoid UIToggleButton::SetState(bool state) 48a3e0fd82Sopenharmony_ci{ 49a3e0fd82Sopenharmony_ci if (state) { 50a3e0fd82Sopenharmony_ci UICheckBox::SetState(SELECTED); 51a3e0fd82Sopenharmony_ci } else { 52a3e0fd82Sopenharmony_ci UICheckBox::SetState(UNSELECTED); 53a3e0fd82Sopenharmony_ci } 54a3e0fd82Sopenharmony_ci Invalidate(); 55a3e0fd82Sopenharmony_ci} 56a3e0fd82Sopenharmony_ci 57a3e0fd82Sopenharmony_civoid UIToggleButton::CalculateSize() 58a3e0fd82Sopenharmony_ci{ 59a3e0fd82Sopenharmony_ci width_ = GetWidth(); 60a3e0fd82Sopenharmony_ci height_ = GetHeight(); 61a3e0fd82Sopenharmony_ci int16_t minValue = (width_ > height_) ? height_ : width_; 62a3e0fd82Sopenharmony_ci corner_ = TOGGLE_BTN_CORNER_RADIUS * minValue / DEFAULT_HOT_HEIGHT; 63a3e0fd82Sopenharmony_ci int16_t radiusDiff = TOGGLE_BTN_RADIUS_DIFF * minValue / DEFAULT_HOT_WIDTH; 64a3e0fd82Sopenharmony_ci radius_ = corner_ - radiusDiff; 65a3e0fd82Sopenharmony_ci rectWidth_ = TOGGLE_BTN_WIDTH * minValue / DEFAULT_HOT_WIDTH; 66a3e0fd82Sopenharmony_ci 67a3e0fd82Sopenharmony_ci Rect contentRect = GetContentRect(); 68a3e0fd82Sopenharmony_ci int16_t dx = (width_ - rectWidth_) / 2; // 2: half 69a3e0fd82Sopenharmony_ci int16_t dy = (height_ / 2) - corner_; // 2: half 70a3e0fd82Sopenharmony_ci int16_t x = contentRect.GetX() + dx; 71a3e0fd82Sopenharmony_ci int16_t y = contentRect.GetY() + dy; 72a3e0fd82Sopenharmony_ci leftCenter_ = {static_cast<int16_t>(x + corner_), static_cast<int16_t>(y + corner_)}; 73a3e0fd82Sopenharmony_ci rightCenter_ = {static_cast<int16_t>(x + rectWidth_ - corner_), static_cast<int16_t>(y + corner_)}; 74a3e0fd82Sopenharmony_ci#if DEFAULT_ANIMATION 75a3e0fd82Sopenharmony_ci if (checkBoxAnimator_.GetState() != Animator::START) { 76a3e0fd82Sopenharmony_ci if (IsRtl()) { 77a3e0fd82Sopenharmony_ci currentCenter_ = (state_ == SELECTED) ? leftCenter_ : rightCenter_; 78a3e0fd82Sopenharmony_ci } else { 79a3e0fd82Sopenharmony_ci currentCenter_ = (state_ == SELECTED) ? rightCenter_ : leftCenter_; 80a3e0fd82Sopenharmony_ci } 81a3e0fd82Sopenharmony_ci backgroundOpacity_ = (state_ == SELECTED) ? OPA_OPAQUE : TOGGLE_BTN_UNSELECTED_OPA; 82a3e0fd82Sopenharmony_ci bgColor_ = (state_ == SELECTED) ? selectedStateColor_ : Color::White(); 83a3e0fd82Sopenharmony_ci } 84a3e0fd82Sopenharmony_ci#else 85a3e0fd82Sopenharmony_ci if (IsRtl()) { 86a3e0fd82Sopenharmony_ci currentCenter_ = (state_ == SELECTED) ? leftCenter_ : rightCenter_; 87a3e0fd82Sopenharmony_ci } else { 88a3e0fd82Sopenharmony_ci currentCenter_ = (state_ == SELECTED) ? rightCenter_ : leftCenter_; 89a3e0fd82Sopenharmony_ci } 90a3e0fd82Sopenharmony_ci backgroundOpacity_ = (state_ == SELECTED) ? OPA_OPAQUE : TOGGLE_BTN_UNSELECTED_OPA; 91a3e0fd82Sopenharmony_ci bgColor_ = (state_ == SELECTED) ? selectedStateColor_ : Color::White(); 92a3e0fd82Sopenharmony_ci#endif 93a3e0fd82Sopenharmony_ci rectMid_.SetRect(x, y, x + rectWidth_, y + (corner_ << 1) + 1); 94a3e0fd82Sopenharmony_ci} 95a3e0fd82Sopenharmony_ci 96a3e0fd82Sopenharmony_civoid UIToggleButton::OnDraw(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea) 97a3e0fd82Sopenharmony_ci{ 98a3e0fd82Sopenharmony_ci if ((image_[SELECTED].GetSrcType() != IMG_SRC_UNKNOWN) && (image_[UNSELECTED].GetSrcType() != IMG_SRC_UNKNOWN)) { 99a3e0fd82Sopenharmony_ci UICheckBox::OnDraw(gfxDstBuffer, invalidatedArea); 100a3e0fd82Sopenharmony_ci } else { 101a3e0fd82Sopenharmony_ci CalculateSize(); 102a3e0fd82Sopenharmony_ci BaseGfxEngine* baseGfxEngine = BaseGfxEngine::GetInstance(); 103a3e0fd82Sopenharmony_ci baseGfxEngine->DrawRect(gfxDstBuffer, GetRect(), invalidatedArea, *style_, opaScale_); 104a3e0fd82Sopenharmony_ci Rect contentRect = GetContentRect(); 105a3e0fd82Sopenharmony_ci Rect trunc = invalidatedArea; 106a3e0fd82Sopenharmony_ci bool isIntersect = trunc.Intersect(trunc, contentRect); 107a3e0fd82Sopenharmony_ci if (!isIntersect) { 108a3e0fd82Sopenharmony_ci return; 109a3e0fd82Sopenharmony_ci } 110a3e0fd82Sopenharmony_ci Style styleUnSelect = StyleDefault::GetBackgroundTransparentStyle(); 111a3e0fd82Sopenharmony_ci styleUnSelect.bgColor_ = bgColor_; 112a3e0fd82Sopenharmony_ci styleUnSelect.bgOpa_ = backgroundOpacity_; 113a3e0fd82Sopenharmony_ci styleUnSelect.borderRadius_ = corner_; 114a3e0fd82Sopenharmony_ci baseGfxEngine->DrawRect(gfxDstBuffer, rectMid_, trunc, styleUnSelect, opaScale_); 115a3e0fd82Sopenharmony_ci ArcInfo arcInfoLeft = {currentCenter_, {0}, radius_, 0, CIRCLE_IN_DEGREE, nullptr}; 116a3e0fd82Sopenharmony_ci styleUnSelect.lineColor_ = Color::White(); 117a3e0fd82Sopenharmony_ci styleUnSelect.lineWidth_ = radius_; 118a3e0fd82Sopenharmony_ci baseGfxEngine->DrawArc(gfxDstBuffer, arcInfoLeft, trunc, styleUnSelect, OPA_OPAQUE, 119a3e0fd82Sopenharmony_ci CapType::CAP_NONE); 120a3e0fd82Sopenharmony_ci } 121a3e0fd82Sopenharmony_ci} 122a3e0fd82Sopenharmony_ci#if DEFAULT_ANIMATION 123a3e0fd82Sopenharmony_civoid UIToggleButton::Callback(UIView* view) 124a3e0fd82Sopenharmony_ci{ 125a3e0fd82Sopenharmony_ci runTime_ = checkBoxAnimator_.GetRunTime(); 126a3e0fd82Sopenharmony_ci float x = static_cast<float>(runTime_) / checkBoxAnimator_.GetTime(); 127a3e0fd82Sopenharmony_ci float coefficient = Interpolation::GetBezierY(x, BEZIER_CONTROL_POINT_X_1, 0, BEZIER_CONTROL_POINT_X_2, 1); 128a3e0fd82Sopenharmony_ci if (state_ == SELECTED) { 129a3e0fd82Sopenharmony_ci currentCenter_.y = rightCenter_.y; 130a3e0fd82Sopenharmony_ci if (IsRtl()) { 131a3e0fd82Sopenharmony_ci currentCenter_.x = rightCenter_.x - static_cast<uint16_t>((rightCenter_.x - leftCenter_.x) * coefficient); 132a3e0fd82Sopenharmony_ci } else { 133a3e0fd82Sopenharmony_ci currentCenter_.x = static_cast<int16_t>((rightCenter_.x - leftCenter_.x) * coefficient) + leftCenter_.x; 134a3e0fd82Sopenharmony_ci } 135a3e0fd82Sopenharmony_ci backgroundOpacity_ = 136a3e0fd82Sopenharmony_ci static_cast<uint8_t>(TOGGLE_BTN_UNSELECTED_OPA + (OPA_OPAQUE - TOGGLE_BTN_UNSELECTED_OPA) * coefficient); 137a3e0fd82Sopenharmony_ci bgColor_ = 138a3e0fd82Sopenharmony_ci Color::GetMixColor(selectedStateColor_, Color::White(), static_cast<uint8_t>(OPA_OPAQUE * coefficient)); 139a3e0fd82Sopenharmony_ci } else { 140a3e0fd82Sopenharmony_ci currentCenter_.y = leftCenter_.y; 141a3e0fd82Sopenharmony_ci if (IsRtl()) { 142a3e0fd82Sopenharmony_ci currentCenter_.x = static_cast<int16_t>((rightCenter_.x - leftCenter_.x) * coefficient) + leftCenter_.x; 143a3e0fd82Sopenharmony_ci } else { 144a3e0fd82Sopenharmony_ci currentCenter_.x = rightCenter_.x - static_cast<uint16_t>((rightCenter_.x - leftCenter_.x) * coefficient); 145a3e0fd82Sopenharmony_ci } 146a3e0fd82Sopenharmony_ci backgroundOpacity_ = static_cast<uint8_t>(OPA_OPAQUE - (OPA_OPAQUE - TOGGLE_BTN_UNSELECTED_OPA) * coefficient); 147a3e0fd82Sopenharmony_ci bgColor_ = Color::GetMixColor(selectedStateColor_, Color::White(), 148a3e0fd82Sopenharmony_ci static_cast<uint8_t>(OPA_OPAQUE * (1 - coefficient))); 149a3e0fd82Sopenharmony_ci } 150a3e0fd82Sopenharmony_ci Invalidate(); 151a3e0fd82Sopenharmony_ci} 152a3e0fd82Sopenharmony_ci 153a3e0fd82Sopenharmony_civoid UIToggleButton::OnStop(UIView& view) 154a3e0fd82Sopenharmony_ci{ 155a3e0fd82Sopenharmony_ci if (state_ == SELECTED) { 156a3e0fd82Sopenharmony_ci bgColor_ = selectedStateColor_; 157a3e0fd82Sopenharmony_ci } else { 158a3e0fd82Sopenharmony_ci bgColor_ = Color::White(); 159a3e0fd82Sopenharmony_ci } 160a3e0fd82Sopenharmony_ci backgroundOpacity_ = (state_ == SELECTED) ? OPA_OPAQUE : TOGGLE_BTN_UNSELECTED_OPA; 161a3e0fd82Sopenharmony_ci Invalidate(); 162a3e0fd82Sopenharmony_ci} 163a3e0fd82Sopenharmony_ci#endif 164a3e0fd82Sopenharmony_ci 165a3e0fd82Sopenharmony_civoid UIToggleButton::EnableRtl(bool isRtl) 166a3e0fd82Sopenharmony_ci{ 167a3e0fd82Sopenharmony_ci isRtl_ = isRtl; 168a3e0fd82Sopenharmony_ci} 169a3e0fd82Sopenharmony_ci 170a3e0fd82Sopenharmony_cibool UIToggleButton::IsRtl() 171a3e0fd82Sopenharmony_ci{ 172a3e0fd82Sopenharmony_ci return isRtl_; 173a3e0fd82Sopenharmony_ci} 174a3e0fd82Sopenharmony_ci} // namespace OHOS 175