1 /* 2 * Copyright (c) 2020-2021 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 #ifndef OHOS_ACELITE_EVENT_LISTENER_H 17 #define OHOS_ACELITE_EVENT_LISTENER_H 18 19 #include "ace_log.h" 20 #include "async_task_manager.h" 21 #include "event_util.h" 22 #include "js_fwk_common.h" 23 #include "keys.h" 24 #include "non_copyable.h" 25 #include "ui_checkbox.h" 26 #include "ui_list.h" 27 #include "ui_radio_button.h" 28 #include "ui_scroll_view.h" 29 #include "ui_slider.h" 30 #include "ui_toggle_button.h" 31 32 namespace OHOS { 33 namespace ACELite { 34 class StateChangeListener final : public UICheckBox::OnChangeListener { 35 public: 36 ACE_DISALLOW_COPY_AND_MOVE(StateChangeListener); StateChangeListener(jerry_value_t fn)37 StateChangeListener(jerry_value_t fn) 38 { 39 fn_ = jerry_acquire_value(fn); 40 isChanging_ = false; 41 state_ = false; 42 } 43 OnChange(UICheckBox::UICheckBoxState state)44 bool OnChange(UICheckBox::UICheckBoxState state) override 45 { 46 bool stateRes = (state == UICheckBox::UICheckBoxState::SELECTED); 47 if (stateRes == state_) { 48 return true; 49 } 50 state_ = stateRes; 51 if (isChanging_) { 52 return false; 53 } 54 isChanging_ = true; 55 jerry_value_t args[1]; 56 jerry_value_t resultProp = jerry_create_boolean(state_); 57 args[0] = jerry_create_object(); 58 const char * const checked = "checked"; 59 ReleaseJerryValue(jerryx_set_property_str(args[0], checked, resultProp), resultProp, VA_ARG_END_FLAG); 60 jerry_value_t globalObject = jerry_get_global_object(); 61 jerry_value_t appViewModel = jerryx_get_property_str(globalObject, ATTR_APP); 62 if (jerry_value_is_function(fn_)) { 63 CallJSFunctionAutoRelease(fn_, appViewModel, args, 1); 64 } 65 ReleaseJerryValue(globalObject, appViewModel, args[0], VA_ARG_END_FLAG); 66 isChanging_ = false; 67 return true; 68 } 69 SetState(bool state)70 void SetState(bool state) 71 { 72 state_ = state; 73 } 74 ~StateChangeListener()75 ~StateChangeListener() 76 { 77 jerry_release_value(fn_); 78 } 79 80 private: 81 jerry_value_t fn_; 82 bool state_; 83 bool isChanging_; // the flag to avoid change event cycle execute 84 }; 85 86 class ViewOnClickListener final : public UIView::OnClickListener { 87 public: 88 ACE_DISALLOW_COPY_AND_MOVE(ViewOnClickListener); 89 ViewOnClickListener(jerry_value_t vm,jerry_value_t fn,bool isStopPropagation)90 ViewOnClickListener(jerry_value_t vm, jerry_value_t fn, bool isStopPropagation) 91 : changeListener_(nullptr), 92 vm_(jerry_acquire_value(vm)), 93 fn_(jerry_acquire_value(fn)), 94 isStopPropagation_(isStopPropagation) {} 95 ~ViewOnClickListener()96 ~ViewOnClickListener() 97 { 98 AsyncTaskManager::GetInstance().CancelWithContext(this); 99 jerry_release_value(vm_); 100 jerry_release_value(fn_); 101 } 102 OnClick(UIView & view,const ClickEvent & event)103 bool OnClick(UIView& view, const ClickEvent &event) override 104 { 105 if (changeListener_) { 106 UICheckBox *checkbox = reinterpret_cast<UICheckBox *>(&view); 107 changeListener_->OnChange(checkbox->GetState()); 108 } 109 if (JSUndefined::Is(fn_)) { 110 return isStopPropagation_; 111 } 112 JSValue arg = EventUtil::CreateEvent(EventUtil::EVENT_CLICK, view, event); 113 EventUtil::InvokeCallback(vm_, fn_, arg, this); 114 115 return isStopPropagation_; 116 } 117 SetComponentListener(StateChangeListener * changeListener)118 void SetComponentListener(StateChangeListener *changeListener) 119 { 120 changeListener_ = changeListener; 121 } 122 123 private: 124 StateChangeListener *changeListener_; 125 jerry_value_t vm_; 126 jerry_value_t fn_; 127 bool isStopPropagation_; 128 }; 129 130 class ViewOnLongPressListener final : public UIView::OnLongPressListener { 131 public: 132 ACE_DISALLOW_COPY_AND_MOVE(ViewOnLongPressListener); ViewOnLongPressListener(jerry_value_t vm,jerry_value_t fn,bool isStopPropagation)133 ViewOnLongPressListener(jerry_value_t vm, jerry_value_t fn, bool isStopPropagation) 134 : vm_(jerry_acquire_value(vm)), fn_(jerry_acquire_value(fn)), isStopPropagation_(isStopPropagation) {} 135 ~ViewOnLongPressListener()136 ~ViewOnLongPressListener() 137 { 138 AsyncTaskManager::GetInstance().CancelWithContext(this); 139 jerry_release_value(vm_); 140 jerry_release_value(fn_); 141 } 142 OnLongPress(UIView & view,const LongPressEvent & event)143 bool OnLongPress(UIView& view, const LongPressEvent &event) override 144 { 145 if (jerry_value_is_undefined(fn_)) { 146 return isStopPropagation_; 147 } 148 149 JSValue arg = EventUtil::CreateEvent(EventUtil::EVENT_LONGPRESS, view, event); 150 EventUtil::InvokeCallback(vm_, fn_, arg, this); 151 152 return isStopPropagation_; 153 } 154 jerry_value_t vm_; 155 jerry_value_t fn_; 156 bool isStopPropagation_; 157 }; 158 159 #ifdef JS_EXTRA_EVENT_SUPPORT 160 161 class KeyBoardEventListener final : public RootView::OnKeyActListener { 162 public: 163 ACE_DISALLOW_COPY_AND_MOVE(KeyBoardEventListener); 164 KeyBoardEventListener(jerry_value_t fn, const uint16_t id); 165 ~KeyBoardEventListener(); 166 bool OnKeyAct(UIView &view, const KeyEvent &event) override; 167 168 private: 169 jerry_value_t fn_; 170 uint16_t id_; 171 }; 172 #endif 173 174 class ViewOnTouchListener final : public UIView::OnDragListener { 175 public: 176 ACE_DISALLOW_COPY_AND_MOVE(ViewOnTouchListener); ViewOnTouchListener(jerry_value_t vm,bool isStopPropagation)177 ViewOnTouchListener(jerry_value_t vm, bool isStopPropagation) 178 : vm_(jerry_acquire_value(vm)), 179 bindTouchStartFunc_(UNDEFINED), 180 bindTouchMoveFunc_(UNDEFINED), 181 bindTouchEndFunc_(UNDEFINED), 182 bindSwipeFunc_(UNDEFINED), 183 isStopPropagation_(isStopPropagation) 184 { 185 } 186 ~ViewOnTouchListener()187 ~ViewOnTouchListener() 188 { 189 AsyncTaskManager::GetInstance().CancelWithContext(this); 190 jerry_release_value(vm_); 191 jerry_release_value(bindTouchStartFunc_); 192 jerry_release_value(bindTouchMoveFunc_); 193 jerry_release_value(bindTouchEndFunc_); 194 jerry_release_value(bindSwipeFunc_); 195 } 196 197 void SetStopPropagation(bool isStopPropogation); 198 bool OnDragStart(UIView& view, const DragEvent& event) override; 199 bool OnDrag(UIView& view, const DragEvent& event) override; 200 bool OnDragEnd(UIView& view, const DragEvent &event) override; 201 void SetBindTouchStartFuncName(jerry_value_t bindTouchStartFunc); 202 void SetBindTouchMoveFuncName(jerry_value_t bindTouchMoveFunc); 203 void SetBindTouchEndFuncName(jerry_value_t bindTouchEndFunc); 204 void SetBindSwipeFuncName(jerry_value_t bindSwipeFunc); 205 206 private: 207 jerry_value_t vm_; 208 jerry_value_t bindTouchStartFunc_; 209 jerry_value_t bindTouchMoveFunc_; 210 jerry_value_t bindTouchEndFunc_; 211 jerry_value_t bindSwipeFunc_; 212 bool isStopPropagation_; 213 }; 214 215 class SliderEventListener final : public UISlider::UISliderEventListener { 216 public: 217 ACE_DISALLOW_COPY_AND_MOVE(SliderEventListener); SliderEventListener()218 SliderEventListener() : bindChangeFunc_(UNDEFINED) {} ~SliderEventListener()219 ~SliderEventListener() 220 { 221 jerry_release_value(bindChangeFunc_); 222 } OnChange(int32_t progress)223 void OnChange(int32_t progress) override 224 { 225 jerry_value_t knobValue = jerry_create_number(progress); 226 jerry_value_t args[1]; 227 args[0] = jerry_create_object(); 228 jerry_value_t result1 = jerryx_set_property_str(args[0], "value", knobValue); 229 // progress will be deprecated in next versions. 230 jerry_value_t result2 = jerryx_set_property_str(args[0], "progress", knobValue); 231 if (!jerry_value_is_error(result1) && !jerry_value_is_error(result2)) { 232 CallJSFunctionAutoRelease(bindChangeFunc_, UNDEFINED, args, 1); 233 } 234 ReleaseJerryValue(result1, result2, args[0], knobValue, VA_ARG_END_FLAG); 235 } 236 SetBindChangeFuncName(jerry_value_t bindChageFunc)237 void SetBindChangeFuncName(jerry_value_t bindChageFunc) 238 { 239 bindChangeFunc_ = jerry_acquire_value(bindChageFunc); 240 } 241 242 private: 243 jerry_value_t bindChangeFunc_; 244 }; 245 246 class ListEventListener final : public ListScrollListener { 247 public: 248 ACE_DISALLOW_COPY_AND_MOVE(ListEventListener); ListEventListener()249 ListEventListener() 250 : bindScrollStartFunc_(UNDEFINED), 251 bindScrollEndFunc_(UNDEFINED), 252 bindScrollSelectedFunc_(UNDEFINED), 253 bindScrollTopFunc_(UNDEFINED), 254 bindScrollBottomFunc_(UNDEFINED) 255 { 256 } ~ListEventListener()257 ~ListEventListener() 258 { 259 ReleaseJerryValue(bindScrollStartFunc_, bindScrollEndFunc_, bindScrollSelectedFunc_, bindScrollTopFunc_, 260 bindScrollBottomFunc_, VA_ARG_END_FLAG); 261 } 262 EventExcute(const int16_t index,jerry_value_t bindScrollFunc)263 void EventExcute(const int16_t index, jerry_value_t bindScrollFunc) const 264 { 265 if (IS_UNDEFINED(bindScrollFunc)) { 266 return; 267 } 268 269 int8_t currentState = this->GetScrollState(); 270 jerry_value_t currentStateValue = jerry_create_number(currentState); 271 jerry_value_t componentIndex = jerry_create_number(index); 272 jerry_value_t args[ARGS_LEN] = {currentStateValue, componentIndex}; 273 CallJSFunctionAutoRelease(bindScrollFunc, UNDEFINED, args, ARGS_LEN); 274 ReleaseJerryValue(currentStateValue, componentIndex, VA_ARG_END_FLAG); 275 } 276 277 // list specific event switch 278 #ifdef FEATURE_LIST_SPECIFIC_EVENT_ENABLE OnScrollStart(int16_t index,UIView * view)279 void OnScrollStart(int16_t index, UIView *view) override 280 { 281 EventExcute(index, bindScrollStartFunc_); 282 } OnItemSelected(int16_t index,UIView * view)283 void OnItemSelected(int16_t index, UIView *view) override 284 { 285 EventExcute(index, bindScrollSelectedFunc_); 286 } SetBindScrollStartFuncName(jerry_value_t bindScrollStartFunc)287 void SetBindScrollStartFuncName(jerry_value_t bindScrollStartFunc) 288 { 289 if (!jerry_value_is_undefined(bindScrollStartFunc)) { 290 bindScrollStartFunc_ = jerry_acquire_value(bindScrollStartFunc); 291 } 292 } SetBindScrollItemSelectedFuncName(jerry_value_t bindScrollItemSelectedFunc)293 void SetBindScrollItemSelectedFuncName(jerry_value_t bindScrollItemSelectedFunc) 294 { 295 if (!jerry_value_is_undefined(bindScrollItemSelectedFunc)) { 296 bindScrollSelectedFunc_ = jerry_acquire_value(bindScrollItemSelectedFunc); 297 } 298 } 299 #endif // FEATURE_LIST_SPECIFIC_EVENT_ENABLE 300 OnScrollEnd(int16_t index,UIView * view)301 void OnScrollEnd(int16_t index, UIView* view) override 302 { 303 EventExcute(index, bindScrollEndFunc_); 304 } 305 SetBindScrollEndFuncName(jerry_value_t bindScrollEndFunc)306 void SetBindScrollEndFuncName(jerry_value_t bindScrollEndFunc) 307 { 308 if (!jerry_value_is_undefined(bindScrollEndFunc)) { 309 bindScrollEndFunc_ = jerry_acquire_value(bindScrollEndFunc); 310 } 311 } 312 OnScrollTop(int16_t index,UIView * view)313 void OnScrollTop(int16_t index, UIView* view) override 314 { 315 EventExcute(index, bindScrollTopFunc_); 316 } 317 SetBindScrollTopFuncName(jerry_value_t bindScrollTopFunc)318 void SetBindScrollTopFuncName(jerry_value_t bindScrollTopFunc) 319 { 320 if (!jerry_value_is_undefined(bindScrollTopFunc)) { 321 bindScrollTopFunc_ = jerry_acquire_value(bindScrollTopFunc); 322 } 323 } 324 OnScrollBottom(int16_t index,UIView * view)325 void OnScrollBottom(int16_t index, UIView* view) override 326 { 327 EventExcute(index, bindScrollBottomFunc_); 328 } 329 SetBindScrollBottomFuncName(jerry_value_t bindScrollBottomFunc)330 void SetBindScrollBottomFuncName(jerry_value_t bindScrollBottomFunc) 331 { 332 if (!jerry_value_is_undefined(bindScrollBottomFunc)) { 333 bindScrollBottomFunc_ = jerry_acquire_value(bindScrollBottomFunc); 334 } 335 } 336 337 private: 338 static constexpr int8_t ARGS_LEN = 2; 339 jerry_value_t bindScrollStartFunc_; 340 jerry_value_t bindScrollEndFunc_; 341 jerry_value_t bindScrollSelectedFunc_; 342 jerry_value_t bindScrollTopFunc_; 343 jerry_value_t bindScrollBottomFunc_; 344 }; 345 } // namespace ACELite 346 } // namespace OHOS 347 #endif // OHOS_ACELITE_EVENT_LISTENER_H 348