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