1 /* 2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #include "core/components/button/button_element.h" 17 18 #include "frameworks/core/common/container.h" 19 20 namespace OHOS::Ace { 21 CreateRenderNode()22RefPtr<RenderNode> ButtonElement::CreateRenderNode() 23 { 24 RefPtr<RenderNode> node = ComponentGroupElement::CreateRenderNode(); 25 if (node) { 26 auto wp = AceType::WeakClaim(this); 27 node->SetOnChangeCallback([wp]() { 28 auto button = wp.Upgrade(); 29 if (button) { 30 button->OnChange(); 31 } 32 }); 33 } 34 return node; 35 } 36 Update()37void ButtonElement::Update() 38 { 39 RenderElement::Update(); 40 41 button_ = AceType::DynamicCast<RenderButton>(renderNode_); 42 auto buttonComponent = AceType::DynamicCast<ButtonComponent>(component_); 43 if (buttonComponent) { 44 SetFocusable(!buttonComponent->GetDisabledState() && buttonComponent->GetFocusable()); 45 } 46 47 auto labelTarget = AceType::DynamicCast<LabelTarget>(component_); 48 if (!labelTarget) { 49 // switch is not label target, button are label target 50 LOGW("not find label target"); 51 return; 52 } 53 auto trigger = labelTarget->GetTrigger(); 54 if (!trigger) { 55 // component not set label trigger 56 LOGW("get label trigger failed"); 57 return; 58 } 59 60 auto weak = AceType::WeakClaim(this); 61 trigger->clickHandler_ = [weak]() { 62 auto button = weak.Upgrade(); 63 if (button) { 64 button->OnClick(); 65 } 66 }; 67 } 68 LocalizedUpdate()69void ButtonElement::LocalizedUpdate() 70 { 71 Update(); 72 auto buttonComponent = AceType::DynamicCast<ButtonComponent>(component_); 73 74 if (Container::IsCurrentUsePartialUpdate() && buttonComponent->GetHasCustomChild()) { 75 // in partial update code path a custom child updates independently 76 return; 77 } 78 ComponentGroupElement::UpdateChildrenForDeclarative(buttonComponent->GetChildren()); 79 } 80 Apply(const RefPtr<Element> & child)81void ButtonElement::Apply(const RefPtr<Element>& child) 82 { 83 RenderElement::Apply(child); 84 auto buttonComponent = AceType::DynamicCast<ButtonComponent>(component_); 85 if (!buttonComponent) { 86 return; 87 } 88 if (buttonComponent->GetAutoFocusState()) { 89 auto wp = AceType::WeakClaim(this); 90 auto buttonElement = wp.Upgrade(); 91 if (!buttonElement) { 92 return; 93 } 94 95 buttonElement->RequestFocus(); 96 } 97 } 98 OnFocus()99void ButtonElement::OnFocus() 100 { 101 if (!button_) { 102 return; 103 } 104 button_->HandleFocusEvent(true); 105 button_->PlayFocusAnimation(true); 106 auto context = context_.Upgrade(); 107 if (context && context->GetIsTabKeyPressed()) { 108 button_->ChangeStatus(RenderStatus::FOCUS); 109 } 110 } 111 OnClick()112void ButtonElement::OnClick() 113 { 114 if (!button_) { 115 return; 116 } 117 button_->HandleClickEvent(); 118 button_->HandleKeyEnterEvent(); 119 } 120 OnClick(const KeyEvent & event)121bool ButtonElement::OnClick(const KeyEvent& event) 122 { 123 if (!button_) { 124 return false; 125 } 126 ClickInfo info(-1); 127 info.SetTimeStamp(event.timeStamp); 128 info.SetGlobalLocation( 129 Offset((GetRect().Left() + GetRect().Right()) / 2, (GetRect().Top() + GetRect().Bottom()) / 2)); 130 info.SetLocalLocation( 131 Offset((GetRect().Right() - GetRect().Left()) / 2, (GetRect().Bottom() - GetRect().Top()) / 2)); 132 info.SetSourceDevice(event.sourceType); 133 info.SetDeviceId(event.deviceId); 134 button_->HandleClickEvent(info); 135 return button_->HandleKeyEnterEvent(info); 136 } 137 OnBlur()138void ButtonElement::OnBlur() 139 { 140 if (!button_) { 141 return; 142 } 143 button_->HandleFocusEvent(false); 144 button_->PlayFocusAnimation(false); 145 auto context = context_.Upgrade(); 146 if (!context) { 147 LOGE("Pipeline context is nullptr"); 148 return; 149 } 150 if (context->GetIsTabKeyPressed()) { 151 button_->ChangeStatus(RenderStatus::BLUR); 152 } 153 context->CancelFocusAnimation(); 154 context->CancelShadow(); 155 } 156 OnChange()157void ButtonElement::OnChange() 158 { 159 if (button_ && IsCurrentFocus()) { 160 button_->DisplayFocusAnimation(); 161 } 162 } 163 164 } // namespace OHOS::Ace 165